Repository navigation
feat(session): add fenced durable task-owner provisioning API - #6303
Conversation
Known owner roots must be verified before construction can repair security. Capture immutable owner authority only when actual managed staging and replacement writers are quiescent, and preserve exact native dispositions. Lore-id: 65e28dc3 Constraint: no owner producer activation or synthetic native completion Confidence: high Scope-risk: narrow Reversibility: easy Tested: actual independent managed staging and replacement fd processes Tested: 19 access and GC codec tests 105 assertions plus package types Tested: 139-pass storage codec access union with 8 existing skips Not-tested: full persistent owner and GC SDK consumer activation
Retained Linux stores publish inside native code, so their store method never opens the JavaScript path publisher's UUID staging window. Use the existing managed path publication and checked replacement APIs directly to hold genuine cross-process descriptors without faking native authority or skipping probes. Lore-id: 54fa128d Constraint: original native result and publication guards remain unchanged Confidence: high Scope-risk: narrow Reversibility: easy Tested: owner access tests on Darwin with genuine independent writer processes Not-tested: fresh Linux and Windows CI at the new head
Give one logical session a fenced manifest-backed output tree independent of movable transcript basenames. Restore exact known owners without repairing replacements and publish only after verified durable copying. Lore-id: 916eb83c Constraint: no SessionManager or task producer activation yet Confidence: high Scope-risk: narrow Reversibility: easy Tested: independent owner setup contention copy lock-fence and manifest-conflict cases Tested: 41 owner capability tests 231 assertions plus vendor Biome types Not-tested: final persistent task move integration in this API prefix
|
Exact new head |
probepark
left a comment
There was a problem hiding this comment.
Review (head 0ea1cdc, gajae-reviewer on behalf of probepark)
CI: green. All planned checks for this head passed, including check:@gajae-code/coding-agent, Virtual integration validation (9m17s), the targeted task-artifact-owner-{access,provisioning} tests and the Windows session-path regression. Only the human-approval gate checks are still open.
Scope: +1632 / -1, 6 files. 626 production lines: managed-session-storage.ts +107/-1, internal/task-artifact-owner-access.ts +229, task-artifact-owner.ts +289. The remaining 1007 lines are tests and fixtures.
Conventions: no changelog fragment; no generated files; no labels; no console.*, new Worker, mock.module or .gjc additions.
Notable:
packages/coding-agent/src/session/task-artifact-owner.ts:185-198vs:225-246: provisioning creates the owner directory (ensureDirectory), optionally copies the legacy tree, and publishesOWNER_MANIFESTlast. If the process dies between those steps, the directory stays without a manifest. On the nextensureManagedTaskArtifactOwner(…, undefined)call, theexistingDirectorybranch then throwstask_artifact_owner_manifest_missingon every retry, so that session can never get an owner without manual cleanup. This matches the stated fail-closed design and the API is not called from production yet, so it does not block this PR. Before SessionManager/TaskTool start using it, decide how to recover from a manifest-less owner directory that this same owner id created.- Changelog: AGENTS.md:202 asks for
changelog.dfragments. The PR body says this layer is inert, with no user-visible default change, and the earlier commits in this series (c2f29e0, 5e37a07, f369cdd) also merged without fragments, so I am not blocking on it. The commit that turns on the runtime behaviour needs a fragment.
Checked and clean: the expectedSubtreeRoot fence in the ManagedSessionDescendantStore constructor rejects any path, dev or ino mismatch, before and after verification, on both the retained and the path-backed branch (managed-session-storage.ts:1516-1555). captureDirectoryIdentity re-lstats after retaining the descriptor. removeTreeExpectedWithParentIdentity rejects ../absolute parents and passes on the parent identity it re-captured, not the one the caller supplied. The legacy copy checks every source entry's dev, ino, size, mtime, ctime and sha256 and re-captures both trees at the end. lock.assertOwned() runs again right before the manifest is published. Each error path closes the stores (recordFailure + AggregateError).
Blocking: none
Verdict: gajae.pr-review-verdict.v1 merge-approved sha256:a4ea91844b59902e4168240e0a27815a99c2897dd7366f1c60ca67fba753adc4 reviewer:human reviewer-id:probepark evidence:ci-green;approve-gate-allow;check-coding-agent-covered;virtual-integration-green;source-626-read;fence-and-lock-checked
The PR body has no verdict line (count=0), so it was not updated. Suggested verdict line: gajae.pr-review-verdict.v1 merge-approved sha256:a4ea91844b59902e4168240e0a27815a99c2897dd7366f1c60ca67fba753adc4 reviewer:human reviewer-id:probepark evidence:ci-green;approve-gate-allow;check-coding-agent-covered;virtual-integration-green;source-626-read;fence-and-lock-checked
|
Merged into dev as
— |
Complete inert API layer
Exact head:
0ea1cdc58ab14b98da7b046752fb216d6f004e7e; integration base:33a29331e74aa39162238ec3f7fb9be8f5e19b85.Provides independently callable
ensureManagedTaskArtifactOwner/ restore behavior using captured profile/session/root authority, actual fenced locks, checked legacy-tree copy, fsync and manifest-last durable publication. Missing/replaced/mismatched owners fail closed instead of creating empty replacements. No automatic SessionManager owner production or TaskTool admission activation.Actual review budget
Production added + deleted versus current
dev: 626, under the 800 maximum and 650 target. This is not a parent-relative claim: it includes readonly access prerequisites from #6292 (337) plus provisioning (289). The access fixture repair is also included in tests. If #6292 lands first, this head must be re-integrated and freshly qualified; no old approval transfers. No GC codec dependency is included because provisioning does not consume it.Complete atomic commits preserve ownership: readonly access, real cross-platform path-writer fixture, then provisioning. Tests/fixtures excluded from production count: access482, writer184, provisioning341.
Executed exact-head verification
Clean QA checkout before and after; genuine strict
0.18.5native dependency, metadata not rewritten:3708c0a4a667f5aa87d7d1fe39f7f003cdb79c141af9cf920e939843cfaf9dbe26555fb71debdd40e0cdb70811847765452facd4cbb4107b646df7cc1a25dcafbun test packages/coding-agent/test/task-artifact-owner-provisioning.test.ts packages/coding-agent/test/task-artifact-owner-access.test.ts packages/coding-agent/test/task-artifact-owner-codec.test.ts packages/coding-agent/test/session-storage.test.ts: 137 pass / 8 existing platform skips / 0 fail / 612 assertions.bun --cwd=packages/coding-agent run check: vendor, Biome and TypeScript exit 0; baseline two warnings/one info retained. Local qualification ID06-owner-provisioning-independent-base33a293; new-head CI/review is pending, not presumed.Safe intermediate and preservation
Real concurrent provisioning, manifest failures, identity swaps, owner restore and both genuine staging/replacement writer guards are exercised through production APIs. Locator/DTOs are data, not deletion permission. This API-only layer stays inert until all deletion/replay consumers qualify; no user-visible runtime default changes, so no release-note fragment is added here.
Upstream SDK MCP initialize-negotiation changes in base33a are retained unchanged. Original protected 44 staged candidate and PR #6240 reference
7e5f7ef2a745bc1c3d012362f00be9a441bdeb76are unchanged. Historical owning/dependent preparations are not current-head approvals.Darwin execution only; no Linux/Windows live native retirement, arbitrary FD revocation, provider/GUI or final aggregate completion is claimed. The leader does not merge; exact-head write-access maintainer approval remains required.