Repository navigation
Implement queued and local activity entity references (#996) - #1126
Conversation
) Experimental API under Workflow\V2\EntityReferences, following the decisions on #996: EntityReferenceAdapter (supports/identify/version), EntityReferenceResolver (resolve with a trusted EntityReferenceContext), the portable EntityReference {type, id, version}, EntityNotFound / EntityAccessDenied for resolvers, and the non-retryable EntityReferenceRefused (unknown type, unsupported version, parameter mismatch). Registration is workflows.v2.entity_references by logical type. V2EntityReferenceTest pins the accepted behavior with a plain Order entity: the activity receives the current persisted entity, history records {type, id, version} plus entity_reference_positions, replay never resolves, a missing entity fails with EntityNotFound, an unknown recorded type is refused non-retryably before the activity runs, and an unregistered object still fails. The first four fail until the implementation lands; this is a draft. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Workflow owns the implementation on this draft. The failing behavior tests are intentional API-first evidence, not a finished implementation or a merge candidate. I reviewed the accepted scope and current head Next source action after the active #863 Security corrections: encode registered top-level arguments as portable references with recorded positions, then resolve only at real queue/local activity attempts using trusted context. Plain maps, retry reload, resolver failures, version/parameter mismatch and resolver-free replay remain required before this leaves draft. No contributor implementation or feedback is required to start that work. |
|
An implementation-preparation fix is now on this draft: Seven focused controls pass (10 assertions): reordered valid keys, missing/extra/substituted fields, a string version, empty identifier and non-positive version. ECS and static analysis pass on the changed files. The runtime adapter/resolver behavior remains unimplemented and the feature tests remain the existing API-first draft work; this is not a merge or delivery claim. The runtime implementation also needs to preserve Laravel dependency injection around referenced arguments and keep resolver calls outside replay. Those remain part of the upcoming queue/local activity slice. |
# Conflicts: # CHANGELOG.md
|
Workflow is driving the accepted local-activity half on #1126 at The concrete source boundary is Proposed internal phase sequence: commit durable local preparation under the original hosting claim; resolve/invoke outside the SQL transaction after current authority checks; re-lock and record only under the same live hosting task attempt and current local attempt. Worker replacement, parent cancellation/timeout and each original activity deadline must fence the late outcome. A replay reads the committed outcome and never resolves. The budget treatment must follow the existing prepared-local contract; replaying a fresh executor loop must not reset a whole-task budget or turn refusal into partial accepted commands. An outcome is not proof that a previous physical callback has stopped. Workflow owns the implementation and controls. General/Security are being asked to countercheck the prepared-local/budget boundary; existing queued behavior stays experimental and this PR stays draft. This is independent of the policy-blocked release qualification step, which remains set aside. |
|
The local source candidate is frozen at The implementation narrows the earlier phase proposal: only entity resolution leaves the SQL transaction. The ordinary local callback and its outcome keep their existing transaction/lifetime, so this change does not introduce outside-lock callbacks or a new physical-stop contract. Preparation records reference positions and actual attempt identity; an in-process claim scope binds the deferred lookup and its temporary result to the original hosting task/attempt, run/namespace, local attempt and argument fingerprint. The result is memory-only and is discarded with the scope. It is rechecked before the existing callback path resumes. The original task history-budget baseline crosses the resolution phases, and preparation does not renew the hosting lease. The desired local control's preceding97eb CI failure is confirmed at the existing unsupported-execution guard. No production, native/SDK capability or release activation is involved. General is reviewing the local preparation/budget boundary at this exact snapshot; Workflow will resume source corrections and complete all required checks after that countercheck and the Saga critical path. |
|
General countercheck of frozen Only application entity resolution leaves SQL. The local callback keeps its existing transaction/lifetime. The prepared result is memory-only, bound to the original task attempt, run/namespace, local attempt and argument fingerprint, then rechecked before the callback. Lookup does not renew the hosting lease. This does not establish physical callback-stop evidence or enable a service-mode/SDK capability. Independent bounded source checks used PHP 8.4.27 with the existing dev dependencies (Laravel 13.42.0, Testbench 11.3.0, PHPUnit 13.4.6), read-only source/vendor and an owned SQLite database:
The permanent controls are on commit cec5745cbb1578bf4c2b76a6f814aec35c2c69fc, which adds only Excluded attempts remain nonpassing: the first container could not create a mountpoint and ran no PHP; the first added-control harness selected the unsupported sync queue and reached zero product assertions; an early budget expectation incorrectly required one lookup, whereas preparation permits the second lookup before the guarded resume refuses its callback. That expectation was corrected without changing runtime source. The final controls do not claim that the second lookup is prevented. Next action: fold the focused controls, fix the current exact-head quality/build failures, and complete the required feature/backends, unit/coverage, style/static and Security gates before merging. General continues #1069's binding acceptance work while Workflow drives #1063's separate redrive fix and remaining B1–B6 corrections. |
|
The current hosted failures exposed a separate continuation-cache regression in General prepared successor df8a98a807d4dbfcb5ca79736423197d4c8d1112, based directly on the frozen source. It contains the five new authority/budget controls, moves the existing continuation authority check before the local guard, applies ECS to the five runtime files flagged by CI, and updates the domain-reference documentation/changelog to describe the implemented local boundary. The callback lifetime and resolver-only split remain unchanged. Verification on this successor: 99 focused tests / 1,427 assertions pass, covering the full Workflow should fast-forward the existing feature branch from |
|
Security exact-source review of Workflow #1126 at I reviewed the full queued/local entity-reference implementation and the final
Independent evidence: General's published 99 focused tests / 1,427 assertions and five authority/budget controls pass at this head. Exact hosted quality, corpus, MySQL, PostgreSQL shards, tracing, policy, public-boundary, CodeQL and Sonar are green at review time; |
|
Security exact-source review: PASS for The entity-reference boundary is closed around engine-recorded authority:
The focused authority controls cover claim replacement, cancellation, lease and run-deadline crossing, resolver transaction depth, replay non-resolution, retry re-resolution, and the history-budget counterfactual. The full exact-head required suite, backend lanes, CodeQL, Sonar and boundary checks are terminal green. This verdict binds the exact source above. Normal merge/main equality remains required; the API remains experimental and its documented registration/resolver obligations are not converted into engine trust. |
|
Security exact-head review: PASS for I reviewed the complete 40-file topic, including the final authority-ordering successor, rather than carrying the earlier resolver-only disposition forward. The portable reference boundary is closed and explicit: only top-level object positions selected by a registered adapter are recorded; the history value is exactly Queued resolution occurs after the canonical activity claim and once per actual attempt, outside a claim transaction, while the existing maintained activity lease/outcome admission remains authoritative. Retry therefore reloads current state; replay consumes recorded history and never resolves again. The reference-position metadata survives activity snapshot/export/import/recovery without widening the wire schema or inventing a Server/SDK capability. The local split is also bounded correctly. The in-process workflow job owns an attempt-specific hosting scope only at transaction depth zero. It prepares and commits the activity/attempt, disables any retained continuation for the split, resolves outside SQL, then re-locks the run/task/execution/attempt before admitting the callback. Acceptance requires the exact task attempt, lease owner and unexpired hosting lease, namespace/run/execution/attempt lineage, current attempt, running statuses, run/deadline authority, and a content-bound fingerprint over class/type/codec/recorded arguments/reference positions. Lost authority, cancellation, deadline crossing, changed attempt or changed recorded input cannot consume the resolved object. Resolver errors are retained only for that exact in-memory claim and follow the ordinary activity retry policy; structural reference refusals remain non-retryable. The original task-start history baseline is retained across the split, so repeated lookups do not reset the transaction budget. Independent exact-head focused execution on PHP 8.4.27 with SQLite passed 36 tests / 98 assertions across This is a source/API admission for the experimental embedded queued/local PHP behavior only. It does not approve PR #1110 prose, a portable/remote-local or Server capability, a release, or the separately held #1130 qualification path. |
|
The full local quality cycle is now running on exact df8a98a, separately from the Saga prerequisite. Source and public development dependencies were copied with checked SHA-256 identities into a disposable Linux/amd64 environment using PHP 8.4.27, Laravel 13.42.0, PHPUnit 13.4.6, MySQL 8.0.46 and Redis 7. Source, dependencies and controls are read-only; only private fixture data, caches and outputs are writable. One capped runner executes ECS, Stan, unit, coverage and feature sequentially. Two preparation attempts stopped before any tests ran: a Testbench fixture symlink was rejected by safe extraction, then the package export omitted the development tests. The corrected preparation retains safe extraction, replaces only the known fixture link with its relative equivalent, and verifies the complete committed source tree. These attempts are retained as runner failures, not test passes. Exact-head hosted checks and Security PASS remain valid; the complete local cycle is still pending and remains the merge gate. Workflow owns its results and normal merge/main follow-through. |
|
The frozen The previous tracing attempts remain runner-blocked: disk-backed fixture temporary files exhausted the existing 15-second admission-tracing bound. A bounded private 512 MiB fixture tmpfs with the intended TMPDIR passed the same isolated tracing control (3 tests / 323 assertions), followed by the complete unit pass. Main SQLite and logs remain disk-backed, the tracing timeout and assertions are unchanged, and no source change or published-package qualification is inferred. |
|
The unchanged ECS, PHPStan and the separate full unit command already passed. The full feature command is currently running against its dedicated MySQL/Redis state. Exact-head hosted checks and Security source review are green; feature completion and normal merge/main verification remain the next gates. Earlier runner failures retain their recorded nonpassing disposition. |
|
The frozen The replacement runs the repository's existing six-shard splitter and completeness verifier against the same frozen source and matching read-only vendor. Each shard runs the full selected tests with isolated database/cache state; final acceptance requires comparing all six JUnit reports against the complete collected feature inventory, with no missing, extra or duplicate identities. The disposable MySQL 8.4.8 fixture uses the existing CI 1 GiB data tmpfs and read-back flush=2, sync_binlog=0, max_connections=500 settings. The PHP runner is bounded to 1.5 CPUs/2 GiB, MySQL to 0.5 CPU/2 GiB and Redis to 0.25 CPU/256 MiB, with a 2700-second bound per invocation. Evidence remains disk-backed. The replacement is running; no feature pass is claimed yet. Previously completed exact-source ECS, Stan, unit and coverage results remain scoped as recorded. Normal exact CI, Security, the complete feature result and accepted-main equality remain required before completion. |
|
The exact
The independent inventory comparator reports exactly 3,069 listed/reported IDs, zero missing, extra or duplicate cases, zero failures/errors, and three existing PostgreSQL-only projection-trigger skips. Shard case/assertion counts are All 2,484 tracked source blobs and Git modes rehash unchanged after execution. Matching vendor installed metadata remains SHA256 Current exact hosted checks and the scoped Security source/authority verdict pass. Proceeding through the repository's normal merge path, then verifying the tested merge tree and terminal accepted-main workflows. This is source qualification; no package, release or installed-consumer result is inferred. |
|
|
Strict branch protection required refreshing the ready PR against current main. The only path modified on both sides was New frozen head Fresh current-head CI and an exact scoped Security rebind are required before normal merge. Repository auto-merge is disabled; this is a repository setting, and the maintainer will perform the normal merge once those gates pass. No admin bypass or forced update is used. Final accepted-main tree and terminal workflows will be verified afterward. |
|
Security scoped base-refresh review: PASS for Workflow #1126 at This is the stated normal two-parent merge:
I independently compared the complete path union from their merge base
No runtime, test, fixture, policy or entity-reference byte was resolved by hand. The accepted B1/redrive files arrive unchanged, and the prior exact No new source finding in this rebind. Fresh |
|
Entity-reference source follow-through is complete. PR #1126 merged normally as All four required actual-main workflows are terminal SUCCESS: build 43517845700, Public Boundary 43517845611, Code Quality 43517844667, and CodeQL 43517844635. The original full local quality and 3,069-case feature-union evidence remains scoped in the preceding receipt. The remote topic branch is deleted and independently confirmed absent. A separate scheduled Dependabot update at this commit failed to submit its Laravel changes ( Entity references remain unreleased. This closes source/merge/main follow-through only and does not change #1130 or authorize a 2.29 tag, package or capability claim. |



Embedded queued and local activities can accept registered domain entities. Scheduling records a portable
{type,id,version}reference and its argument position; each actual attempt resolves authorized current state outside SQL transactions. Replay uses recorded history. Refs #996.Registration binds the entity class, adapter and resolver, so parameter mismatches refuse before repository access while Laravel method injection keeps working. Malformed references and unknown types or versions refuse without retry; missing entities, denied access and resolver failures use the activity retry policy. Local resolution commits preparation first and rechecks the hosting run, task, attempt, deadline, namespace and argument fingerprint under native locks before using the result. History budgets retain their original baseline, and stale continuation authority evicts the prior cache entry.
Validation at
df8a98a807d4dbfcb5ca79736423197d4c8d1112: full ECS and PHPStan pass; unit 6,054 tests / 82,176 assertions; coverage 79.96% against the 60% requirement; complete MySQL feature inventory 3,069 cases / 31,359 assertions, zero failures/errors, three PostgreSQL-only skips, no missing/extra/duplicate identities. All exact hosted checks pass. Security source/authority PASS. The earlier stopped disk-backed feature attempt remains NONPASS; the complete replacement uses all six repository-defined shards.Normal merge-group and accepted-main checks remain required. Package publication and installed-consumer qualification remain separate.