Repository navigation
Description
Residual measured while implementing #8116 (PR pending on claude/issue-8116-provenance-predicate-to-spec).
The gap
#8116 sank the #7865 provenance derivation into @objectstack/spec/data and taught the per-object resolution sites in @objectstack/lint to warn when a reference resolves to an injected anchor with no storage behind it on an ADR-0015 external object. That covers the two rules that resolve fields per object today:
validate-expressions.ts(buildFieldIndex/ the object-bound expression surfaces),validate-semantic-roles.ts(stageField/highlightFields).
The filter-position field checks are structurally different: they judge a field name against the object-independent blanket union SYSTEM_FIELDS (packages/lint/src/system-fields.ts), which by design answers "could this name be a system column anywhere" and therefore never flags a system name. Measured read sites:
packages/lint/src/validate-widget-bindings.ts:479(dashboard filter effective field),packages/lint/src/validate-react-page-props.ts:476(aggregate/filter field refs),packages/lint/src/validate-page-field-bindings.ts:343,packages/lint/src/validate-flow-template-paths.ts:100(CRUD-nodefiltertemplate paths).
So filter: [["owner_id", "=", "..."]] on a view/widget/page bound to a federated object lints clean while the runtime degrades exactly as #8116's warning describes (on SQLite: constant-false, HTTP 200, zero rows, no error).
Why it did not ride #8116's PR
Attaching the marker at these sites first requires converting each rule from the blanket union to the per-object derivation (injectedColumnsFor / unprovisionedInjectedColumnsFor) — #5378-shaped work with its own false-positive analysis per surface (each rule's tolerance for names it cannot resolve differs). The #8116 ruling scoped that card to the provenance predicate move only. The spec-side prerequisite now exists, so this is pure lint wiring.
Pointers
- Marker:
unprovisionedInjectedColumnsFor(packages/lint/src/system-fields.ts, finding: author-time expression validation resolves injected anchors on external objects but cannot warn they are unprovisioned — the #7865 provenance marker is unreachable from @objectstack/lint #8116) overunprovisionedInjectedColumns(@objectstack/spec/data). - The warning shape and severity reasoning to reuse:
warnUnprovisionedAnchorsinpackages/lint/src/validate-expressions.ts. - History: lint: five hand-copied
SYSTEM_FIELDSlists in packages/lint should derive from the spec's declarations #4330 (the blanket union's origin and its deliberate cost asymmetry), Author-time expression validator is blind to registry-injected system columns —record.owner_id/created_at/organization_idare rejected as unknown fields #5378, [Decision]applySystemFieldsinjects platform anchors intoexternalobjects the platform provisions no storage for — three consumers have now independently re-derived "that column is not really there" #7865, finding: author-time expression validation resolves injected anchors on external objects but cannot warn they are unprovisioned — the #7865 provenance marker is unreachable from @objectstack/lint #8116.
Generated by Claude Code
Activity
hotlong commentedon Aug 13, 2026
Triage: lands in
domain:devx(packages/lint).pm:queue,type: Bug— the #8116 unprovisioned-anchor warning was scoped to the two per-object resolution rules; the four filter-position sites judge against the object-independentSYSTEM_FIELDSblanket union by construction and so structurally cannot flag the same degradation class the warning exists to catch. Pure lint wiring per the filer, reusing an already-shipped marker (unprovisionedInjectedColumnsFor) and warning shape (warnUnprovisionedAnchors) — no new decision surface.Size/model suggestion: M,
mode:subagent,model: opus(four call sites, each with its own false-positive tolerance per the filer's note — needs care, not just mechanical copy-paste).Generated by Claude Code
feat(lint): the objectstack-ai#8116 unprovisioned-anchor warning reac…
fix(lint): warn when `searchableFields` declares an unprovisioned inj…
test(lint): pin the four unprovisionedAnchors threading sites in vali…
fix(lint): resolve flow-variable template roots, and gate the record …
docs(lint): re-anchor the dead tracker citations in packages/lint/src…