Skip to content

fix(spec): step 18's rationale gains the form-view-subform-columns-closed fragment - #21090

Merged
os-justin merged 2 commits into
mainfrom
claude/issue-20901-rationale-fragment
Oct 1, 2026
Merged

os-justin merged 2 commits into
mainfrom
claude/issue-20901-rationale-fragment

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20901

Clause-②: no

One STEP18_RATIONALE fragment in packages/spec/src/migrations/registry.ts: id form-view-subform-columns-closed, order 54 (the highest at base 5dbeb7d7b7 was 53), inserted where its id sorts. It covers the form-view carrier closure, the D2 conversion form-view-subform-columns-canonicalized, and the identity-only sibling inline-grid-column-identity-only-currency-scale-refused. Each sentence restates the two entry sources and the conversion source. The list sits outside the generated markers and is hand-written; gen:migration-registry is a no-op on this diff. A patch changeset for @objectstack/spec is included because the rationale string ships in dist/migrations. This is review item 4 of the at-tier record 5921114874 on #20953. The card stays open, and the seat closes it by hand.

Verification at head 8ebaf237c4 (merges origin/main dff98c1f51)

  • Rationale pins (step18-rationale-merge, compliance-families-retirement, conversions-major18-merge): 31 passed. migrations.test.ts and inline-grid-column-carriers.test.ts: 179 passed. Spec local suite: 588 files, 17318 passed. Spec typecheck: exit 0.
  • check:generated: all 15 artifacts are up to date after a spec build. The upgrade guide prints majors up to PROTOCOL_MAJOR (17), so it does not print step 18 and has no diff here.
  • dispatch-gates --ran: 82 derived, 82 run, 0 NOT-MEASURED.
  • Ablation (fragment removed, anchor 1 to 0, restored to the HEAD blob): no pin went red. The merge test pins the sort order and the joined text; no test pins this fragment by id.

Acceptance notes

  • The review counted entries without a fragment of their own id: 207 of 253 at 06f079864a. Fragments are per retirement family, so the number of families without one is not counted. carrier: none named. Noted here under the filing gate, with no reach: measured today. The generated guide prints major 17 only (build-upgrade-guide.ts loops to PROTOCOL_MAJOR, 17 at this head). Step 18's rationale does reach os migrate meta --step, whose default chain ends at major 18 (packages/cli/src/commands/migrate/meta.ts). There, a family without a fragment is left out of the paragraph, not misstated. This was read from the source and not measured at that door.

Generated by Claude Code

claude added 2 commits October 1, 2026 04:49
…osed fragment

One STEP18_RATIONALE fragment for the inline grid column family: the
form view's subforms[].columns closure, its D2 conversion
form-view-subform-columns-canonicalized, and the identity-only currency
scale refusal. Inserted where its id sorts, order one above the highest
(53 at the base). Plus a patch changeset for @objectstack/spec.

Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling labels Oct 1, 2026
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

1 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 — 137 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 94608a7d72ecef7bf61d10dbab3bd80aea311055 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from b221c59fe88b5bbbf9c4424d1946a624a7cf036d — the merge of head 8ebaf237c4f1c26060891f62dfa990547b82aa7a into base 94608a7d72ecef7bf61d10dbab3bd80aea311055, 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 b221c59fe88b5bbbf9c4424d1946a624a7cf036d && git checkout b221c59fe88b5bbbf9c4424d1946a624a7cf036d
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 94608a7d72ecef7bf61d10dbab3bd80aea311055 8ebaf237c4f1c26060891f62dfa990547b82aa7a && git checkout -B drift-repro 94608a7d72ecef7bf61d10dbab3bd80aea311055 && git merge --no-ff 8ebaf237c4f1c26060891f62dfa990547b82aa7a

node scripts/docs-audit/affected-docs.mjs --json 94608a7d72ecef7bf61d10dbab3bd80aea311055

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

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 8ebaf237c4f1c26060891f62dfa990547b82aa7a
Local-runs: none

① Derived judgments

Inputs read: card #20901 (body; every comment — triage 5916820410, claim 5916997003, dev reports 5918594163 / 5920703403 / 5925602674, seat rulings 5918621378 / 5920724494 / 5925624097, landing records 5919493523 and 5921552300 as corrected, dispatch note 5924906441), the at-tier record 5921114874 on PR #20953 (its ③ item 4 is this fragment's source), PRs #20927 and #20953 (bodies, merged as bee75cebe6 and c6b3a01d5d), PR #21090 (body, file list: 2 files, +41 / −0), the net diff origin/main...8ebaf237c4 (merge base dff98c1f51, which the head merges as its second parent; the one source commit is 51fcedaa0b), the two D3 entry sources, the declared-type entry 18.inline-grid-column-currency-scale-refused.ts, the D2 conversion form-view-subform-columns-canonicalized in conversions/registry.ts, and the head's check-runs. Tree facts were read with git show / git grep / git diff / git log against the fetched refs; nothing was checked out, built, run or re-run. The dispatch order and the dispatching seat's conclusions were read as comments on the card, not adopted.

Accept-set and public-surface changes the diff implies

  1. No accept set moves, in either direction. The diff adds one element to the hand-written STEP18_RATIONALE list in packages/spec/src/migrations/registry.ts (+31) and one changeset (+10). No schema, conversion, entry, export, key or default is touched. The only published thing that changes is the VALUE of MIGRATIONS_BY_MAJOR[18].rationale — step18.rationale is joinRationale(STEP18_RATIONALE) (registry :6054), MIGRATIONS_BY_MAJOR is { 17: step17, 18: step18 } (:19161), re-exported from migrations/index.ts, and ships in dist/migrations/index.js / .mjs (package.json files[] carries dist; the ./migrations export resolves there). RIGHT: a longer string, no widening, no narrowing.
  2. Placement and numbering, per the list's own header (:5006-5022) and scripts/step18-rationale-merge.test.ts. The id form-view-subform-columns-closed sits at position 25 of 54, between form-view-option-default-retired and list-view-page-mount-retired, which is where it sorts under the test's strict less-than string order on id; the whole list stays sorted and every id is kebab-case. order 54 is one above the highest at the dev's base 5dbeb7d7b7 (53 fragments, max order 53), and also one above the highest at the merge base dff98c1f51 and at origin/main fed0db8f69 as read 2026-10-01 (both 53 / 53), so the number is right against every base this PR can land on; the 54 orders are unique and contiguous. The element matches the test's ELEMENT regex exactly (the id / order / text: lines and six-space-indented text lines, closed by },): parsing the head's file with that regex yields 54 elements and the ]; residue the test demands; the text has no leading or trailing space; it renders last, after cube-member-sql-expression-retired (53). RIGHT.
  3. Generated regions. The diff holds one hunk, at :5507, outside every os-generated marker — as the file header (:37-42) says the step rationale is hand-written. Emulating build-migration-registry.ts's renderRegion by text (comment lines verbatim at four spaces, the literal at four spaces with its trailing semicolon swapped for a comma, entries sorted by id within major) over every entry file at the head and comparing against the six regions in the head's file: semantic:17 (77 entries), semantic:18 (256), retired-key:17 (29), retired-key:18 (213), retired-def:17 (53), retired-def:18 (158) — all six byte-identical, and the totals (333 / 242 / 211) are the dev's. Both finding(spec): an inline grid column is judged on only one of its carriers — FormViewSchema.subforms[].columns is z.array(z.any()), and a currency column's scale reaches no refusal when its type comes from the child field #20901 entries and the declared-type entry are in the semantic:18 region, byte-identical to their sources. CI: check:migration-registry runs in Lint & Repo Gates and check:upgrade-guide in Type Check · source gates; both green. RIGHT — the generator is a no-op on this diff.
  4. No pin names this fragment by id. The merge test pins the list's shape, sort, order integrity and the joined paragraph, not any one fragment; that is the list's design for every fragment, and the dev's ablation (fragment deleted, every leg green) is what that design predicts. Noted under ③, not a defect of this PR.

The fragment, sentence by sentence. Author-shown: os migrate meta --step prints hop.rationale under ── protocol 18 ── (packages/cli/src/commands/migrate/meta.ts:428-430) and --json carries it per hop (:662-668); the default terminus is CHAIN_TERMINUS_MAJOR = max(PROTOCOL_MAJOR, ...MIGRATION_MAJORS) = 18 (:89, :606). The generated upgrade guide does not print it today (build-upgrade-guide.ts:78 loops to PROTOCOL_MAJOR, and PROTOCOL_VERSION is 17.0.0). Every sentence below is judged at the head, which is main plus this fragment, so "true" means true on main the moment this PR lands.

  • S1 "It also closes the form view's inline grid columns: subforms[].columns, on view.form and on formViews entries, was z.array(z.any()) while a relationship field's inlineColumns was already the strict InlineGridColumnSchema, so a mis-keyed column published clean and drew a blank grid column, and scale on a currency column, which the other carrier refuses under the maintainer's rulings of 2026-09-23 (option B) and 2026-09-24 (option 乙), published green." TRUE, since bee75cebe6. Sources: the entry :5-7 (the two carriers), :17 (surface: view.form and each formViews entry), :26-29 (mis-keyed column published clean and drew a blank grid column; scale on a currency column refused on the other carrier under those two rulings, green here); the conversion docblock (conversions/registry.ts:9844-9845, "z.array(z.any()) through 17.5.0"); field.zod.ts's INLINE_GRID_COLUMN_HISTORY ("rendered as blank cells"); and the card's own measurement of 17.5.0. The two dates are the entries' own words (both entries carry them); field.zod.ts cites the same rulings by comment id (5791803339 on [finding] FieldSchema.scale on a currency field is offered to authors by the field designer, ignored by every display face, and still enforced on writes — half-live in the direction that surprises #19629, letter B; 5805782503 on [Decision] Ruling 5791803339 points currency authors at currencyConfig.precision — but nothing reads that key, and removing scale leaves two console faces rendering currency with zero decimals until objectui#10221 lands #19910, letter 乙) and the dates are not re-read here. One register nuance, not a falsity: ruling B retired scale from the currency FIELD type and 乙 worded the remedy; the column mirror's refusal is triage's carry of both (declared-type entry :22-23), and "refuses under the maintainer's rulings" is the identity-only entry's own phrasing (:25-27). "the other carrier refuses" is present tense inside a past-tense clause; it is true then and now.
  • S2 "The carrier now references that schema, so both carriers are judged by it, with its own prescriptions." TRUE: view.zod.ts:4399 columns: z.array(InlineGridColumnSchema) with the finding(spec): an inline grid column is judged on only one of its carriers — FormViewSchema.subforms[].columns is z.array(z.any()), and a currency column's scale reaches no refusal when its type comes from the child field #20901 comment above it; the entry :8-9, :30-31.
  • S3 "The D2 conversion form-view-subform-columns-canonicalized respells a { field } column as { name }, the respelling field-column-lists-canonicalized makes on inlineColumns: it rewrites stored rows and assembled artifacts and lists the edit under os migrate meta, and it is retired from the load path, so an author writing field meets the refusal." TRUE. The entry at :9877-9881 (toMajor: 18, retiredFromLoadPath: true, retiredAfter: '17.5.0') and field-column-lists-canonicalized (:7700) both call the one respellInlineGridColumns (:7639-7656: a dict with a string field and no name has the key renamed, every other key kept). Stored rows: conversions/stored.ts replays the full chain with includeRetired: true (:17, :104), and the conversion walks every form payload mapViewPayloads reaches. Assembled artifacts: the conversion's own viewItems walk, and the artifact door replays a retired entry when the floor is below the runtime label or at or below the entry's retiredAfter (artifact-forward-conversion.ts:37; ADR-0087 amended 2026-09-30) — with the label at 17.5.0 and retiredAfter 17.5.0 every artifact that can carry field is inside the window, and a floor above 17.5.0 cannot carry it, so the clause holds at every moment. Listed under os migrate meta: step18.conversionIds is derived from CONVERSIONS_BY_MAJOR[18], which lists the entry at order 51, and conversions/apply.ts:58 says applyMetaMigrations applies the chain directly; os migrate meta is the house spelling (44 occurrences in the registry's strings). Load path: includeRetired defaults to false at the authoring doors (apply.ts:34) and the column schema's alias table refuses field with the prescription naming name.
  • S4 "A view saved with a failing column is refused with the column schema's prescription, and a stored row carrying one is diagnosed at rehydration; neither is stripped, because which column an unknown key or a mixed field/name entry meant is the author's call, and a conversion that dropped the key would accept at load what the parse now refuses." TRUE: the entry :12-14, :34-35; ADR-0087 addendum 2026-07-31 ("Writes stay gated; reads diagnose, never drop": saveMetaItem 422; loadMetaFromDb warns [metadata_spec_invalid] and registers the row anyway); respellInlineGridColumns returns a both-keys entry by reference ('name' in entry), and the conversion's fixture carries { field: 'amount', name: 'total' } untouched in after.
  • S5 "Its D3 record is the semantic entry form-view-subform-columns-closed." TRUE: entry :16; semantic:18 region :6052. The phrase is the list's own — three other fragments say "Its D3 record is the semantic entry".
  • S6 "On both carriers, the reach of inline-grid-column-currency-scale-refused extends to a column that declares no type: such a column takes its type from the child field, which the column schema cannot see, when the console hydrates it, so defineStack's cross-reference check re-parses a column whose name is a currency field of the child object as the type it renders as, and the refusal of its scale is the column schema's own." TRUE: stack.zod.ts:2720-2786 — collectHydratedInlineColumnErrors, called from validateCrossReferences (:2855), walks every field's inlineColumns and every subforms[] of view.form and of each formViews entry, skips a column that declares type, resolves the child field's type through HYDRATED_INLINE_COLUMN_TYPE (one row, currency), re-parses { ...column, type: resolved } with InlineGridColumnSchema.safeParse and reports each issue's own message. "when the console hydrates it" is the identity-only entry :7-8 and stack.zod.ts's pin citation (hydrateColumns at .objectui-sha db11afd4967c) — an objectui reading outside this record's inputs, consistent with the field.zod.ts superRefine comment; UNSOURCED here, under-reach only if wrong. "the child object": for inlineColumns the column names a field of the object that owns the relationship field (judge(field.inlineColumns, obj.name, …)), which the schema places on the child — the family's term, as the identity-only entry's surface uses it.
  • S7 "Reach: the child object must be declared in the same stack; a column naming no field of it, or a subform whose child object comes from another package, is not judged there." TRUE, verbatim from the identity-only entry :32-34, and what the code does: fieldsByObject is built from config.objects alone, judge returns on a missing child object or a missing field, and this check never consults artifactObjects (the validateCrossReferences docblock: the two artifact-scoped classes only). "Reach:" as a sentence opener is new to the fragment list but is both entries' own register.
  • S8 "It has no D2 conversion, for the declared-type entry's reason: deleting the key is the migration, and a conversion that dropped it would accept it at load, the grace window ruling B refused." TRUE: zero hits for identity-only or currency-scale-refused in conversions/registry.ts at the head; the identity-only entry :11-13, :20; the declared-type entry :24-27 ("No alias and no grace window, per ruling B. NOT mechanically converted"); field.zod.ts's superRefine comment ("No alias and no grace window (ruling B's own words)"). Ruling B here is the 2026-09-23 ruling S1 names — consistent.
  • S9 "Its D3 record is the semantic entry inline-grid-column-identity-only-currency-scale-refused." TRUE: entry :15; region :6534.

Nothing over-broad was found; the one unsourced clause is the objectui hydration reading in S6, sourced to the entry and the pin citation. Does the fragment say anything the rulings it cites did not rule? No. It attributes exactly two things to maintainer rulings — the currency scale refusal (B, 乙) and the grace-window refusal (B) — exactly as the entries and field.zod.ts attribute them. The carrier closure, the D2 vehicle (retiredAfter 17.5.0, the sibling id) and the identity-only reach extension are stated as facts of the code and the entries, which they are; they were triage and seat decisions on #20901 (5916820410, 5918621378, 5920724494) and the fragment claims no ruling for them. It restates no population count, no retiredAfter reasoning and no objectui-mirror status — correctly left to the entries and the conversion docblock. Register against its neighbours: it opens "It also …" like its render neighbours (orders 52 and 53), names the D2 conversion and the D3 entries the way cube-refresh-key-retired and cube-member-sql-expression-retired do, and cites rulings by date and option letter rather than by tracker number. Every neighbour carries a tracker number ("(#9227)", "(#17063, …)", "(#12868, …)") and this fragment carries none; that is what AGENTS.md :16-17 asks of author-shown runtime strings, so the neighbours are the deviation (the dev's second out-of-scope finding). It is longer (about 2.4 KB against 1.2-1.6 KB for most neighbours) because one fragment carries two D3 entries and a D2 conversion — the shape the at-tier item 4 asked for, with duration-keys-unit-in-key as the per-family precedent.

The changeset .changeset/20901-step18-rationale-form-view-subform-columns.md, sentence by sentence. Frontmatter '@objectstack/spec': patch — see ②. The title "fix(spec): protocol 18's migration rationale now covers the form view's inline grid columns and the identity-only currency scale refusal (#20901)" — true; a tracker number in CHANGELOG text is the house form, not a runtime string. "MIGRATIONS_BY_MAJOR[18].rationale gains one fragment, form-view-subform-columns-closed." TRUE (item 1 above). "It is the paragraph os migrate meta --step shows for the protocol 17 → 18 hop." TRUE (meta.ts:428-430). "The new sentences say that a form view's subforms[].columns now takes the strict InlineGridColumnSchema a relationship field's inlineColumns takes, that the conversion … respells a { field } column as { name } in stored rows and assembled artifacts while an author writing field is refused, and that defineStack refuses scale on a column that declares no type when its name is a currency field of a child object declared in the same stack (…)." TRUE — an accurate précis of S2, S3, S6 and S7. "Text only: no schema, conversion or migration entry changes, and conversionIds and semantic for step 18 are unchanged." TRUE: conversionIds is derived from an untouched CONVERSIONS_BY_MAJOR, and the semantic region is byte-identical to the merge base.

The PR body, sentence by sentence. "Part of #20901" and "Clause-②: no" — right (② below; the Part-of guard is green and the card is open). "order 54 (the highest at base 5dbeb7d7b7 was 53), inserted where its id sorts" — TRUE (item 2). "It covers the form-view carrier closure, the D2 conversion …, and the identity-only sibling …" — TRUE. "Each sentence restates the two entry sources and the conversion source." TRUE, with the S6 nuance (the hydration clause is the entry's, which rests on the pin citation). "The list sits outside the generated markers and is hand-written; gen:migration-registry is a no-op on this diff." TRUE (item 3). "A patch changeset for @objectstack/spec is included because the rationale string ships in dist/migrations." TRUE (item 1). "This is review item 4 of the at-tier record 5921114874 on #20953." TRUE. "The card stays open, and the seat closes it by hand." TRUE at the read. Verification section: the counts (31, 179, 588 files / 17318, typecheck, 15 artifacts, 82 derived) and the ablation are the dev's own runs, not re-run here; the check-runs below stand for the CI-visible families (Test Core runs test and test:repo, which holds step18-rationale-merge.test.ts; Lint & Repo Gates holds check:migration-registry; Type Check · source gates holds check:upgrade-guide). "The upgrade guide prints majors up to PROTOCOL_MAJOR (17), so it does not print step 18 and has no diff here." TRUE. "no pin went red … no test pins this fragment by id" — consistent with the test file. Acceptance notes: "207 of 253 at 06f079864a" is quoted from the review record; at this head it is 208 of 256 semantic:18 entries without a fragment of their own id (54 fragments, six of which are family ids that are not an entry id — compliance-deadline-keys-retired, cron-positions-deleted, duration-keys-unit-in-key, element-filter-retired, element-form-retired, page-component-filter-record-to-rule-array). "Fragments are per retirement family, so the number of families without one is not counted." TRUE. "carrier: none named." TRUE. "The generated guide prints major 17 only" — TRUE. "Step 18's rationale does reach os migrate meta --step, whose default chain ends at major 18" — TRUE (CHAIN_TERMINUS_MAJOR = 18 at this head since MIGRATION_MAJORS is [17, 18]). "There, a family without a fragment is left out of the paragraph, not misstated." TRUE by construction of joinRationale. "This was read from the source and not measured at that door." — honest; this record reads the same source and measures nothing at the door either.

② Semver level

Clause-②: no

'@objectstack/spec': patch, title fix(spec):, Clause-②: no with no arm — matches what the diff publishes. The only published change is a longer string value in dist/migrations (the MIGRATIONS_BY_MAJOR[18].rationale paragraph). No export is added, removed or renamed (STEP18_RATIONALE and joinRationale are module-private; the Type Check family that carries check:api-surface is green), no accept set widens or narrows, no key is added to any payload. AGENTS.md's Post-Task Checklist step 3: anything that publishes takes a changeset, a fix in a released package takes patch, never none and never skip-changeset — the string ships in the tarball, so a changeset is owed and patch is its level. In scripts/pm/clause2-line.mjs's terms the body's line Clause-②: no is key-initial, its value token is no and no parenthetical follows, so readClause2Line returns declared, value no, arm null; the question the value answers (does this card widen an accept set or the public surface) is no for a text-only addition to a shipped string, and the absent arm is right because nothing narrows — (narrowing) would declare a break that does not exist, and yes would force minor for a widening that does not exist. No **BREAKING** banner and no ADR-0087 marker, correctly, since the changeset declares no break. Check Changeset is green on the head.

③ Boundary flags

Dev report 5925602674: no deviations key; one deviation stated in summary (hand-written, against the note's "regenerated"); open_questions: []; two out_of_scope_findings; plus a register note and the ablation note. Seat ruling 5925624097 answered each; this record judges them on its own inputs.

  1. Deviation: dispatch note 5924906441 said "The registry is regenerated, never edited by hand"; the dev hand-wrote the fragment. ANSWERED: right. The file header (:37-42) and the merge test's own docblock ("The file is hand-written, so nothing regenerates it") place the rationale outside the generated regions, and the generator emulation in ① item 3 shows every region untouched. The note was wrong in detail.
  2. Register note: the fragment carries no tracker number while every neighbour does. ANSWERED: right, per AGENTS.md :16-17. The neighbours are the deviation (flag 4).
  3. Out-of-scope 1 — the family-wide STEP18_RATIONALE gap: 208 of 256 entries at the head have no fragment of their own id, families uncounted; the declared-type sibling inline-grid-column-currency-scale-refused has no fragment of its own and is named here only as the entry whose reach this one extends. Carrier: this PR's Acceptance notes, as the corrected landing record 5921552300 and the dispatch note ordered (it was never filed as a card, and has no reach: — the generated guide projects major 17 only; os migrate meta --step reaches 18 but omits a missing family rather than misstating it). ESCALATED to the domain:spec seat as backlog owed before protocol 18 ships; not held against this head.
  4. Out-of-scope 2 — tracker numbers in neighbouring fragments' author-shown text, which check:doc-authoring does not read in this position. Carrier packages/spec/src: 1,277 comment lines still cite 170 deleted tracker numbers (1,295 sites) — the staged remainder of ruling C+D on #19123, measured by PR #20226 #20234 stage 11, the next PR on the file's hand-written parts, queued behind this one. ESCALATED there; not held.
  5. Ablation: deleting the fragment turned no pin red, and the dev added none. As dispatched — the merge test pins the list's shape, sort and joined text, not a fragment by id — so a future deletion of this fragment, like any other, is invisible to tests. Noted, not held: a per-id pin is a list-wide design question, not this PR's.
  6. acceptance_line_as_written — the os migrate meta --step reach added to the Acceptance note is verified from meta.ts in ①; its "not measured at that door" is honest and this record measured nothing there either.
  7. Serial on registry.ts: the dispatch queued this PR behind [Decision] analytics field gate (#20917): an authored cube member whose sql is an expression — keep the stand-down, judge its identifiers, refuse it, or retire expressions #20943's PR feat(spec)!: an analytics cube member's sql is a column reference, and the showcase done rate moves to its dataset (#20943) #20998 (landed 5d5e679873); the head merges origin/main dff98c1f51, and the two-dot diff against origin/main fed0db8f69 (read 2026-10-01) still shows registry.ts at +31 / −0 — nothing else has landed on the file since. packages/spec/src: 1,277 comment lines still cite 170 deleted tracker numbers (1,295 sites) — the staged remainder of ruling C+D on #19123, measured by PR #20226 #20234 stage 11 waits behind this PR, as the note says.
  8. Skipped check-runs: Build Docs and Console Pin Gate (paths filters — no docs path and no console path is touched), Packed-tarball smoke (opt-in) (label absent), Auto Label and Check PR Size (their own conditions). Nothing in this diff reaches objectui or the docs tree. Noted, not held.
  9. Not re-measured: every count, the ablation and the local gate runs in the PR body and the dev report; the check-runs are the gate verdicts.

Check-runs on 8ebaf237c4 (read last, 2026-10-01T06:21Z; 39 runs, 35 names after dedupe keeping the newest started_at): 30 success, 5 skipped (Auto Label, Build Docs, Check PR Size, Console Pin Gate, Packed-tarball smoke (opt-in)), 0 failure, 0 still running. Green: Build Core, Check Changeset, Check Documentation Links, Dogfood Regression Gate 1-3 and aggregate, Dogfood Verify CLI, Flag docs affected by code changes, Governed Surface Queue Guard, Lint & Repo Gates, Spec property liveness, Temporal Conformance (live PG + MySQL), Test Core 1-6 and aggregate, Type Check (consumer gates, debt ledger, source gates, workspace), TypeScript Type Check, filter, and the four PR-hygiene guards (same issue, same single-writer path, Part-of must not close its card, card claims branch). No governed surface in the file list.

Implemented-by: claude/issue-20901-rationale-fragment
Reviewed-by: session_01Sfe5YjBLwB9J3y8fvm2xq1

VERDICT: PASS

Adopted and posted by domain:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1) · 2026-10-01T06:25Z · rendered by the seat's at-tier review subagent on this head. The seat read its served tier family from the subagent transcript before posting.


Generated by Claude Code

@os-justin
os-justin marked this pull request as ready for review October 1, 2026 06:27
@os-justin
os-justin added this pull request to the merge queue Oct 1, 2026
Merged via the queue into main with commit 2742e53 Oct 1, 2026
44 checks passed
@os-justin
os-justin deleted the claude/issue-20901-rationale-fragment branch October 1, 2026 06:48
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/s tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants