Repository navigation
finding(app-shell): ActionPreview's INHERITED_TARGET docblock cites the resolver as reading field.reference_to — a key @objectstack/spec refuses by name, so an author who follows it writes metadata the platform rejects #10159
Description
Activity
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsClaim: PM loop round 1 —
domain:uiexecution seat
Session:session_01BA3nKVUwKQJf8DBxrSVtNC
Branch:claude/issue-10159-action-preview-reference-citation
Worktree:objectui-issue-10159
Domain:domain:ui
Seat:domain:ui#1
File surface:packages/app-shell/src/views/metadata-admin/previews/ActionPreview.tsx(theINHERITED_TARGETdocblock only), a pin beside its existing tests, and one.changeset/10159-…mdif the presence gate requires it (stop on breach; explain in the report)
Container & model:S,mode:subagent,model: opus(default judgement tier) —dispatch-gates.mjsrefuses for this repo from the objectstack checkout ⇒ no path-derived mandate
Clause-②: no
Thread-read: none
Serial constraints cleared: every open PR's file list read 2026-09-24T16:12Z (objectui#10292, #10285, #10284, #10283, #10279, #10278, #10273, #10270, #10268, #10264, #10255, #10253, #10169, #9488, #9391, #8941) ⇒ none touchesActionPreview.tsx. PR objectui#10271, which last edited it, is merged.Scope
The card's fix, verbatim: 「One line: make the citation quote what the resolver reads.
⚠️ And cite it by content, not by a path or a line — AGENTS.md #11 is why this recurred at all.」 Onorigin/main,ActionPreview.tsxstill quotesfield.reference_to, a key@objectstack/specrefuses by name, while the resolver readsfield.reference. ⇒Fixes #10159.⛔ The card's two unfiled observations (the second param-collection handler in
RecordDetailView; the deadRuntimeField.reference_todeclaration in the resolver) are out of scope here.domain:uiseat #1 ·session_01BA3nKVUwKQJf8DBxrSVtNC· claim · 2026-09-24T16:12Zobjectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsos-dev-report
{
"issue": 10159,
"status": "done",
"branch": "claude/issue-10159-action-preview-reference-citation",
"pr": "#10305",
"session": "session_01BA3nKVUwKQJf8DBxrSVtNC — the PM's session, stamped by the harness on this run (subagent, so the parent's id)",
"premise_still_valid": true,
"summary": "Premise held on origin/main 5ea623e: the INHERITED_TARGET docblock in ActionPreview quotedreferenceTo: param.reference ?? field.reference_to, and the resolver's only such site (in resolveActionParam) readsfield.reference. Fixed the quote, one line, still cited by content. Added the pin ActionPreview.inheritedTargetCitation-10159.test.ts. It re-derives the quote from the docblock and requires it to occur, as whole tokens, in the resolver's code with comments masked by scripts/js-comment-mask.mjs. It carries a landing proof, a lit CONTROL and a boundary DISCRIMINATOR, and no line numbers. The changeset uses the empty-frontmatter no-release form, based on a measured emit: INHERITED_TARGET is not exported, so its docblock reaches no emitted .d.ts. That follows the objectui#6572 vs #5213 precedent. Claim 5817814228 named this branch. The assignee (os-bill) was left untouched. The fenced files were not touched, and no open PR created after the claim's 16:12Z reading overlaps. Draft PR #10305 was stored byte-identical to what was sent (6808 bytes). CI was in_progress at the single reading taken after opening (42 check runs: 21 success, 3 skipped, 18 in_progress); it is not waited on, per contract. Commits carry no attribution trailers (model-free by omission). The worktree and node_modules were removed cleanly, without --force.",
"tests": "Final commit ee6d0de, run from the repo root under os-verify-lock:pnpm exec vitest runon the new pin + ActionPreview.locations + ActionPreview.iconSeam gaveTest Files 3 passed (3),Tests 14 passed (14).pnpm --filter @object-ui/app-shell type-check(echoedtsc --noEmit && tsc -p tsconfig.test.json) gave VERDICT command-exit 0;tsc -p tsconfig.test.json --listFilesOnlycounts the pin once. Dependency closureturbo run build --filter=@object-ui/app-shell^...gave 28/28 cached, and the dist outputs are present. Lock-free gates at ee6d0de:pnpm check:control-bytesOK.pnpm check:new-line-citations: 0 added, over 3 files compared, synthetic controls PASS, VERDICT exit 0.node scripts/check-changeset-presence.mjsexit 0 (empty frontmatter). A raw control-byte grep over the 3 files found nothing. On content identical to HEAD (changeset on disk), all exit 0: check-test-path-roots, check-hand-rolled-comment-mask (no carrier outside DEBT), check-comment-mask-corpus (1 disagreeing file, the pre-existing DocsIndex.tsx residue held under objectui#7882), check-changeset-no-major, check-changeset-claims (report-only), check-pending-changeset-literals, check-lint-coverage (46/46), and the script tests markdown-test-inputs + unit-registry-absence-collision (2 files, 40 tests passed). At 9e8b671, before the changeset existed: the whole previews/tests/ dir ran 13/13 files and 135 tests passed, with 13 equal to the directory's file count. Lint, narrowed and proven: the population comes from ESLint's own config (both source files linted; the changeset getsFile ignored because no matching configuration was supplied). Count from --format json: 2 files, 0 errors, 0 warnings, in the package's own form (inline config honoured). Invariance: no projectService/parserOptions.project in eslint.config.js and no fs read in eslint-rules/, so untouched files' verdicts cannot move. Repo-widepnpm lintis declared to CI. Ablation, one-time, from committed 9e8b671, via objectstack scripts/ablation-replace.mjs in WRAP mode plus the script's own trap restore on EXIT INT TERM, with an absolute path and a HEAD-blob hash check. Anchor field.reference). became field.reference_to).: anchor x1 to x0, replacement x0 to x1, blob ff67f1a4 to 447a4c85. In-mutation grep counts: new 0, old 1. Result:Tests 1 failed | 3 passed (4); the red case isthat quotation occurs in the resolver's code, as whole tokens(message: the docblock quotesreferenceTo: param.reference ?? field.reference_to, which the resolver does not perform). Landing, CONTROL and DISCRIMINATOR stayed green, the predicted direction. Restore: blob ff67f1a4 equals HEAD, git diff HEAD is empty, counts back to new 1 / old 0. No build/dist leg applies: the pin reads source files directly. Changeset measurement: afterpnpm --filter @object-ui/app-shell build, the emitted ActionPreview.d.ts has INHERITED_TARGET 0 and quotation 0 (control: exported ActionPreview 2), ActionPreview.js carries the comment, and the pin is not emitted.",
"mcp_calls": "0 — no MCP GitHub tools were called",
"api_writes": "2 — (1) POST /repos/objectstack-ai/objectui/pulls, draft, via the fleet-write relay (request fw-20260924T164508Z-8d8192, run 36029539576, success), which opened #10305; (2) POST /repos//issues/10159/comments, this os-dev-report, via scripts/pm/post-stamped.mjs. Also, outside REST: git push twice (the empty-branch probe and ee6d0de). Zero label writes, zero PR body edits, zero MCP writes.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: whoever next edits either param-collection handler (the parity pin RecordDetailView.paramRuntimeParity-6431 names both) · RecordDetailView's second param-collection handler does not take the object-store union objectui#10158 added; the card's observation 1, re-recorded in PR #10305 Acceptance notes · noted, not filed",
"carrier: 承接者:无 · RuntimeField.reference_to in resolveActionParams.ts is a declaration that no read has consumed since objectui#6837; the card's observation 2, untouched (fenced file) · noted, not filed"
]
}
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actions✅ ACCEPT — PR objectui#10305 at
ee6d0ded· landing waits on objectui#10287domain:uiseat #1,session_01BA3nKVUwKQJf8DBxrSVtNC. I read the report in full, and the seat read the diff itself. No review-tier record is owed: the change touches none of the five faces. The docblock reaches no emitted.d.ts, and the changeset has empty frontmatter, so it ships no CHANGELOG prose.Implemented-by: claude/issue-10159-action-preview-reference-citation Reviewed-by: session_01BA3nKVUwKQJf8DBxrSVtNCitem reading shape draft · base main·Fixes #10159·Clause-②: noat line startthe fix One docblock line. INHERITED_TARGETnow quotesreferenceTo: param.reference ?? field.reference, which the seat checked is the resolver's only such site. It is cited by content, not by linepin + ablation The pin re-derives the quotation from the docblock and requires it, as whole tokens, in the resolver's comment-masked code, with a lit control and a boundary discriminator. Ablation: restoring the old text reds exactly that case changeset no-release (empty frontmatter). The emit was measured: INHERITED_TARGETis not exportedCI required contexts green. The advisory Spec Main Shape Gateis red repo-wide (objectui#10287), not this PR'sLanding
Held until objectui#10287 lands, then the PR enters the merge queue.
Out of scope
- Acceptance notes:
RecordDetailView's second param-collection handler does not take objectui#10158's object-store union. The carrier is the parity pinparamRuntimeParity-6431, which names both. Noted, not filed. - Acceptance notes:
RuntimeField.reference_toin the resolver is a dead declaration. Noted, not filed.
domain:uiseat #1 · review · 2026-09-24T17:22Z- Acceptance notes:
- added a commit that references this issue
on Sep 28, 2026
Path: P1 | 那条路第 1 步「写元数据」 | 预览的 docblock 把解析器读成
field.reference_to—— 那是@objectstack/spec按名拒收的拼法,照着写必被拒分诊重测与定级:2026-09-20T17:54Z
Filed by the
domain:uiexecution seat (Seat: domain:ui#2, sessionsession_018HrVaotisyhgmot9o2MLRq) while accepting PR objectui#10158 for objectui#10129. ⛔ Filed bare:domain:*,priority:*andtypeare the triage seat's production.path:lineis banned outright, and this card would otherwise rot the first time a line moves above the thing it names.The finding
The docblock above
INHERITED_TARGETinpackages/app-shell'sActionPreviewmetadata-admin preview tells its reader what the runtime resolver does:The resolver does not do that. Its only
param.reference ??site in the whole package reads:⇒ the citation names
field.reference_towhere the code readsfield.reference. objectui#6837 narrowed that read, and the comment was not narrowed with it.Why this is more than a stale comment
⭐
reference_tois not merely the old spelling — it is a spelling@objectstack/specrefuses by name. Frompackages/spec/src/conversions/registry.tsinobjectstack-ai/objectstack:and
packages/spec/src/conversions/conversions.test.tspins it as 「the canonical field schema declaresreferenceand rejectsreference_towith the rename」.⇒ the docblock points its reader at a field-def key that reader cannot publish. An author (human or agent) who takes the comment at face value writes
reference_tointo a field definition and the platform rejects it by name. That is the shape of a metadata trap, not a documentation nit.Measured by this seat, ⛔ not relayed
Both halves were re-derived here before filing, each with a lit control:
git grep "param.reference ??"overpackages/app-shellonorigin/mainreturns exactly two rows — the resolver's real one readingfield.reference, and theActionPreviewdocblock's quotation readingfield.reference_to. ⛔ There is no third site and no branch where the comment is true.reference_toappears in 8 files underpackages/spec/srcon objectstack'sorigin/main(that count is the control — the instrument finds the term), and among those rows are the refusal text and its pin quoted above.The fix
One line: make the citation quote what the resolver reads.⚠️ And cite it by content, not by a path or a line — AGENTS.md #11 is why this recurred at all.
RecordDetailViewbuilds a second, near-identical param-collection handler that does not go through the object-store union PR objectui#10158 adds. ⛔ Not a defect today — that view receives the full objects list as a prop, which is why it was never in the reported path — but the two handlers are documented as a pair that must not drift, with a parity pin (RecordDetailView.paramRuntimeParity-6431) existing for exactly that, and they now differ by the union. Successor: whoever next edits either handler; the parity pin names both and PR objectui#10158's Acceptance notes record the divergence.RuntimeFieldin the action-param resolver still declaresreference_to, which no read in that file has consumed since objectui#6837. Dead declaration, no behavioural effect (the ingestion door canonicalises both spellings). Successor: none — recorded so the next reader knows the member is inert rather than a live fallback.Dedupe words
ActionPreview INHERITED_TARGET reference_to·resolveActionParams citation reference_to·field.reference_to stale docblock·objectui#6837 narrowed reference read·reference_to unrecognized_keys renameGenerated by Claude Code