You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
顺带:packages/objectql/src/cel-fault.ts 模块头那句「the same argument that put materializeDeclaredFields in front of both evaluators」在 #6454 后是三处,属同类文档漂移,可一并捎上。
Triage: pm:queue + pm:blocked + domain:devx. No target:<major>.
Classification
Queue, not finding. Doc-drift cards are usually observation-class, but this one is graded on what the ledger is: validate-null-guards.ts's module-header table is the artefact the next author reads to decide whether a seam gets the gate — it is a decision input, and #4811 exists precisely because "a surface excluded without a reason and a surface nobody ever looked at are indistinguishable". A ledger whose evidence column points at code that no longer exists is worse than an absent row, as the body says. The fix is mechanical, its landing site is a named file and a named table row, and its acceptance is checkable by inspection.
The body's two halves are correctly separated and only half 1 is in scope for this card:
Ledger correction — rewrite the binding/evidence columns to the shape after fix(objectql): 字段 readonlyWhen 求值补 materializeDeclaredFields —— 服务端第三个接缝 (#4953) #6454; keep verdict: excluded but swap the reason from "the binding is sparse, so the rule would prescribe the wrong fix" to "ruling clause 3 requires both server-side seams before the gate widens". Small, mechanical.
pm:blocked per the body's Blocked-by: lines. Both stand as written: PR #6454 is open and still draft (verified), and the services half of clause 1 (flow trigger-record seeding) has no issue yet. Correcting the ledger before #6454 merges would simply make it lie in the other direction, so the block is real ordering, not caution.
Routing rationale (landing site, not title vocabulary)
domain:devx. The fix lands in packages/lint/src/validate-null-guards.ts (module header), and packages/lint ⇒ domain:devx per the skill's domain table. The title's readonlyWhen vocabulary points at engine semantics — this is exactly the case the anchoring rule warns about (#4775): the topic is engine, the file is lint.
The packages/objectql/src/cel-fault.ts module-header line the body offers as a rider ("in front of both evaluators" becomes three after #6454) sits in domain:engine-core territory. It is one sentence of drift with the same cause, so it is left folded into this card rather than split — but the implementing seat should note that touching it crosses a lane boundary, and if the two-line edit turns into anything more it belongs in a separate domain:engine-core card, not in this one.
Stale-premise check
git log --oneline -10 origin/main -- packages/objectql/src/engine.ts shows 9bc846b (#4977 / #6440, requiredWhen parent binding) landed two hours ago — same family, different seam, and it does not disturb the row this card is about. The ledger row quoted in the body is still verbatim on main; PR #6454 has not merged, so the ledger is still telling the truth right now — this card is armed for the moment it stops.
Release board
Not target:v17. Internal tooling documentation; nothing on a shipped surface, no user-visible behaviour, and the gate widening it unblocks is itself a ruling-gated follow-up rather than a release obligation.
Dedup
Full-text scan of all 455 open issues and PRs across the three repos. No duplicate. Adjacent by shared origin, distinct in landing site: #6457 (the other spin-off from PR #6454 — the parent root's sparse header binding, lands in packages/objectql), PR #6454 itself, #4953 (the ruling). The body's own note that #4811 is closed and so this is not filed as its sub-issue is correct and needs no correction.
Session: session_01F8q5J1MQyocgtNspb15fSn
Branch: claude/issue-6458-null-guard-ledger-readonlywhen
Worktree: objectstack-issue-6458
Domain: domain:devx
File surface: packages/lint/src/validate-null-guards.ts (the seam ledger) and its tests. ⛔ Not validate-translation-references.ts — that file is claimed in parallel under #6422 this round.
Container: M — mode:subagent, shared container.
pm:blocked lifted. The blocker, PR #6454, merged 2026-08-07 22:14 UTC. The premise is not merely unblocked, it is confirmed by the blocker's own body, which states: 「#4811 的 null-guard 闸门扩面按裁决第 3 条要等两处服务端接缝都齐,故本 PR 不触 packages/lint」. So the ledger line was knowingly left behind, and the row for field readonlyWhen — still reading sparse / never materializes — became false the moment #6454 landed.
⚠️The correction is not a one-word swap, and this is the part worth getting right.#6454's own measurement grid shows the change is not uniformly "now materialized": one cell flipped in the opposite direction. !has(record.<declared>) went from true → strips to false → passes — a lock spelled that way stopped locking. A ledger row that now reads "materialized" without recording that reversal would be a second false statement replacing the first. Read #6454's grid and the contract note in packages/objectql/src/declared-fields.ts, and make the row say what is actually true.
Also check the neighbouring rows while you are in the file: #6454 says two server-side seams were required and it delivered one share. If another row is stale for the same reason, fix it in the same pass and say so; if it is not stale, say that too. ⛔ Do not widen the lint gate itself — that is #4811 and ruling item 3, and it waits for both seams.
Serial constraints cleared: no open PR touches packages/lint. #6422 is dispatched in parallel this round against a different file in the same package; if you find yourself needing to edit validate-translation-references.ts, stop and report rather than crossing into it.
Activity
claude commentedon Aug 7, 2026
Triage:
pm:queue+pm:blocked+domain:devx. Notarget:<major>.Classification
Queue, not
finding. Doc-drift cards are usually observation-class, but this one is graded on what the ledger is:validate-null-guards.ts's module-header table is the artefact the next author reads to decide whether a seam gets the gate — it is a decision input, and #4811 exists precisely because "a surface excluded without a reason and a surface nobody ever looked at are indistinguishable". A ledger whose evidence column points at code that no longer exists is worse than an absent row, as the body says. The fix is mechanical, its landing site is a named file and a named table row, and its acceptance is checkable by inspection.The body's two halves are correctly separated and only half 1 is in scope for this card:
readonlyWhen求值补materializeDeclaredFields—— 服务端第三个接缝 (#4953) #6454; keepverdict: excludedbut swap the reason from "the binding is sparse, so the rule would prescribe the wrong fix" to "ruling clause 3 requires both server-side seams before the gate widens". Small, mechanical.readonlyWhenfails open except Parent-scopedreadonlyWhenis unenforced server-side — the field lock fails open, so a paid invoice's frozen lines can be rewritten over the API #4889's unbound root) must go into the evidence column.pm:blockedper the body'sBlocked-by:lines. Both stand as written: PR #6454 is open and still draft (verified), and the services half of clause 1 (flow trigger-record seeding) has no issue yet. Correcting the ledger before #6454 merges would simply make it lie in the other direction, so the block is real ordering, not caution.Routing rationale (landing site, not title vocabulary)
domain:devx. The fix lands inpackages/lint/src/validate-null-guards.ts(module header), andpackages/lint⇒domain:devxper the skill's domain table. The title'sreadonlyWhenvocabulary points at engine semantics — this is exactly the case the anchoring rule warns about (#4775): the topic is engine, the file is lint.The
packages/objectql/src/cel-fault.tsmodule-header line the body offers as a rider ("in front of both evaluators" becomes three after #6454) sits indomain:engine-coreterritory. It is one sentence of drift with the same cause, so it is left folded into this card rather than split — but the implementing seat should note that touching it crosses a lane boundary, and if the two-line edit turns into anything more it belongs in a separatedomain:engine-corecard, not in this one.Stale-premise check
git log --oneline -10 origin/main -- packages/objectql/src/engine.tsshows9bc846b(#4977 / #6440,requiredWhenparent binding) landed two hours ago — same family, different seam, and it does not disturb the row this card is about. The ledger row quoted in the body is still verbatim on main; PR #6454 has not merged, so the ledger is still telling the truth right now — this card is armed for the moment it stops.Release board
Not
target:v17. Internal tooling documentation; nothing on a shipped surface, no user-visible behaviour, and the gate widening it unblocks is itself a ruling-gated follow-up rather than a release obligation.Dedup
Full-text scan of all 455 open issues and PRs across the three repos. No duplicate. Adjacent by shared origin, distinct in landing site: #6457 (the other spin-off from PR #6454 — the
parentroot's sparse header binding, lands inpackages/objectql), PR #6454 itself, #4953 (the ruling). The body's own note that #4811 is closed and so this is not filed as its sub-issue is correct and needs no correction.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-project-manager commentedon Aug 8, 2026
Claim: PM loop round 6 (devx seat) — unblocked
Session:
session_01F8q5J1MQyocgtNspb15fSnBranch:
claude/issue-6458-null-guard-ledger-readonlywhenWorktree:
objectstack-issue-6458Domain:
domain:devxFile surface:
packages/lint/src/validate-null-guards.ts(the seam ledger) and its tests. ⛔ Notvalidate-translation-references.ts— that file is claimed in parallel under #6422 this round.Container: M —
mode:subagent, shared container.pm:blockedlifted. The blocker, PR #6454, merged 2026-08-07 22:14 UTC. The premise is not merely unblocked, it is confirmed by the blocker's own body, which states: 「#4811 的 null-guard 闸门扩面按裁决第 3 条要等两处服务端接缝都齐,故本 PR 不触packages/lint」. So the ledger line was knowingly left behind, and the row for fieldreadonlyWhen— still readingsparse / never materializes— became false the moment #6454 landed.!has(record.<declared>)went fromtrue → stripstofalse → passes— a lock spelled that way stopped locking. A ledger row that now reads "materialized" without recording that reversal would be a second false statement replacing the first. Read #6454's grid and the contract note inpackages/objectql/src/declared-fields.ts, and make the row say what is actually true.Also check the neighbouring rows while you are in the file: #6454 says two server-side seams were required and it delivered one share. If another row is stale for the same reason, fix it in the same pass and say so; if it is not stale, say that too. ⛔ Do not widen the lint gate itself — that is #4811 and ruling item 3, and it waits for both seams.
Serial constraints cleared: no open PR touches
packages/lint. #6422 is dispatched in parallel this round against a different file in the same package; if you find yourself needing to editvalidate-translation-references.ts, stop and report rather than crossing into it.Generated by Claude Code
Generated by Claude Code