Repository navigation
fix(lint): one-line fix lines for the last eight fenced author-time rule ids (slice 21); os explain carries what they explained - #24292
Conversation
…ule ids; os explain carries what they explained
The `fix:` line (the finding's `hint`) of flow-template-field-unprovisioned,
flow-template-lookup-traversal, page-field-unprovisioned,
page-section-group-unknown, print-page-block-unprintable,
form-section-group-unknown, filter-token-unknown and component-props-invalid
is one remedy line of at most 200 characters on every variant that ran past
200. What the lines used to explain moves into one RULE_EXPLANATIONS entry per
id, behind `os explain RULE_ID`. Messages, ids, severities, paths and
accept/refuse results are unchanged.
- The two anchor ids print the shared one-line anchor fix
(`unprovisionedAnchorFix`); the long form, `unprovisionedAnchorHint`, lost
its last two callers and is deleted.
- The two section-group ids share `checkSectionGroupRefs`: the declared group
list is no longer echoed, the nearest group is named ("Did you mean").
- The print id no longer lists the printable set; its explanation does, held
equal to PRINTABLE_PAGE_COMPONENT_TYPES by the rule's test.
Claude-Session: https://claude.ai/code/session_01LFqdRsuM5nkqoJdHd5ztVk
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFqdRsuM5nkqoJdHd5ztVk Co-authored-by: Claude <noreply@anthropic.com>
…ng key a form resolves its object from Claude-Session: https://claude.ai/code/session_019oFY6Hi35J7atvgVFnmoaK Co-authored-by: Claude <noreply@anthropic.com>
…er binding; changeset carries the re-measured lengths Claude-Session: https://claude.ai/code/session_019oFY6Hi35J7atvgVFnmoaK Co-authored-by: Claude <noreply@anthropic.com>
… still word their own Claude-Session: https://claude.ai/code/session_019oFY6Hi35J7atvgVFnmoaK Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check18 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 3bb34a41895f2290e454397819501a44c0c1aa6a && git checkout 3bb34a41895f2290e454397819501a44c0c1aa6a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin d537a318b3116a2bcb4f70cf85ffd2a05c13d002 49e48cd217971ca1cc040c2d779f3a4a5c9682ba && git checkout -B drift-repro d537a318b3116a2bcb4f70cf85ffd2a05c13d002 && git merge --no-ff 49e48cd217971ca1cc040c2d779f3a4a5c9682ba
node scripts/docs-audit/affected-docs.mjs --json d537a318b3116a2bcb4f70cf85ffd2a05c13d002 |
席位核对 (seat check) · PR #24292 · #22161 slice 21 ·
|
| item | reading |
|---|---|
| Shape | Draft, base main. The body's line 1 is Part of #22161, line 2 is Clause-②: no, and the body has no closing keyword, so the card stays open for its close-out slice. Assignee zhuangjianguo = the card's. 15 files, all inside the claim's surface. |
| The slice's work, read in the diff | The 8 ids' hints become one remedy line each. unprovisionedAnchorHint is deleted, and its two callers move to the shared unprovisionedAnchorFix. checkSectionGroupRefs (object-field-groups.ts) builds both section-group ids' line, which is why validate-form-layout.ts has no diff, so the claim's conditional keep holds. printableList() is gone from the print rule. No message, rule id, severity or path line changes. |
RULE_EXPLANATIONS |
rule: 'ID' entries on main → this head: 0 → 1 for each of the 8 ids. Slice 20's entries survive the merge (flow-loop-body-uncontained 1). |
| Tracker ids | The added #22161 mentions are in comments and describe titles only, none in a runtime string, which is the earlier slices' convention. |
| Changeset, sentence by sentence | .changeset/22161-s21-validate-fix-lines.md: "@objectstack/lint": patch, Clause-②: no. Checked against the diff: the 8 before → after lengths (the dev's census, method in the report); the two examples (print-page-block-unprintable, flow-template-lookup-traversal on a variable); "Lists are no longer echoed" (the declared-group list and printableList() are both removed); "The anchor ids converge" (unprovisionedAnchorFix); "Unchanged: every message …". The section-group line names the nearest group only when suggestName finds one; "Did you mean" reads that way. The publish-gate FROM → TO figures are the dev's runtime probe and were not re-measured here. |
| Gates (check-runs on this head, read now) | 37 runs: 20 success, 6 skipped, 11 in progress (Test Core 1–6, Build Core, the type-check lanes, Lint · repo & tooling gates), 0 failure. Not converged, so it does not land yet. |
| Accepted deviations | (1) The whole spec repo project was run locally (11 of its files read packages/lint/src). (2) The packages/cli tiers and a built os validate / os explain are declared to CI. (3) Reverse verification swapped in main's whole-file blobs, proven by blob hash. (4) A commit landed before a queued tree-swap leg, so the restore kept it (shown in the head). (5) main moved after the one merge; none of the new commits touches packages/lint. (6) The trailers are AGENTS.md's model-free pair. (7) No label writes. |
| Out of scope | filed #24293: filter-token-unknown's message says the value "matches no record, and the surface renders empty", while the runtime refuses it (UnknownFilterTokenError, 400 FILTER_TOKEN_UNKNOWN, core/src/utils/filter-tokens.ts:547), re-read by the seat. #22161's close-out slice (census re-measure on main, the react-pages.mdx carry) is this card's own remainder. The two long-name 200-character edges and the historical unprovisionedAnchorHint comment in validate-expressions.test.ts: Acceptance notes. |
| Landing | After every check on this head is green: pr_ready then automerge_enable, through the relay. On merge, the card goes back to pm:queue for its close-out slice, with a Release: line. |
Generated by Claude Code
Part of #22161
Clause-②: no
Slice 21 of the card. It covers the other 8 author-time
packages/lintids that slice 2 fenced. Those ids are inside the card's close condition (triage answer A, comment6219576699), and this slice uses the shape of slices 11–20. Each finding'shintfor these 8 ids (the CLI'sfix:line, and the runtime finding'shint) is now one remedy line of at most 200 characters. What the old lines explained is now in each id's newRULE_EXPLANATIONSentry, whichos explain RULE_IDprints. The card stays open. The last section lists what is left.Claim:
6247309763. It is the newestClaim:on the card and names this branch; I checked that before any edit. This run resumes fromclaude/issue-22161-s21-validate-hints@c4eca88abc, which a dead earlier run pushed with no PR and no report. It never started over from zero. I reviewed that head's three commits (fe9bb145cfix lines and entries,8160ab7daamainmerge,c4eca88abchangeset) hunk by hunk and kept them, with the corrections listed under "On top of the inherited head". Every reading below was taken again in this run.What changes
One remedy line per finding. The table lists every hint the lint suite fires for the eight ids, before and after, as distinct hints · length range. The instrument is a census preload over the whole lint suite:
Array.prototypepush / unshift / map / filter / forEach / find / some / every / flatMap / concat / slice hooks that record every finding-shaped object, with itshint,fix,message,where,pathandseverity. "Before" is this branch's tests run againstmain's rule sources, which are93b4acb57blobs written into the tree and restored under a trap (method below). "After" is this branch at its final head. The runtime column comes from a scratch probe of the runtime gate (below), FROM → TO.runRuntimeAuthoringRules)flow-template-field-unprovisionedflowwrite, 2xx advisory, 362 → 175flow-template-lookup-traversalflowwrite, 2xx advisory, 249 → 131 (trigger root), 314 → 126 (flow variable)page-field-unprovisionedpagewrite (a reference-integrity member on the frozenflowdefault)page-section-group-unknownpagewrite (same)print-page-block-unprintablepagewrite, 422 issue, 362 → 170form-section-group-unknownsurfaces: CLI_ONLY)filter-token-unknownsurfaces: CLI_ONLY)component-props-invalidpagewrite, 422 issue, value line 248 → 157 (page:tabs), 250 → 159 (object-grid), 253 → 162 (record:details), 258 → 167 (record:related_list)Measured on
mainfirst, as the order asked. I ranmainitself at93b4acb57, with its own rule sources and its own tests. All eight ids fire over 200 there, at the lengths the seat's record6217435246lists: 362, 316, 362, 279, 362, 275, 259 and 258. Onmainthe census finds 11 ids over 200: these eight, plus the 3 repo-gate ids outside the condition. Some lines did not change.filter-token-unknown's four "Did you mean" lines (132–161) were one remedy line already. So werecomponent-props-invalid's retired-key line (164–181) and its node-binding line (188). Only the value-rejection line (248–258 → 157–167) moves.What each line says now.
unprovisionedAnchorFix()) that the other unprovisioned-anchor ids already print.config.expandopt-in on the trigger root, and never on a variable root.fields.os explain print-page-block-unprintablefor the printable list. This finding is also refused at the save door, where norule:line carries the pointer.os explaincarries the rest. Each of the eight ids gains aRULE_EXPLANATIONSentry, so itsrule:line now carries theos explainpointer. What the lines stopped saying is there:columnMap, or opt the object out (ownership: 'none',systemFields: { audit: false }), shared with the earlier anchor entries;config.expanddoes: a one-hop re-read of the triggering record as the run's identity. It covers the trigger record alone;PRINTABLE_PAGE_COMPONENT_TYPESby the rule's test, and the three reasons a block is refused;CONTEXT_TOKENSby the rule's test) and the date macros. It also says where{record_id}resolves, and that the runtime refuses an unresolvable placeholder;I checked every fact in the eight entries against the rule source and its docblock, and against the spec where they cite it:
date-macros.zod.ts,PRINTABLE_PAGE_COMPONENT_TYPESandComponentPropsMap. I also checked the runtime they describe: the automation engine'sexpandDeclaredLookupsforconfig.expand, and@objectstack/core'sUnknownFilterTokenErrorfor the 400. WhyClause-②: noholds:RULE_EXPLANATIONS(already published) gains eight keys.So no published name is added. The one removed function,
unprovisionedAnchorHint, was module-exported fromsystem-fields.tsbut is reached by no package entry.node scripts/check-platform-checklist.mjs --changed-from origin/mainreads OK (1 anchor judged, 0 lost).Nothing else moves. Every
message, rule id, severity andpathis unchanged, and so is what each rule accepts or refuses. The census proves this mechanically: it records the (message,where,path,severity) tuple of every finding. For each of the eight ids, the set of those tuples is identical withmain's sources and with this branch's: 1, 8, 8, 4, 55, 6, 27 and 123 tuples, 0 differing. Every other id's rows are identical too: 4067 rows, run under the same instruments, with one extra row explained in the Verification section.The two files the claim named conditionally
packages/lint/src/object-field-groups.ts: kept.checkSectionGroupRefs()builds thehintof both section-group ids.validate-form-layout.tsandvalidate-page-field-bindings.tscall it with their rule id, so the one-line form lives there. That is whyvalidate-form-layout.tsitself has no diff.packages/lint/src/system-fields.ts: kept.unprovisionedAnchorFix(), which builds both anchor ids' hint, lives there. The edit deletesunprovisionedAnchorHint(), the long form those two ids called. They were its last two callers. The edit also rewrites the shared fix's docblock.On top of the inherited head
mainmerged first (1e1554e15, clean). Slice 20'srule-explanations.tsentries (b6805ac0f) merged without a conflict, and all 20 entries are present: the twelvelint-flow-patterns.tsids plus these eight.data.objectas a form's own binding. The rule readsobjectName,objectordata.object(viewObjectName).walkPageComponents).unprovisionedAnchorFix()'s docblock said every unprovisioned-anchor rule in the package prints that wording. Two (validate-expressions.ts,validate-semantic-roles.ts) still word their own fix, as the cause docblock beside it already notes. It now says so.File surface: the claim's
The diff touches six rule files, but only five have a diff.
validate-form-layout.tshas none, because its hint is built inobject-field-groups.ts. The rest of the diff:rule-explanations.ts, entries for these eight ids only;object-field-groups.tsandsystem-fields.ts, as explained above;.changeset/22161-s21-validate-fix-lines.md.It does not touch
lint-flow-patterns.ts,lint-startup-registry-verdict.tsorcontent/docs/**. 15 files, +674 / −76.Verification
Final head
49e48cd21. Heavy runs went throughscripts/pm/os-verify-lock.sh(slotissue-22161-s21), and each reading below is itsVERDICTline. Every exit code was captured before any pipe.49e48cd21: 143 files / 6847 passed, VERDICT 0. The census run is the same run.mainleg.main's93b4acb57blobs of the 14 changed lint files were written into the tree only. Their landing was proved by blob hash. They were restored fromHEADby absolute path under an EXIT/INT/TERM trap, and the restore was proved by blob hash, an emptygit diff HEADand a clean status.lazy-deps/runtime-lazy-depscases. The lint dist did not exist yet, and it does now.main's 8 rule sources were swapped in (same method), with this branch's tests: 6 files / 70 tests red, exactly this slice's six test files. The pins fail on the old text, so they can fail. Restore proved the same way. This one leg is also the census "before" column above.49e48cd21, VERDICT 0 each.tsuppluscheck-dts-emitted, 6/6 declaration files.tscpluscheck:test-typecheckOK (2 files / 6 errors / 2 pinned, unchanged).tsc -p tsconfig.test.json --listFileslists all six changed test files.repoproject (--project repo, whose cross-package pins readpackages/lint/src):packages/lint: 11 / 201 passed, VERDICT 0.runRuntimeAuthoringRuleswithtsx: 6pageand 3flow. It ran withmain's 8 rule sources swapped in (same method), then on this branch. Results are in the table above. No write changes channel. Eachpagecase ran 4 rules and eachflowcase 9 rules, on both sides.validation-rule-json-schema-uncompilablerow appears that the earlier legs did not record. It comes from the five dist-dependent cases, which ran once the lint dist existed. It is not one of the eight ids.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths, at49e48cd21: 64 families over 15 paths since the merge base93b4acb57. Each family was run one by one and its exit code recorded. 62 exit 0. 2 exit 3 (PREREQUISITE NOT MET) and are NOT MEASURED:check:dual-build-cjs-loadsneeds every package built, andcheck:lean-entry-closureneedspackages/objectql/dist.--ranreports 64 derived, 62 run, 2 NOT-MEASURED, 0 UNRUN. This diff adds no import edge, so CI's full build gives those two their reading. For every family CI runs, this PR's own check-runs are the reading.check:dev-prereqsandcheck:skill-frame-freshnesswere not run: the diff touches neither apackages/specbuild input nor the four-axis frame files.grep -naPover every changed file and this body finds nothing (exit 1). A planted control byte is found (exit 0).Acceptance notes
filter-token-unknown's verdict sentence contradicts the runtime it describes. It says an unresolvable placeholder "is sent to the data engine as a literal string, matches no record, and the surface renders empty". So does the rule file's module header. The runtime refuses such a filter instead:UnknownFilterTokenError(FILTER_TOKEN_UNKNOWN, 400,packages/core/src/utils/filter-tokens.ts). That is the spec's own declared behaviour (date-macros.zod.ts: "the runtime resolver throws").packages/objectql/src/engine-filter-token-today-spelling.test.tspins the refusal. The new entry states the refusal. This slice keeps messages unchanged by its shape, so the sentence is not edited here. It was not measured throughos validatein this run (the CLI was not built), so it is noted, not filed.The 200-character bound is measured over the suite's fixtures, as in slices 11–20. Some lines interpolate names:
Long enough names can push either past 200. The anchor line's wording predates this slice.
component-props-invalid's test re-measures its two type-naming lines at the longest typeComponentPropsMapdeclares.The census sees what the lint suite fires. It measures 213 of the 215 id-shaped rule constants the root barrel exports. The other two never fire in the suite.
chart-config-missinghas no emit site inpackages/lint/src.react-prop-deprecated's hint is the react-blocks contract's ownnotefor a deprecated prop.mainmoved after the one merge. The branch carriesmainat93b4acb57, andorigin/mainis now ate15897c0f. None of the 5 newer commits touchespackages/lint. Per the order, I merge again only for a conflict, amain-caused red or a queue removal.validate-expressions.test.tsstill names the deletedunprovisionedAnchorHintin a historical comment about an earlier card. It is outside this slice's surface and left as written.Not run locally, declared to CI.
packages/clitiers.test/explain-rule-id.test.tsholds everyRULE_EXPLANATIONSkey disjoint from theos explainschema names and resolves each through the command.os validate/os explainthrough a built CLI.@objectstack/lint.Remaining for this card
The census at
49e48cd21covers the whole lint suite: 239 ids fire, and 3 are over 200. All 3 are outside the close condition (repo gate, not author-time):lint-startup-registry-verdict.ts'sstartup-open-vocabulary-verdict972,startup-verdict-assertive-wording972 andstartup-source-unparseable254. No author-timepackages/lintid fires a hint orfix:over 200 characters in the suite. The close-out slice still owes two things: the census re-measured onmainafter this lands, and thecontent/docs/ui/react-pages.mdxtranscript carry from slice 15's landing record6136999237.Generated by Claude Code