Skip to content

Embedded v2 history import reads and attaches across namespaces (published 2.11.1) #765

Closed

Description

@rmcdaniel

Delivered in PHP Server2.11.8, immutable source fa3fc2f2f6b8935ea4a6eea47f6a9221e2adafff, with published Core2.15.12. Installed-image acceptance proves canonical workflow/activity visibility and resolution, rejected cross-namespace run/instance imports with zero writes, idempotent same-namespace import, activity-poll replay and workflow-history continuation fencing, and all signing-key URL/body/configuration controls. All369 Server files and2259 committed Core files match before/after; the immutable image and matching chart publisher pass. No Cloud deployment is claimed.

Source delivery includes #905, #893 and Core2.15.12. Normal protected merge and exact Security reviews remain linked in those records. This issue's acceptance is complete. Broader ingress/recovery work remains in #789.

Original problem and acceptance:

Published Server 2.11.1, with Workflow 2.10.2's EmbeddedV2HistoryImport, lets an embedded v2 history import in one namespace read and change another namespace's workflow state. The route is admin-only, but namespaces are meant to stay isolated.

1. Cross-namespace duplicate. EmbeddedV2HistoryImport::existingRunOutcome looks the bundle's run up in any namespace. A bundle already imported into namespace B, imported again into namespace A, answers 200 with already_imported for A, which holds no such run.

2. Cross-namespace instance attach. EmbeddedV2HistoryImport::writeBundle finds the workflow instance in any namespace and attaches the imported run to it. A run imported into namespace A becomes the current run, and bumps the run count, of an instance that belongs to namespace B.

Evidence. Both behaviors were recorded three times from the published image, with identical results, in tests/Fixtures/ServerParity/workflow-import.json under workflow_import.published_defects (cross_namespace_duplicate, cross_namespace_instance_attach). The fixture arrives with #764.

Native behavior (#764). A run id held in another namespace is refused as run_id_conflict. An instance of another namespace is refused rather than taken over, and the other namespace is left unchanged. The parity fixture keeps the published answers bounded as defects, so native isn't required to reproduce them.

Suggested PHP fix. Scope both lookups by the requested namespace: the existing-run check and the instance resolution in the write. A run id or instance id already present in another namespace should then be a conflict.

Activity

  1. rmcdaniel commented on Oct 25, 2026

    @rmcdaniel
    MemberAuthor

    General is implementing the PHP root correction in durable-workflow/workflow#928. Current-source counterfactual coverage reproduces both original defects in all twelve named/null namespace and write/preview cases: twelve assertion failures, zero test errors, against the unchanged Workflow 2.13.1 import class.

    The candidate restricts run-idempotency to the target namespace, reports an explicit foreign-instance conflict before preview/write, and scopes the transaction's locked instance lookup so a preflight race cannot attach the run to a foreign instance. The ordinary run-number-conflict control now explicitly selects its existing namespace, preserving the intended SQL uniqueness/rollback check. Full current-candidate qualification is running; no merged or published correction is claimed.

    The reference audit from #764 is retained in Workflow #928, including parent/child links, signal/update command IDs and other copied relational identifiers. These direct target guards do not complete that audit or the installed-image acceptance. Native/shared/frozen work remains with its owner. Server #526's separate query-authority race remains open in draft #758.

  2. rmcdaniel commented on Oct 25, 2026

    @rmcdaniel
    MemberAuthor

    The direct target guards are now visible in Workflow draft PR #929 at 5c766e3188fb1fb7ac9ebb267773bcc5e37912f6. Full ECS/PHPStan and 44 tests / 607 assertions pass locally; exact counterfactual and current-scope evidence is in durable-workflow/workflow#929 (comment). Workflow #928 retains the full copied-reference graph and compatible quarantined-lineage work. Hosted qualification and independent partial source review are live. This is source-only, with no package or Server image publication; keep #765 open through complete fixed-image acceptance.

  3. rmcdaniel commented on Oct 25, 2026

    @rmcdaniel
    MemberAuthor

    Workflow draft PR #929 now includes the active signal/update command-reference boundary at f0e6e9be13de3d5d3dcdf5de42af720bc35ad8bd. Each message must bind to a matching command imported from the same bundle and transaction. SQLite, MySQL 8.0.46 and PostgreSQL 17.11 each pass 82 tests / 779 assertions; counterfactual worker completions reproduce foreign-command mutation before the guard. Evidence: durable-workflow/workflow#929 (comment) . Full copied-reference/historical/lineage acceptance remains in Workflow #928, including the new source-only projection audit in comment 6402344424. Keep #765 open through complete source and fixed published-image verification. Native/shared/frozen work remains with its owner; no publication is claimed.

  4. added a commit that references this issue on Oct 25, 2026
  5. rmcdaniel commented on Oct 25, 2026

    @rmcdaniel
    MemberAuthor

    Native reference isolation for embedded v2 import, from the Security review of #764. General owns the published PHP side in Workflow #928 and Core #929. Published Server 2.11.1, with Workflow 2.10.2 through 2.13.1, copies every reference a bundle carries without checking it. Native refuses such a bundle. This is the audit of every field the importer copies, at #764 head 6f109c2c118bf3c3c309eb606631357d5a29e6a4.

    Published defects beyond the two run/instance lookups already recorded here:

    • Lineage. A link's related run or instance can belong to another namespace. History export then lists that foreign run's metadata, and retention and cancellation traverse the link.
    • Commands. A signal's or update's command_id can name another workflow's command. Later application then updates that command by id alone: applied_at, plus outcome for updates.
    • Task payloads. A task payload's activity_execution_id can name another run's activity. A lost lease then settles that activity, because it is looked up by id alone.
    • Signing key in the URL. signing_key is read from the query string too. Access logs, tracing and client history keep URLs.

    What native does (writes are atomic, and nothing is committed on refusal):

    Copied field Runtime use found Native rule
    commands/signals/updates[].resolved_run_id Retention deletes by it Must be the imported run (references.foreign_run)
    commands/signals/updates[].requested_run_id Retention deletes by it Null, the imported run, or another run of the same workflow in this namespace (write check)
    signals[].command_id Signal application joins and updates the command A signal command of this bundle; the application join and update also require the same instance
    updates[].command_id Update application joins and updates the command An update command of this bundle; same instance on application
    updates[].failure_id Only checked for non-empty A failure of this bundle, or an id no failure holds
    history_events[].workflow_task_id, workflow_command_id Read only with workflow_run_id A task or command of this bundle
    activities[].current_attempt_id Observation join, run-scoped One of that activity's own attempts
    activities[].attempts[].workflow_task_id / task_id Heartbeat and claim joins A task of this bundle. Attempts of an activity the importer skips are refused.
    tasks[].payload.{activity_execution_id, activity_attempt_id, timer_id, workflow_signal_id, workflow_update_id, workflow_command_id} and resume_source_id for those kinds Claims are run-scoped. Lost-lease settlement was not, and now is. A row of that kind in this bundle
    failures[].source_id (kind activity_execution) Display An activity of this bundle. Other kinds are display-only and stay as recorded.
    workflow.archive_command_id Display A command of this bundle
    links.parents/children endpoints Export, retention, cancellation The related run must exist in this namespace and in the instance named. A run or instance in another namespace refuses the import. A run that exists nowhere yet is not written, and its own import writes the link once both runs exist. A self-link is refused. Export also omits any related run of another namespace.
    signals[].signal_wait_id, attempts[].worker_attempt_id Identity within the run, or metadata Inert
    Ids inside history event payloads Readers stay within the run. Child runs are resolved only through workflow_links (fenced above) or a namespace-checked visible-run lookup. History, not references

    The signing key is read only from the body or the configured secret. A query signing_key in any spelling, signing_key[] included, gets 422 signing_key_in_query, and the answer never repeats the value.

    Evidence: rust/tests/execution/workflow_import_fences.rs runs on SQLite, PostgreSQL and MySQL. It covers refusal in both lineage directions, refusal of a foreign instance, a deferred link that a later foreign run never captures, refusal of each foreign row reference, forged signal and update rows refused at application, worker and operator 403s with admin as the positive control, and the URL signing key. Each refusal is checked against byte-for-byte export snapshots of the other namespace. Without the fence and predicates, five of the seven tests fail.

    🤖 Generated with Claude Code

  6. rmcdaniel commented on Oct 25, 2026

    @rmcdaniel
    MemberAuthor

    PHP source follow-through is now at Workflow PR #929 head c2d32ac2171587e27f76c6b8ad7393f2e1e62456, still draft. Evidence and exact remaining gates cover the new-import lineage slice, same-bundle message command ownership, and direct target guards.

    Both lineage directions now check namespace plus run/instance identity, missing endpoints do not become physical edges, and display/export and ChildRunHistory reader fallback cannot attach a later unrelated run. Mutating consumers were not fenced at this head; Security found those gaps, addressed in the successor below. Qualifying omission exposed a PostgreSQL reciprocal-import race; a real two-process regression now observes a complete serializable retry and exactly one edge. The common 100-case cohort passes on SQLite/MySQL/PostgreSQL, with only the two PostgreSQL-specific controls skipped on the other databases. Retained PHP replay consumers pass 76/3,789; the 17 new lineage controls all fail against the preceding importer/readers with zero test errors.

    The native copied-field audit is received for PHP comparison. Next are task payload/lost-lease references, resolved/requested run IDs, historical task/command IDs and the other copied references. Legacy dangling-edge recovery, continuation/retry compatibility and MySQL/SQLite concurrency remain unqualified. The PHP signing-key URL path also remains required here. Existing source review applies to earlier slices only; no current-head acceptance, package publication, Server consumer update or fixed published image is claimed.

    Successor and correction: durable-workflow/workflow#929 (comment). Exact head 5e01a93 awaits review; this receipt is historical evidence for c2d32ac2 only.

  7. rmcdaniel commented on Oct 25, 2026

    @rmcdaniel
    MemberAuthor

    Security re-review of Workflow PR #929 exact head c2d32ac2171587e27f76c6b8ad7393f2e1e62456 found two remaining PHP lineage authority blockers: history-only missing endpoints are still consumed by scoped child cancellation and parent-resume mutation paths without an exact materialized edge, and self-lineage is still accepted/resolved. Exact source paths, counterexamples, and required controls are recorded in durable-workflow/workflow#929 (comment).

    The new import/store/view work is not accepted at this head. PostgreSQL serializable retry evidence remains valid; MySQL/SQLite absent-row concurrency, legacy dangling-edge recovery, and the broader copied-reference audit remain open separately.

  8. rmcdaniel commented on Oct 25, 2026

    @rmcdaniel
    MemberAuthor

    PHP import follow-through is at Workflow draft PR #929 head 5e01a938a8766af8f47861aba69d5497bf6731d0. Exact source evidence and open gates are recorded for review. This successor fences imported child cancellation/parent-resume effects with exact directed edges and rejects self-lineage, addressing Security's two c2d32ac2 blockers. It has not yet been accepted.

    The 129-case importer cohort passes on SQLite, MySQL and PostgreSQL; 18 scope-effect cases pass on each database. The 47 current controls against preceding production source produce 42 assertion failures, five valid-pair passes and zero errors. Native scope behavior (63/525), focused child consumers (46/2,076) and retained PHP replay consumers (76/3,789) pass. Hosted quality/corpus are green; unit/feature are pending. A broader local selection hit a tracing subprocess timeout, so full-suite completion is not claimed.

    The prior handoff's fallback claim has been narrowed to the display/export and ChildRunHistory readers it actually covered; mutating paths were unsafe at that old head. Legacy dangling-edge recovery, continuation/retry import compatibility, MySQL/SQLite concurrency, the remaining copied-reference/runtime audit and PHP signing-key URL path remain open. No package, consumer update or fixed published image is claimed. General next addresses the separately owned Workflow #931 service-operation authority boundary while this exact-head review runs; #928/#765 remain General commitments.

  9. rmcdaniel commented on Oct 30, 2026

    @rmcdaniel
    MemberAuthor

    Current release-boundary reconciliation (2026-10-30): this defect remains unfixed in published Server 2.11.7 / Core 2.15.7, and the current Server 2.11.8 draft PR #877 consumes published Core 2.15.8, which also predates the fix.

    Workflow PR #929's exact head a6f9195ba74a7dd601943efb3467c8bf6696427e retains its prior Security source and terminal hosted-run acceptance, but it remains draft, merge-conflicting/behind main, unpublished, and explicitly incomplete for the broader copied-reference/concurrency/full-suite gates in its body. No package or installed Server correction can be claimed from that source state.

    Risk disposition is unchanged: this is an existing admin-only namespace-isolation defect on a released surface. It should remain the dependency-aware public follow-through through rebased source qualification, immutable Core publication, Server consumer update, and installed-image verification. It does not add a hold to PR #877 because withholding that independent patch release would not repair this exposure. General has the current handoff; no operator action is requested.

  10. rmcdaniel commented on Oct 31, 2026

    @rmcdaniel
    MemberAuthor

    The PHP URL-key fix is reviewable in draft #893, head 369f2ba51e8c9e15e366438d828f09a59f6a74b6 / tree 01af5635e496446331085215653c404a88282a83.

    The controller now refuses a query-string signing key before importing, including case variants, arrays, encoded/normalized names and empty/bare fields, and returns 422 signing_key_in_query without repeating the value. Explicit signing keys come only from JSON; configured keys keep working. On the preceding source, all ten URL cases return 201 instead. The fixed selection passes all 14 tests / 72 assertions, including valid signed body/configured imports and existing discovery/import behavior. Pint and its non-fixing check pass; the normal broader PHP selection is running.

    The Core namespace/reference fix is separately at Workflow #929, 6b8e9d5a, with all five extended database cells and hosted CI passing. Its complete local quality cycle remains open, and 2.15.11 is not yet published. Server #893 still uses published Core 2.15.10. No fixed published Server image or new Security acceptance is claimed; #765 stays open through Core adoption and actual image acceptance.

  11. rmcdaniel commented on Oct 31, 2026

    @rmcdaniel
    MemberAuthor

    The normal protected merge queue completed successfully: PR #893 merged as ac65ab661428181bbdf4e133fe89656c9b440f7e at 22:15:39 UTC. All three reviewed source/test/documentation blobs match the merged main exactly. Merge-group PHP qualification and shared fixture selection passed. Normal main PHP and Sonar checks are now running. No image publication or installed-image delivery is claimed; Core adoption and this issue's published-image acceptance remain open under the existing release gates.

  12. rmcdaniel commented on Nov 1, 2026

    @rmcdaniel
    MemberAuthor

    The downstream cached-summary check confirms a separate Server guard is needed in addition to the Core update. Prepared source is backed up on this branch, commit 3c6ccf15f7ee9207628b591ccc13694ceaf8f399.

    NamespaceWorkflowScope now requires the canonical run and instance to belong to the exact requested namespace before a run or cached summary can be selected. A summary must also name its run's actual instance. These predicates apply before search, counting and pagination, so cached business keys cannot leak through query matches. Reads do not rewrite the foreign instance. Workflow and standalone-activity lists are covered, including named, case-variant and embedded-null owners and valid same-namespace controls.

    On both SQLite 3.40.1 and MySQL 8.0.46, the same 16 cases against unchanged Server main produce 13 intended failures, three valid controls and zero errors, even with the proposed Core fix present. The Server guard passes 16 tests / 56 assertions on each database. Four adjacent workflow-control, standalone-activity, visibility-query and message-stream files pass 97 / 1,514 on SQLite. Pint and its non-fixing check pass. The complete normal local PHP selection then passed at 2026-11-01 01:02:20 UTC: 3,467 tests / 71,512 assertions / 182 skips / six PHPUnit deprecations, zero failures. The initial run stopped at an entrypoint test because this QA image lacked the production helper; restoring its exact bytes and executable mode made the original test pass (one / five) before the successful complete rerun. Server source stayed unchanged, and all 2,259 Core files still match aabcc1cc after the full run. This does not replace the required published dependency pin or normal final PR checks.

    This is a combined unreleased source experiment with exact Core aabcc1ccb7e9157e9cd685ce108c4862e21329e5; all 2,259 Core files match that archive. The separate preceding published Core 2.15.10 installation matched all 2,250 tagged files and reproduced the same 13 failures. The branch's Composer files still pin 2.15.10, so it is not ready for integration: the new guard uses the prepared Core namespace helper. Next, finish Core qualification/publication, adopt 2.15.11 through normal Composer resolution, open the consumer PR and complete normal Server qualification and protected integration. Actual installed-package/image acceptance remains open under existing publication gates. No fixed package or image is claimed.

  13. rmcdaniel commented on Nov 1, 2026

    @rmcdaniel
    MemberAuthor

    Security source review of exact prepared commit 3c6ccf15f7ee9207628b591ccc13694ceaf8f399: the cached-summary and direct run guards are sound, but one legacy mutation boundary remains before this source can complete #765.

    runSummaryQuery() now requires the summary, canonical run and canonical instance to have the exact requested namespace, and it binds the summary instance ID to the run instance ID. runQuery() likewise requires exact run/instance ownership. The new named/case-variant/null/list/search/run controls correctly cover that read surface.

    However, taskQuery(), task() and lockTaskForMutation() still accept a task by its own namespace and a run by its own namespace without requiring the run's canonical WorkflowInstance to have that namespace. This is reachable from the same legacy state already constructed by LegacyImportedNamespaceVisibilityTest: instance namespace other, DEFAULT or null; imported run namespace default; and an imported ready workflow/activity task whose namespace is also default. The fixed importer prevents new corruption, but it deliberately preserves existing rows.

    Independent exact-commit control confirms the source path. A disposable non-root, read-only, network-disabled PHP 8.3.36 container ran eight in-memory SQLite cases against the clean owner worktree. Task read/query and mutation-lock controls produced six intended failures: all three foreign instance owners (other, DEFAULT, and embedded null) returned the default task when the expected result was no task. Both valid same-namespace controls passed. Result: 8 tests / 9 assertions / 6 intended failures / 2 valid passes. The container was removed and the owner worktree remained clean. This is a local regression control, not a live exploit or customer-impact claim.

    Server worker polling and workflow/activity completion, failure, heartbeat, cancellation and prepared-local paths use these task helpers before calling the package bridges. The package bridge then locks the task and run by ID and does not revalidate the instance namespace. Consequently, hiding the run/list does not prevent a valid default worker from leasing or mutating a legacy task whose run is attached to another namespace's instance.

    Required boundary for the #765 consumer fix:

    • make task selection require exact task namespace plus the same canonical run-and-instance ownership predicate used by runQuery();
    • make the mutation lock revalidate that canonical ownership under its run/task locks;
    • audit task entry points that still issue direct namespace-only task/run queries;
    • add old-source-failing workflow and activity worker controls for named, case-variant and embedded-null foreign instance owners, proving poll/mutation refusal and unchanged task/run/instance rows, with valid same-namespace controls.

    This blocks Security acceptance of 3c6ccf15 as the complete downstream namespace guard. It does not invalidate the Core 2.15.11 package acceptance, establish exploitation/customer impact, or block unrelated Server/Rust work. Published Server remains unchanged; normal Core pin, complete Server qualification and exact published-image acceptance remain required.

  14. rmcdaniel commented on Nov 1, 2026

    @rmcdaniel
    MemberAuthor

    The additional legacy task boundary is corrected in prepared source a79f7558b25640c4603d7725e4bf846ef4414606. This includes current main 59fd28d2, the earlier cached-summary guard and the normal published Core 2.15.11 pin (e5ef31fc1). All 2,259 installed Core files and 13 runtime origins match immutable 20bbe940; no package-source overlay remains.

    Task reads and mutation locks now require exact task, run and canonical instance ownership. Activity polling revalidates that ownership under run/task locks before the package's ID-based claim can write a lease or attempt. The workflow claim lock and compatibility backfill use the same predicate. Both worker-replacement release paths require canonical ownership, and activity execution/attempt references must belong to the task's run before an attempt can expire. Custom activity bridges can retain tasks outside the package table; existing package rows still require canonical ownership.

    LegacyImportedTaskOwnershipTest has 46 cases covering named, case-variant, embedded-null and valid default instance owners. It exercises helper reads/locks, workflow/activity polling, heartbeat/completion/failure, worker replacement, sticky-state preservation and copied activity execution/attempt run references. Refused operations compare instance, run, summary, task, history, execution and attempt rows before/after.

    On both SQLite 3.40.1 and MySQL 8.0.46, unchanged application source e82a7741 with actual published Core 2.15.11 produces 32 intended failures, 14 passing controls, zero errors. Default workflow polling already refuses the foreign owner; activity polling, helper access, all 18 foreign mutation cases, both replacement paths and the two copied-reference cases expose the remaining gaps. The corrected source plus the earlier visibility tests passes 62 tests / 368 assertions on each database. Command: vendor/bin/phpunit tests/Feature/LegacyImportedTaskOwnershipTest.php tests/Feature/LegacyImportedNamespaceVisibilityTest.php. Pint's non-fixing check passes all five changed PHP files.

    The final normal broader PHP selection completed at 2026-11-01 05:42:29 UTC on fixture-only successor 9669784bd74a602a8054af87eeea7956bc8e70b2: 3,513 tests /71,824 assertions /zero failures or errors /182 backend skips /six existing deprecations. The first full run's eight failures and the one-line explicit-namespace fixture correction are retained in the diagnosis; deregistration/fault/retry assertions are preserved. After the full pass, all2,259 package files still match immutable Core2.15.11 and13 origins resolve inside its normal installation. The three complete release-contract files also pass138/1,621; initial missing-jq runner failures were repaired without changing source/tests.

    Additional qualification found the separate library poll-window gap described in that diagnosis. Prepared Core source b04a656e filters exact task/run/instance ownership before LIMIT and prepares an unpublished2.15.12 patch. Its complete activity-bridge file passes86/532 on MySQL8 and Postgres17; all15 new controls pass on SQLite. A deliberately labeled single-file unreleased-source consumer experiment changes the original failing mixed-queue HTTP probe to1/6PASS. The persistent Server vendor files remain stock21511; this experiment is not a published-package acceptance.

    Next: finish that Core patch's full quality cycle/review/protected integration and immutable publication, adopt it normally in Server, then complete exact-source protected checks and fixed-image acceptance. Security review and the existing publication gate remain open. No accepted-source readiness, new package/image, or deployment is claimed.

  15. rmcdaniel commented on Nov 1, 2026

    @rmcdaniel
    MemberAuthor

    The broader run at prepared a79f7558 with normal published Core2.15.11 finished 3,513 tests /71,758 assertions /eight failures /zero errors /182 skips /six deprecations. All eight failures stop at the same deregistration fixture's initial activity poll. That fixture creates an explicitly identified embedded workflow without passing its namespace; reservation uses insert-or-ignore and leaves the canonical instance owner null, while test model events assign default to the run/tasks. The new guard refuses that inconsistent fixture. I am correcting the fixture to create an explicit default-owned workflow, preserving all deregistration/fault-injection/retry assertions, then rerunning it and the full selection. This failed run is retained and is not a pass.

    An additional mixed-queue probe also identifies a real product follow-through: with ten foreign-instance legacy activities before a valid default-owned activity, the Server guard refuses the foreign leases but the library's namespace-only poll fills its SQL window with them. Actual HTTP result is an empty task instead of the legitimate task: one test /six assertions /one intended failure /zero errors. The library must apply exact task/run/instance ownership before LIMIT, rather than relying solely on the Server's preclaim refusal. General is correcting that query on a separate Core branch, then will qualify/publish a patch and adopt it through normal Composer. This is not evidence of live customer impact and does not alter immutable2.15.11 provenance or its import fix.

  16. rmcdaniel commented on Nov 1, 2026

    @rmcdaniel
    MemberAuthor

    General installed-image counterfactual, November1 11:35 UTC: unmodified published PHP Server 2.11.7, immutable image durableworkflow/server@sha256:96e3e7de8c58f31bfb1ef4d5bddddc2678f4684f5cb3505e6e9ddc6fa3f7f625, contains Core2.15.7 /37ebce7b4da876ae388d13278262449139647fd4. This is the installed baseline, distinct from newer development lockfiles.

    Two isolated read-only-image controls (workflow and standalone activity) each seed one canonical owner and three legacy imports whose instance owner is foreign, mixed-case or null, while run/summary claim the requested namespace. Both list APIs return all four business keys. Both current-run/explicit-run helpers also resolve the three wrong-owner runs. The canonical positive control passes and instance rows remain unchanged. These are synthetic reproductions, not evidence of customer impact.

    Merged #905 and Core2.15.12 source repairs remain qualified. The same standalone probe is ready for the fixed published PHP image after #911's normal protected merge/publication, and this issue remains open for that installed acceptance.

  17. rmcdaniel commented on Nov 1, 2026

    @rmcdaniel
    MemberAuthor

    Published-image acceptance complete on November1 UTC for PHP Server2.11.8, source fa3fc2f2f6b8935ea4a6eea47f6a9221e2adafff, with Core2.15.12 / 7c80ffccdb6ab6e6ace8339618a9d6f1d6d9432f.

    Immutable image: durableworkflow/server@sha256:3848d5d5cd1b23bd2881e3fdecea64cc44b72e6fb812e577c2db6d0872d065dd. The normal publisher and matching immutable Helm chart both passed; the index contains amd64+arm64. Local installed behavior below ran on amd64, PHP8.3.36 / SQLite3.46.1, in disposable UID1000/init containers with read-only image files, no network, synthetic data and no application/package source mount.

    • Workflow and activity list APIs each return only the canonical owner. Foreign, mixed-case and embedded-null instance owners remain invisible; current/explicit-run resolution is refused, with instance rows unchanged. The canonical positive controls pass. These are the same controls that fail on published2.11.7.
    • Actual embedded import succeeds201. The same-namespace repeat remains200/already_imported. A foreign run ID is rejected422/target.run_id_conflict; a foreign instance is rejected422/target.instance_namespace_conflict. Both rejected requests leave all workflow rows unchanged.
    • The activity poll first returns its legitimate task. After changing its instance owner, replaying the same poll_request_id returns200 with no task and changes no workflow/activity row. A legitimate workflow-history continuation returns200; after owner change the continuation returns404/task_not_found, again with all workflow/activity rows unchanged.
    • All10 signing-key URL spellings/shapes are rejected422/signing_key_in_query, without key echo or workflow writes. Valid signatures still import201 using either a JSON-body key or server configuration.

    Every cell checks all369 Server source/config/migration files against the qualified source and all2259 committed Core files against the tagged archive, before and after; all match. All12 Core runtime origins resolve inside the installed package. The image adds only its declared .package-provenance file, verified against the image labels and root copy. Composer's path-package locator (84c0f745...) is recorded separately from the verified immutable Git source above. Initial locator/provenance assumptions and two invalid worker-fixture setups were corrected; only successful final cells are acceptance evidence.

    Successful installed cells ran12:11:01–12:11:14 (retention/list),12:25:12–12:25:15 (worker/history) and12:27:42–12:27:45 (import/signing). Diagnostic fixtures follow the test definitions committed with the qualified source; these local observations supplement protected CI and the public publisher's first-run, source-free Compose, protocol-catalog and TLS checks. No Cloud deployment or customer-impact claim is made.

    This completes #765's published ownership/import/poll/signing acceptance and the downstream Server delivery for Workflow#928. The broader ingress/recovery requirements in #789 remain separate and open.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions