Repository navigation
fix(lint): one-line fix lines for the 11 validate-widget-bindings rule ids (slice 17); os explain RULE_ID carries what they explained - #23581
Conversation
… (slice 17) (WIP) Each hint of the eleven ids is one remedy line of at most 200 characters; what the lines explained moves into RULE_EXPLANATIONS, behind os explain. table-count-only and widget-legacy-analytics-shape gain an entry. Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz Co-authored-by: Claude <noreply@anthropic.com>
… lines (WIP) Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz Co-authored-by: Claude <noreply@anthropic.com>
…-lint-slice-17-widget-hints
…rate meta sentence (WIP) spec's repo-tier pin judges every os migrate meta prescription in packages/lint/src; the moved sentence is now the house sentence, in one plain-quoted literal. Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): ⛔ 2 release-owned page(s) name something this change touched. These are read-only:
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 c6cfd50a88191d540d36559709c1abac5a86609d && git checkout c6cfd50a88191d540d36559709c1abac5a86609d
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin f3fd209b34c6c0c5f815ddc195ec70b6a64abaed 33460e98bd632fe274a136c348ded90bedc415f3 && git checkout -B drift-repro f3fd209b34c6c0c5f815ddc195ec70b6a64abaed && git merge --no-ff 33460e98bd632fe274a136c348ded90bedc415f3
node scripts/docs-audit/affected-docs.mjs --json f3fd209b34c6c0c5f815ddc195ec70b6a64abaed
|
Part of #22161
Clause-②: no
Slice 17 of the card: the over-long
fix:lines, continued in slices 11 to 16's shape, for the whole-file slicepackages/lint/src/validate-widget-bindings.ts. Each finding'shint(the CLI'sfix:line, the runtime issue'shint) of the 11 rule ids in that file whose hint ran past 200 characters is now one remedy line of at most 200 characters, and what the lines used to explain is each id'sRULE_EXPLANATIONSentry behindos explain RULE_ID. The card stays open: other author-time ids still carry a hint over 200 characters (the last section).Claim:
6180782552(newestClaim:on the card, naming this branch; verified before the first edit).What changes
086fa4640and at this head:dashboardwrite)dashboard-filter-field-unprovisionedchart-field-unknowndashboard-filter-field-unknownchart-measures-missingwidget-legacy-analytics-shapewidget-measures-missingwidget-filter-field-unknownwidget-legacy-analytics-unrenderabletable-count-onlychart-dimensions-missingdashboard-filter-field-not-includedThe base maxima equal the claim's lengths id for id (561, 415, 403, 369, 338, 330, 322, 320, 311, 291, 218). A count that falls is a list that no longer makes each hint distinct; a count that rises is a case this slice added (a five-measure dataset, a dataset with no measures, a one-key legacy widget).
dashboard-filter-field-unknownandwidget-filter-field-unknownno longer append the object's field list (account.detailon the dotted arms,Object fields:on the bare arms). The verdict's "Did you mean" names the nearest field on the dotted arms; the bare dashboard-filter arms keep their own "Did you mean" after the remedy.dashboard-filter-field-not-includedno longer lists the dataset's declaredincludepaths: the remedy names the one to add.chart-measures-missing,widget-measures-missing,chart-dimensions-missing) have no "Did you mean" to point at, so they still name what the dataset declares, bounded to the first three names and then an ellipsis (a new localdeclaredFew()), or "it declares no measures yet". This is a deviation from a bare remedy, stated so the reviewer can rule on it.unconsumed-widget-optionprecedent).dashboard-filter-field-unprovisionednow prints the shared one-lineunprovisionedAnchorFix()the other anchor ids print, and its entry gains the sharedUNPROVISIONED_ANCHOR_REMEDYparagraph (columnMap,ownership: 'none',systemFields: { audit: false }); the widget'sfilterBindingsopt-out and the suppression were already in the entry.include, and the verdict's "Did you mean" names the nearest field.chart-field-unknown's entry gains what replaces each refused key (x-axis from the first dimension, y-axis bindings one per mark fromvalues, series membership fromvaluesand a second dimension to split) and the houseos migrate meta --from 17sentence, which left the x-axis hint.fix:line names up to three declared names.os explainentry, so theirrule:line now carries the pointer:table-count-only(why a count-only, dimensionless table renders one summary row; that a flat record listing is an object-bound ListView, ADR-0017; the suppression) andwidget-legacy-analytics-shape(the cutover's removed keys, that DatasetWidget reads only the dataset, that strict parse preempts the rule oncompile/validate, the suppression). Both ids already had a rule id constant on the root barrel (TABLE_COUNT_ONLY,WIDGET_LEGACY_ANALYTICS_SHAPE), so no published name is added andClause-②: noholds. Seven existing entries gain text; none is removed.message, rule id, severity andpathis unchanged, and so is what the rule accepts or refuses. Every hunk in the rule file is ahintexpression, a comment, the newdeclaredFew()helper, the removeddatasetHint/suppressHint/fixHint/shapeHintlocals, and the import swapunprovisionedAnchorHint→unprovisionedAnchorFix(the long form is still used by two other rule files).File surface: the claim's
The claim (
6180782552) namesvalidate-widget-bindings.tsand its tests,rule-explanations.ts(entries for these ids only), the consumer tests that pin these hints' text, and.changeset/22161-s17-*.md. The diff is exactly four paths: those two source files, the one test file, and.changeset/22161-s17-widget-binding-fix-lines.md. The one shared-text edit outside the eleven entries is the docblock ofUNPROVISIONED_ANCHOR_REMEDY, which now listsdashboard-filter-field-unprovisionedamong its users.Pin sweep, repo-wide (examples and docs included):
git grepfor each id, its constant and every distinctive old hint phrase. The only files pinning these hints' text are invalidate-widget-bindings.test.ts;examples/app-showcase/test/dashboard-filter-vocabulary.test.ts,runtime-gate.test.ts,validate-chart-bindings.test.ts,validate-react-page-props.test.tsandmetadata-protocol'sprotocol.runtime-gate-stored-universe.test.tsname the ids but read no hint of them; no docs transcript quotes one. So nopackages/cliorpackages/metadata-protocolrider was needed. Each flipped pin asserts the new text exactly, or the fact it still carries (the dimension clause on a measureless chart, the'metric' or 'kpi'alternative, the declared names), plus the absence of the moved list.The runtime wire
All 11 run at the runtime publish gate:
validateWidgetBindingsisCLI_AND_RUNTIMEwithruntimeTypes: ['dashboard']. Measured at the door withrunRuntimeAuthoringRules, a scratch probe of 15dashboardwrites run against the base rule sources and the branch's:issues[].hint:widget-legacy-analytics-unrenderable320 → 105;dashboard-filter-field-unknown196 / 195 / 290 → 148 / 147 / 137 (an inherited bare field, a re-targeted bare field, a dotted path);dashboard-filter-field-not-included213 → 139;widget-filter-field-unknown220 → 126.advisories[].hint:widget-legacy-analytics-shape338 → 112;dashboard-filter-field-unprovisioned550 → 173;chart-field-unknown413 / 294 / 324 → 150 / 124 / 127 (x-axis, y-axis, series);chart-measures-missing240 → 96;widget-measures-missing310 → 134;chart-dimensions-missing297 → 156;table-count-only311 → 136.Readers of
hint, read-only against the local objectui checkout atb434f5f47:saveAdvisoryToast.tsprints an advisory's hint after its message, so the seven advisories shorten in Studio's save toast;DraftChangesPanel.tsxreadshintonly for its in-browser security-posture pass; no source reads a 422 issue'shint. REST forwardsissues/advisoriesas JSON. No reader in either repository matches onhinttext. The changeset states FROM → TO.Tests
Every heavy run went through
scripts/pm/os-verify-lock.sh(slotissue-22161-s17).validate-widget-bindings.test.tsgains a slice-17 block. It records every finding of the 11 ids the file fires, and holds every recordedfix:line to one line of at most 200 characters with none of the moved clauses (suppressWarnings,Object fields:,Fields on ",Declared include paths, the old declared-list spellings). A coverage control names every id and every multi-arm hint (dashboard filter dotted / explicit / inherited; chart x-axis / y-axis / series / declared-but-unselected; measures with and without dimensions). Exact pins read the three-name bound with its ellipsis, the no-measures wording, and both legacy lines; a check per id asserts thatexplainRule(id)holds what the line stopped saying.086fa4640Test Files 139 passed (139), Tests 6,738 passed, 5 skipped; branchefc9582c3139 / 6,754 passed, 5 skipped; VERDICT command-exit 0 both; at the final head33460e98b(after the merge and the fix below, lint rebuilt) Test Files 139 passed (139), Tests 6,759 passed, VERDICT 0.efc9582c3, and again a lint build at the final head33460e98b, andpnpm --filter @objectstack/lint run typecheck(tsc --noEmit+check:test-typecheckOK, 2 files / 6 errors / 2 pinned signatures held), VERDICT command-exit 0.--project unit): Test Files 289 passed (289), Tests 4,317 passed, VERDICT 0; none of the 11 ids fires there.@objectstack/metadata-protocol: Test Files 236 passed, 3 skipped (239), Tests 28,409 / after the merge 28,412 passed, 19 skipped, VERDICT 0; onlydashboard-filter-field-unknownfires there (140 characters after; the probe above carries FROM).@objectstack/spectest:repo: its first run at the merge head turnedretired-key-migrate-sentence.test.tsred (3 failed of 1,033). Theos migrate metasentence moved intochart-field-unknown's entry was split across two literals and was not the house sentence. It is now the house sentence in one plain-quoted literal, and that test file passes (15 / 15). At the final head33460e98bthe whole project: Test Files 61 passed (61), Tests 1,033 passed, VERDICT 0.os validate(built CLI) onapp-crm,app-todo,app-showcaseandapp-multi-package: exit 0 each, 9 / 7 / 68 / 3rule:lines, and none of the 11 ids fires on any of them, so the apps' output is unaffected by this slice.app-showcasefirst exited 1 before any rule ran (Cannot find module …connector-slack/dist: an unbuilt dependency, not a verdict); it passed after a locked build of its closure.baa3efa02, throughscripts/ablation-replace.mjsunder the lock, with a shelltraprestoringHEADby absolute path. The rule suite imports the rule source, so there is no dist leg.table-count-only's hint gains back its suppression and ADR-0017 tail (anchor x1 → x0, replacement x0 → x1, blobd5b1b5debf34→f9431ca5f49a).d5b1b5debf34== HEAD,git diff HEADempty,git status --porcelainempty.npx eslint --no-inline-config --format jsonover the three changed.tsfiles: 3 files, 0 errors, 0 warnings. The config enables no type-aware linting (noparserOptions.project), so no untouched file's verdict can move. A control-character scan of every changed file found no match.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths: 62 derived at the final head33460e98b(4 paths vs merge base252775d1d), each run with its exit code captured before any pipe: all 62 exit 0,check:type-check-debtincluded.--ran: "62 derived famil(ies) accounted for — 62 run, 0 NOT-MEASURED (a DERIVED zero — all 62 recorded an exit code and none of them is 3)". The artifact-roster and PR-context families are CI's. Atbaa3efa02all 62 exited 0,check:dual-build-cjs-loadsafter a first refusal (exit 3, PREREQUISITE NOT MET: unbuilt dists, while another locked build was running) and a rerun.origin/mainmerged once throughscripts/pm/os-regen-merge.sh, without conflict, no regeneration owed (the branch edits no generated artifact;mainbroughtpackages/cli,packages/metadata-protocolandpackages/spectest changes, nopackages/lintfile).Acceptance notes
dashboard-filter-field-unprovisionedat 177 (the shared anchor fix with the object and column names).data-model-rules.tsids slice 16 listed (object/missing-name-field,rollup/non-numeric-aggregand,field/select-missing-options) do not appear in this census at the base or at the head, so their current lengths are NOT MEASURED here.Remaining for this card
The lint census at this head has 33 ids with a hint over 200, longest first, by file. Of slice 16's remaining author-time list, still over 200 here:
lint-flow-patterns.ts(2):flow-double-brace-interpolation1413,flow-bare-dollar-reference1234data-model-rules.ts(3 measured):unique/legacy-organization-composite578,unique/unscoped-declared-index380,unique/double-declaration279 (the other three NOT MEASURED, above)validate-capability-references.ts(1):capability-reference-unknown241lint-liveness-properties.ts(1):liveness-planned-property230validate-page-field-bindings.ts(2):page-section-count-not-multi-value228,page-field-unknown206validate-list-view-mode.ts(1):list-view-filters-in-views-mode219The other 23 over 200 at this head are the 3 repo-gate ids (
startup-open-vocabulary-verdict,startup-verdict-assertive-wording,startup-source-unparseable) and 20 ids outside slice 16's author-time list, which this slice did not reclassify against PR #22448's fenced list (slice 16 counted 21 fenced): thelint-flow-patterns.tsflow idsflow-loop-body-uncontained,flow-multi-write-unfiltered,flow-try-catch-without-catch,flow-decision-inclusive-overlap,flow-approval-revise-target-not-service-owned,flow-time-relative-antipattern,flow-date-equality-filter,flow-runas-unscoped,flow-decision-mode-invalid,flow-decision-unconditional-branch,flow-error-label-not-fault,flow-branch-label-unmatched, pluspage-field-unprovisioned,print-page-block-unprintable,flow-template-field-unprovisioned,flow-template-lookup-traversal,page-section-group-unknown,form-section-group-unknown,filter-token-unknownandcomponent-props-invalid. Each next slice should reclassify against PR #22448's own list before claiming.Generated by Claude Code