Repository navigation
Keep embedded history imports within their target namespace #928
Description
The continuation authority blocker is corrected in exact draft PR #929 head a6f9195ba74a7dd601943efb3467c8bf6696427e / tree 1cd553c06a1110e81683d6cf392e5db33d11961f. Both continue-as-new paths now require the exact locked imported parent/child edge before copying a child link or imported parent reference; an unresolved raw imported parent reference is not propagated. The six new successor controls pass with 49 assertions and produce four intended failures against 5e01a938, while the two legitimate imported-edge cases remain green. The exact full lineage matrix passes on SQLite and MySQL (55 tests / 402 assertions, two PostgreSQL-only skips each) and PostgreSQL (55 / 445, no skips). Focused ECS/PHPStan pass. Exact evidence and counterfactual. Security accepts this immutable source and terminal hosted run 40252025019: all eight executed jobs passed, seven path/bounded-selection jobs skipped, none failed. The PR remains draft and behind main; no merge, publication, or deployment is claimed, and any rebase/successor requires fresh validation.
The broader fix fences imported targets, same-bundle commands, directed lineage effects, and self-lineage. Its retained 129-case import cohort passed on SQLite/MySQL/PostgreSQL; new scope controls passed on each database; 42 prior-source assertion failures plus five valid controls and zero errors demonstrated the preceding defects. Earlier evidence.
Next: finish hosted exact-head review, legacy dangling-edge recovery, retry compatibility, MySQL/SQLite concurrency, remaining copied-reference/runtime consumers and the native copied-field/runtime audit. Complete full unit/coverage/feature qualification before merge/publication. Publish a qualified immutable Core package and verify the actual PHP Server consumer/image under its existing publication gates. PHP signing-key URL follow-through remains in Server #765; separate query authority is in Server #526 / draft #758.
An embedded v2 history bundle imported into one namespace can resolve an existing run or workflow instance in another namespace. Published PHP Server reproduction and downstream delivery requirements are tracked in durable-workflow/server#765. The defect remains present in current Workflow 2.13.1.
The importer must reject a globally conflicting run ID rather than return already_imported for another namespace. It must also refuse to attach an imported run to a foreign workflow instance, preserve all existing rows, and keep same-namespace repeat imports idempotent. Preview and actual import must agree on these conflicts, including the embedded null namespace.
The related reference audit from durable-workflow/server#764 also remains required before declaring the import boundary complete: both directions of lineage links, signal/update command references, and other copied relational IDs must preserve namespace ownership. Define safe handling for unresolved related IDs without silently creating future cross-namespace edges. Preserve legitimate import and same-namespace lineage behavior, and qualify the affected database families.
General owns the PHP implementation and downstream follow-through. Source tests and a merged Core fix do not complete Server delivery: publish a new immutable Workflow package, update the Server consumer, and verify the actual fixed published image under its existing publication gates. Native implementation and shared fixtures remain with their current owner.
Activity
rmcdaniel commentedon Oct 25, 2026
Lineage compatibility decision: simply rejecting every unresolved endpoint would prevent importing a parent and child whose bundles both contain the edge in either order. The current import contract explicitly permits diagnostic lineage from separate bundles, so the remaining fix must preserve that legitimate journey while preventing active cross-namespace edges.
The candidate design is quarantined deferred import state, bound to the namespace and exact import/receipt identity. Deferred edges must stay absent from replay, export, runtime and wait projections. Activation requires both endpoints to exist and be revalidated in that namespace under an atomic fence; an unrelated later run with a matching ID must not capture the edge. Retry, cleanup and expiry behavior must be explicit and inspectable. Security reviewed these design boundaries in coordination; no schema or implementation acceptance is claimed yet.
The next source action is the complete copied-reference inventory and ownership checks, beginning with signal/update command IDs and their later application path, plus update failure references, activity attempt/task references, history references and both lineage directions. Direct target guards are isolated in draft #929. Keep #928 and downstream Server #765 open through complete graph qualification and installed delivery.
rmcdaniel commentedon Oct 25, 2026
Lineage design update from the native owner's current implementation: omitting an unresolved physical edge is different from rejecting the entire import. Because a normal source link appears in both endpoint exports, the second endpoint's own import may be able to materialize the link after both runs exist in the same namespace. This could preserve either import order without persistent pending state. No quarantine table or schema change has been implemented; the earlier quarantine discussion remains a candidate, not a settled implementation requirement.
PHP needs an additional check before adopting that path. Source inspection at
f0e6e9beshowsRunLineageView::resolveRun()globally finding a bundle/history-supplied related run ID after its same-instance lookup.ChildRunHistoryalso has run/instance fallback resolution. Typed history can therefore reconstruct lineage independently of the physical link writer; omitting an unresolvedworkflow_linksrow alone is not yet proof that a later foreign or unrelated matching ID cannot be resolved. This is a source finding, not a newly executed lineage leak or native-runtime claim.Next proof: exercise parent-first and child-first source bundle imports, then introduce unrelated matching IDs and rebuild/query/export the lineage. Validate both physical links and history/projection fallback lookups. Preserve legitimate same-namespace related imports and original history attribution. Historical event-command references also need their own controls: continuation moves an accepted message command to the successor, so the earlier event's identifier cannot be treated as an active same-run message-command reference. Remaining copied fields stay in the full #928 audit.