Repository navigation
metadata-protocol: two producers still store a second package's active row of an object that a runtime-authored row owns — a draft promoted after the owner's save, and a package-less owner — past ADR-0029 D9.9's save-door refusal (family close-out) #23630
Description
Blocked-by: #23495
Blocked-by: #23473
Filing gate ①, finding class (b), the close-out card for the ADR-0029 D9.9 family (the second-package refusal that PR #23510 landed for #23416).
reach: a public door, measured once. POST /api/v1/packages/com.probe.q/publish-drafts, at HttpDispatcher.handlePackages on a real stack, answered 200 (outcome published, failed: []). It stored an active row bound to com.probe.q of an object that a runtime-authored row of com.probe.p owns. The save door refuses that same row with 422 OBJECT_OVERLAY_PACKAGE_MISMATCH. This was measured at #23473's merge commit 192d2051da (main 8d05456cbe + PR #23504), in dev report 6187145964 on #23473.
Filed by domain:spec seat 4 (#18917) · sunhaolin · session session_0121ooBYRmS8ziFXm9ai5YHm, at PR #23504's re-review. ⛔ Not a claim. Lane, type and grade are triage's.
Reader who acts: triage, to grade and route the fix (packages/metadata-protocol; by the lane table, domain:engine); then the owning seat.
Dedupe: a semantic search of objectstack issues for "ADR-0029 D9.9 second package overlay package mismatch draft promote publish-drafts" returns 43 hits, closed included. None covers D9.9 on the promote path or the package-less owner. The nearest are:
- metadata-protocol: the draft doors naming no package resolve three addresses — the save and read inherit the active binding, the discard reads the draft rows, the publish takes the first draft row a package-agnostic findOne returns #23495 (open): the package-less draft doors resolve three addresses. That is a different defect: address resolution, not ownership.
- publishPackageDrafts can promote (and drain) ANOTHER package's draft row — the promote resolves the draft without the ADR-0048 package dimension #8907 (closed):
publishPackageDraftspromoted another package's draft (the ADR-0048 package dimension). - metadata-protocol: a save naming a package beside an existing package-less row of the item mints a second row, and the read naming no package keeps serving the unbound one (S6, reachable through today's doors) #23291 (closed by fix(metadata-protocol): the read naming no package serves the row the package-less save writes, beside a package-unbound row (S6) #23489): the S6 card. It held the sentinel-owner case at metadata-protocol: a save into a second package of an object a runtime-authored row owns answers 200 while the registry refuses the ownership —
classifyObjectContributionprotects code owners only (ADR-0029 D9.9) #23416's landing (6173278619) but closed without it; member 2 below is still live.
The family (enumeration pin)
The D9.9 refusal (overlayPackageMismatchError) is asked at the save door. Two producers still reach the state it refuses.
- A draft promoted after the owner's row exists.
- The sequence: Q's draft of object X is saved (
saveMetaItem, mode draft) before P's runtime-authored row of X exists. P's row is then saved. Q's draft is then promoted, either bypublishMetaItemnaming package Q, or byPOST /api/v1/packages/:id/publish-drafts(publishPackageDrafts). - Outcome: success. The rows become
[P, Q]and the registry still serves P. - Seam: the promote path (
promoteDraftForPublish/publishPackageDraftsinpackages/metadata-protocol/src/protocol.ts) does not ask the D9.9 question. The registry write-through (applyObjectRegistryMutation) then refuses to layer it, so the stored row is one nothing serves.
- The sequence: Q's draft of object X is saved (
- A package-less owner (the
sys_metadatasentinel).- The sequence: a save naming no package writes the unbound row first. Saves into P and Q then all succeed.
- Outcome: the rows become
[P, Q, package-less], and the registry owner is the sentinel. - PR fix(metadata-protocol)!: a save into a second package of an object a runtime-authored row owns is refused (ADR-0029 D9.9) #23510 left this arm out on purpose: D9.9's prescription would tell the author to bind to
'sys_metadata', which is not a package, so the remedy is a wording decision. Its acceptance notes reported it for this close-out. - Re-measured live at
192d2051da(6187145964).
What it costs today. Each producer leaves an object held by two packages' rows. Since PR #23504, an uninstall of the owner without keepData meets that state and refuses 409 RESOURCE_CONFLICT with nothing removed. That is safe, but the package cannot be uninstalled until a row is removed by hand. The stored second row is one the registry never serves.
Acceptance.
- Member 1: each promote door refuses the row D9.9 refuses at the save door, with the same code and prescription, pinned per door:
publishMetaItemandpublish-drafts. - Member 2: decided and pinned. Either refuse with a prescription that names a real way out, or adopt the orphan; that wording is the owning seat's or the decision box's.
- Rows stored before D9.9 stay as they are. The uninstall pre-flight already handles them.
dedupe words: D9.9 draft promote second package; publish-drafts OBJECT_OVERLAY_PACKAGE_MISMATCH; runtime-authored owner draft; promoteDraftForPublish; sys_metadata sentinel owner package-less
Activity
objectstack-fleet commentedon Oct 15, 2026
Triage: first grade ·
bug·priority:p1·target:v18·domain:engine·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-15T07:54ZRead fresh. Two producers still store a second package's active row of an object that a runtime-authored row owns. ADR-0029 D9.9's save door refuses exactly that row (
422 OBJECT_OVERLAY_PACKAGE_MISMATCH, PR #23510).publishMetaItemandPOST /api/v1/packages/:id/publish-draftslet through a draft saved before the owner's row existed. This was measured once at a real door (200, dev report6187145964on metadata-protocol: uninstalling a package that shares an object with another package now leaves a half-uninstalled package (sys_packages row gone, its row of the shared object stranded) after PR #23464's per-item 409 #23473).sys_metadatasentinel. Further saves into P and Q all succeed.Grade: p1 +
target:v18(filing-gate.md〈定级判据〉)./metastore door, and thepublish-draftsREST door, refuse a row they accept today. That is a door's answer narrowing: the protocol class, in any lane.409 RESOURCE_CONFLICTuntil a row is removed by hand, and a stored row nothing serves.Lane
domain:engine(packages/metadata*, by the lane table):promoteDraftForPublish/publishPackageDraftsinpackages/metadata-protocol/src/protocol.ts.Order:
protocol.ts.os-bill) is in flight in the same file'supdateData/deleteDataversion-check region. The claim declares the region, and a hunk that meets it waits.Scope:
publishMetaItemandpublish-drafts. CONTROL: a promote with no second-package owner is unchanged.objectstack-fleet commentedon Oct 15, 2026
pm:queue→pm:blocked·domain:engineseat 1 ·sunhaolin·session_01GP3comALHRcRBixS2TEnLF· 2026-10-15T08:22Z. ⛔ Not a claim.Blocked-by: #23495
Blocked-by: #23473
Why it waits:
promoteDraftForPublishandpublishPackageDraftsinpackages/metadata-protocol/src/protocol.ts. metadata-protocol: the draft doors naming no package resolve three addresses — the save and read inherit the active binding, the discard reads the draft rows, the publish takes the first draft row a package-agnostic findOne returns #23495 is in flight there (claim 6187661344). It moves the same promote door's draft address, from a package-agnosticdraftKeyread to the draft save's address. Member 1's ownership check belongs on the address metadata-protocol: the draft doors naming no package resolve three addresses — the save and read inherit the active binding, the discard reads the draft rows, the publish takes the first draft row a package-agnostic findOne returns #23495 settles, so it is serial behind metadata-protocol: the draft doors naming no package resolve three addresses — the save and read inherit the active binding, the discard reads the draft rows, the publish takes the first draft row a package-agnostic findOne returns #23495.[P, Q, package-less], is objectql/metadata-protocol: a save naming a package of a runtime object the registry holds under the sys_metadata sentinel answers 200, but the registry keeps the package-less definition, so the saved row never goes live #23514's seam:classifyObjectContribution'ssys_metadatasentinel carve-out.Unlock: when #23495 and #23473 are both closed, the unlock scan returns this card to
pm:queue. Its claimant then reads #23495's and #23514's merged diffs first. Member 1 is then the whole card, unless #23514's PR does not pin member 2. In that case member 2 comes back here.Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 2 · 2026-10-15T11:57Z
Session:
session_01GP3comALHRcRBixS2TEnLFAccount:
sunhaolin(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23630-promote-doors-d99Worktree:
objectstack-issue-23630Domain:
domain:engineSeat:
domain:engine#1(seat post #6367)File surface:
packages/metadata-protocol/src/protocol.ts, the promote doors only:promoteDraftForPublish(the per-item publish) andpublishPackageDrafts(POST /api/v1/packages/:id/publish-drafts), asking D9.9's question through the existingclassifyObjectContribution/overlayPackageMismatchError. Plus new pins per door (real kernel) and one changeset.changeset/23630-*.md. Stop on any other breach and explain it in the report.Container & model:
M,mode:subagent,model: TIER_DEFAULT(this run'sdispatch-gates.mjs --tier: "no path-derived mandate"; a door narrowing reusing an existing refusal)Clause-②: no
Responsibility: the risk is produced by
metadata-protocol's promote doors, which do not ask ADR-0029 D9.9's question the save door asks. A draft saved before a runtime owner's row existed is promoted into a second package's active row | no platform path covers it: the D9.9 refusal (PR #23510) runs at the save door only |POST /api/v1/packages/:id/publish-draftsand the per-item publish reach it. The former was measured200at a real door (#23473's report 6187145964).Thread-read: 6187770366
Serial constraints cleared:
Blocked-by:targets of 6187770366 are closed: metadata-protocol: the draft doors naming no package resolve three addresses — the save and read inherit the active binding, the discard reads the draft rows, the publish takes the first draft row a package-agnostic findOne returns #23495 (PR fix(metadata-protocol)!: the per-item publish and the draft discard that name no package act on the draft the draft save writes (#23495) #23654 →57994c311f) and metadata-protocol: uninstalling a package that shares an object with another package now leaves a half-uninstalled package (sys_packages row gone, its row of the shared object stranded) after PR #23464's per-item 409 #23473 (PR fix(metadata-protocol)!: an uninstall that would drop a table another stored row still serves is refused 409 before anything is removed #23504 →7cb33cfef).origin/main57994c311f. The D9.9 references (overlayPackageMismatchError/classifyObjectContribution/OBJECT_OVERLAY_PACKAGE_MISMATCH) number 0 insidepromoteDraftForPublishand 0 insidepublishPackageDrafts, while the controlsaveMetaItemhas 3. So that PR did not do this card's work.pm:blockedon metadata-protocol: deleting a runtime object hydrated at boot answers "it no longer exists" but keeps it registered and served until a restart — the delete heal re-registers the boot baseline before its unregister limb (Part of #23514) #23645). This card is member 1 only.reassignOrphanedMetadata.classifyObjectContribution's sentinel arm and the D9.9 call insaveMetaItem. This card only callsclassifyObjectContributionat the promote doors. Whichever lands second mergesmainand re-runs the other's D9.9 pins.Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{
"issue": 23630,
"status": "done",
"branch": "claude/issue-23630-promote-doors-d99",
"pr": "#23683",
"head": "5298b986e1c6f032c9f2e34ce82d94de4d327f90 (merges origin/main 7e6e4e1, clean, no conflict; fix commit 5c2385e)",
"session": "session_01GP3comALHRcRBixS2TEnLF (subagent: the dispatching PM session)",
"premise_still_valid": true,
"summary": "Member 1 is fixed at one site. promoteDraftForPublish (packages/metadata-protocol/src/protocol.ts) is the promotion step both doors call: publishMetaItem and publishPackageDrafts (POST /packages/:id/publish-drafts). After its gated draft read, it now asks classifyObjectContribution(name, promoteInto) and throws overlayPackageMismatchError on a mismatch, before repo.promoteDraft writes. That is the save door's judge and envelope (OBJECT_OVERLAY_PACKAGE_MISMATCH / 422): no new code, message or dialect. Hypotheses: H1 confirmed at base 57994c3 (D9.9 refs 0 in promoteDraftForPublish, 0 in publishPackageDrafts; saveMetaItem 4 by my regex, code plus comment mentions, the seat counted 3). H2 confirmed: the address is promoteInto (the stated binding, or the item's package for an adopted unbound draft), as the save door judges its resolved address. H3 measured from code: any promotion throw already yields 200 with success false, outcome refused, the causal draft in failed[] with its catalogued code and 4xx message, and the rest BATCH_ABORTED (ADR-0067 D2). That shape is kept, so the batch door refuses inside its declared outcome rather than with an HTTP 422, and no decision was needed. H4 reproduced per door on a real composition: both answered success, rows [active P, active Q], registry P. Member 2 stays with #23514 (sentinel arm untouched); the PR closes the card with Fixes #23630 and says so.",
"tests": "All under scripts/pm/os-verify-lock.sh; verdicts from its VERDICT command-exit line. New pin packages/runtime/src/package-promote-runtime-owner-refusal.integration.test.ts (real ObjectQL + SqlDriver better-sqlite3 + PackageServicePlugin + protocol + HttpDispatcher.handlePackages; 6 cases: the two refusals with code+status and message equal to the save door's answer for the same row, nothing written; CONTROLS: no second-package owner per door, the owner's own draft via publish-drafts, the adoption of an unbound draft into P). RED BEFORE at base: 'Tests 2 failed | 4 passed (6)', exit 1 ('expected null to be an instance of Error'; batch 'success: true'); one-off probe at base: publishMetaItem success 'Published draft — type=object, name=probe_ticket [seq=3]', publish-drafts 200 outcome published failed [], rows [active:com.probe.p, active:com.probe.q], registry owner com.probe.p, label P. GREEN AFTER: 'Tests 6 passed (6)' exit 0, pre-merge and post-merge. ABLATION at 5c2385e via scripts/ablation-replace.mjs WRAP: anchor 'const layer = this.classifyObjectContribution(request.name, promoteInto);' 1 -> 0, blob fa49911fd8 -> 034c466abb, planted non-mismatch verdict; metadata-protocol rebuilt; ablation-dist-preflight: marker in dist/index.js and dist/index.cjs; predicted 2 red / 4 green, observed 'Tests 2 failed | 4 passed (6)'; restore blob == HEAD fa49911fd8, git diff HEAD empty; rebuilt; --absent: marker in none of 24 built files, tree clean; pin 6 passed. metadata-protocol whole suite, 3 shards (--shard=1/3,2/3,3/3, --maxWorkers=2), pre-merge and post-merge identical: 80+78+78 files passed, 3 skipped; 1340+17832+1391 = 20563 tests passed, 19 skipped; all exit 0. Typecheck metadata-protocol + runtime (tsc + check:test-typecheck): exit 0 pre- and post-merge ('27 file(s) / 190 error(s) / 68 pinned signature(s) held'). Targeted import-side runs post-merge (declared narrowing; full suites are CI's): objectql 8 files 109 passed; runtime 6 files (http-dispatcher, meta-published-runtime-publish, packages-publish-drafts-response-conformance, package-uninstall-* x3) 282 passed; rest 3 files 90 passed; all exit 0.",
"gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 5298b98 (final head; stderr: tree of objectstack-ai/objectstack at 5298b98; 3 paths vs merge base 7e6e4e1): 65 commands, each run with exit captured before any pipe; 65 exit 0. check:dual-build-cjs-loads and check:type-check-debt first exit 3 (PREREQUISITE NOT MET: no dist / closure-build lock timeout), re-run after a locked full turbo build (75 tasks, exit 0): both exit 0 ('110 published require entry point(s) across 68 package(s) load'; '1 ledger entr(ies) re-measured ... none above its recorded number'). check-adr-0087-registration: not-required (no-migration-prescription), BREAKING+bang+clause-②-narrowing. --ran: 'Run reconciliation — 65 derived, 65 run, 0 NOT-MEASURED, 0 UNRUN' (a derived zero, all exits recorded), exit 0. Tree clean after the build. CI check-runs on 5298b98 at report time: success — Check Changeset, Governed Surface Queue Guard, Lint · PM dispatch-gates, Lint · scoped · tooling self-tests, Dogfood Regression Gate, Check PR Size, Check Documentation Links, Flag docs affected by code changes, Auto Label, filter, and the four claim/closing guards; skipped — Build Docs, Console Pin Gate, Dogfood Verify CLI, Dogfood shard matrix, Temporal Conformance, Packed-tarball smoke; 17 in_progress (Lint & Repo Gates lanes, TypeScript Type Check lanes, Test Core, Build Core among them): in_progress is the honest value, not waited on.",
"files_changed": [
".changeset/23630-promote-doors-d99.md (+30, minor, Clause-②: no (narrowing), BREAKING, FROM -> TO per door, one-line remedy, ADR-0087 not-required (no-migration-prescription))",
"packages/metadata-protocol/src/protocol.ts (+26, promoteDraftForPublish only)",
"packages/runtime/src/package-promote-runtime-owner-refusal.integration.test.ts (+312, new pin; landing package for the pins is runtime because the real composition and the publish-drafts HTTP door live there)"
],
"line_budget": "n/a: no skills/** or governed path touched; 368 changed lines, under the 3000 human-merge threshold",
"mcp_calls": "0",
"api_writes": "3 — via the fleet-write relay (one repository_dispatch stroke, run 38750482600, conclusion success): POST /repos/objectstack-ai/objectstack/pulls (draft #23683) + POST /repos//issues/23683/assignees (sunhaolin; read-back: body 10435 bytes sent = stored, assignees sunhaolin); and POST /repos//issues/23630/comments (this report, scripts/pm/post-stamped.mjs). Plus git pushes (not REST): empty-branch probe, 19479a3, 89da7a5, 5c2385e (bc1a8fe with it), 5298b98. No label write (none in scope; the diff carries a changeset).",
"deviations": [
"Merged origin/main (7e6e4e1, includes #23659's protocol.ts delete-region change) once BEFORE opening the PR, per AGENTS.md §10; the whole local verification above was re-run on the merged head.",
"PR body carries the claim's line verbatim, 'Clause-②: no', while the changeset carries 'Clause-②: no (narrowing)'. That follows the role file's copy-the-claim rule and #23510's precedent for the same family. If the seat wants the arm in the body too, the edit is one line: replace 'Clause-②: no' with 'Clause-②: no (narrowing)' on line 2.",
"Import-side suites (objectql, rest, runtime) ran as targeted file sets, not whole packages; a declared narrowing, CI runs them in full.",
"Commit trailers use AGENTS.md's model-free pair (Claude-Session + Co-authored-by: Claude) and the PR footer uses AGENTS.md's session-URL form, not the harness reminder's model-named trailer and footer.",
"Lock: three queue timeouts (exit 99, NOT MEASURED), each re-run with the same OS_VERIFY_LOCK_SLOT; longest holder pid 1457 (issue-23649 runtime+objectql full suites, ~29 min)."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: #23514 · member 2, the package-less (sys_metadata sentinel) owner, untouched here; named as remaining open in the PR body · noted, not filed",
"carrier: none (PR #23683 Acceptance notes only) · applyObjectRegistryMutation's mismatch-branch note ('Unreachable from saveMetaItem … other callers (rollback, publish promotion)') is now unreachable from publish promotion too; still true as written, outside the surface · noted, not filed"
]
}
objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{
"issue": 23630,
"round": "patch round 2, contract review 6195338637 (FAIL, finding ①4) and seat ruling 6195354019 (route A)",
"status": "done",
"branch": "claude/issue-23630-promote-doors-d99",
"pr": "#23683",
"head": "ea873b091f2297c29653d2c39ab613cae4ccfba5 (round commits: ed80f06 merge of origin/main cbe7712, no conflict, no rebase; 7cd3026 pins; 3f0acc1 changeset; ea873b0 guard)",
"session": "session_01GP3comALHRcRBixS2TEnLF (subagent: the dispatching PM session)",
"premise_still_valid": true,
"summary": "Route (A) is implemented. The new D9.9 check in promoteDraftForPublish is now guarded by !this.isSealedManagedItem(singularType, request.name). So an object a code package ships (sealed, ADR-0131 D6) keeps the store's NOT_OVERRIDABLE / 403 at both promote doors, the save door's answer for that row, and never reaches classifyObjectContribution's packaged mismatch arm. Finding ①4 was reproduced first at 3f0acc1 (round-1 check, no guard): per-item 422 OBJECT_OVERLAY_PACKAGE_MISMATCH, batch failed[0].code OBJECT_OVERLAY_PACKAGE_MISMATCH. The harness CAN register a code-packaged object: registry.registerObject with _packageId O and _provenance 'package', getPackagedObjectOwner answers O. Q's draft is seeded as a row at rest, since the save door refuses that draft today. Two CONTROLs pin it per door: publishMetaItem naming Q answers NOT_OVERRIDABLE / 403, equal to the save door's answer for the same row; publish-drafts answers outcome refused with failed[0].code NOT_OVERRIDABLE. Nothing is written either way. The runtime-owner pins are unchanged and green. The changeset's Unchanged list now names the code-packaged owner's answer. Fixes #23630 is kept; member 2 rides #23514. origin/main cbe7712 (#23688) was merged before the edit; main has since moved to 3bc407d (#23687), which touches none of the three files, so it was not merged. The PR body is NOT edited, see deviations: a ready replacement is at /tmp/claude-0/-home-user/79a0eb1c-a60a-5921-bcd2-b214eeb839c8/scratchpad/issue-23630/pr-body-r2.md.",
"tests": "Declared narrowing for this round, per the dispatch: targeted file sets only; the whole-package farms are CI's. All under scripts/pm/os-verify-lock.sh. RED FIRST at 3f0acc1: pin file 'Tests 2 failed | 6 passed (8)', VERDICT command-exit 1; per-item received code OBJECT_OVERLAY_PACKAGE_MISMATCH status 422; batch received failed[0].code OBJECT_OVERLAY_PACKAGE_MISMATCH. GREEN at ea873b0 (metadata-protocol rebuilt): 'Tests 8 passed (8)', exit 0. ABLATION of the guard at ea873b0 via scripts/ablation-replace.mjs WRAP: anchor '&& !this.isSealedManagedItem(singularType, request.name)) {' 1 -> 0, replaced by an always-true term carrying marker ablated_23630_guard; blob 700377269e -> f2e19c39ab; rebuilt; ablation-dist-preflight: marker in dist/index.js and dist/index.cjs; predicted 2 red / 6 green, observed 'Tests 2 failed | 6 passed (8)' (the two code-packaged CONTROLs). Restore: blob == HEAD 700377269e, git diff HEAD empty; rebuilt; --absent: marker in none of 24 built files, tree clean; pin 8 passed. Targeted suites at ea873b0, each part's own exit echoed: metadata-protocol, the 46 files naming publishMetaItem / publishPackageDrafts / promoteDraftForPublish / OBJECT_OVERLAY_PACKAGE_MISMATCH / classifyObjectContribution / overlayPackageMismatch: 46 files, 1039 passed, exit 0. objectql, 14 save-door / promote-door / D9.9 files: 206 passed, exit 0. runtime, 6 files (http-dispatcher, meta-published-runtime-publish, packages-publish-drafts-response-conformance, package-uninstall-* x3): 282 passed, exit 0. Typecheck metadata-protocol + runtime (tsc + check:test-typecheck): exit 0, '27 file(s) / 190 error(s) / 68 pinned signature(s) held'.",
"gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at ea873b0 (final head; stderr: tree of objectstack-ai/objectstack at ea873b0; 3 paths vs merge base cbe7712; 459 changed lines): 65 commands. They ran after a locked full turbo build (75 tasks, exit 0), each with its exit captured before any pipe: 65 exit 0. Among them: check:dual-build-cjs-loads '110 published require entry point(s) across 68 package(s) load'; check:type-check-debt '1 ledger entr(ies) re-measured … none above its recorded number'; check-adr-0087-registration not-required (no-migration-prescription). --ran: 'Run reconciliation — 65 derived, 65 run, 0 NOT-MEASURED, 0 UNRUN' (derived zero), exit 0. Tree clean. CI check-runs on ea873b0 at report time: 34 success, 6 skipped, 0 failed, none pending.",
"files_changed": [
".changeset/23630-promote-doors-d99.md (round: +1 Unchanged bullet, the code-packaged owner keeps 403 NOT_OVERRIDABLE, batch failed[] code, never OBJECT_OVERLAY_PACKAGE_MISMATCH)",
"packages/metadata-protocol/src/protocol.ts (round: the guard plus its comment, inside promoteDraftForPublish only)",
"packages/runtime/src/package-promote-runtime-owner-refusal.integration.test.ts (round: seedStoredDraft and registerCodeOwner helpers, two code-packaged-owner CONTROLs, doc header)"
],
"line_budget": "n/a: no skills/** or governed path touched; 459 changed lines vs main, under the 3000 human-merge threshold",
"mcp_calls": "0",
"api_writes": "1 — POST /repos//issues/23630/comments (this report, scripts/pm/post-stamped.mjs via the fleet-write relay). Plus git pushes (not REST): ed80f06, 7cd3026, 3f0acc1 + ea873b0. No PR-body write and no label write.",
"deviations": [
"PR BODY NOT EDITED — dispatch vs role-file conflict, the role file followed. The dispatch says to edit the body through 'the relay's PR-body op your role file names'. The role file names no such op: it says the dev writes the body once, at pr_create, never PATCHes, and names the change in the report for the seat to write. The relay has no pr-body row; its issue_patch op would be that PATCH. The replacement body is ready, with no footer as the dispatch asks, 11939 bytes, angle-bracket and control-byte scans clean: /tmp/claude-0/-home-user/79a0eb1c-a60a-5921-bcd2-b214eeb839c8/scratchpad/issue-23630/pr-body-r2.md. The seat's write: one fleet-write action {op: 'issue_patch', issue: 23683, body: that file}. The live body (5298b98's) is stale on four points: 6 cases (now 8), no guard paragraph, no code-packaged CONTROL or second ablation row, and an acceptance note that says the code-packaged case is not pinned.",
"Verification narrowed per the dispatch (targeted files, no whole-package farms locally).",
"origin/main moved to 3bc407d after the merge; not merged (no overlap with the three files, PR mergeable_state was 'unknown' while GitHub recomputed; CI on ea873b0 is 34 success / 0 failed)."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: #23514 · member 2, the package-less (sys_metadata sentinel) owner, untouched (seat ruling 6195354019) · noted, not filed"
]
}
objectstack-fleet commentedon Oct 15, 2026
ACCEPT → PR #23683 comment 6197738889 ·
domain:engineseat 1 · 2026-10-15T17:05Z ·Clause-②: no (narrowing), contract review 6197699504 PASS atTIER_DEFAULT(round 1 FAIL 6195338637, route A 6195354019) · no card filed · landing per 〈B〉 now that every check is green; member 2 rides #23514.Generated by Claude Code