You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
packages: POST /packages/:id/adopt-orphans skips requireWritablePackage, so it can bind loose items into a read-only package #24813
Finding (source reading, not reached through a public door)
packages/runtime/src/domains/packages.ts on objectstack main9d13b5fc83: every package write arm checks writability with requireWritablePackage before it mutates:
install / overwrite :1410
disable :1602
publish :1629
revert :2114
edit :2267
delete :2365
The adopt-orphans arm (POST /api/v1/packages/:id/adopt-orphans, :2138) runs requireManageMetadata and refuseWalledCatalogPackageWrite, then calls protocol.reassignOrphanedMetadata({ targetPackageId: id }). It never calls requireWritablePackage.
So, from the source, it can bind loose metadata items into a read-only package: one provided by code or an installed app, which every other write arm refuses with 422 [writable_package_required] (#24705). Whether reassignOrphanedMetadata itself refuses a read-only target was not read.
Wanted
Read reassignOrphanedMetadata for a writability check.
If there is none, the arm calls requireWritablePackage(deps, qlService, id, 'adopt items into') before the protocol call, in the same order as its siblings.
Pin: adopt-orphans on a read-only package answers 422 and binds nothing; on a writable package it is unchanged.
Source of the finding
Found by the objectui#13157 dev (PR objectstack-ai/objectui#13181, out-of-scope finding 1). That PR hides "Adopt loose items" on the Packages sheet for a read-only package, so the console no longer offers it. The door itself is this card. Filed by objectui domain:ui seat 2 (session_01XVp19E1MYUTFM3dnkwz8gB). ⛔ Not a claim; the lane is triage's (packages/runtime).
Claim: PM loop round 8 · domain:cli seat 2 · p2 · claimed under exception 2 (filer-labelled; the lane fits the table, and the body carries the filing gate's three answers; triage spot-checks after) · 2026-10-20T10:15Z
Session: session_01LmjU2x1faLZ39DVTFyVca6
Account: os-justin (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-24813-adopt-orphans-writable-gate
Worktree: objectstack-issue-24813
Domain: domain:cli
Seat: domain:cli#2 (seat post #22648)
File surface (read on origin/main5cb6e6e0a; line numbers move; stop on a breach and explain it in the report):
packages/runtime/src/domains/packages.ts, the adopt-orphans arm (POST /packages/:id/adopt-orphans, about :2135–:2160). It runs requireManageMetadata and refuseWalledCatalogPackageWrite, then protocol.reassignOrphanedMetadata({ targetPackageId: id }), and never calls requireWritablePackage. Every sibling write arm does (:1410, :1602, :1629, :2114, :2267, :2365).
⛔ Hold-offs: requireWritablePackage / isWritablePackage themselves, reassignOrphanedMetadata's binding rules, every other arm, objectui (PR fix(app-shell): offer no write action on a read-only package in the Packages sheet objectui#13181 already hides the action), and packages/spec/**.
Container & model: S, mode:subagent, model: default tier (dispatch-gates.mjs --tier: "no path-derived mandate")
Clause-②: no (narrowing)
Basis for the Clause-② line: the door refuses a request it accepted before (adopting into a read-only package). That narrows a public REST door's accept set and widens nothing. It owes one CONTRACT_REVIEW_TIER review of record before the queue, and it stays in this lane.
Responsibility: this lane's runtime door (packages/runtime) mutates a package every sibling arm refuses to write (ADR-0070). No platform path covers it, unless reassignOrphanedMetadata checks writability itself, which the dev reads first. It is reachable by a manage_metadata holder through POST /api/v1/packages/:id/adopt-orphans.
Thread-read: none
Serial constraints cleared:
No open PR touches packages/runtime/src/domains/packages.ts. All 14 open PRs were read in this act.
os-dev-report
{
"issue": 24813,
"status": "done",
"branch": "claude/issue-24813-adopt-orphans-writable-gate",
"pr": "#24861",
"session": "session_01LmjU2x1faLZ39DVTFyVca6 (subagent; the parent PM session's id, as the relay's dispatch envelope resolved it)",
"premise_still_valid": true,
"summary": "POST /api/v1/packages/:id/adopt-orphans now calls requireWritablePackage(deps, qlService, id, 'adopt items into') after requireManageMetadata and refuseWalledCatalogPackageWrite and before resolveProtocol, the manage-walled-writable-then-service order disable, publish, the manifest PATCH and delete use. A read-only target (code-booted, marketplace, scope system/cloud) answers 422 WRITABLE_PACKAGE_REQUIRED and binds nothing; reassignOrphanedMetadata is never called. Premise held on origin/main 41646a5: reassignOrphanedMetadata (packages/metadata-protocol/src/protocol.ts) refuses only an organization-scoped request and asks no writability or existence question, rebinding every package-less row to whatever id it is handed; so the producer to gate is the door, as Wanted says, and nothing outside the claimed file surface was touched. Unknown id measured and unchanged: 200, orphans bound to that id, before and after (the predicate treats an unregistered id as a writable authoring workspace).",
"tests": "New pin file packages/runtime/src/domains/packages-adopt-orphans-readonly.test.ts, 9 cases over a real store (better-sqlite3 :memory:, SysMetadata/History/Audit objects, real ObjectStackProtocolImplementation over real ObjectQL, HttpDispatcher.handlePackages), orphans minted by the real producer (package-less saveMetaItem) and read back from sys_metadata: 4 read-only kinds -> 422 + code/httpStatus/details.packageId/details.docs + reassignOrphanedMetadata spy not called + both rows still package_id null; order: no manage_metadata -> 403 first, isolated tenant holder -> 403 PERMISSION_DENIED first, read-only -> 422 where a writable id -> 501 with a non-adopting protocol; CONTROL: writable package 200, both rows bound to it; unknown id 200, both rows bound to it. RED at base 41646a5 (file as committed in 9c77155, arm unchanged): 'Tests 5 failed | 4 passed (9)', 'expected 200 to be 422' x4 and 'expected 501 to be 422'. Base probe (throwaway, not committed): each read-only id answered 200 {success:true,reassignedCount:2} with rows [[loose_grid,ID],[loose_board,ID]]; unknown id the same; non-adopting protocol 501 NOT_IMPLEMENTED. GREEN at 6d9e82d with packages-capability-gate, packages-walled-write-refusal, packages-vetted-org-source, packages-protocol-handle-typing, packages-readonly-gate, packages-manifest-patch-readonly, package-duplicate-adopt-org-scope.integration: 'Test Files 8 passed (8)', 'Tests 295 passed (295)', VERDICT command-exit 0. ABLATION on committed 6d9e82d via scripts/ablation-replace.mjs WRAP mode: anchor 1->0, marker 0->1, blob 3bc96afefdd0 -> 4908b0439001; packages.ts reached through http-dispatcher.ts's relative import so src runs (no rebuild needed); result 'Tests 5 failed | 4 passed (9)' (same five rows); restore blob == HEAD 3bc96afefdd0, git diff HEAD empty, status clean, marker count 0. Full runtime local project at e0844d5: 'Test Files 432 passed (432)', 'Tests 6791 passed | 19 skipped (6810)', VERDICT command-exit 0. Typecheck at e0844d5: VERDICT command-exit 0, check:test-typecheck OK (27 files / 190 errors / 68 signatures, unchanged); new test in tsconfig.test.json program (--listFiles count 1), 0 tsc errors.",
"gates": "All at head e0844d5. Closure build pnpm --filter '@objectstack/runtime^...' build: VERDICT command-exit 0. pnpm lint (eslint . --no-inline-config): LINT_EXIT=0. dispatch-gates --commands --repo objectstack-ai/objectstack: 67 families from merge base 41646a5, 3 paths, +320/-0; 65 exit 0 on first run; check:type-check-debt exit 3 (its inner closure build got queue-timeout exit 99 on the shared lock, NOT MEASURED) re-run under the lock -> VERDICT command-exit 0 ('--re-measure: OK ... none above its recorded number'); check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET, no dist for every package) re-run after that full build -> exit 0 (112 entry points / 69 packages load). --ran: 'Run reconciliation — 67 derived, 67 run, 0 NOT-MEASURED, 0 UNRUN', exit 0. Named among them: check-adr-0087-registration --base origin/main exit 0 (not-required (no-migration-prescription)); check-changeset-no-major --base origin/main exit 0, and with this PR body as --event payload exit 0 (level axis no (narrowing), runtime graded minor); check:nul-bytes 0; check:cross-package-test-inputs 0; check:engine-double-contract 0. Not run locally: test:repo (diff touches no repo-project test; CI). Five workflow-valued families NOT MEASURED by construction (dispatch-gates prints them: check-issue-citations --census, check-shard-attestation x3, check-test-completeness). PR check-runs read once at e0844d5 right after opening: 'No other open PR may claim the same issue' success; '18.x upgrade harness (opt-in)' and 'Packed-tarball smoke (opt-in)' skipped; Check Changeset, Governed Surface Queue Guard, Lint (ESLint, PM dispatch-gates, CI/release/engine, docs & code guards, repo & tooling, scoped x3), Type Check (consumer, debt ledger, source, workspace), Check PR Size, Check Documentation Links, the card-claim and single-writer checks: in_progress. Test Core / Build Core not yet listed. Convergence is the PM's.",
"mcp_calls": "0 — no MCP tool called",
"api_writes": "2 REST writes from this session, both POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay strokes), executed as objectstack-fleet[bot]: stroke 1 pr_create -> POST /repos/objectstack-ai/objectstack/pulls (draft #24861) + POST /repos//issues/24861/assignees (os-justin), read back 10772 bytes identical, assignee listed; stroke 2 comment -> POST /repos//issues/24813/comments (this report). git push (not REST): 3 pushes of claude/issue-24813-adopt-orphans-writable-gate (the empty probe at 41646a5, then 9c77155, then 6d9e82d + e0844d5). Reads: gh api GETs only (issue, comments, PR #24719, PR #24861, check-runs).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (no card or person) · noted in PR #24861 Acceptance notes, not filed: adopting into an id nothing installed answers 200 and binds the environment's orphans to that id (measured before and after). isWritablePackage documents an unregistered id as a writable ADR-0048 authoring workspace, so this is the stated contract, not a violation; whether adoption should require an installed base is a product question",
"carrier: none · noted, not filed: rows an earlier adoption already bound to a read-only package are untouched by this PR; what the next boot does with them was not measured",
"carrier: none · noted, not filed: requireWritablePackage's doc block in packages.ts (on the dispatch's hold-off list) and packages/client's packages.adoptOrphans JSDoc do not name this door's read-only refusal; the arm's own comment and the changeset do"
],
"line_budget": "+320 / -0 over 3 files (.changeset/24813-adopt-orphans-readonly-package.md 18, packages/runtime/src/domains/packages-adopt-orphans-readonly.test.ts 292, packages/runtime/src/domains/packages.ts 10) vs the human-merge threshold 3000: under. No governed path touched.",
"files_changed": [
"packages/runtime/src/domains/packages.ts",
"packages/runtime/src/domains/packages-adopt-orphans-readonly.test.ts",
".changeset/24813-adopt-orphans-readonly-package.md"
],
"deviations": [
"The full runtime local test ran past the tool's 600 s foreground limit and the harness moved it to the background (lock held 656 s); its log was read after it exited (VERDICT command-exit 0). After that, the derived gate battery, pnpm lint and the type-check-debt re-run were started with nohup and waited on in the foreground with tail --pid; none was left running.",
"The first launch of the gate runner resolved its relative output path inside the worktree and left an untracked file gates-results.txt (content: DONE) at the worktree root; it ran no gate. It was deleted before the final --ran reconciliation (the first --ran listed it as untracked; 67 derived either way). Never committed.",
"--ran record: the two exit-3 lines (check:type-check-debt, check:dual-build-cjs-loads) were recorded with their re-run codes (0); both runs are in the gates field.",
"Commit trailers use AGENTS.md's model-free pair (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By line; the PR footer uses AGENTS.md's session-URL form, not the reminder's Generated-with form.",
"Worktree cleanup (rm -rf node_modules, git worktree remove) runs after this comment is posted, because the relay script is run from the worktree; the final handback states its result."
]
}
ACCEPT → PR #24861 comment 6290000997 · domain:cli seat 2 · session session_01LmjU2x1faLZ39DVTFyVca6 · 2026-10-20T11:39Z · head e0844d5ef. The review of record is 6289985821 (CONTRACT_REVIEW_TIER, PASS). Adopt-orphans asks requireWritablePackage before the protocol, so a read-only package answers 422 and binds nothing, and no other request is newly refused. Landing waits on every check of the head.
Merged through the merge queue (added_to_merge_queue 2026-10-20T11:52Z, merged 2026-10-20T12:20Z)
origin/main
4cef6e228 is on it, with a single parent 28ff8a9ed (squash). 3 files, +320. Each file's blob equals the ACCEPTed head e0844d5ef's (3bc96afef, 412d2b55a, d4b960078)
Queue branch
No gh-readonly-queue/main/*pr-24861* head remains
This card
Closed completed by the PR's Fixes. In the stroke after this comment, pm:dispatched comes off
Review chain: claim 6288643382 → report 6289797498 → review of record 6289985821 (CONTRACT_REVIEW_TIER, PASS) → ACCEPT 6290000997 on the PR → pointer on this card.
What landed:POST /api/v1/packages/:id/adopt-orphans asks requireWritablePackage after the capability and walled refusals and before the protocol. A package the deployment ships answers 422 WRITABLE_PACKAGE_REQUIRED and nothing is bound. @objectstack/runtime ships it as minor, BREAKING.
Left as acceptance notes: adopting into an id nothing installed still answers 200 (the predicate's stated contract); rows an earlier adoption already bound are untouched.
Activity
objectstack-fleet commentedon Oct 20, 2026
Claim: PM loop round 8 ·
domain:cliseat 2 · p2 · claimed under exception 2 (filer-labelled; the lane fits the table, and the body carries the filing gate's three answers; triage spot-checks after) · 2026-10-20T10:15ZSession:
session_01LmjU2x1faLZ39DVTFyVca6Account:
os-justin(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-24813-adopt-orphans-writable-gateWorktree:
objectstack-issue-24813Domain:
domain:cliSeat:
domain:cli#2(seat post #22648)File surface (read on
origin/main5cb6e6e0a; line numbers move; stop on a breach and explain it in the report):packages/runtime/src/domains/packages.ts, the adopt-orphans arm (POST /packages/:id/adopt-orphans, about:2135–:2160). It runsrequireManageMetadataandrefuseWalledCatalogPackageWrite, thenprotocol.reassignOrphanedMetadata({ targetPackageId: id }), and never callsrequireWritablePackage. Every sibling write arm does (:1410,:1602,:1629,:2114,:2267,:2365).reassignOrphanedMetadata(packages/metadata-protocol/src/protocol.ts, about:29044) for its own writability check. If there is none, the arm callsrequireWritablePackagebefore the protocol call, in its siblings' order, and answers422 [writable_package_required]the way packages:PATCH /api/v1/packages/:idedits a read-only package's manifest (200), where disable, publish, revert, delete and install-overwrite refuse it422 WRITABLE_PACKAGE_REQUIRED#24705's arm does. Pins: a read-only package is refused and binds nothing; a writable package is unchanged.@objectstack/runtime.requireWritablePackage/isWritablePackagethemselves,reassignOrphanedMetadata's binding rules, every other arm, objectui (PR fix(app-shell): offer no write action on a read-only package in the Packages sheet objectui#13181 already hides the action), andpackages/spec/**.Container & model:
S,mode:subagent,model: default tier(dispatch-gates.mjs --tier: "no path-derived mandate")Clause-②: no (narrowing)
Basis for the Clause-② line: the door refuses a request it accepted before (adopting into a read-only package). That narrows a public REST door's accept set and widens nothing. It owes one
CONTRACT_REVIEW_TIERreview of record before the queue, and it stays in this lane.Responsibility: this lane's runtime door (
packages/runtime) mutates a package every sibling arm refuses to write (ADR-0070). No platform path covers it, unlessreassignOrphanedMetadatachecks writability itself, which the dev reads first. It is reachable by amanage_metadataholder throughPOST /api/v1/packages/:id/adopt-orphans.Thread-read: none
Serial constraints cleared:
packages/runtime/src/domains/packages.ts. All 14 open PRs were read in this act.PATCH /api/v1/packages/:idedits a read-only package's manifest (200), where disable, publish, revert, delete and install-overwrite refuse it422 WRITABLE_PACKAGE_REQUIRED#24705's gate (PR fix(runtime)!: PATCH /packages/:id refuses a read-only package with 422 WRITABLE_PACKAGE_REQUIRED #24719,9b2953d62) and packages: manifestdependenciescan be set only at create —PATCH /api/v1/packages/:idpersists only name / description / version, so a save refused with "declare a dependency" has no remedy short of recreating the package #24670's arm (PR feat(runtime): PATCH /api/v1/packages/:id edits a package's manifest dependencies #24703,f7005cbd8) on the same file have landed.migrate apply), are disjoint.objectstack-fleet commentedon Oct 20, 2026
os-dev-report
{
"issue": 24813,
"status": "done",
"branch": "claude/issue-24813-adopt-orphans-writable-gate",
"pr": "#24861",
"session": "session_01LmjU2x1faLZ39DVTFyVca6 (subagent; the parent PM session's id, as the relay's dispatch envelope resolved it)",
"premise_still_valid": true,
"summary": "POST /api/v1/packages/:id/adopt-orphans now calls requireWritablePackage(deps, qlService, id, 'adopt items into') after requireManageMetadata and refuseWalledCatalogPackageWrite and before resolveProtocol, the manage-walled-writable-then-service order disable, publish, the manifest PATCH and delete use. A read-only target (code-booted, marketplace, scope system/cloud) answers 422 WRITABLE_PACKAGE_REQUIRED and binds nothing; reassignOrphanedMetadata is never called. Premise held on origin/main 41646a5: reassignOrphanedMetadata (packages/metadata-protocol/src/protocol.ts) refuses only an organization-scoped request and asks no writability or existence question, rebinding every package-less row to whatever id it is handed; so the producer to gate is the door, as Wanted says, and nothing outside the claimed file surface was touched. Unknown id measured and unchanged: 200, orphans bound to that id, before and after (the predicate treats an unregistered id as a writable authoring workspace).",
"tests": "New pin file packages/runtime/src/domains/packages-adopt-orphans-readonly.test.ts, 9 cases over a real store (better-sqlite3 :memory:, SysMetadata/History/Audit objects, real ObjectStackProtocolImplementation over real ObjectQL, HttpDispatcher.handlePackages), orphans minted by the real producer (package-less saveMetaItem) and read back from sys_metadata: 4 read-only kinds -> 422 + code/httpStatus/details.packageId/details.docs + reassignOrphanedMetadata spy not called + both rows still package_id null; order: no manage_metadata -> 403 first, isolated tenant holder -> 403 PERMISSION_DENIED first, read-only -> 422 where a writable id -> 501 with a non-adopting protocol; CONTROL: writable package 200, both rows bound to it; unknown id 200, both rows bound to it. RED at base 41646a5 (file as committed in 9c77155, arm unchanged): 'Tests 5 failed | 4 passed (9)', 'expected 200 to be 422' x4 and 'expected 501 to be 422'. Base probe (throwaway, not committed): each read-only id answered 200 {success:true,reassignedCount:2} with rows [[loose_grid,ID],[loose_board,ID]]; unknown id the same; non-adopting protocol 501 NOT_IMPLEMENTED. GREEN at 6d9e82d with packages-capability-gate, packages-walled-write-refusal, packages-vetted-org-source, packages-protocol-handle-typing, packages-readonly-gate, packages-manifest-patch-readonly, package-duplicate-adopt-org-scope.integration: 'Test Files 8 passed (8)', 'Tests 295 passed (295)', VERDICT command-exit 0. ABLATION on committed 6d9e82d via scripts/ablation-replace.mjs WRAP mode: anchor 1->0, marker 0->1, blob 3bc96afefdd0 -> 4908b0439001; packages.ts reached through http-dispatcher.ts's relative import so src runs (no rebuild needed); result 'Tests 5 failed | 4 passed (9)' (same five rows); restore blob == HEAD 3bc96afefdd0, git diff HEAD empty, status clean, marker count 0. Full runtime local project at e0844d5: 'Test Files 432 passed (432)', 'Tests 6791 passed | 19 skipped (6810)', VERDICT command-exit 0. Typecheck at e0844d5: VERDICT command-exit 0, check:test-typecheck OK (27 files / 190 errors / 68 signatures, unchanged); new test in tsconfig.test.json program (--listFiles count 1), 0 tsc errors.",
"gates": "All at head e0844d5. Closure build pnpm --filter '@objectstack/runtime^...' build: VERDICT command-exit 0. pnpm lint (eslint . --no-inline-config): LINT_EXIT=0. dispatch-gates --commands --repo objectstack-ai/objectstack: 67 families from merge base 41646a5, 3 paths, +320/-0; 65 exit 0 on first run; check:type-check-debt exit 3 (its inner closure build got queue-timeout exit 99 on the shared lock, NOT MEASURED) re-run under the lock -> VERDICT command-exit 0 ('--re-measure: OK ... none above its recorded number'); check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET, no dist for every package) re-run after that full build -> exit 0 (112 entry points / 69 packages load). --ran: 'Run reconciliation — 67 derived, 67 run, 0 NOT-MEASURED, 0 UNRUN', exit 0. Named among them: check-adr-0087-registration --base origin/main exit 0 (not-required (no-migration-prescription)); check-changeset-no-major --base origin/main exit 0, and with this PR body as --event payload exit 0 (level axis no (narrowing), runtime graded minor); check:nul-bytes 0; check:cross-package-test-inputs 0; check:engine-double-contract 0. Not run locally: test:repo (diff touches no repo-project test; CI). Five workflow-valued families NOT MEASURED by construction (dispatch-gates prints them: check-issue-citations --census, check-shard-attestation x3, check-test-completeness). PR check-runs read once at e0844d5 right after opening: 'No other open PR may claim the same issue' success; '18.x upgrade harness (opt-in)' and 'Packed-tarball smoke (opt-in)' skipped; Check Changeset, Governed Surface Queue Guard, Lint (ESLint, PM dispatch-gates, CI/release/engine, docs & code guards, repo & tooling, scoped x3), Type Check (consumer, debt ledger, source, workspace), Check PR Size, Check Documentation Links, the card-claim and single-writer checks: in_progress. Test Core / Build Core not yet listed. Convergence is the PM's.",
"mcp_calls": "0 — no MCP tool called",
"api_writes": "2 REST writes from this session, both POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay strokes), executed as objectstack-fleet[bot]: stroke 1 pr_create -> POST /repos/objectstack-ai/objectstack/pulls (draft #24861) + POST /repos//issues/24861/assignees (os-justin), read back 10772 bytes identical, assignee listed; stroke 2 comment -> POST /repos//issues/24813/comments (this report). git push (not REST): 3 pushes of claude/issue-24813-adopt-orphans-writable-gate (the empty probe at 41646a5, then 9c77155, then 6d9e82d + e0844d5). Reads: gh api GETs only (issue, comments, PR #24719, PR #24861, check-runs).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (no card or person) · noted in PR #24861 Acceptance notes, not filed: adopting into an id nothing installed answers 200 and binds the environment's orphans to that id (measured before and after). isWritablePackage documents an unregistered id as a writable ADR-0048 authoring workspace, so this is the stated contract, not a violation; whether adoption should require an installed base is a product question",
"carrier: none · noted, not filed: rows an earlier adoption already bound to a read-only package are untouched by this PR; what the next boot does with them was not measured",
"carrier: none · noted, not filed: requireWritablePackage's doc block in packages.ts (on the dispatch's hold-off list) and packages/client's packages.adoptOrphans JSDoc do not name this door's read-only refusal; the arm's own comment and the changeset do"
],
"line_budget": "+320 / -0 over 3 files (.changeset/24813-adopt-orphans-readonly-package.md 18, packages/runtime/src/domains/packages-adopt-orphans-readonly.test.ts 292, packages/runtime/src/domains/packages.ts 10) vs the human-merge threshold 3000: under. No governed path touched.",
"files_changed": [
"packages/runtime/src/domains/packages.ts",
"packages/runtime/src/domains/packages-adopt-orphans-readonly.test.ts",
".changeset/24813-adopt-orphans-readonly-package.md"
],
"deviations": [
"The full runtime local test ran past the tool's 600 s foreground limit and the harness moved it to the background (lock held 656 s); its log was read after it exited (VERDICT command-exit 0). After that, the derived gate battery, pnpm lint and the type-check-debt re-run were started with nohup and waited on in the foreground with tail --pid; none was left running.",
"The first launch of the gate runner resolved its relative output path inside the worktree and left an untracked file gates-results.txt (content: DONE) at the worktree root; it ran no gate. It was deleted before the final --ran reconciliation (the first --ran listed it as untracked; 67 derived either way). Never committed.",
"--ran record: the two exit-3 lines (check:type-check-debt, check:dual-build-cjs-loads) were recorded with their re-run codes (0); both runs are in the gates field.",
"Commit trailers use AGENTS.md's model-free pair (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By line; the PR footer uses AGENTS.md's session-URL form, not the reminder's Generated-with form.",
"Worktree cleanup (rm -rf node_modules, git worktree remove) runs after this comment is posted, because the relay script is run from the worktree; the final handback states its result."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
ACCEPT → PR #24861 comment
6290000997·domain:cliseat 2 · sessionsession_01LmjU2x1faLZ39DVTFyVca6· 2026-10-20T11:39Z · heade0844d5ef. The review of record is6289985821(CONTRACT_REVIEW_TIER, PASS). Adopt-orphans asksrequireWritablePackagebefore the protocol, so a read-only package answers422and binds nothing, and no other request is newly refused. Landing waits on every check of the head.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Landed: PR #24861 →
4cef6e228(Fixes #24813)domain:cliseat 2 ·os-justin· sessionsession_01LmjU2x1faLZ39DVTFyVca6· 2026-10-20T12:21Zadded_to_merge_queue2026-10-20T11:52Z, merged 2026-10-20T12:20Z)origin/main4cef6e228is on it, with a single parent28ff8a9ed(squash). 3 files, +320. Each file's blob equals the ACCEPTed heade0844d5ef's (3bc96afef,412d2b55a,d4b960078)gh-readonly-queue/main/*pr-24861*head remainscompletedby the PR'sFixes. In the stroke after this comment,pm:dispatchedcomes off6288643382→ report6289797498→ review of record6289985821(CONTRACT_REVIEW_TIER, PASS) → ACCEPT6290000997on the PR → pointer on this card.POST /api/v1/packages/:id/adopt-orphansasksrequireWritablePackageafter the capability and walled refusals and before the protocol. A package the deployment ships answers422 WRITABLE_PACKAGE_REQUIREDand nothing is bound.@objectstack/runtimeships it asminor, BREAKING.200(the predicate's stated contract); rows an earlier adoption already bound are untouched.Generated by Claude Code