Repository navigation
fix(lint): one-line fix hints for the six data-model-rules ids (#22161 slice 18) - #23907
Conversation
Part of the #22161 slice-18 work. Claude-Session: https://claude.ai/code/session_013jYeZqax65nQWvPNayiCT3 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jYeZqax65nQWvPNayiCT3 Co-authored-by: Claude <noreply@anthropic.com>
…8-data-model-rules-hints
📓 Docs Drift Check4 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 0a794031e93f399e4291beb4f59ea4c80f63f01a && git checkout 0a794031e93f399e4291beb4f59ea4c80f63f01a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 570f01d270a37aeadfe078a6892797428151a7a8 3993be17dd8ee163d800c58e23f1b3d9ecada860 && git checkout -B drift-repro 570f01d270a37aeadfe078a6892797428151a7a8 && git merge --no-ff 3993be17dd8ee163d800c58e23f1b3d9ecada860
node scripts/docs-audit/affected-docs.mjs --json 570f01d270a37aeadfe078a6892797428151a7a8 |
Review: ACCEPT · #22161 slice 18 · PR #23907 @
|
Part of #22161
Clause-②: no
Slice 18 of #22161 (claim
6213942673): every rule id inpackages/lint/src/data-model-rules.tswhosefixran past 200 characters now prints one remedy line. The text those lines used to explain is inRULE_EXPLANATIONS, whichos explain RULE_IDprints. This follows the shape of slices 11–17. Messages, ids, severities, paths and accept/refuse results do not change.Before → after (characters of the fix text, longest variant measured)
unique/legacy-organization-compositeos validate/os build(registryhint),os lintunique/unscoped-declared-indexhint)object/missing-name-fieldos lintonly (lintDataModel)unique/double-declarationos validate/os build(registryhint),os lintrollup/non-numeric-aggregandos lintonly (lintDataModel)field/select-missing-optionsos lintonly (lintDataModel)The probe that measured these calls the built
@objectstack/lintdist directly. It covers every arm of each rule (both index spellings, all four scope quadrants, a declared tenant column, every option-field type, nine child types underminandmax) with long object and column names. The base readings match slice 16's report (578 / 380 / 327 / 279 / 207). The higher 592 / 303 / 300 come from the longer names in the probe. Base6db53acd6, branch492ab98d.What moved where
unique/unscoped-declared-index: the line keeps the two scope words. What'organization'makes the driver build, and theos migrate meta --from 17house sentence for existing sources, are now a new paragraph of its explanation. The sentence is still a single plain-quoted literal, soretired-key-migrate-sentence.test.tsstill judges it.unique/legacy-organization-composite: the line is "respell + keepfields+ therecreate_index/ pre-flight cost". The in-place NULL-safety, what the constraint then means, and the probe's report-instead-of-boot-failure moved to its explanation. The line no longer depends on the column list.unique/double-declaration: the contradiction arm no longer names the column or where each word may live. That is now an explanation paragraph. The two redundancy arms were already under 200 and drop one word.object/missing-name-field: the line now points atos explain title-format-retired, whose existing entry already says why atitleFormattemplate does not count. No new entry was added: an entry needs an exported id constant, which would widen@objectstack/lint's public surface. That is outside this slice'sClause-②: no.rollup/non-numeric-aggregand: the line no longer names the parent object, so its length no longer grows with that name. The existing entry already carries the reasoning.field/select-missing-options: trimmed wording only.The census blind spot (the dispatch's mechanism hypothesis, measured)
The slice-17 push-preload census reads objects that carry a
hint, which is theAuthoringFindingshape. Replicated at base: 231 ids carry ahint, the same count slice 17 reported.object/missing-name-field,rollup/non-numeric-aggregandandfield/select-missing-optionsDO fire in the lint suite, but only asLintIssue.fix, becauselintDataModelis not a registry rule and nothing adapts its findings into ahint. So the census missed them because of the shape it reads, not because the suite never fired them. Recordingfixtoo gives 327 / 282 / 207 at base. The new test file readsfixdirectly over every arm.Runtime reach
None of the six runs at the runtime publish gate. The three uniqueness entries are
surfaces: CLI_ONLY, and the other three run only inos lint's sweep. Measured withrunRuntimeAuthoringRules({ type: 'object', … })on one write per id: 10 rules run, the controlsecurity-owd-unsetfires, and none of the six does. So no 422issues[].hintor 2xxadvisories[].hintchanges.Tests
packages/lint/src/data-model-rules.fix-lines.test.ts: an exact-line pin for each id's fix, a bound of one line and ≤200 characters over every finding fired across all six ids (with a coverage control requiring all six to fire), and the facts the moved text now carries inos explain.55223df1, viascripts/ablation-replace.mjsunder the lock): the old tail was restored onunique/legacy-organization-composite(anchor 1 → 0, blobdd03cc6b34c6→15bc83a0f5ab). Predicted exactly 2 red; observedTests 2 failed | 6 passed (8)(the exact-line pin and the bound). Restored: blob == HEAD andgit diff HEADempty.@objectstack/lint: 141 files / 6790 tests passed andtypecheckpassed (tsc + check:test-typecheck), at merge head3993be17dd. Earlier at55223df1: 141 / 6789.492ab98d: 300 / 302 files on the full run, 4469 tests passed. The 2 failing files were a prerequisite (the CLI's owndistwas not built) and passed afterpnpm --filter @objectstack/cli build, together withtest/data-model-rules.test.ts(3 files, 85 tests). Every existing pin on these fixes (ADR-0079, titleFormat, both scope words, "the exact index bare true built", "keep fields exactly as they are", recreate_index, pre-flight, and the options / picklist pair) still holds unchanged.@objectstack/spectest:repoat492ab98d: 63 files / 1070 tests passed. This includes the house-sentence scan over the moved sentence.os validateandos lintwith the built CLI on app-crm, app-todo, app-showcase and app-multi-package: all exit 0.os validatereports none of the six.os lintreportsobject/missing-name-field5 times (1 on crm, 4 on showcase), and its→ fix:line is now 188 characters.origin/mainonce (no conflict). feat(spec)!: retire the view form's visibleOn and the page component's visibility as keys; their ADR-0089 renames leave the load path (F4 of #23543) #23836'srule-explanations.tsedit is in another entry.Remaining after this slice (this census, hint-shaped, over 200, by file)
The slice-17 census, replicated at base
6db53acd6, finds 32 ids. This slice removes three; the other three of its six were never hint-shaped. Recordingfixfinds no other fix-only id over 200.lint-flow-patterns.ts(14)validate-page-field-bindings.ts(4)lint-startup-registry-verdict.ts(3)validate-flow-template-paths.ts(2)validate-component-props.ts,validate-list-view-mode.ts,validate-form-layout.ts,validate-filter-tokens.ts,validate-capability-references.ts,validate-print-page-blocks.tsSlice 19 (claim
6213957180) covers several of these files. The per-id list is in the report on #22161. The count differs from slice 17's 33 (withlint-flow-patterns.tsat 2). The id→file mapping here is agit grepof the literal id, which can attribute an id to the first file that spells it. This is a reading, not a correction of the earlier one.Acceptance notes
RULE_EXPLANATIONSentry forobject/missing-name-fieldorfield/select-missing-options. Giving them one needs exported id constants (a public-surface widening). The first id points attitle-format-retired's entry instead, and the second lost no reasoning.Generated by Claude Code