Repository navigation
docs(lint): os explain for the two list-view binding verdicts, and the whole-collection docblocks say what is now true - #24858
Conversation
…e whole-collection docblocks `os explain` gains entries for list-view-object-unknown and list-view-object-outside-closure; list-view-field-unknown's skip paragraph now says the runtime door refuses the binding instead. The packageScope docblock and the runtime gate's comment no longer say a whole-snapshot miss may come from another package: that is true only on the CLI. No verdict change. Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz Co-authored-by: Claude <noreply@anthropic.com>
Resolves the AuthoringRuleContext.packageScope docblock conflict with the flow-trigger closure change: keeps that change's "Read by two rules" sentence and this branch's "exists nowhere" correction. Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check6 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 4 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin cc51177407590fb56167b25527353ba46b3c6635 && git checkout cc51177407590fb56167b25527353ba46b3c6635
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin abd5acdaf788df2092064c56583fd73d837fb858 e846d135088e64fd376a80fd4f4a3c9d0b1b0dde && git checkout -B drift-repro abd5acdaf788df2092064c56583fd73d837fb858 && git merge --no-ff e846d135088e64fd376a80fd4f4a3c9d0b1b0dde
node scripts/docs-audit/affected-docs.mjs --json abd5acdaf788df2092064c56583fd73d837fb858 |
Closes #24796
Clause-②: no
Comments and explanation text only. No verdict, severity or accept set moves.
What changed
packages/lint/src/authoring-rules.ts: theAuthoringRuleContext.packageScopedocblock (it ships in the published.d.ts). It used to say an object missing from a whole snapshot "may come from another package". It now says that what such a miss means depends on who built the snapshot. On the CLI the stack is one app, so "exists nowhere" cannot be decided. At the runtime door with no closure in force the snapshot is the whole served collection, so the object exists nowhere, and a list view bound to it is refusedlist-view-object-unknown.packages/lint/src/runtime-gate.ts: the comment at thepackageScopespread inrunRuntimeAuthoringRulesgets the same fix. It used to say "from one a whole-collection snapshot merely does not carry". It now says that without a closure the snapshots carry the whole collection, and only the CLI still cannot decide.packages/lint/src/rule-explanations.ts:os explain list-view-object-outside-closureentry. It covers the package closure's limbs (asnarrowObjectsToPackageClosurekeeps them), why the binding is not resolvable by declaration, the matching dataset-door verdict, why field positions stay unjudged, and the remedy (declare the dependency, or bind inside the closure).os explain list-view-object-unknownentry. It covers the whole collection a write with no package is judged against, why that lets the door say "exists nowhere", why the nearest name rides thefix:line rather than the verdict, why an empty collection is not judged, and why the CLI still skips the binding.LIST_VIEW_BINDING_SCOPE): the binding keys, one finding per list view, and that drafts and stored rows are not judged. This is the patternLIST_VIEW_HEAD_ONLYalready uses.list-view-field-unknownentry said "An unresolvabledata.objectskips the whole list view". That is now true only onos validate/os build/os lint. The paragraph now names the two runtime ids that refuse the binding instead. The pinned phrase "one typo yields one finding" is kept.packages/lint/src/validate-list-view-field-refs.test.ts: the existing pin "os explaincarries what the verdicts no longer say" now also covers the two new ids. Each must have an entry, and each entry must name its closure/collection facts and its sibling id..changeset/24796-list-view-binding-explanations.md:@objectstack/lintpatch.Each text was checked against the implementation:
validate-list-view-field-refs.ts(the two report functions and their section docblocks),reference-integrity-suite.ts(thewholeCollection/packageScopedispatch), andruntime-gate.ts(narrowObjectsToPackageClosure,packageScopeInForce). Neither entry describes the flow door'sflow-trigger-unknown-objectverdict, which open PR #24839 is changing.Parity / pin tests
rule-explanations.test.tschecks only that each key is an exported rule id. It does not require every rule id to have an entry. Both ids are already exported from the root barrel (LIST_VIEW_OBJECT_OUTSIDE_CLOSURE,LIST_VIEW_OBJECT_UNKNOWN), and that test passes unchanged. The parity pattern this family uses is the per-rule facts pin invalidate-list-view-field-refs.test.ts, and that is what this PR extends. No generated artifact pins the explanation set.Verification (head
f6a4f21b73)pnpm --filter '@objectstack/lint^...' build: VERDICT command-exit 0.vitest runonrule-explanations.test.ts,validate-list-view-field-refs.test.ts,runtime-gate.whole-collection.test.tsandruntime-gate.package-closure.test.ts: 4 files, 185 tests passed.@objectstack/lintpnpm test: 150 files passed; 6974 tests passed, 5 skipped.@objectstack/lintpnpm typecheck:tsc --noEmitclean, andcheck:test-typecheckOK.@objectstack/clitest/explain-rule-id.test.ts(unit tier, after building lint and the cli dependency closure): 14 tests passed. That suite holds rule ids disjoint fromos explainschema names.dispatch-gates --commands: 66 derived commands (65, pluscheck-changeset-fixed, whose roster sits under.changeset/) all exit 0.check:dual-build-cjs-loads,check:lean-entry-closureandcheck:type-check-debtfirst exited 3 (PREREQUISITE NOT MET: no workspace build, and a lock queue timeout). That is not a measurement. They went green when re-run aftercheck:type-check-debt --re-measurebuilt the workspace: re-measure OK, 26 raw errors, none above the record.check:doc-authoring(no tracker number in author-facing strings) andcheck:nul-bytesare among the greens.scripts/ablation-replace.mjs --deleteremoved thelist-view-object-unknownregistry row (anchor 1 to 0, blob0cd9479e66to6ea77f0c56). The facts test went red with the assertion naming the missingos explain list-view-object-unknownentry (expected undefined to be defined). The file was then restored withgit checkout HEAD --: the blob equals HEAD (0cd9479e66) andgit diff HEADis empty. The test readssrcthrough a relative import, so no rebuild leg applies.Acceptance notes
flow-trigger-unknown-objectiswarningand not closure-keyed) — one policy across three doors? #24669 flow-trigger closure). It edits the samepackageScopedocblock inauthoring-rules.tson the lines next to this one ("Read byvalidateListViewFieldRefsonly" becomes "Read by two rules"). It also edits other parts ofrule-explanations.ts. Whichever lands second gets a mechanical conflict in that docblock. The two sentences do not contradict each other, so the merge only needs both kept.Generated by Claude Code