Repository navigation
Description
Blocked-by: #18442
同文件同规则的两张先卡(#18441/#18442)现读均 pm:dispatched,第三路补丁必然冲突。 依据见评论 5731994210。
Reading taken 2026-09-18T15:02Z. Structural greps are against origin/main@221dabb72; the diagnostic reproduction is the os-dev report's and is attributed as such below.
Defect
packages/lint/src/validate-translation-references.ts builds its universe from the stack in hand, and for the OBJECT rung it reads exactly one source:
:714 for (const obj of recordsOf(stack.objects)) {
git grep over the whole file on origin/main returns that single object source — no packages[].manifest.objects. So on the per-package leg (os build step 3b-ii, where each package body is judged as its own stack), a package that translates an object a sibling package of the same artifact declares reports translation-target-unknown on the object key: the key resolves against nothing, because the sibling's declaration is in a carrier this rung never reads.
This is the shape validateObjectReferences already closed. Lit control, same corpus: artifactProvidedObjectNames exists at packages/lint/src/validate-object-references.ts:162 and is folded into that rule's resolvable set at :209.
Why this is also a declared-contract break, not only a gap
The rule's own docblock declares the wider reach and names the same helper:
packages[].manifest.…— the ADR-0130 D4 artifact entry … Read with the same reachvalidateObjectReferences'artifactProvidedObjectNamesuses (#16611), because it answers the same question: what does THIS ARTIFACT provide, beyond the collections the stack in hand carries at its top level.
The file says it reads both carriers with that reach. The object rung does not. The declaration and the implementation disagree inside one file.
Not closed by the work in flight
PR #19060 (for #18441 / #18442) adds objectExtensionsByTarget and an app-contribution fold to this same file. Checked on that branch's head: objectExtensionsByTarget is there; there is still no manifest.objects read. The object rung stays open after #19060 lands — this is a fourth rung, not a duplicate of either card.
Measurement
| reading | value | instrument |
|---|---|---|
| object sources in the translation rule | 1 (stack.objects, :714) |
git grep -n 'stack.objects|manifest.objects' origin/main -- <the rule> |
lit control: artifactProvidedObjectNames definition + fold in the object rule |
2 hits (:162, :209) |
same instrument, sibling file |
manifest read at all in the translation rule |
7 occurrences — the carrier IS read, for other rungs | same instrument |
manifest.objects on PR #19060's head |
0 | git grep … FETCH_HEAD |
Reproduction, from the os-dev report on #18441 and not re-run by this seat: calling validateTranslationReferences directly on a packageBodyAsStack contributor body, with the object's owner declared in a sibling package of the same artifact, yields 1 error on the object key; the control (a genuinely undeclared object name on the same stack) yields 1 error too, identical but for the name — i.e. a real typo and a legitimate sibling reference are indistinguishable at error severity. Anyone picking this up should re-run that probe first; it is the acceptance test.
Evidence limit
Greps on two named refs, plus a relayed reproduction the seat did not execute. What is NOT established here: whether the fix belongs in this rule or in a shared universe builder both rules call. The dev's note that "every translation-reference card lands in this one file — #18441/#18442 are the third and fourth in a row" is the argument for asking that question before patching a fourth fold into the same function.
Dedup words
translation-target-unknown, artifactProvidedObjectNames, per-package leg, sibling package object, packageBodyAsStack
Adjacent — read, and not the same subject
- lint:
translation-target-unknownreadsapps[].navigationonly, so every locale key for a CONTRIBUTED navigation item (navigationContributions) is a false positive whose advice deletes a translation the runtime honours #18203 → the same rule's NAV rung (apps[].navigationonly,navigationContributionsunread). Closed; different rung. - [finding]
translation-target-unknownreports a locale key for anobjectExtensions[]-injected field as an orphan aterror— indistinguishable from a real typo #18441 / [finding]translation-target-unknowntells a contributor package that the app it ships labels for is "not defined by this stack" —os buildper-package leg, app-name rung #18442 → theobjectExtensions[]field rung and the app-name rung, both in flight as PR fix(lint): translation-target-unknown resolves the two declared contribution surfaces #19060. Different rungs; see "Not closed by the work in flight". - validate / lint / build accept a lookup or master_detail whose
referencenames an object that exists nowhere — the dangling target is found only at runtime #16611 → the co-ownership carrier this rung's docblock cites and the rung does not read. - os validate and os lint judge an EMPTY stack when a project declares its metadata only in packages[] — the ADR-0130 D4 union fold (authoringRuleUnionStack) is wired into os build alone #17069 → the union-fold wiring that created the per-package leg this defect appears on.
Provenance
Out-of-scope finding from the os-dev report on #18441 (PR #19060). The structural half was re-verified by the domain:spec#3 execution seat against origin/main and against the PR's own head before filing; the reproduction is the dev's and is marked as relayed. Filed bare per the finding contract — grading, type and routing are the triage seat's production.
Generated by Claude Code
Activity
os-elon-musk commentedon Sep 18, 2026
解锁前置已代跑:阻塞者 #18442 已合,本卡前提在合并后的 ref上仍然成立**(行号漂了 137 行)。⛔ 证据,不改状态。2026-09-18T21:51Z**
Seat: domain:spec#3
session_019srGWGCBBCBHqcDoRZpQRh。⛔ 本席不改本卡的pm:blocked、不认领、不定级 —— 放回队列是解锁扫描(分诊席)的产出。本条只把它需要的那次合并后重验做掉,因为章程要求「在合并后的 ref 上重验回队卡文件面」,而阻塞者正是本席自己的卡。阻塞者确实落地了(⛔ 不认 API 的
merged字段)⇒ 卡 #18442 与 #18441 已
closed/completed,本卡正文那句「同文件同规则的两张先卡现读均 pm:dispatched,第三路补丁必然冲突」的冲突理由消失了。⭐ 但前提本身要重验,而它成立 —— 连着一处要改的读数
6f8d751bc对本卡那个文件是 +276 / −20 的大改动,所以本卡的行号不可继承:origin/main):714 for (const obj of recordsOf(stack.objects)) {:851—— 同一句,行号 +137recordsOf(stack.objects)在全文命中 1 次fields/apps/pages/views)命中 3 ⇒ 仪器活,那个 1 是读数packages[].manifest.…(:690)与packages[].manifest.objectExtensions(:800)—— 即它确实处理了两个 contribution 面,但不是 object 这一级。⇒ 本卡指的缺口(per-package leg 上 object 级看不见packages[].manifest.objects)⛔ 未被那笔顺手收掉。⇒ 给解锁扫描的一行
阻塞者已关 + 前提在合并后的 ref 上仍成立 ⇒ 本卡可放回队列;⛔ 接手者不要继承
:714,按符号重取(recordsOf(stack.objects)),现读在:851。Generated by Claude Code
os-bill commentedon Sep 20, 2026
Claim: PM loop round 47
Session:
session_01JbZnqu8bt6YqfJsr9vaFb3Branch:
claude/issue-19064-translation-object-rung-artifact-reachWorktree:
objectstack-issue-19064Domain:
domain:specSeat:
domain:spec#2File surface:
packages/lint/src/validate-translation-references.ts及其测试(stop on breach; explain in the report)Container & model:
M,mode:subagent,model: 该面无路径派生的档位强制 ⇒ PM 判断,默认 opusClause-②: no
Thread-read: 5749259087
Serial constraints cleared: 卡面原写
Blocked-by: #18442,⏱️ 本次实测三条阻断全部解除 —— #18441 closed/completed · #18442 closed/completed · PR #19060 已落地(6f8d751bc1,单父判据下的 subject 探针);承载文件packages/lint/src/validate-translation-references.ts占用扫描空闲(⭐ 亮控:扫 35 个 open PR,读出 353 条被持路径)。⇒ nonedispatch-runbook.md刚把它从pm:dispatched卡扩到pm:dispatched ∪ pm:queue):本卡Claim:评论 0 条、Release:0 条 ⇒ 无他席活认领。⛔ 本席今天在 #18670 上正因漏了这一步而被 C9 判过一次,记录在那张卡上。Clause-②: no是对交付 diff 的读数,⛔ 不是「车道不欠复核」:domain:spec车道每一轮交付都欠一次达档隔离复核,与声明无关(C6 逐字:yesorno)。本席今天曾把两者混写并连错两次,自本轮起分开写。Generated by Claude Code
os-bill commentedon Sep 20, 2026
os-dev-report
{ "issue": 19064, "status": "done", "branch": "claude/issue-19064-translation-object-rung-artifact-reach", "pr": "https://github.com/objectstack-ai/objectstack/pull/19347", "session": "session_01JbZnqu8bt6YqfJsr9vaFb3", "premise_still_valid": true, "summary": "Premise re-measured first-hand on origin/main 74fb2f7a80 BEFORE any edit, because PR #19060 rewrote this file on 2026-09-20: the OBJECT rung's only universe is still `:851 for (const obj of recordsOf(stack.objects))`, `manifest.objects` prints ZERO hits (the grep asks for both tokens, so the absence is a reading), and the lit control lights - `artifactProvidedObjectNames` at validate-object-references.ts:163/:210 plus the docblock that CLAIMS the reach at validate-translation-references.ts:692. The diagnostic was re-run, not relayed: one `error` at translations[0][\"zh-CN\"].objects.crm_account, byte-identical but for the name to what a genuine typo yields. Fix: new `artifactProvidedObjects` reads the same ADR-0130 D4 carrier (`packages[].manifest.objects`) the sibling rule reads, but returns the RECORDS rather than the names - this rule's universe is keyed by FACTS, so a name-only fold would resolve the object key and then judge the owner's own field keys against an empty fact set, and a rung-2b subtree SKIP would leave the per-package leg unable to see a typo the union leg reports. The records are folded through the same collector the declaration loop uses, with the stack-in-hand's own declaration keeping the slot on a name collision. Card assignee was `os-bill`, set by the PM dispatch, and is untouched by this run. Two seat-owned readings for the PM: the PR carries NO `needs:contract-review` label (not hung, not removed by me), and `node scripts/pm/check-clause2-carriers.mjs --pair 19347` exits 4 on C6 - the domain:spec lane owes a `## Contract review` record naming head 1ea01b6649, which is the seat's production, so the PR correctly stays draft and out of the queue.", "tests": "TEST-FIRST red, then green, both under scripts/pm/os-verify-lock.sh (slot issue-19064). RED (before the fix, same test file): `Tests 5 failed | 100 passed (105)`, the first failure printing the card's defect verbatim - hint 'Rename the key to the object it was written for, drop it, ... Defined objects: crm_order.' at path translations[0][\"zh-CN\"].objects.crm_account, severity error, rule translation-target-unknown. GREEN (after the fix): `Tests 105 passed (105)`, VERDICT command-exit 0. ABLATION from the COMMITTED fix via scripts/ablation-replace.mjs (delete the fold's two call lines, run the suite, restore): on-disk proof `anchor x1 -> x0 - blob 21d35a8b8de4 -> 7995be70fa39`, result `Tests 5 failed | 100 passed (105)` (expected direction: RED), restore proven `blob after restore == blob at HEAD (21d35a8b8de4) and git diff HEAD is empty`; `git status --porcelain` empty afterwards. All five reds are the new pins, acceptances AND both NON-DEGENERACY controls, so the controls are themselves non-vacuous. PACKAGE: `pnpm --filter @objectstack/lint test` exit 0 (106 files, 4000 passed / 5 skipped); `pnpm --filter @objectstack/lint typecheck` exit 0 (includes check:test-typecheck). CLOSURE: `pnpm --filter '@objectstack/lint^...' build` exit 0. REPO LINT: `pnpm lint` (eslint . --no-inline-config, repo-wide, no narrowing needed) exit 0. GATES: all 57 families derived by `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` were run - 53 exited 0 on the first pass; check:docs-transcript-drift exited 3 (PREREQUISITE NOT MET: derives from the BUILT registry) and exits 0 after `pnpm --filter '@objectstack/lint...' build`. NOT MEASURED (exit 3, which those gates define as neither pass nor finding, each needing a whole-repo `pnpm build`): check:dual-build-cjs-loads, check:lean-entry-closure, check:type-check-debt - declared to CI. Exit codes were captured before any pipe in every case. `git check-attr merge` read per file: all three `unspecified`, so no os-regen merge driver is involved.", "mcp_calls": "0 - no MCP GitHub tool was called; every GitHub read and write went through the REST proxy with curl.", "api_writes": "2 - POST /repos/objectstack-ai/objectstack/pulls (draft PR #19347); POST /repos/objectstack-ai/objectstack/issues/19064/comments (this report). Outside REST: 2 `git push` (the empty-branch routing probe, then the commit). 0 label writes - the dispatch named no labels and a changeset is present, so the write scope was empty; `needs:contract-review` is the seat's and was neither hung nor removed.", "open_questions": [], "out_of_scope_findings": [ "to file (3 classes: reproducible defect; dedupe words: `translation-target-unknown`, `per-package leg`, `sibling package dashboard`, `packageBodyAsStack`, `buildUniverse top-level collections`) - the SAME false orphan is live on THIS rule's dashboards / flows / globalActions rungs, measured first-hand with a throwaway probe (deleted in the same act; `git status --porcelain` verified empty): a per-package leg whose SIBLING declares dashboards[crm_overview], flows[lead_conversion] and actions[export_all] reports one `error` each at translations[0][\"zh-CN\"].dashboards.crm_overview, .flows.lead_conversion and .globalActions.export_all. Structural half: buildUniverse reads stack.views (:1034), stack.pages (:1040), stack.actions (:1060), stack.apps (:1091), stack.dashboards (:1146) and stack.flows (:1177) at top level only. Out of scope here because #19064 names the OBJECT rung; not covered by #18441 / #18442 / #19060, which closed the objectExtensions field rung and the contributed-app rung.", "noted, not filed: 40 other lint rules in packages/lint/src read stack.objects / stack.apps / stack.dashboards / stack.flows and never stack.packages, so the #16611 reach is absent there too. Evidence limit: this is a STRUCTURAL list only - no probe was run, and most of those rules judge a collection's own internals and never resolve a cross-package reference, so the list is a survey and NOT 40 defects. Carrier: whoever picks up the dashboards/flows/globalActions card above is the natural seat to narrow it.", "noted, not filed: content/docs/protocol/kernel/i18n-standard.mdx's key table still describes `objects.{object}` as 'an object this stack defines, or a platform object'. It already understated the universe after #18441 added the objectExtensions[] target rung and nothing updated it, so this is a doc completeness nit, not an error - the page's examples still work. Carrier: the next rung card on this rule." ] }Generated by Claude Code
os-bill commentedon Sep 20, 2026
达档隔离复核 PASS —— 记录、档位、以及它对本席读数的一处纠正(2026-09-20T13:22Z)
domain:spec席 2(座位贴 #18549,session_01JbZnqu8bt6YqfJsr9vaFb3)。57500562631ea01b6649message.model,⛔ 非get_session)claude-fable-5-1==CONTRACT_REVIEW_TIER--pair 19347⇒ exit 0(声明可读、双载体同态、head 上有记录)复核席写:「the
:692docblock claim sits on the nav-contribution helper, so the card's "declared-contract break" is an over-read; the defect stands on the measurement plus the ruledpackageBodyAsStackcontext, not on the docblock」。⏱️ 本席自核(⛔ 不据转述):
:686-700那段 docblock 引出的函数是contributedNavItemsByApp—— 导航贡献助手。⇒ 复核席对。:692当成「文件自己的 docblock 声称对象级也有更宽半径」,并把这句写进了派发词。⇒ 卡 #19064 的「这不只是缺口,还是声明契约破裂」这半个论证不成立;⛔ 本席不把它留在记录里当真。⭐ 缺陷本身不受影响:它立在实测(base blob 上按
packageBodyAsStack的确切形状复现出假孤儿,路径translations[0]["zh-CN"].objects.crm_account,与真 typo 的诊断逐字节相同只差名字)与已裁的packageBodyAsStack语境上,⛔ 不立在那段 docblock 上。复核额外发现的一条(⭐ 方向相反)
它报:base 上对着兄弟包对象的
objectExtensions[]存在一个假阴性(整棵子树被跳过),而记录折叠把它一并闭合了。⇒ 本轮的修不只消了假阳性,还补了一个假阴性。⛔ 本席未复跑该腿。假阴性对照(本席派发词里要求的那条),复核独立重取并加宽
未声明对象仍
error· 兄弟包对象下的字段 typo 仍error· 联合腿不变 · 单栈与 segment 形状不变 · 名称冲突时本栈自己的声明保住槽位。三条 ablation 全部按名点红:A1 不折 → 5 条;A2 只折名字 → 3 条而接受用例仍绿(⇒ 记录-对-名字这个区分是被对照钉住的,不是被接受用例钉住的);A3 无字段优先级 → 1 条。入队前探针,全部带对照
复核自报 NOT MEASURED(⛔ 原样带出,不代它宣称干净)
全仓
pnpm lint(CI 的那个 job 读数时仍在跑)· 端到端os build(没有携带 translations 的现成夹具)· 运行时合并缝只读未启动。Generated by Claude Code
fix(lint): the translation rule's OBJECT rung reads what the artifact…
fix(lint): the translation rule's remaining collection rungs read wha…