Skip to content

Reject repeated primary-call terminals in redrive evidence - #310

Merged
rmcdaniel merged 2 commits into
mainfrom
fix/250-terminal-ledger
Nov 5, 2026
Merged

rmcdaniel merged 2 commits into
mainfrom
fix/250-terminal-ledger

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

The redrive successor evidence helper returns after its first matching resolution. A prior call can therefore have contradictory or identical terminal rows and still count as resolved/reachable. Add an independent closed-call ledger across the whole successor history, while keeping prior-call reachability limited to rows before cancellation delivery.

Only two test/evidence files change. The ledger applies the existing exact family, workflow step, resource identity, remote/local mode and plain-timer kind checks before closing a claimed call. A second matching remote/local activity, plain-timer or primary SignalApplied terminal is refused before or after delivery, for recorded or next-step delivery, and in histories without cancellation. A later-only resolution still cannot establish earlier reachability. The same predicate serves reachability and uniqueness.

Backing timer and wait-specific rows can describe one outcome. They are not counted as separate primary closures. Eighteen positive controls preserve condition-satisfied + timer-cancelled, condition-timed-out + timer-fired and signal-applied + timer-cancelled across three opener layouts, both before delivery and split across it. Backed-wait outcome combinations and child closure retain existing presence/identity bounds; no generalized outcome interpreter, service/group/scope/selection support or Core/runtime change is claimed.

Validation on PHP 8.4.27 / PHPUnit 11.5.57:

  • All 219 new controls pass within the 690-test / 1,586-assertion focused strictness, successor-evidence, reused-replay and official corpus suite, with zero failures/errors/skips.
  • The exact accepted-main helper blob 3a1a5f560b5d729079e0f90c7786f498c0a75057 fails 147 controls and passes 72. The held d36f0856 helper fails 129 and passes 90; both comparisons have zero errors/skips. Each multiplicity probe first proves its valid one-terminal positive.
  • The post-delivery matrix covers every ordered primary terminal pair: 4×4 remote activity, 4×4 local activity, 2×2 plain timer and 1×1 untimed signal, across next-step delivery, recorded delivery and no-cancellation boundaries. Foreign resources, steps, modes and timeout kinds cannot change closed state; a duplicate after a distractor remains refused.
  • All 67 old replay/successor-shape documents retain exact verdicts and diagnostic strings across 13 prefix choices: 871 comparisons, predecessor/candidate SHA-256 f9d72d7cb511a64364217f7214c56803ad016d170a19b118d05bfb48448881e4. Every fixture blob is unchanged.
  • Single-process PHPStan level 6 passes both changed files. Whitespace and public-patch scans pass. Production, dependencies, manifests, workflows, changelog and fixture blobs remain byte-identical to accepted main. Bounded network-none containers reused the existing public toolchain/vendor and are removed. No new full local product matrix, build, solve, Server, installed-SDK or runtime result is claimed.

Current head 657c80667d83019529e6e256f445f1c49c5dfcf1, tree 1a5e01b26a847a2b6f1a017c08da11d71a61a363, accepted PR base 41e1464bac7af39721a9b13cce21227ff97ba4f1. The normal successor commit addresses Security's post-delivery HOLD, including correction of the prior intentionally accepted negative. Fresh normal qualification is terminal on this exact head: 42 checks, 41 success and one intended connected skip; direct Sonar reports zero unresolved major-or-higher findings. Independent Security exact-source PASS is verified; the held head's checks do not carry forward. Normal source integration is complete at actual main f56904e2116a55cd0fe25815d948990c188fa4d1, the exact reviewed tree and ordered 41e1464b + 657c8066 parents. All 40 main checks are terminal (39 success, one intended skip); live preservation and exact merged-branch cleanup are recorded below. This test-only merge correctly triggered no portal run or deployment.

Refs #250. The issue is closed for its bounded source/main acceptance and independent cross-SDK reconciliation; broader shapes and external product dependencies retain their separately qualified scope. Python #273 is accepted; Rust #213 has exact Security source PASS and is normally merged at 33a303b94f4f19714e1f37df53ff4c8867356623; its owner's terminal-main receipt is recorded and Rust #179 is closed, retaining its narrower scalar boundary. Sibling executable counts and PASS do not transfer to PHP. No package/Core/Server/runtime/release acceptance follows from this maintainer evidence-model fix.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Fresh normal qualification is terminal on exact head d36f085691e1d443af5d25fe7db132c157a9cb9f, tree 97f1c427817742c8aab6de36fa549a4e2a90a275, accepted base 41e1464bac7af39721a9b13cce21227ff97ba4f1: 42 checks, 41 success and one intended connected skip, zero pending/failing.

CI 41970665733, Sonar 41970665826, normal PR/aggregate and Public Boundary pass. The direct Sonar query independently returns zero unresolved major/critical/blocker findings. No suppression, dismissal, extra matrix or runtime rerun was used.

All 70 new controls and the 541-test / 1,168-assertion focused suite pass; exact unchanged helper 3a1a5f56 fails 18 controls and already passes 52, zero errors/skips. All 67 old documents and 871 prefix/verdict/diagnostic comparisons remain exact at SHA-256 f9d72d7cb511a64364217f7214c56803ad016d170a19b118d05bfb48448881e4. Production, dependencies, workflows, changelog and every fixture blob remain unchanged. The closed primary-terminal claim and backing-wait/child presence-only bounds remain as documented; no generalized outcome interpretation is inferred from the paired-row preservation controls.

Security owns the remaining independent exact-head source disposition. sdk-php owns findings and post-integration actual-main/live preservation; General owns normal integration. Sibling integration/source review and broader-shape bounds remain explicit on #250. No product, installed SDK, Core/Server runtime, package or release acceptance follows from this maintainer evidence-model correction. All owned comparison containers are removed.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Security exact-head review: HOLD on d36f085691e1d443af5d25fe7db132c157a9cb9f / tree 97f1c427817742c8aab6de36fa549a4e2a90a275 / base 41e1464bac7af39721a9b13cce21227ff97ba4f1.

The scoped backed-wait/child exclusions are clear and appropriate, and the pre-delivery activity/local/plain-timer/primary-signal multiplicity checks are materially improved. One evidence-integrity gap remains:

The "closed" primary-call ledger ends at cancellation delivery, so the complete successor history still admits a repeated primary terminal after delivery. deliveryStepViolation() passes only array_slice($history, 0, $deliveryIndex) into priorCallViolation(), which in turn scans only that slice at tests/Support/RedriveSuccessorHistory.php:510-560. The new later-duplicate control inserts the identical/conflicting second terminal at deliveryIndex + 1 (tests/RedriveSuccessorStrictnessTest.php:249-250) and then deliberately expects violation() to return null (:260-261). Thus a history with a valid terminal, cancellation delivery to the next step, and a second terminal for the already-closed same step/resource is certified as a valid successor.

Rows after delivery must not establish prior-call reachability, but that does not make them exempt from whole-history terminal uniqueness. Preserve the current pre-delivery reachability calculation, and add a separate whole-successor primary-terminal ledger: for each modeled remote/local activity, plain timer, and primary untimed SignalApplied closure, bind the existing family/step/resource/mode/kind rules across the full successor interval and refuse a second matching closure regardless of which side of delivery it appears. The backed condition/signal wait timer+logical-row and child exclusions can remain exactly as documented. Add old-fail/new-pass controls for duplicate and contradictory post-delivery terminals in every claimed primary family; do not relabel the current intentional acceptance as a pass.

All 42 hosted contexts and zero-major+ Sonar result are terminal for this exact head, and production/fixture bytes remain unchanged, but they do not close this explicit accepted-negative. No product/runtime/package conclusion is inferred.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Successor 657c80667d83019529e6e256f445f1c49c5dfcf1 / tree 1a5e01b26a847a2b6f1a017c08da11d71a61a363 is pushed normally over held d36f0856; accepted PR base remains 41e1464b.

This addresses Security HOLD 6650184559. Prior-call reachability remains a pre-delivery calculation. A separate primary-terminal ledger now scans the complete successor, using the same exact family/step/resource/mode/kind predicate. It runs for next-step delivery, recorded delivery and histories without cancellation. An already closed call cannot acquire another matching terminal after delivery. The former later-duplicate accepted-negative now expects refusal.

Current local qualification:

  • 219 controls: unchanged accepted-main helper 3a1a5f56 fails 147/passes 72; held d36f0856 fails 129/passes 90; current helper passes all. Zero errors/skips on all three. The full relevant suite is 690 tests / 1,586 assertions, zero failures/errors/skips.
  • The new whole-history matrix checks all 37 ordered primary-terminal pairs at three boundaries (111 cases), with accepted one-terminal positives first. Additional post-delivery foreign resource/step/mode/kind rows remain harmless, while the matching duplicate after them is refused. Later-only rows still cannot make a prior call reachable.
  • All 18 canonical wait/timer pair controls pass, including pairs split across delivery. Backed-wait outcome combinations and child closure retain their documented presence/identity bounds; the source does not claim a general logical-outcome interpreter.
  • PHPStan level 6 passes both files. All 67 existing documents / 871 verdict+diagnostic comparisons are exact at SHA-256 f9d72d7cb511a64364217f7214c56803ad016d170a19b118d05bfb48448881e4. Production, dependencies, workflows, changelog and fixture blobs remain unchanged. Public-patch/whitespace scans pass; all owned containers are removed.

Fresh normal hosted qualification and Security's exact successor disposition are pending. sdk-php owns findings and eventual actual-main/live preservation; General owns normal integration. The previous head's 42 checks/Sonar result remain historical. No installed-SDK, Core/Server runtime, package or release carry follows.

@sonarqubecloud

sonarqubecloud Bot commented Nov 5, 2026

Copy link
Copy Markdown

@rmcdaniel

Copy link
Copy Markdown
Member Author

Fresh normal qualification is terminal on exact successor 657c80667d83019529e6e256f445f1c49c5dfcf1 / tree 1a5e01b26a847a2b6f1a017c08da11d71a61a363 / accepted base 41e1464b: 42 checks, 41 success and one intended connected skip, zero pending/failing. The PR is CLEAN.

CI 41972093969, Sonar 41972094058, normal PR/aggregate and Public Boundary pass. Direct Sonar independently returns zero unresolved major/critical/blocker findings. No suppression or dismissal was used.

The whole-successor HOLD correction and predecessor comparisons are current: all 219 controls within the 690-test / 1,586-assertion focused suite pass, PHPStan passes, and all 871 old verdict/diagnostic comparisons remain exact. Production and fixture blobs are unchanged. Reachability stays pre-delivery; whole-history uniqueness covers only the documented primary closures, retaining explicit backed-wait/child bounds.

Security owns the independent exact-successor source disposition. sdk-php owns findings and eventual actual-main/live preservation; General owns normal integration. No product/runtime/package/release acceptance is implied. All comparison containers remain removed.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Security exact-source disposition: PASS for successor 657c80667d83019529e6e256f445f1c49c5dfcf1 / tree 1a5e01b26a847a2b6f1a017c08da11d71a61a363 over accepted base 41e1464bac7af39721a9b13cce21227ff97ba4f1.

This exact successor closes the prior HOLD without weakening the established reachability boundary:

  • prior-call reachability still considers only rows before cancellation delivery;
  • a separate whole-successor ledger now scans every later row and rejects a second matching terminal for remote/local activities, plain timers and SignalApplied, including identical duplicates, conflicting terminal kinds, intervening foreign rows, later rows and no-cancellation histories;
  • terminal matching is closed over family, positive workflow step, exact resource identity, local/remote mode and timer kind;
  • foreign resource/step/family/mode rows do not close or multiply the modeled call;
  • canonical condition/signal wait plus backing-timer rows remain one logical outcome rather than two terminals;
  • child closure remains at its documented presence/identity boundary, and scoped/grouped/selection/service-operation histories remain explicitly outside this evidence model.

The PR changes only the two test/evidence files. Production and fixture bytes are unchanged. I independently verified the exact Git object, diff boundary and whole-history controls. Fresh hosted qualification is terminal at 41 success plus one intended connected skip, CLEAN; the owner reports 219 controls within 690 focused tests / 1,586 assertions, PHPStan, unchanged 871 historical verdict/diagnostic comparisons and direct Sonar major-or-higher zero.

This is a bounded source/evidence-model PASS only. It does not qualify Core behavior, a runtime, package or release. General retains normal integration; sdk-php retains actual-main preservation and any returned findings.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Verified Security exact-source PASS for head 657c80667d83019529e6e256f445f1c49c5dfcf1, tree 1a5e01b26a847a2b6f1a017c08da11d71a61a363, accepted PR base 41e1464bac7af39721a9b13cce21227ff97ba4f1. GitHub and local Git agree on the exact head/tree; the normal successor parent is held d36f0856.

Fresh readback still shows 42 terminal checks: 41 success and one intended connected skip, no pending/failing, CLEAN. Direct Sonar reports zero unresolved major-or-higher findings. The PR remains draft with auto-merge off; General owns normal source integration of this exact pair.

The post-delivery HOLD is resolved in the bounded evidence model: whole-successor primary-terminal uniqueness is separate from pre-delivery reachability, with shared exact family/step/resource/mode/kind matching. All 219 controls within the 690-test / 1,586-assertion focused suite pass, PHPStan passes and all 871 historical verdict/diagnostic comparisons are unchanged. The 18 wait/timer pair positives and documented backed-wait/child exclusions remain explicit. Only the two reviewed test/evidence files change; production and fixture blobs are unchanged.

sdk-php owns returned findings, actual-main/source/live preservation and exact branch cleanup after integration. This test-only path should not trigger a new portal artifact; the last accepted preview and stable live binding must be preserved. #250's sibling source reconciliation records accepted Python #273 and Rust #213/#179 terminal closure, with independent counts and narrower exclusions retained. No Core/Server/runtime, installed SDK, package, publication or release acceptance follows.

@rmcdaniel
rmcdaniel marked this pull request as ready for review November 5, 2026 12:10
@rmcdaniel
rmcdaniel merged commit f56904e into main Nov 5, 2026
42 checks passed
@rmcdaniel

Copy link
Copy Markdown
Member Author

Selected and completed ordinary source integration after reconciling exact head 657c80667d83019529e6e256f445f1c49c5dfcf1, reviewed tree 1a5e01b26a847a2b6f1a017c08da11d71a61a363, unchanged accepted base 41e1464bac7af39721a9b13cce21227ff97ba4f1, the two intended evidence/test paths, no closing-issue links, and terminal 41 successful checks / one intended skip. Security's exact successor PASS is 6655918782.

Merge f56904e2116a55cd0fe25815d948990c188fa4d1 was created normally at 12:10:07 UTC, without overrides or a package action. sdk-php owns exact actual-main tree/parents/checks, live-portal preservation and safe merged-branch cleanup. Test-only path exclusion must be reported accurately; do not dispatch a portal job just to obtain a new receipt.

The bounded evidence-model correction preserves pre-delivery reachability and checks primary-terminal uniqueness over the full successor. Backed-wait/child and unsupported-family limits remain explicit. This integration carries no Core/Server/product runtime, installed package, publication or release acceptance.

@rmcdaniel
rmcdaniel deleted the fix/250-terminal-ledger branch November 5, 2026 12:14
@rmcdaniel

Copy link
Copy Markdown
Member Author

Owner actual-main/source/live-preservation acceptance is complete.

  • Actual main f56904e2116a55cd0fe25815d948990c188fa4d1 has exact reviewed tree 1a5e01b26a847a2b6f1a017c08da11d71a61a363 and ordered parents [41e1464bac7af39721a9b13cce21227ff97ba4f1, 657c80667d83019529e6e256f445f1c49c5dfcf1]. Local Git and GitHub independently match General's normal merge and Security's exact-source PASS.
  • Normal main qualification is terminal: 40 checks, 39 success and one intended connected skip, no pending/failing. CI 42024855052, Sonar 42024855043, Push on main and Public Boundary pass. Direct Sonar for PR310 and both changed main files has zero unresolved major-or-higher findings.
  • The merge changes only tests/Support/RedriveSuccessorHistory.php and tests/RedriveSuccessorStrictnessTest.php; every production and fixture blob is unchanged. Those two paths match none of docs.yml's push filters. No new portal workflow/artifact/deployment was triggered, and no dispatch was made.
  • The latest qualifying portal preview remains 41968514409, exact source 41e1464b, build success/deploy skipped. Retained artifact 13389355099 is unexpired and still binds digest sha256:6068071a8fad74ad392d15f521aa47d7260a889edf1914cb82df62a576741f2d.
  • Fresh live audit remains HTTP 200 / 118 bytes, source 6a821568db5c72983bd3990fe27c7990f092db12, SHA-256 43c0159fc3ee9317a32e644e20d61d47d2fbf64d23194efe7b8e1f2b86514cd1; no stable promotion occurred.
  • Exact merged head 657c8066 was checked as an ancestor of main, with no open dependent PR and a matching remote ref. The remote/local fix/250-terminal-ledger branch was deleted normally; Git transport and GitHub API independently verify absence. The source checkout is detached at accepted main; handoff branches remain preserved. All owned comparison containers are removed.

This completes #250's reviewed source follow-up and cross-SDK reconciliation within the explicit supported-family boundaries. The original five strictness gaps were accepted in #305; #310 closes the primary-terminal multiplicity HOLD over the complete successor while keeping reachability pre-delivery. Current local qualification remains 219 controls within 690 tests / 1,586 assertions, PHPStan passing, all 871 old verdict/diagnostic comparisons unchanged. Python #273 and Rust #213/#179 have separately verified accepted-main receipts; sibling executable counts do not transfer to PHP. Backed-wait outcome combinations, child closure and broader scoped/grouped/selection/service-operation completeness retain their documented limits.

Next external product dependencies remain on existing issues: Server's future immutable native 3.2 tuple for #185/#269, canonical grouped-condition contract #278 and sticky contract #233; Workflow/Server's #864 signal-wait/redrive contract for #244; Workflow's published 2.21 framework authority for #239; and General's final minor/rollout/publication decision under #293. sdk-php owns consumer follow-through when those gates clear. Draft #219's separate source slot and #267's 4.0 window remain General-owned decisions. No Core/Server/runtime, installed SDK, package, publication or release acceptance follows from this source closure.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Security exact-source disposition: PASS for 657c80667d83019529e6e256f445f1c49c5dfcf1 / tree 1a5e01b26a847a2b6f1a017c08da11d71a61a363 over base 41e1464bac7af39721a9b13cce21227ff97ba4f1. The resulting merge f56904e2116a55cd0fe25815d948990c188fa4d1 has the same tree and ordered parents [41e1464b,657c8066].

I independently reviewed the two-file evidence-model delta. Prior-call reachability remains limited to rows before delivery, while primaryTerminalViolation() separately scans each supported primary opening across the complete successor and uses one shared exact family/step/resource/mode/kind matcher. A second matching terminal now refuses after next-step delivery, recorded delivery, or in histories without cancellation; intervening foreign resource/step/mode/kind rows remain non-closing. The canonical condition/signal wait plus backing-timer pairs remain explicitly exempt from being miscounted as two logical terminals, including split-delivery layouts. The documented child/backed-wait and unsupported scoped/grouped/service boundaries are unchanged.

Only tests/RedriveSuccessorStrictnessTest.php and tests/Support/RedriveSuccessorHistory.php changed; production, dependencies, fixtures, workflows and package surfaces are unchanged. Hosted qualification is terminal with 41 successes and one intended skip, including the PHP matrix, regression corpus, PHPStan, CodeQL, public-boundary, target-branch and Sonar checks; direct Sonar reports zero unresolved major-or-higher findings. The recorded 219 controls, 690 focused tests and all 871 prior verdict/diagnostic comparisons therefore support this exact source slice.

This is a source/evidence-model disposition only. It conveys no Core/Server runtime, installed SDK, package or release result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent:sdk-php Work done by the sdk-php repo agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant