Repository navigation
[finding] ADR-0005 and ADR-0010 document wire payloads whose error opens with a retired tag AND whose code is lowercase — an author copying them writes a matcher the runtime never satisfies #19706
Description
Activity
objectstack-fleet commented
on Sep 22, 2026 ContributorMore actionsTriage:
domain:skills(docs/adr/0005-…md·docs/adr/0010-…md) · p2 · Bug ·area:api; rationale: two ADRs document wire payloads whosecodeis lowercase, against the published SCREAMING_SNAKE ledgerPath: 可对外的 API | api-backend.error-envelope-ledger(P1) | P② | p2
Graded by the triage seat (session_01Tw7jnJinGHvoGSi8aFkhPJ) at 2026-09-22T19:30Z. ⛔ ThePath:line lives here, not in the body: no instrument reads it, and rewriting a filer's body risks the platform's citation rewrite.Two defects, and this grading keeps only the consequential one in scope.
In scope — the lowercase
code.docs/adr/0005anddocs/adr/0010print payloads with"code": "invalid_metadata","not_overridable","package_locked","item_locked","frozen_path"— all lowercase. The declared contract is published:packages/spec/src/api/error-code-ledger.zod.tslists those codes in SCREAMING_SNAKE, and the checklist itemapi-backend.error-envelope-ledger(P1, active) asserts membership in that union. An author copying an ADR writes a matcher that never fires. ⭐ This half is pre-existing — ⛔ not caused by the bracketed-opener retirement — and needs no blocker.Out of scope — the retired bracketed opener in the same examples. That rides the prose round on #19705.
⚠️ Governed surface.docs/adr/**is governed 面, so this PR goes the draft + human-merge route and ⛔ must not be mixed with non-governed edits in one diff. If the round wants to fix both halves, it opens two PRs.Precedent to cite, ⛔ not a duplicate: #4003 (closed
completed) swept ~100 lowercase emitters to the SCREAMING catalog. The ADR prose was left behind by that sweep — same mechanism, different file.Generated by Claude Code
- addedarea:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsThe API a customer can call, and integrations — REST, connectors, webhooks, jobsbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3and removed
on Sep 22, 2026 huangyiirene commented
on Sep 23, 2026 CollaboratorMore actionsClaim: PM loop round R2 (skills seat 1) —
batch3 on the maintainer's word of the previous date and this one (「后续并发降到3」, repeated on resumption); in flight 0 → 1
Session:session_01Wnstp2kTth7sGXfr8fXypc
Branch:claude/issue-19706-adr-payload-code-screaming-snake
Worktree:objectstack-issue-19706
Domain:domain:skills
Seat:domain:skills#1
File surface:docs/adr/0005-metadata-customization-overlay.md(:349) anddocs/adr/0010-metadata-protection-model.md(:480 / :483 / :486 / :489) — the five wire-payload"code"values spelled lowercase, corrected to the members of the published ledgerpackages/spec/src/api/error-code-ledger.zod.ts(SCREAMING_SNAKE), each measured against the ledger and the runtime producer; ⛔ theerroropener's retired[tag]untouched (the other half rides #19705 per the triage grading); ⛔ a code with no ledger member is reported, never invented; ⛔ nothing outside the two ADRs — the CLI--if-matchhelp text the card mentions is non-governed code and ⛔ does not ride a governed PR (stop on breach; explain in the report)
Container & model:M,mode:subagent,model: TIER_DEFAULT—node scripts/pm/dispatch-gates.mjs --tier docs/adr/0005-metadata-customization-overlay.md docs/adr/0010-metadata-protection-model.mdatdc1b98680(2026-09-23T00:59Z) printed verbatim: "Model tier — no path-derived mandate: the surface hits none of the 3 declared glob(s), derived here, not recalled."docs/adr/**— Tier H on thecheck-governed-merges.mjsregister: draft PR with the 维护者速读, the maintainer merges; the lane's review of record is rendered in-seat at the served tier (fable).
Clause-②: no
Thread-read: 5782685945
Ruling-ref: none — triage-graded (5782685945:domain:skills, p2, Bug,area:api; in scope the lowercasecodehalf only, pre-existing, no blocker; the bracketed-opener half is #19705's)
Serial constraints cleared: all 20 open PRs' file lists read at 2026-09-23T00:59Z: one touchesdocs/adr/**(PR #19666 ondocs/adr/0130-…md) and none touches this card's two files;git ls-remote --heads originscanned for the card number and the file stems: no branch.Dispatch basis: a p2 product defect on a governed doc surface — two ADRs print refusal payloads whose
codean author would copy into a matcher that never fires (the runtime and the published ledger spell SCREAMING_SNAKE). 北极星「优先级」第 3 条 read fresh at 2026-09-23T00:59Z (objectstack non-epic open p0 1 — #2714, atrackingcard — · p1 33): applied by this seat as label-based (seat post #7623 r15) — this card carriesbugandarea:api, nottooling, and is not contract hygiene. Premise re-read onorigin/maindc1b98680by the dev before editing (the five lowercase codes at the lines above;INVALID_METADATA,NOT_OVERRIDABLE,ITEM_LOCKEDpresent in the ledger;PACKAGE_LOCKED/FROZEN_PATHNOT found by the seat's grep — measure what the runtime emits for those two cases);premise_still_valid: falseper site is a first-class outcome.
Generated by Claude Code
huangyiirene commented
on Sep 23, 2026 CollaboratorMore actionsos-dev-report
{
"issue": 19706,
"status": "done",
"branch": "claude/issue-19706-adr-payload-code-screaming-snake",
"pr": "#19765",
"session": "session_01Wnstp2kTth7sGXfr8fXypc — subagent run, parent's (PM skills seat 1) session id",
"premise_still_valid": true,
"premise_note": "The card premise holds for 4 of 5 sites. Site 0010:489 (L4 frozen_path) is premise_still_valid: false: no runtime producer emits any code for a frozen-path refusal, so there is no correct token to write, and the line is left unchanged (see sites[4]).",
"summary": "Changed the payloadcodetoken at 4 of the 5 dispatched sites, each to the ErrorCode ledger member the runtime producer emits for that refusal: 0005:349 INVALID_METADATA, 0010:480 NOT_OVERRIDABLE, 0010:486 ITEM_LOCKED, and 0010:483 package_locked → ITEM_LOCKED. The 0010:483 change is mapped, not uppercased: no PACKAGE_LOCKED exists anywhere; the runtime refuses package-layer locks as ITEM_LOCKED/403 with lockSource 'package', pinned by a test; ADR-0010 §3.2 itself normalises L2 into L3. Site 0010:489 (frozen_path) is unchanged because L4 is unimplemented and no producer exists; the answer belongs to the spec lane. Only the token bytes changed (+4/-4): the [tag] openers (#19705), status numbers and all other text are untouched. Draft PR #19765 is Tier H and stays draft for the maintainer; the skip-changeset label was written and read back. The assignee on #19706 was already set (huangyiirene, by the PM) and was not written.",
"sites": [
{
"site": "docs/adr/0005-metadata-customization-overlay.md:349",
"before": "invalid_metadata",
"after": "INVALID_METADATA",
"premise_still_valid": true,
"ledger": "packages/spec/src/api/error-code-ledger.zod.ts:615 (@objectstack/metadata-protocol)",
"producer": "packages/metadata-protocol/src/protocol.ts:16096-16100 saveMetaItem spec-validation refusal:${type}/${name} failed spec validation: …, code='INVALID_METADATA', status=422 (the exact sentence the sample prints)"
},
{
"site": "docs/adr/0010-metadata-protection-model.md:480 (L1)",
"before": "not_overridable",
"after": "NOT_OVERRIDABLE",
"premise_still_valid": true,
"ledger": "error-code-ledger.zod.ts:623",
"producer": "protocol.ts:15758-15759 saveMetaItem code='NOT_OVERRIDABLE' status=403; sys-metadata-repository.ts:1639,1652-1653 assertAllowed code='NOT_OVERRIDABLE' status=403"
},
{
"site": "docs/adr/0010-metadata-protection-model.md:483 (L2)",
"before": "package_locked",
"after": "ITEM_LOCKED",
"premise_still_valid": true,
"mapping": "mapped, not uppercased: a ledger member under another name, used and said so (Zone 1 clause)",
"ledger": "error-code-ledger.zod.ts:617 (no PACKAGE_LOCKED member; whole-tree git grep -i for package_locked outside docs/ and content/: 0 hits, exit 1 unpiped)",
"producer": "sys-metadata-repository.ts:1766-1768 readOnlyBaseOverrideError code='ITEM_LOCKED' status=403 lockSource='package' (TSDoc: 'ADR-0010's own reserved value for a lock the PACKAGE layer asserts'), pinned by sys-metadata-repository.package-writability.test.ts:767 { code: 'ITEM_LOCKED', status: 403, lockSource: 'package', packageId }; and protocol.ts:14144-14145 lockWriteRefusal code='ITEM_LOCKED' status=403 for a package-declared protection.lock translated by spec/src/shared/protection.zod.ts:276-277 (_lockSource='package'); the example's own item, SETUP_APP, declares protection.lock 'full' at platform-objects/src/apps/setup.app.ts:39-40 (package com.objectstack.setup, apps/setup/src/index.ts:22). ADR-0010 §3.2: L2 resolves into _lock + _lockSource 'package' so protocol code sees the single normalised L3 shape."
},
{
"site": "docs/adr/0010-metadata-protection-model.md:486 (L3)",
"before": "item_locked",
"after": "ITEM_LOCKED",
"premise_still_valid": true,
"ledger": "error-code-ledger.zod.ts:617",
"producer": "protocol.ts:14144-14145 lockWriteRefusal and :14212-14213 assertLockAllowsDelete code='ITEM_LOCKED' status=403. The adjacent lowercase 'item_locked' at :14157/:14223 is the persisted sys_metadata_audit.code column, a separate vocabulary by ADR-0112 D6b (:160, :164), not the wire token"
},
{
"site": "docs/adr/0010-metadata-protection-model.md:489 (L4)",
"before": "frozen_path",
"after": "frozen_path (UNCHANGED)",
"premise_still_valid": false,
"ledger": "no member (no FROZEN_PATH or any frozen-path code)",
"producer": "none: 0 readers of _frozenPaths/defaultFrozenPaths under packages/** (only non-ADR hit: header comment spec/src/kernel/metadata-protection.zod.ts:10); the Phase 2 evaluator packages/spec/src/shared/json-path.ts does not exist; ADR-0010 Phase 2 carries no Implemented mark. Control leg: the same search finds the NOT_OVERRIDABLE/ITEM_LOCKED emitters. Not invented, per the dispatch.",
"owning_lane": "spec (domain:spec): register a code when L4 is implemented, or amend ADR-0010 to mark L4 unimplemented"
}
],
"ledger_membership_script": {
"note": "One-shot scratchpad script (issue-19706/ledger-membership.mts, not in the tree): imports ErrorCode from packages/spec/src/api/error-code-ledger.zod.ts via tsx, reads ErrorCode.options, and checks every "code": value in the two ADRs; the control leg asserts NOT_OVERRIDABLE in and not_overridable out",
"before": {
"exit": 1,
"output": [
"tree=/home/user/objectstack-issue-19706 HEAD=dc1b98680 ErrorCode members=338",
"NON-MEMBER docs/adr/0005-metadata-customization-overlay.md:349 "invalid_metadata"",
"NON-MEMBER docs/adr/0010-metadata-protection-model.md:480 "not_overridable"",
"NON-MEMBER docs/adr/0010-metadata-protection-model.md:483 "package_locked"",
"NON-MEMBER docs/adr/0010-metadata-protection-model.md:486 "item_locked"",
"NON-MEMBER docs/adr/0010-metadata-protection-model.md:489 "frozen_path"",
"control: NOT_OVERRIDABLE in union=true; not_overridable in union=false",
"VERDICT sites=5 members=0 non-members=5"
]
},
"after": {
"exit": 1,
"output": [
"tree=/home/user/objectstack-issue-19706 HEAD=dc1b98680 ErrorCode members=338",
"MEMBER docs/adr/0005-metadata-customization-overlay.md:349 "INVALID_METADATA"",
"MEMBER docs/adr/0010-metadata-protection-model.md:480 "NOT_OVERRIDABLE"",
"MEMBER docs/adr/0010-metadata-protection-model.md:483 "ITEM_LOCKED"",
"MEMBER docs/adr/0010-metadata-protection-model.md:486 "ITEM_LOCKED"",
"NON-MEMBER docs/adr/0010-metadata-protection-model.md:489 "frozen_path"",
"control: NOT_OVERRIDABLE in union=true; not_overridable in union=false",
"VERDICT sites=5 members=4 non-members=1"
],
"note": "exit 1 is expected: the only non-member is 0010:489 frozen_path, left unchanged on purpose"
}
},
"tests": "No package source touched, so no package test or typecheck is owed (the diff is docs/adr/** only). Evidence = the ledger-membership probe (before 0/5 members at dc1b986, after 4/5 at 58bf48a, residue = L4 by design) plus the 19 derived gate commands below, all run at tree 58bf48a with exits captured before any pipe;node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.list→ exit 0, "Run reconciliation — 19 derived, 19 run, 0 NOT-MEASURED, 0 UNRUN." No ablation or reverse verification applies (no code or gate was changed).",
"gates": [
{
"cmd": "node scripts/check-adr-links.mjs",
"exit": 0,
"verdict": "✅ check-adr-links: 690 relative link destination(s) under docs/adr/ resolve"
},
{
"cmd": "node scripts/check-adr-links.mjs --self-test",
"exit": 0,
"verdict": "✅ check-adr-links --self-test: discrimination, census, ADR-0046 pin and baseline staleness all verified"
},
{
"cmd": "node scripts/check-adr-symbol-anchors.mjs",
"exit": 0,
"verdict": "✅ check-adr-symbol-anchors: 2121 anchors across 140 records resolve — 302 symbol (276 declaration, 26 literal), 1792 file-level, 27 cross-repo, 6 exempt, 3 continuation."
},
{
"cmd": "node scripts/check-adr-symbol-anchors.mjs --self-test",
"exit": 0,
"verdict": "✅ check-adr-symbol-anchors --self-test: every finding class provoked, healthy anchors silent, population live, wiring pinned (2121 live anchors)"
},
{
"cmd": "node scripts/check-ci-filter-parity.mjs",
"exit": 0,
"verdict": "OK: all 185 declared cross-package glob(s) (132 unique) are covered bycoreorcrosspkg"
},
{
"cmd": "node scripts/check-closing-keyword-parity.mjs",
"exit": 0,
"verdict": "check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators; sweep found 5 file(s) carrying the grammar across 9249 tracked file(s), all registered)."
},
{
"cmd": "node scripts/check-closing-keyword-parity.mjs --self-test",
"exit": 0,
"verdict": "✓ check-closing-keyword-parity --self-test: 40 assertions, 5 mutations of the shipped parsers each driven to red."
},
{
"cmd": "node scripts/check-comment-mask-corpus.mjs",
"exit": 0,
"verdict": "✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 7012 files, 0 disagree, 0 unparseable"
},
{
"cmd": "pnpm --filter @objectstack/lint run check:doc-formula-expressions",
"exit": 0,
"first_exit": 3,
"verdict": "✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 443 files / 1381 TS blocks judged clean by @objectstack/formula.",
"note": "first run exit 3 = PREREQUISITE NOT MET (@objectstack/lint unbuilt, nothing measured); built viabash scripts/pm/os-verify-lock.sh -c \"pnpm exec turbo run build --concurrency=2 --filter=@objectstack/formula --filter=@objectstack/lint\"→ "os-verify-lock: VERDICT command-exit 0 · held the lock 149s"; re-run exit 0; ran.list records the re-run"
},
{
"cmd": "pnpm check:adr-anchors",
"exit": 0,
"verdict": "check-adr-anchors: OK (53 anchored file(s), every governing ADR still referenced; 134 decision number(s) …; 37124 citation(s) across 4829 file(s) resolve …)"
},
{
"cmd": "pnpm check:cross-package-test-inputs",
"exit": 0,
"verdict": "OK: 29 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob"
},
{
"cmd": "pnpm check:doc-authoring",
"exit": 0,
"verdict": "✓ doc authoring guard: sibling-package prose ids hold the baseline — 819 pinned site(s) across 231 file(s) … no growth, no burn-down unrecorded."
},
{
"cmd": "pnpm check:driver-memory-census",
"exit": 0,
"verdict": "check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live"
},
{
"cmd": "pnpm check:gitlink-declared",
"exit": 0,
"verdict": "check-gitlink-declared: OK (9249 index entries -- 0 gitlink(s) at mode 160000 …)"
},
{
"cmd": "pnpm check:nul-bytes",
"exit": 0,
"verdict": "check-nul-bytes: OK (scanned 9242 text file(s) -- 9242 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes)."
},
{
"cmd": "pnpm check:pm-governed-merges",
"exit": 0,
"verdict": "✓ check-governed-merges --self-test: 441 assertions …",
"note": "the package script is --self-test only: checker health, not a verdict on this diff"
},
{
"cmd": "pnpm check:pm-prior-rulings",
"exit": 0,
"verdict": "✓ check-prior-rulings self-test: 155 cases pass …",
"note": "self-test only: checker health"
},
{
"cmd": "pnpm check:refd-timer-probe",
"exit": 0,
"verdict": "OK check-refd-timer-probe: 7007 source file(s) swept; the process-global timer probe is read in packages/qa/refd-timer-testkit/src/index.ts and nowhere else."
},
{
"cmd": "pnpm check:watch-hint-literal",
"exit": 0,
"verdict": "✓ check-watch-hint-literal: 71 declaration(s) across 4 rostered name(s)"
},
{
"cmd": "pnpm check:error-code-casing",
"exit": 0,
"verdict": "✓ no unlisted lowercase error codes in 6427 scanned file(s) (ADR-0112).",
"note": "EXTRA, not derived; a neighbour, not a measurement of this diff: SCAN_ROOTS = ['packages'], .ts/.tsx only (scripts/check-error-code-casing.mjs:59,248), so it never reads ADR prose"
}
],
"gate_derivation": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands (no paths) → exit 0; stderr: "gate list derived from the tree of 'objectstack-ai/objectstack' at commit 58bf48a"; change set 2 path(s) vs merge base dc1b986 (committed 2, working tree 0, untracked 0); 19 command(s). Outside that runnable total, per the tool: 2 workflow-valued families NOT MEASURED (shard-attestation, test-completeness), the Test Core CI job (5 steps) and 4 type-check lanes NOT MEASURED locally (CI-owned), and 14 pending-changeset families not applicable because this PR has no changeset.",
"governed_merges": "node scripts/pm/check-governed-merges.mjs --pr 19765 → exit 3 (= paths ARE governed, per the script's exit table); "⛔ GOVERNED — a human merge is the review record for this PR"; "⚖️ landing tier: H(人合)"; docs/adr/** ×2; size +4/-4 = 8 changed lines, at or under 5000",
"clause2_pair": "node scripts/pm/check-clause2-carriers.mjs --pair 19765 → exit 4, row C6: card declares Clause-②: no and carries domain:skills (a lane that owes a contract review every round) and no## Contract reviewrecord names head 58bf48a. The seat owes that record (the claim says it is rendered in-seat); per the standing clause the dev does not hang, clear or wait on it. needs:contract-review on PR #19765: absent (labels read back: skip-changeset only). claim and PR-body Clause-② lines both read DECLAREDno.",
"ci": "in_progress at 2026-09-23T01:15Z (single read, no polling): 33 check runs = 11 success, 11 skipped, 11 in_progress; Governed Surface Queue Guard success; Lint & Repo Gates and Test Core in_progress; TypeScript Type Check not yet reported. Convergence is the PM's to read.",
"changeset": "none; label skip-changeset. docs/adr/** publishes nothing: 0 of 70 published package.json files[] entries resolve to docs/adr, the root package is private, and no package.json or tsup config references docs/adr (git grep exit 1; control pattern hits).",
"line_budget": "8 changed lines (+4/-4) across 2 files, at or under the 5000-line human-merge threshold; no skills/** path touched, so no skill line or token ratchet applies",
"files_changed": [
"docs/adr/0005-metadata-customization-overlay.md (+1/-1, line 349)",
"docs/adr/0010-metadata-protection-model.md (+3/-3, lines 480, 483, 486)"
],
"concurrency": "H4 held: origin/main re-fetched before the PR opened, still dc1b986 (0 incoming commits), so there was nothing to merge. The only open PR created after the claim (#19763) touches no docs/adr/** path.",
"deviations": [
"L2 (0010:483) became ITEM_LOCKED rather than an uppercased package_locked. This is the Zone 1 clause "if a ledger member exists under another spelling, use it and say so", measured against the producer. It is flagged in the PR 维护者速读 for the maintainer to confirm.",
"Acceptance probe after-state is exit 1 (4/5 members): the remaining site is L4, left unchanged under the Zone 1 no-invention clause.",
"Commit trailer: the harness reminder asked for a model-named Co-Authored-By; I used AGENTS.md's model-free pair (Claude-Session + Co-authored-by: Claude), which the reminder says repo instructions override, and which the pre-push hook enforces (check:commit-card-trailers passed).",
"PR body footer: the harness reminder asked for its own two-line block; I used AGENTS.md's single session-URL footer block, because platform-readings says stacking the harness block stores three attribution blocks. Read-back: 1 footer; the stored body is byte-identical to the sent body minus the trailing newline.",
"git push ran twice: the empty-branch write probe required by os-dev rule 1, then the commit. Both are in the git-push budget item."
],
"api_writes": "3 REST writes + 2 git pushes. git push x2 (empty branch, then 58bf48a) to refs/heads/claude/issue-19706-adr-payload-code-screaming-snake; POST /repos/objectstack-ai/objectstack/pulls (draft, 201, #19765); POST /repos//issues/19765/labels (skip-changeset, via scripts/pm/label-write.mjs, HTTP 200, read back MATCHES); POST /repos//issues/19706/comments (this os-dev-report). No 429 or pace refusal was met.",
"mcp_calls": "0 — no MCP GitHub tool used (read or write)",
"open_questions": [
{
"question": "L2 (ADR-0010 :483): confirm package_locked → ITEM_LOCKED (the code the runtime emits for package-layer locks) rather than a distinct package code",
"options": [
"A keep ITEM_LOCKED: matches ADR-0010 §3.2 (L2 normalises into L3 _lock + _lockSource package), both runtime producers, and the lockSource package pin; no wire change",
"B register a distinct PACKAGE_LOCKED: a new ledger code plus a new producer, i.e. a wire change for a condition the runtime already answers, and against §3.2"
],
"recommendation": "A: it documents the contract that exists; B is a spec-lane wire decision with no measured consumer"
},
{
"question": "L4 (ADR-0010 :489, frozen_path): no producer exists. How should the ADR payload be settled? (spec lane; not blocking this PR)",
"options": [
"A leave it until L4 is implemented; the implementing PR registers the code in the ledger and corrects this line in the same change",
"B amend ADR-0010 now to mark L4 (and its payload) as unimplemented",
"C register FROZEN_PATH now: not viable, since the ledger refuses a code no package stamps (check:error-code-provenance; the ledger header calls such rows dead weight)"
],
"recommendation": "A: it keeps declared equal to enforced without inventing a code; B is cheap if the maintainer wants the ADR honest today"
}
],
"out_of_scope_findings": [
"class: a · packages/cli/src/commands/meta/delete.ts:115: the --if-match help text says "refused with 409 metadata_conflict" while the CLI surfaces code METADATA_CONFLICT (format.error-code-fields.test.ts:80, delete-json-error-code.test.ts:157); a script matching the help text's token never fires. Note that delete-reset-carriers.test.ts:367 pins the help text with /metadata_conflict/, so a fix moves that pin too. Non-governed; the triage grading kept it off this governed PR · dedupe words: cli if-match help metadata_conflict lowercase, delete.ts help text error code casing",
"carrier: the prose round on #19705 (same two ADRs) · ADR-0010 prose still spells codes lowercase outside the payload "code" lines: :97 and :103 (layer diagram), :213, :501, :601-602; outside the five-site contract, untouched, noted in the PR Acceptance notes, not filed",
"carrier: the prose round on #19705 / 承接者:无 · ADR-0010 L2 payload's other fields describe the unimplemented Phase 3 surface (metadataDefaults.lock=full, a "package" key where the runtime's package-layer refusal carries packageId + lockSource); token-only scope; noted in Acceptance notes, not filed",
"carrier: spec lane decision (承接者:无, no PR) · L4 frozen_path site: no producer (see sites[4] and open_questions[1]); noted in the PR as an unresolved site, not filed"
],
"cleanup": "worktree /home/user/objectstack-issue-19706: node_modules removed, thengit worktree removeexit 0 without --force (remote branch sha = local HEAD 58bf48a and porcelain clean were verified first); absence then confirmed (directory gone, 0 worktree-list entries). No dev server or background process was started."
}
Generated by Claude Code
huangyiirene commented
on Sep 23, 2026 CollaboratorMore actionsACCEPT —
domain:skillsseat 1 (session_01Wnstp2kTth7sGXfr8fXypc, seat post #7623), 2026-09-23T01:42Z — PR #19765 at head58bf48af1d4c0f75075ca80484e46efb65828dd5(round 0).Checklist, read against GitHub and the fetched head on a review worktree, not the report: draft, base
main, first lineFixes #19706,Clause-②: no; one single-parent commit ondc1b98680; two files, +4 / −4 — four token edits (docs/adr/0005:349 →INVALID_METADATA;docs/adr/0010:480 →NOT_OVERRIDABLE, :483package_locked→ITEM_LOCKED(a mapping, not an uppercasing: noPACKAGE_LOCKEDexists, the runtime's package-layer refusal isITEM_LOCKED+lockSource: 'package', pinned by a test, and §3.2 normalises L2 into L3), :486 →ITEM_LOCKED) and :489frozen_pathdeliberately unchanged (no ledger member, no producer — L4 is unimplemented; ⛔ not invented). Each token read by the seat at its producer (protocol.ts:16096–:16100 / :15758 / :14144,sys-metadata-repository.ts:1766–:1768) and in the ledger (:615 / :617 / :623). Acceptance re-read by the seat: every"code":in the two ADRs against the ledger — 0 / 5 members before, 4 / 5 after, the residue L4 by design. The[tag]openers (#19705's), the status numbers and all other text untouched. Gates re-run by the seat at the head:check-adr-links,check-adr-symbol-anchors,check:adr-anchors,check:doc-authoring,check:nul-bytes— all 0;check-governed-merges.mjs --pr 19765exit 3 GOVERNED Tier H (docs/adr/** ×2, 8 lines). The dev's 19-family derivation reconciled--ran19 / 19 / 0. CI at this head: 31 latest-per-name check runs — 22 success, 9 skipped, 0 in progress, 0 other (the seat's read at 01:41 UTC of this date);check-expected-skips.mjs --pr 197650 (every skipped run in the roster). Record: 5787341220 (PASS, rendered in-seat at the served tier). Report 5787309652 parses;mcp_calls0; three REST writes plus two pushes; no body PATCH by the dev.The dev's two open questions, graded in-lane: L2 → A (
ITEM_LOCKED; a distinct package code is a spec-lane wire decision with no measured consumer); L4 → A (leave until implemented; B — an ADR note marking L4 unimplemented — is the maintainer's if wanted; C not viable). Both put to the maintainer in the 席位意见.Deviations recorded, none blocking: the acceptance probe's after-state is 4 / 5 by design; the commit trailers use the repository's model-free pair per AGENTS.md; two pushes (probe + commit).
Out of scope, noted by the dev, ⛔ not filed:
packages/cli/src/commands/meta/delete.ts:115's--if-matchhelp text spells409 metadata_conflict(the CLI surfacesMETADATA_CONFLICT; a test pins the help text) — non-governed, class a, the filing door bars this seat → the maintainer's items; ADR-0010 prose outside the payload lines still lowercase (:97, :103, :213, :501, :601–:602) — the prose round on #19705; the L2 payload's other fields describe the unimplemented Phase 3 surface — noted.Landing: Tier H (
docs/adr/**) — draft stays draft; the 四件套 in this act (this ACCEPT,needs-user-decision, 席位意见, review requested from os-zhuang / hotlong); the maintainer merges after confirming the L2 mapping. At MERGED: the card closes byFixes; the seat takespm:dispatchedand the assignee off.
Generated by Claude Code
- added a commit that references this issue
on Sep 28, 2026
Filing gate: ① defect. Class (c) — 「AI 写元数据会被运行时拒收或静默丢弃的陷阱」, in its matcher form: the payloads are copy targets, and a matcher built from them never fires.
Filed by the
domain:specexecution seat (session_013RDBh5DqXd2xnLwvHLgLFr), surfaced by the #16245 dev as an out-of-scope finding it correctly ⛔ did not touch:docs/adr/**is Tier H governed surface and this card's triage boundary forbade editing it. ⇒ this needs the governed route (draft PR + human merge), ⛔ never a rider.The carriers
Each documents a wire payload of the refusal envelope.
TWO defects in one payload, and the second is the older one
① The bracketed opener. The
errorstring opens with the lowercase[tag]that PR #19683 (card #16245) removes from the two@objectstack/metadata-protocolproducers, on the 2026-08-29 maintainer ruling thaterroris human language andcodeis the machine token.②⚠️ This disagrees with Prime Directive #3 and with what the runtime actually emits, which is SCREAMING_SNAKE (
codeis spelled lowercase. The same payloads show e.g."code": "not_overridable".NOT_OVERRIDABLE). ⭐ This half is pre-existing — ⛔ not caused by #16245 — and it is the more consequential of the two, becausecodeis the axis a consumer is supposed to match on.⇒ an author or a codegen run that copies these payloads writes a matcher against a token the runtime never produces. It fails silently: no gate reads ADR prose, and the matcher simply never fires.
The same observation, one lane over
packages/cli's--if-matchflag help text says409 metadata_conflictin lowercase while the CLI emitscode: METADATA_CONFLICT. ⛔ Not filed separately and ⛔ not falsified by #16245 — it names the refusal rather than quoting the bytes — but it is the same lowercase-vs-SCREAMING_SNAKE shape and worth fixing in the same pass if the fixer's lane reaches it.Route
docs/adr/**takes a draft PR reviewed and merged by a human, ⛔ never a seat's own landing. Defect ② can be settled from the runtime alone and does not wait on #16245; defect ① does.Blocked-by: #16245for the opener half only.Dedupe words:
ADR-0005 ADR-0010 wire payload bracketed opener·adr payload lowercase code vocabulary prime directive 3Generated by Claude Code