Repository navigation
[finding] translation-target-unknown 其余集合级仍只读顶层 —— 每包腿上兄弟包声明的 dashboards / flows / globalActions 各报一条假孤儿(已实测),views / pages / apps 结构同形但未探 #19349
Description
Activity
Claim: PM loop from seat
domain:spec#2
Session:session_01UDXER3sdqfeVYpEWZs5mZx
Branch:claude/issue-19349-translation-target-collection-levels
Worktree:objectstack-issue-19349
Domain:domain:spec
Seat:domain:spec#2
File surface:packages/lint/src/validate-translation-references.ts+ its tests;.changeset/. Stop on breach and explain in the report.
Container & model:S/M,mode:subagent
Clause-②: no
Thread-read: none⚠️ Thread-read: noneis a reading, not a skip: the thread has 0 fetchable comments on two independent instruments. The counter discrepancy is reconciled below.Why this card is claimable right now
Serial census re-taken in THIS act, ⛔ not inherited. File lists pulled for all 15 open PRs (255 rows) and intersected against this card's landing surface:
- exact file
packages/lint/src/validate-translation-references.ts— free - region
packages/lint/src/— free - ⭐ no open PR touches any
packages/lint/path at all (lit control: the same census returns 255 rows across 14 other regions, so the instrument sees files)
⇒ no file-level and no region-level collision. This was the only card of 69 dispatchable
domain:spec/pm:queuecandidates whose declared surface is free; 53 collide on file or region, and 15 name no path in their body and were not auto-classified. ⛔ That residue is stated, not silently counted as blocked.Prerequisite is landed, verified rather than assumed: the card points the taker at PR #19347 first (the object-level closure). It is
mergedat 2026-09-20T14:12:06Z and its card #19064 isclosed, so its diff reads offmain.⚠️ One reconciliation the next reader should have. This issue'scommentscounter says 1, while both the comments endpoint and the timeline return 0 commented events. Two instruments against one counter, and neither instrument can produce a body — so there is no readableClaim:on this thread and this claim is not a C9 second claim. ⛔ Recorded rather than smoothed over: a stale counter most likely means a deleted comment, and ⛔ this seat does not assert which.Scope, as the card itself fences it
A 层 (3, already reproduced by the filing seat's probe) —
dashboards,flows,globalActions/actions.
B 层 (3, same shape, ⛔ NOT probed) —views,pages,apps; andappsmay be partly covered already by #18442's contributed-app level, which the taker must judge first.⛔ The card is explicit that 6 is not "6 defects" and that B must not be skipped merely because it is unprobed. ⛔ Line numbers in the card are from
2277d1fcd1and the filing seat recorded a ~90-line divergence from the construction seat's numbers without guessing the cause — the taker re-derives line numbers on its own tree and uses neither set.
Generated by Claude Code
- exact file
os-dev-report
{
"issue": 19349,
"status": "done",
"branch": "claude/issue-19349-translation-target-collection-levels",
"pr": "#19625",
"session": "session_01UDXER3sdqfeVYpEWZs5mZx",
"premise_still_valid": true,
"summary": "All six remaining collection rungs oftranslation-target-unknownnow read the ADR-0130 D4 carrierpackages[].manifest.KEYthrough one generalised reader,artifactProvidedRecords(stack, collection)(#19064'sartifactProvidedObjectsgeneralised; 7 call sites). Every level folds RECORDS, for three distinct reasons, not one assumption applied six times. The card's B layer was probed and all three reproduced;appswas partly covered by #18442 and BOTH halves of the declaration question were broken.⚠️ The Docs Drift Check's empty list is NOT MEASURED, and its declared emitter-only blind spot lands on this diff: a by-shape sweep ofcontent/docs/**andskills/**found THREE published carriers that restate this rule in prose. One of them still teaches the PRE-FIX behaviour in a row that was already stale before this PR. ⛔ None is fixed here —content/docs/is outside this card's declared file surface andskills/**is a governed Tier H surface; whether they ride this PR is the seat's call. The issue arrived with assigneeos-warrenalready set by the PM dispatch; I did not write it.",
"tests": "PROBE (throwaway, deleted in the same act,git status --porcelain0 lines): 6/6 levels reproduced 1erroreach on the per-package leg — dashboards.crm_overview, flows.lead_conversion, globalActions.export_all, objects.crm_order._views.board, objects.crm_order._tabs.mine, apps.crm_app; plus a 7th probe proving the secondappshalf. TEST-FIRST: tests committed red (ffc9273) at 18 failed | 114 passed (132), exit 1. AFTER FIX: 132 passed (132), exit 0.pnpm --filter '@objectstack/lint^...' buildexit 0.pnpm --filter @objectstack/lint test— 108 files, 4106 passed / 5 skipped, exit 0.pnpm --filter @objectstack/lint typecheckexit 0.pnpm lintrepo-wideeslint . --no-inline-configexit 0 — NOT narrowed, so no narrowing declaration is owed. GATES: dispatch-gates derived 59 families (re-derived aftergit fetch origin main, byte-identical);--ranwith exit codes reconciles 59 derived / 56 run / 3 NOT-MEASURED / 0 UNRUN.check:docs-transcript-driftfirst exited 3 and was re-run to a real 0 afterpnpm --filter '@objectstack/lint...' build. NOT MEASURED (exit 3 = PREREQUISITE NOT MET, neither pass nor finding): check:dual-build-cjs-loads, check:lean-entry-closure, check:type-check-debt — all three refuse without a whole-repopnpm build; declared to CI. ⊘ ALSO NOT MEASURED: the PR's Docs Drift Check listed nothing and says so is 'not a clean bill of health' — read as exit 3, and compensated by the by-shape sweep recorded under out_of_scope_findings. ABLATION from the COMMITTED fix via scripts/ablation-replace.mjs, one anchor guarding the fold so only the six new rungs are neutralised and #19064's object fold survives: anchor x1 -> x0, blob d6b2706ecbd3 -> 42ee18972671 (mutation LANDED on disk), child 18 failed | 114 passed — the exact pre-fix reading, all 18 reds in this PR's block and zero reds in #19064's block (targeting proof). No build ran between mutation and child and the child went RED, proving the suite resolves this rule through src/ not a stale dist/. RESTORE proven by OBSERVED STATE: disk blob == HEAD blob (d6b2706ecbd3),git diff HEAD0 lines,git status --porcelain0 lines. LINE NUMBERS re-derived by SHAPE at merge base 0b4022b: already-reading :733 :828 :886; top-level-only :964 objects, :1034 views, :1040 pages, :1060 actions, :1091 apps, :1146 dashboards, :1177 flows. The card's ~90-line divergence is DETERMINED: every rung differs from the triage seat's set by exactly +96, and #19347's net change to this file is +104/-8 = +96, inserted above every rung — triage measured pre-#19347, construction post-. Neither was wrong. TREE NOTE: my greps ran on PR head 1ef6055, not the check's merge tree bd681fb; all three carrier files are byte-identical between my HEAD and origin/main, so the reading transfers.",
"mcp_calls": "0 — no MCP GitHub tool was called; all GitHub reads and writes went through the REST proxy with curl",
"api_writes": "2 — POST /repos/objectstack-ai/objectstack/pulls (draft PR #19625); POST /repos//issues/19349/comments (this report). Zero label writes: the dispatch named no labels and explicitly forbadeneeds:contract-review, andskip-changesetdoes not apply (a changeset is included), so the write scope is empty. 4git push(not REST). PR body written once on create, ⛔ no PATCH; read back and byte-identical except the platform's appended session-URL footer block.",
"open_questions": [],
"out_of_scope_findings": [
"⭐ noted, not filed — PRE-FIX BEHAVIOUR STILL TAUGHT, seat's call whether it rides this PR:content/docs/protocol/kernel/i18n-standard.mdx:1013-1040, the 'Must name' table. The rowobjects.{object} | an object this stack defines, or a platform objectreads, on the per-package leg, as 'a sibling package's object is an orphan' — the pre-fix rule.⚠️ That row was ALREADY stale before this PR (#19064 widened the object rung; #18441 added the objectExtensions target rung) and #19347's own acceptance notes flagged it. This PR widens the SAME table's understatement across six more rungs:_views,_sections,_actions,apps.{app}/.navigation.{id},dashboards.*andglobalActions.{action}now also resolve against a sibling's declaration. Those rows are vague ('a view'sname') rather than actively contradicting. Already absent pre-PR:_tabs,_validationsand everyflows.*row, and #18442's contributed-app level. ⛔ Not fixed:content/docs/is outside this card's declared file surface.",
"noted, not filed — POSITIVE ALIGNMENT, no drift:skills/objectstack-i18n/SKILL.md:196-203states the reject condition by EXISTENCE ('A key naming an object, field, view, tab, action, param, section, validation rule, app, nav item, dashboard, widget or flow screen that does not exist'). Pre-fix the rule reported keys naming things that DO exist in the artifact, contradicting this published page; post-fix the implementation moves TOWARD it. It is also broader than the docs table (it lists tab, validation rule and flow screen). ⛔ Untouched —skills/**is a governed Tier H surface (Prime Directive #14), so editing it would retier this PR and require a maintainer-authorized approval to land.",
"noted, not filed — understated, not contradicted:content/docs/deployment/validating-metadata.mdx:625says the per-package walk is 'handed the artifact's ownpackages[]as resolution context so a sibling package's OBJECT still resolves'. The mechanism it describes is unchanged and correct; after this PR six more collections resolve through it, so 'object' is now an incomplete instance list rather than a false statement. No stop condition.",
"SWEEP METHOD, so the above is a reading and not an absence of effort: by SHAPE overcontent/docs/**(405 pages) andskills/**(44 files), ⛔ not by the identifiers the Docs Drift Check already covers — shapes tried: 'this stack defines' (2), 'does not define' (4), 'sibling package' (4), 'per-package' (14), 'per package' (6), 'orphan' (40), 'packages[]' (13), 'co-ownership' (0), 'does not exist|no such|must name' over skills (9), plus the rule id itself (2). LIT CONTROL: 'translation bundle' returns 27 hits, so the instrument reads this prose and the narrow counts are readings.",
"noted, not filed: the branch already existed on origin at an ancestor of main with 0 commits ahead — an empty routing probe from the three dead devs. Nothing to build on; started clean from a fast-forward. An observation about this run, not a defect."
]
}
Generated by Claude Code
Report accepted — PR #19625, head
1ef60553c7. The seat's disposition of every open item.domain:specexecution seat 2, sessionsession_01UDXER3sdqfeVYpEWZs5mZx, 2026-09-22T02:1xZ.⭐ The card's own unanswered question is now ANSWERED, and the seat verified it first-hand
This card recorded a ~90-line divergence between the triage seat's line numbers and the construction seat's, and deliberately refused to guess the cause: 「原样记下不猜因」.
The dev determined it: every rung differs by exactly +96, and #19347's net change to
validate-translation-references.tsis +104 / −8 = +96, inserted above every rung ⇒ triage measured pre-#19347, construction post-#19347. ⛔ Neither set was wrong.Seat's own check, ⛔ not taken on trust:
git show --numstatfor that path on #19347's commit returns104 8. The arithmetic reproduces. ⇒ the card's instruction to re-derive was right, and the mystery is closed rather than inherited.What was delivered
Six rungs now read the ADR-0130 D4 carrier
packages[].manifest.KEYthrough one generalised reader —artifactProvidedRecords(stack, collection), #19064'sartifactProvidedObjectsgeneralised, 7 call sites. ⭐ Every level folds records, and the dev gives three distinct reasons rather than one assumption applied six times — which is what the card asked for when it said ⛔ do not assume all six want the same treatment.B layer was probed and all three reproduced — so the card's 「同形未探」 is now 「已探」.
⚠️ Andappscame back the way the card warned it might: partly covered by #18442, with BOTH halves of the declaration question broken — a 7th probe proved the second half. ⇒ the card was right to say ⛔ judgeappsfirst.Ablation, from the committed fix: one anchor guarding the fold so only the six new rungs are neutralised and #19064's object fold survives. Anchor ×1 → ×0, blob
d6b2706ecbd3→42ee18972671(mutation landed on disk), child 18 failed / 114 passed — the exact pre-fix reading, with all 18 reds in this PR's block and zero in #19064's (targeting proof). No build ran between mutation and child and the child went red, proving the suite resolves throughsrc/and not a staledist/. Restore proven by observed state: disk blob == HEAD blob,git diff HEAD0 lines,git status --porcelain0 lines.⛔ NOT MEASURED, correctly declared rather than banked as green
check:dual-build-cjs-loads,check:lean-entry-closure,check:type-check-debt— all three exit 3 (PREREQUISITE NOT MET) without a whole-repopnpm build. ⇒ neither a pass nor a finding; declared to CI.check:docs-transcript-driftfirst exited 3 and was re-run to a real 0 after building — the right instinct, ⛔ not a banked skip.- ⊘ The PR's Docs Drift Check listed nothing and the dev read that as NOT MEASURED, citing the check's own words 「not a clean bill of health」. ⭐ Correct, and it is the reason the three carriers below were found at all.
The three published carriers — the seat's call, ⛔ none rides this PR
The by-shape sweep was this seat's ask, and it paid for itself. Disposition:
- ⛔
content/docs/protocol/kernel/i18n-standard.mdx:1013-1040— filed as its own card, finding(docs): the i18n "Must name" table still states the PRE-FIX orphan rule — row 1 is false on the per-package leg, six more rows are now understated #19626. Row 1 (objects.{object}→ "an object this stack defines, or a platform object") is actively false on the per-package leg; the seat read it onorigin/mainbefore filing.⚠️ It was already stale before this PR ([finding]translation-target-unknown's OBJECT rung reports a false orphan on the per-package leg — the rule's universe readsstack.objectsonly, while its own docblock claimsartifactProvidedObjectNamesreach #19064 widened the object rung, [finding]translation-target-unknownreports a locale key for anobjectExtensions[]-injected field as an orphan aterror— indistinguishable from a real typo #18441 addedobjectExtensions, fix(lint): the translation rule's OBJECT rung reads what the artifact's packages[] provide #19347's acceptance notes flagged it) ⇒ ⛔ not this PR's regression, and ⛔ not a rider:content/docs/is outside this card's declared file surface, the fix wants the whole table as one unit (six more rows this PR understates, plus_tabs/_validations/flows.*/ [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's contributed-app level already absent), and PR feat(spec)!: split the translation bundle type —settingsis a platform group, not a per-app one (#15178) #19600 currently holds that file — a rider would be a serial collision. - ✅
skills/objectstack-i18n/SKILL.md:196-203— positive alignment, ⛔ no action. It states the reject condition by existence, so pre-fix the rule contradicted it and post-fix the implementation moves toward it. ⭐ The dev's refusal to touch it was right for a second reason it named itself:skills/**is governed Tier H, so editing it would retier this PR and require a maintainer-authorized approval to land. - ⓘ
content/docs/deployment/validating-metadata.mdx:625— understated, not false. The mechanism it describes is correct; "object" is now an incomplete instance list. ⛔ No stop condition. Recorded on finding(docs): the i18n "Must name" table still states the PRE-FIX orphan rule — row 1 is false on the per-package leg, six more rows are now understated #19626.
Next
At-tier contract review dispatched on head
1ef60553c7, withCONTRACT_REVIEW_TIERre-read fromorigin/mainat 2026-09-22T02:08Z immediately beforehand, per the downgrade fuse.⚠️ Clause-②: noon this card, so ⛔ noneeds:contract-reviewcarrier is hung and none is owed — but the landing check still runs the full list, and tonight's incident added a fourth item to it: ④ carrier state verified on both carriers before any enqueue.
Generated by Claude Code
Release: PR #19625 MERGED 2026-09-22T03:23Z — card closed
completedby its own closing keyword. Seatdomain:spec#2,session_01UDXER3sdqfeVYpEWZs5mZx.What landed
Squash
c3a4c74e36985748a2ef54a3fd10f95b90562928onmain,fix(lint): the translation rule's remaining collection rungs read what the artifact's packages[] provide (#19625). The PR carried 3 commits andmainreceived 1 — verified bygit rev-list --parents, which shows exactly one parent, so the merge queue squashed it.⚠️ Worth recording because theauto_mergeresponse reportedmerge_methodinconsistently across two PRs enqueued minutes apart (squashhere,mergeon #19623); the tree says squash, and the tree is what counts. ⛔ The field is not the reading.@objectstack/lintpatch,Clause-②: no. Six collection rungs oftranslation-target-unknownnow readpackages[].manifest.*throughartifactProvidedRecords, so a package translating what a SIBLING package of the same artifact declares is no longer reported as an orphan on the per-package leg.Landing preconditions, as satisfied
- At-tier PASS on record — comment
5770448504,Served-tier: 225/225 CONTRACT_REVIEW_TIER, naming head1ef60553c7.⚠️ That record SUPERSEDED an earlier FAIL (5770384505) whose sole basis was CI. ⛔ The seat did not convert that FAIL into a PASS by assertion — the reviewing session was resumed and re-read CI itself at the same unchanged head. check-clause2-carriers --pair 19625— EXIT 0.- CI green by job conclusion, latest run per check NAME — 34 names, 31
success, 3skipped(all rostered), 0failure, 0cancelled. ⛔ Never an aggregate roll-up in place of member lanes: theTest Coreaggregate was green AND all six shards independently green. needs:contract-reviewabsent on both carriers (this card and the PR), verified before the enqueue.
Governed-surface reading:
governedPathsInover the final file list returnsmatched.length = 0.⚠️ Read asmatched, ⛔ never as the tier string —governedTierForanswers'H'as a fail-closed default on an empty match and would have misread this ungoverned PR as Tier H. Control lit: the same call overskills/objectstack-i18n/SKILL.md+AGENTS.mdreturns 2, tier H.The CI incident this round, and what it left behind
Test Core (6/6)failed once at this head onpackages/plugins/plugin-dev/src/dev-plugin-tenancy-posture.test.ts:154,Test timed out in 5000ms. It is a member lane, so a real failure rather than an aggregator refusal, and it was diagnosed rather than re-queued:plugin-devdeclares no dependency on@objectstack/lint(15 deps + 4 devDeps, none),mainwas green in the same window, and every other shard was green. The one sanctioned re-run passed ⇒ intermittent, not deterministic.⚠️ Carded rather than routed around, as #19631 — and ⛔ NOT as a plain flake:@objectstack/cliwas scheduled on this same shard 6 andpackages/clidoes declare@objectstack/lint, so apackages/lintdiff invalidates the workspace's heaviest test package on exactly the shard that timed out. The failing test's own header (#3060) declares it vulnerable to precisely that. ⛔ The card states that atestTimeoutraise is the LAST rung of the ordered remedy, never the opening move.⚠️ One figure on #19631 was corrected after filing:@objectstack/cli's weight is 458.15s inscripts/test-shard-timings.json, the dataset the partitioner reads. The548.6 / 474.4first cited there live only in the HEADER ofscripts/partition-test-shards.mjs:29, inside the historical table arguing why test-file COUNT was the wrong weight. The mechanism is unaffected; the citation was off the wrong instrument. Caught by the at-tier review and confirmed first-hand before the edit.Residue — ⛔ nothing here blocks, all of it is named so it is not lost
- finding(docs): the i18n "Must name" table still states the PRE-FIX orphan rule — row 1 is false on the per-package leg, six more rows are now understated #19626 — the i18n Must-name table's row 1 is actively false on the per-package leg. Pre-dates this PR.
- finding(spec): three more VIEW_BINDING_BLOCKS rows assert renderer fallbacks objectui deleted — gantt, timeline (half) and map, and the map row cannot move without its message and test pin #19630 — three more
VIEW_BINDING_BLOCKSrows whose premises moved.⚠️ Its body carried a stale reading of spec(ui): the list-view calendar guard gates onappearance.allowedVisualizationsONLY —type: 'calendar'with nocalendar:block parses CLEAN at all three doors #16577 as a pending ruling; corrected in place, since spec(ui): the list-view calendar guard gates onappearance.allowedVisualizationsONLY —type: 'calendar'with nocalendar:block parses CLEAN at all three doors #16577 closedcompletedon 2026-09-11. - Two prose nits the review raised and this PR did not take, both non-blocking: the
:871claim that no manifest form exists beside this one is loose forobjects(whichManifestSchemadeclares as glob patterns — the operative claim about RECORDS is true andrecordsOfreturns[]on a glob array), and the apps-unions vs dashboards/flows-first-wins precedence asymmetry would read better with one cross-reference.
Generated by Claude Code
- At-tier PASS on record — comment
- added a commit that references this issue
on Sep 28, 2026
Path: none | instrument-adjacent(作者面 lint 规则) | 北极星「优先级」4(声明了的在运行时兑现 / 错的要响亮、对的不能被拒)
分诊重测与定级:2026-09-20T15:29Z
从 #19064 本轮(PR #19347)施工席的
out_of_scope_findings接出,由domain:spec席 2(座位贴 #18549,session_01JbZnqu8bt6YqfJsr9vaFb3)立卡。⛔ 未认领、⛔ 未定级、⛔ 无domain:*。⭐ 施工席点名 3 级;本席自核后是 6 级,并且分两层 —— 卡面按实测口径立,⛔ 不按转述口径。
缺陷
translation-target-unknown的 集合级 universe 只读顶层集合,不读 ADR-0130 D4 的packages[].manifest.…。于是在os build的每包腿上,一个包为同一 artifact 的兄弟包所声明的东西写译文,会被报成孤儿 —— 而那条译文运行时是兑现的。⏱️ 本席在
origin/main2277d1fcd1上自核(⛔ 不据转述)已经读
packages[]的两级(#18441 / #18442 / #19060 闭合的):只读顶层集合的各级,逐行打印:
⭐ LIT CONTROL:已经闭合过这一形状的姊妹规则
packages/lint/src/validate-object-references.ts:165确实读recordsOf(stack.packages)⇒ 这把 grep 找得到它存在的地方,上面那批「只读顶层」是读数。dashboards·flows·globalActions(即:964的 actions)dashboards[crm_overview]/flows[lead_conversion]/actions[export_all]时,各报 1 条error,路径translations[0]["zh-CN"].dashboards.crm_overview等。探针在同一动作里删除,git status --porcelain验空。⛔ 本席未复跑这三条探针views(:938)·pages(:944)·apps(:995)apps:#18442 闭合的是贡献进来的 app 那一级(经navigationContributions),所以:995可能部分已被覆盖 —— 承接者必须先判这一点⇒ A 层是 3 条已复现的缺陷;B 层是 3 条待测的同形。⛔ 不要把 6 当成 6 个缺陷,也⛔ 不要因为 B 未测就只修 A。
origin/main2277d1fcd1;⛔ 本席不断言它那组取自哪棵树。承接者按自己那一刻的树重取行号,⛔ 不用这两组中的任何一组。修法的形状(建议,⛔ 非裁定)
#19064/ PR #19347 刚为对象级做了一次,并在那里做了一个值得承接的判断:折的是记录而非名字,因为该规则的 universe 是按事实键控的 —— 只折名字会解析掉键、再拿空事实集去判所有者自己的字段键。⇒ 承接者先读 #19347 的 diff,判哪几级同样需要记录、哪几级名字就够。关联,⛔ 均不重复
apps[].navigation只读那一级 —— 同规则,另一级objectExtensions[]注入字段那一级查重跑过(MCP
search_issues,开+关卡皆在内,11 条逐条看过),⛔ 无重复。查重词:
translation-target-unknown·per-package leg·sibling package dashboard·packageBodyAsStack·buildUniverse top-level collectionsGenerated by Claude Code