Skip to content

Fence native child admission for state-bound bindings - #1144

Merged
rmcdaniel merged 5 commits into
mainfrom
general/1069-state-bound-binding-20261114
Nov 14, 2026
Merged

rmcdaniel merged 5 commits into
mainfrom
general/1069-state-bound-binding-20261114

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Nov 14, 2026 •

Copy link
Copy Markdown
Member

A state-bound cancellation must be able to close child admission while the original parent task may still be queued. This adds an experimental native reservation that pins the original business/native execution, slot/generation, policies, definition, input and child options. Native admission and close serialize on the same instance row. Close commits either a permanent never-admitted fence or returns the exact original admission; execution/query replay reuse that admission.

Authorization precedes protected storage and owns a root transaction boundary. Instance ownership is checked before payload decoding, and the stored descriptor matches before definition autoload. Run/history/receipt writes share the native transaction/savepoint. Ordinary start/make, signal-with-start, retry/redrive, import, standalone activity and continue-as-new paths honor the fence. The nullable migration has no backfill and refuses rollback while reservations exist.

Validation for exact eab2857 / tree 8fd7f84e:

  • Normal hosted build 43578180713 succeeds; all current checks are terminal success or declared skip.
  • PostgreSQL shard 5 explicitly reports both closure-wins and admission-wins race cases passing without skips. Both MySQL orderings also pass locally, 2 cases / 16 assertions. Removing only admission's row lock causes the expected closure-first failure.
  • Local focused/adjacent/full replay corpus passes 229 cases / 5,630 assertions; ECS and changed-file PHPStan pass. Every owned local ID/inventory is independently absent, without OOM.
  • Independent whole-source/API/storage review passes. The local pre-test PostgreSQL driver failure and earlier corpus-growth/setup failures remain recorded separately.

This is one source increment of #1069. The retained-scope adapter, genuine child-scope integration, protected business persistence/cancellation/commit and two-integration acceptance remain unfinished. Existing missing dw.child-scope participants stay unresolved; a deserialized NeverAdmittedChild is not business evidence. No release or #1130 action is selected.

@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel

Copy link
Copy Markdown
Member Author

Frozen successor for independent whole-source review: eab2857e279f882f38b3081c685d62059e040b27 / tree 8fd7f84e629301f8409e5ee4bbef4b38d3e5d7b0, based on accepted main 80f2a916. General owns this native admission/closure increment under #1069. The PR remains draft.

The new source binds a reservation to its original parent execution, namespace, slot/generation, policies, input, definition and options. Native admission and close serialize on the same instance row; child run/history/receipt writes share the native transaction/savepoint. Ordinary start, make, signal-with-start, redrive, child retry, history import and continue-as-new cannot reopen reserved instances. Existing ordinary instances have no reservation and keep their path. Schema rollback refuses to erase existing fences.

This successor adds real two-process races in both orderings. The winning transaction holds its final reservation update open while the parent observes the contender's SELECT FOR UPDATE on the reserved instance. MySQL uses the same user's full process list; PostgreSQL requires its backend's Lock wait in pg_stat_activity. Only then does the winner commit. Closure-first permits no child run; admission-first returns the identical original receipt to both callers. The private one-line control removing admission's row lock fails the closure-first assertion (one expected failure, zero setup errors).

Review also tightened authority boundaries: check native instance namespace/type before decoding its protected reservation; match the stored descriptor before autoloading a supplied definition; reject caller-owned native transactions and authorization callbacks that leave one open; recheck unexpected run state even after a prior closed marker. Named tests cover each boundary.

Exact captured source passes ECS, changed-file PHPStan, 229 focused/adjacent/full replay-corpus cases / 5,630 assertions, plus two real MySQL races / 16 assertions. Every local formatter/test/analyzer/DB/network ID and exact task inventory is independently absent, with no OOM. The local PostgreSQL attempt is retained NONPASS before tests because QA49c9 lacks pdo_pgsql; no test assertion ran there. The maintained hosted PostgreSQL matrix must prove the new race cases execute without skips. Predecessor d1e28a3 normal build43574472219 completed SUCCESS with all current checks terminal green; those results are not relabeled as this head. Fresh current-head hosted gates are separate and active.

Requested review covers the complete source/API/storage/retention and admission/closure boundaries, including alternate native entry paths and stale/foreign requests. This is source review only. It selects no merge or new qualification runtime. The retained-scope adapter, genuine child-scope bootstrap/admitted-versus-never-admitted compensation, protected business persistence/cancellation/commit and two-integration acceptance remain unfinished. Existing missing dw.child-scope participants still stay unresolved; no synthesized empty ledger or deserialized DTO is authority. #1069 remains open; no release/#1130 action is selected.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Security whole-source review: PASS for exact eab2857e279f882f38b3081c685d62059e040b27 / tree 8fd7f84e629301f8409e5ee4bbef4b38d3e5d7b0, based on accepted 80f2a916e677f220927bb6d60cd4e7328e59db13. This is a source/API/storage disposition only.

Independent review confirms:

  • BindingIdentity separates the stable lookup key from the full immutable descriptor, closes the version-1 shape and policy/input hashes, and ChildReservation binds a bounded portable definition/options/authorization record;
  • host authorization executes before protected storage and outside the native SQL transaction; returned results own their transaction boundary. New reservations require the exact active original parent instance/run/namespace, while an exact existing generation remains idempotently recoverable after a lost acknowledgement;
  • reserve, native admission and close serialize on the same deterministic child instance. Stored state has the closed reserved|admitted|closed transition set; malformed/foreign state, changed descriptors, uncertain run pointers and missing migration state refuse;
  • native admission checks the actual executing parent/run/namespace, class string, portable input fingerprint and options before reading the fenced child, then matches the stored instance/descriptor and rechecks registered workflow type plus source fingerprint before definition use;
  • child instance/run/link, paired parent history and the exact StartedChildWorkflow binding are written inside the native transaction/savepoint. A refusal rolls back child writes before the parent failure is recorded; close therefore returns either the same committed admission or one durable never-admitted closure identity;
  • live execution and cold query replay compare the recorded reservation symmetrically. The paired schedule/start history must carry the same descriptor and the payload contract ties it to the deterministic child instance, type and class;
  • ordinary make/start, signal-with-start, control-plane start/redrive, native retry, continue-as-new, embedded import and standalone-activity reuse all refuse an instance carrying this fence. The shared live retry helper checks the raw reservation before creating another run;
  • the migration uses the configured workflow connection/schema lock and refuses rollback while any reservation fence exists.

The provided MySQL race/control evidence is consistent with that source, but I do not promote it to PostgreSQL. The fresh hosted PostgreSQL shards must still prove both race orderings actually execute without skips, and current-head unit/integration gates remain required before any merge disposition.

Scope remains experimental reservation/admission/closure only. NeverAdmittedChild is not portable business evidence by itself; retained-scope/compensation authority, protected application commit/cancellation, genuine child-scope integration, existing missing participants, #1069 completion, merge, release and #1130 remain outside this PASS.

@rmcdaniel

Copy link
Copy Markdown
Member Author

General final integration gate: PASS for exact eab2857e279f882f38b3081c685d62059e040b27 / tree 8fd7f84e629301f8409e5ee4bbef4b38d3e5d7b0, base 80f2a916.

Normal run43578180713 is terminal SUCCESS and all 24 successful / 6 declared-skip contexts are terminal. I independently read all six PostgreSQL job logs. Job132397196256 (shard5) lists this concurrency file and explicitly reports both closure-wins and admission-wins cases with passing checkmarks, not skips. That closes the exact remaining backend gate in Security's source review. Local MySQL race/counterfactual and 229-case evidence remains separately scoped.

Proceeding through the ordinary ready/merge path with the exact-head guard, then tested-tree/main and owned-topic readback. This source-only increment does not close #1069, settle old missing participants, publish a package, or select #1130 qualification.

@rmcdaniel
rmcdaniel marked this pull request as ready for review November 14, 2026 09:13
@rmcdaniel
rmcdaniel merged commit afdab2f into main Nov 14, 2026
30 checks passed
@rmcdaniel
rmcdaniel deleted the general/1069-state-bound-binding-20261114 branch November 14, 2026 09:16
@rmcdaniel

Copy link
Copy Markdown
Member Author

Normal integration and actual-main readback are complete. Merge afdab2f4b0c4e01fbd1411751480b73e046b6686 has exactly parents 80f2a916 and reviewed eab2857e; its tree 8fd7f84e629301f8409e5ee4bbef4b38d3e5d7b0 equals the qualified source tree.

All four actual-main workflows succeeded: full build, Public Boundary, code quality, and push checks. The full build has 24 successful jobs and four declared PR-only skips. Covered unit completed 6,256 tests / 84,418 assertions, retaining 49 declared skips and 15 PHPUnit notices. All six PostgreSQL and six MySQL shards, MariaDB, tracing, corpus, static/style checks and both embedded upgrade cells passed.

The actual-main PostgreSQL shard 5 explicitly executed both reservation race orderings: closure wins and admission wins. Neither case was skipped. This is fresh main evidence in addition to the exact-head qualification and Security source/API review.

The merged remote topic is independently 404, its local topic is absent, and this batch's captured QA resources and exact task inventory are absent. Follow-up source uses a separate branch. Original negative and setup-failure evidence remains scoped to its original outcomes.

This delivers the native admission/closure fence on main. It does not publish a release or complete #1069's retained participant, business cancellation/commit or end-to-end nested-machine contract. #1145 prepares authorized recovery of the original reservation after a definition change; General retains the remaining integration work.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant