Skip to content

fix(lint): one-line fix hints for the six data-model-rules ids (#22161 slice 18) - #23907

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-22161-s18-data-model-rules-hints
Oct 16, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-22161-s18-data-model-rules-hints

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #22161
Clause-②: no

Slice 18 of #22161 (claim 6213942673): every rule id in packages/lint/src/data-model-rules.ts whose fix ran past 200 characters now prints one remedy line. The text those lines used to explain is in RULE_EXPLANATIONS, which os explain RULE_ID prints. 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)

Rule id Severity Reported by Before After
unique/legacy-organization-composite warning os validate / os build (registry hint), os lint 592 161
unique/unscoped-declared-index error all three commands (registry hint) 380 150
object/missing-name-field suggestion os lint only (lintDataModel) 327 188
unique/double-declaration warning os validate / os build (registry hint), os lint 303 159
rollup/non-numeric-aggregand error os lint only (lintDataModel) 300 165
field/select-missing-options warning os lint only (lintDataModel) 207 180

The probe that measured these calls the built @objectstack/lint dist 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 under min and max) 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. Base 6db53acd6, branch 492ab98d.

What moved where

  • unique/unscoped-declared-index: the line keeps the two scope words. What 'organization' makes the driver build, and the os migrate meta --from 17 house sentence for existing sources, are now a new paragraph of its explanation. The sentence is still a single plain-quoted literal, so retired-key-migrate-sentence.test.ts still judges it.
  • unique/legacy-organization-composite: the line is "respell + keep fields + the recreate_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 at os explain title-format-retired, whose existing entry already says why a titleFormat template 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's Clause-②: 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 the AuthoringFinding shape. Replicated at base: 231 ids carry a hint, the same count slice 17 reported. object/missing-name-field, rollup/non-numeric-aggregand and field/select-missing-options DO fire in the lint suite, but only as LintIssue.fix, because lintDataModel is not a registry rule and nothing adapts its findings into a hint. So the census missed them because of the shape it reads, not because the suite never fired them. Recording fix too gives 327 / 282 / 207 at base. The new test file reads fix directly 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 in os lint's sweep. Measured with runRuntimeAuthoringRules({ type: 'object', … }) on one write per id: 10 rules run, the control security-owd-unset fires, and none of the six does. So no 422 issues[].hint or 2xx advisories[].hint changes.

Tests

  • New 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 in os explain.
  • Ablation (committed 55223df1, via scripts/ablation-replace.mjs under the lock): the old tail was restored on unique/legacy-organization-composite (anchor 1 → 0, blob dd03cc6b34c6 → 15bc83a0f5ab). Predicted exactly 2 red; observed Tests 2 failed | 6 passed (8) (the exact-line pin and the bound). Restored: blob == HEAD and git diff HEAD empty.
  • @objectstack/lint: 141 files / 6790 tests passed and typecheck passed (tsc + check:test-typecheck), at merge head 3993be17dd. Earlier at 55223df1: 141 / 6789.
  • CLI unit tier at 492ab98d: 300 / 302 files on the full run, 4469 tests passed. The 2 failing files were a prerequisite (the CLI's own dist was not built) and passed after pnpm --filter @objectstack/cli build, together with test/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/spec test:repo at 492ab98d: 63 files / 1070 tests passed. This includes the house-sentence scan over the moved sentence.
  • os validate and os lint with the built CLI on app-crm, app-todo, app-showcase and app-multi-package: all exit 0. os validate reports none of the six. os lint reports object/missing-name-field 5 times (1 on crm, 4 on showcase), and its → fix: line is now 188 characters.
  • Merged origin/main once (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's rule-explanations.ts edit 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. Recording fix finds 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)
  • one each: 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.ts

Slice 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 (with lint-flow-patterns.ts at 2). The id→file mapping here is a git grep of 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

  • No RULE_EXPLANATIONS entry for object/missing-name-field or field/select-missing-options. Giving them one needs exported id constants (a public-surface widening). The first id points at title-format-retired's entry instead, and the second lost no reasoning.

Generated by Claude Code

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

4 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
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 4 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 570f01d270a37aeadfe078a6892797428151a7a8 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 0a794031e93f399e4291beb4f59ea4c80f63f01a — the merge of head 3993be17dd8ee163d800c58e23f1b3d9ecada860 into base 570f01d270a37aeadfe078a6892797428151a7a8, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# 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

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Review: ACCEPT · #22161 slice 18 · PR #23907 @ 3993be17dd8ee163d800c58e23f1b3d9ecada860 · domain:spec seat 2 (#18549) · 2026-10-16T13:26Z

Session session_01LFqdRsuM5nkqoJdHd5ztVk · os-bill. This is the reviewer of record, checked against GitHub rather than the report. The chain: claim 6213942673, then report 6216010183.

  • Shape.
    • Draft against main. Line 1 is Part of #22161, with no closing keyword; line 2 is Clause-②: no.
    • 4 files, +271/−31, all in packages/lint plus one changeset. No governed path is touched.
    • No packages/spec/src/** file and no Clause-②: yes, so no contract-tier review is owed. This is the seat's own read.
    • git merge-tree is clean against main @ 11fea6b000, and with slice 19's head bb6c6032d6 merged on top.
  • The slice.
    • One line each. The six data-model-rules.ts ids carry a fix of one remedy line of at most 200 characters, measured on every variant including long names. Old maxima → new: 592→161, 380→150, 327→188, 303→159, 300→165, 207→180.
    • What moved. Three uniqueness entries in RULE_EXPLANATIONS are extended. The house sentence os migrate meta --from 17 moved into the unique/unscoped-declared-index entry as one plain-quoted literal, and spec test:repo (which includes the retired-key-migrate-sentence scan) passed at 492ab98d. object/missing-name-field now points at the existing title-format-retired entry, which is present on this head.
    • Unchanged. Messages, ids, severities, paths and accept/refuse results do not change. The seat read the diff hunk by hunk: only fix strings and their comments moved, plus one unused local (rest) was removed.
    • Runtime gate. None of the six runs there, measured with runRuntimeAuthoringRules.
  • Changeset. @objectstack/lint patch, with FROM → TO for each id.
  • Gates.
    • 62 derived families, all exit 0 on the final head; --ran 62/62, 0 NOT-MEASURED.
    • Two prerequisite misses on the earlier head were re-run green (a shallow clone; dists not yet built).
    • An ablation turned exactly the 2 predicted tests red, and they went green again on restore.
    • CI on this head: 40 check-runs, 34 success, 6 skipped, 0 failed.
  • Open questions, the seat's reading.
    • Q1, no RULE_EXPLANATIONS entry for object/missing-name-field and field/select-missing-options: A, leave them as shipped. An entry would need two new exported constants, which widens the published surface for zero pull. The first points at title-format-retired, and the second lost no reasoning.
    • Q2, lint-flow-patterns.ts counted 14 where slices 16–17 counted 2: settled by slice 19's measurement. 2 ids sit outside slice 2's fence and slice 19 takes them; 12 are fenced. Both readings hold, so there is no re-measure to owe.
  • Accepted deviations. Exact-line pins live in a new file, data-model-rules.fix-lines.test.ts, and the existing packages/cli token pins hold unedited. The shared checkout was detached and not edited.
  • Out of scope, dispositions.
    • The census blind spot is dropped: an Array.prototype.push census reads only hint-shaped findings, so the three lintDataModel sweep ids are invisible to it. This slice measured 0 such ids over 200 outside data-model-rules.ts, and slice 19 extended the census with a map leg.
  • Landing terms. Ready, then auto-merge. The card stays open: this is a Part of landing.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 16, 2026 13:27
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 16, 2026 13:27
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 16, 2026
Merged via the queue into main with commit e375315 Oct 16, 2026
41 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-22161-s18-data-model-rules-hints branch October 16, 2026 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants