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
{{ message }}
Repository navigation
Type the rect-requiring resolution rows as ref-bearing instead of proving it by comment #3576
SnapshotNode.ref became optional in #3547. The type still lets a pipeline row that requires a rect carry a ref-less node, and four acting-path sites print node.ref unguarded. They are safe today only because of a producer fact recorded in the field's JSDoc (packages/kernel/src/snapshot.ts, the "A ref-less node also carries no rect" paragraph): producers measure geometry only for refs they issued, so a rect-bearing node always has a ref. That invariant is currently a runtime fact, not a type fact. Make it one.
Required behavior
A resolution row whose policy declares resolution.requireRect: true is typed so its node cannot be ref-less, and the acting-path prints stop being provable-by-comment.
Add the narrow type beside SnapshotNode (name it for the domain, e.g. an addressable-node type = SnapshotNode & { ref: string }), and a pipeline entry point that narrows a resolved target through the row's requireRect policy — one place that turns the producer fact into the type fact.
The rect-requiring consumers take the narrowed type: src/commands/interaction/runtime/target-visibility-stages.ts, resolution-disclosure.ts, the acting rows in src/daemon/interaction/internal/find.ts (find.ts:200, :426), and selector-action-resolution.ts:43 / selector-pipeline.ts:245 as the narrowing demands.
Read rows keep returning plain SnapshotNode — a ref-less node is legitimately selectable by text and by find/wait/get. One outcome type cannot serve both rows; that is why this needs a narrowing entry, not a field type.
Measured cost (why this was deferred)
A first attempt typed the resolver and classifier as addressable (SnapshotAddressableNode + a hasSnapshotRef guard) instead of narrowing at the pipeline entry: tsc -b produced 28 errors across 5 files (18 in packages/selectors/src/__tests__/interaction-targeting.test.ts, 7 inside interaction-targeting.ts, one each at selector-pipeline.ts:245, selector-action-resolution.ts:43, and the new test). The guards relocate inward — tree walks yield SnapshotNode[] — and the four named prints are fed by the pipeline outcome, not by the resolver, so typing the resolver does not reach them. The narrowing entry is the smaller change; expect test-fixture widening more than new logic.
Completion conditions
The four prints listed above read a ref the checker knows is present; no new ?? ''-style coercion appears.
No behavior change is possible; if a test's observable output moves, that is a bug in the narrowing, not an expected diff.
Dependencies
#3547 (optional ref, the producer-fact JSDoc) and #3515 (the router case proving a ref-less text line is selectable but never a target — the runtime side of this invariant).
Activity