Skip to content

fix(spec): os migrate meta guidance for fourteen more migration-entry families states each lesson in words, not tracker numbers (stage 7) - #20568

Merged
os-justin merged 2 commits into
mainfrom
claude/issue-20233-migrate-meta-tracker-free-stage-7
Sep 29, 2026
Merged

os-justin merged 2 commits into
mainfrom
claude/issue-20233-migrate-meta-tracker-free-stage-7

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Part of #20233
Stage 7: the actor-, hot-, external-, query-, delete-, etl-, storage-, apimethod-, dashboard-, notification-, record-, runtime-, rls- and scim- families.

Clause-②: no

Text only. In these families' ADR-0087 semantic entries, the reason / replacement / acceptanceCriteria prose that os migrate meta prints now states in words what each cited ruling, measurement or fix decided, instead of a tracker number (form D, ruling C+D 5749154545). ADR ids stay. No entry id, from / to, conversion or matcher changes.

  • The stage-6 carry-over: 18.rest-api-endpoint-handler-status-retired names the API skill.
  • packages/cli/test/migrate-meta-engine-guidance.test.ts adds the fourteen families to COVERED_PREFIXES; its REWRITTEN floor rises to 174.
  • registry.ts, spec-changes.json and docs/protocol-upgrade-guide.md are regenerated.
  • patch changeset.

The census, the text-only proof, the ablation and the test runs are in the dev report on #20233 (5883241063).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1

…query-, delete-, etl-, storage-, apimethod-, dashboard-, notification-, record-, runtime-, rls- and scim- migration entries states each lesson in words (stage 7)

Every tracker-id site in the reason / replacement / acceptanceCriteria text
of the fourteen families is rewritten to say what the cited ruling,
measurement or fix decided. ADR ids stay. registry.ts, spec-changes.json and
the upgrade guide are regenerated by their generators.

Also: rest-api-endpoint-handler-status-retired names the API skill, whose
factual sweep corrected the handlerStatus sentence.

Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1
Co-authored-by: Claude <noreply@anthropic.com>
…amilies; patch changeset

COVERED_PREFIXES gains actor-, hot-, external-, query-, delete-, etl-,
storage-, apimethod-, dashboard-, notification-, record-, runtime-, rls- and
scim-; the REWRITTEN floor rises 147 -> 174 by the 27 entries this stage
rewrote for the first time. Assertions unchanged.

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

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. ⚠️ 1 changed file(s) yielded no anchor (packages/spec/spec-changes.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/spec-changes.json) — pages documenting those are invisible to this run
  • 3 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 — 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 f6ceddc3c4deb9d56025fff9fae03d65b62e95a7 → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json f6ceddc3c4deb9d56025fff9fae03d65b62e95a7

⚠️ 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: fee9df53f7f3d2cd64ff5fa7b1d079aff350f719
Local-runs: none

Inputs read: card #20233 (body + all 27 comments, incl. rulings and the stage-1…7 records), PR #20568 body, its 33-file list and the net diff origin/main...fee9df53f7 (merge-base 288611e3), the 46 check-runs on the head, ruling C+D 5749154545 on #19123, ruling A 5858839916, and — to check rewritten sentences — the cited cards and threads by REST plus git show of main's commits and CHANGELOGs. Nothing built, run or re-run; the only local operation beyond reads was a three-way git merge-file of registry.ts written into scratch (see ③).

① Derived judgments

Accept set — nothing moves (right). I mapped every changed line of the 28 entry files, on both sides of every hunk, to its enclosing object key: only reason, replacement and acceptanceCriteria are touched. No id, surface, from / to, conversion, matcher, import or comment token changes; every removed ADR-NNNN token is present on an added line (ADR-0033 / 0049 / 0058 Amendment II.2 / 0078 / 0087 / 0090 D3 / 0104 all kept). The three generated projections change only text: registry.ts +195/−126 — the entry files' own +195/−126; spec-changes.json 16 rationale + 4 replacement fields (the sixteen protocol-17 entries whose reason changed and the four whose replacement changed; protocol-18 entries do not project until that major ships); docs/protocol-upgrade-guide.md 25/25 lines. Tracker ids on added lines across all four: 0. check:migration-registry (Lint & Repo Gates) and check:spec-changes / check:upgrade-guide (Type Check · source gates) are success on the head. Clause-②: no is the right reading.

Public surface — the printed guidance changes, as intended (right). The surface that moves is the text os migrate meta prints for 28 semantic entries. 73 distinct #N tokens leave the prose (63 objectstack ids, objectstack#6739, five objectui ids, cloud#1203, duly#109, and the two decision-batch numbers #119 / #121); 0 remain on added lines; a scan of the non-comment lines of all 30 entries under the fourteen prefixes at head finds no #NN… at all, including the three untouched entries (dashboard-refresh-interval-unit-in-key, record-highlights-field-icon-retired, rls-check-on-select-or-delete-policy-refused). Comment lines are untouched (#20234's carrier).

Form D — each rewrite says what its source decided. Sampled against sources, weighting the dead and unreadable ids:

Wording notes, none a FAIL item (no decision invented, overstated or changed; no number returns): (i) runtime-httpserver: "since publish stopped refusing them" — #5111 narrowed publish's blanket refusal to per-endpoint gating (unsupported subset + namespace gate); the sentence's lesson (from 17 on, setFallbackHandler is the only entry path because declarative endpoints execute) stands. (ii) etl: "the activationEvents, dynamic plugin-loading and widget / i18n retirements each let an earlier tombstone go" — the activationEvents entry on main records its own tombstone going with DynamicLoadRequest under the plugin-runtime removal; the pattern each entry records is the one named, the actor is grouped loosely, as the base's "#4657/#4834/#5055 way" already grouped it. (iii) storage: "the email plugin's large-attachment storage work" — #5172 is the attachments-through-storage-references card; "large" is a gloss on its size-driven reasoning.

Would a reader of os migrate meta now be misled? No. Every dropped id is replaced by a clause resolvable inside the printed block (header + why: + verify:): e.g. hot-reload-inert's verify: "That ruling's keep itself stands" points at the 2026-08-25 ruling its own why: names; notification's "(it was the jointly ruled repair's business)" points at the repair its why: describes; rls-cross-class's "the earlier refusal of an array comparand under $ne" names the sibling entry's refusal. No dangling antecedent found across the 28 blocks, and no sentence now states a decision its source did not take.

Pin (right). COVERED_PREFIXES gains exactly the fourteen prefixes the PR body names (41 total; every prefix selects at least one entry — 30 under the fourteen). REWRITTEN 147 → 174: the 27 added rows are the 27 entry files under the fourteen prefixes the diff touched (26 with four/five-digit sites plus dashboard-widget-chart-config-structure-refused, which carried only a decision-batch number); rest-api-endpoint-handler-status-retired was already a row. Assertions and detector unchanged. The file is queue-population by name (not .e2e/.live), so it ran in Test Core (turbo run test test:repo), 6/6 shards success.

PR body, sentence by sentence — true of the diff. Part of #20233, no closing keyword (gate "Part-of PR must not also close its card": success). The stage line's fourteen families = the fourteen prefixes added. Clause-②: no stands alone. "Text only … ADR ids stay. No entry id, from / to, conversion or matcher changes" — proved above. Carry-over sentence — true (#13823 provenance). Pin sentence (COVERED_PREFIXES + fourteen, floor 174) — true. "regenerated" — the equality gates are success. "patch changeset" — '@objectstack/spec': patch. The report id 5883241063 is the stage-7 dev report on the card. The changeset body's claims (no surface changes; the chain rewrites exactly what it rewrote before) hold: no surface line and no conversion is touched.

Report-count notes, immaterial and not in the PR body: the dev report says seven cited ids answer 404; my probe of every removed id reads six. It says 63 objectstack ids; the removed lines carry 64 including objectstack#6739.

② Semver level

@objectstack/spec patch — right. The published package's content changes (the entry prose is runtime data: MIGRATIONS_BY_MAJOR is imported by the CLI and printed), so skip-changeset would be wrong; no type, schema, accept set, conversion or export moves, so nothing above patch is owed. packages/cli changes a test only — no changeset owed. Check Changeset: success (both runs). Clause-②: no — right: no accept set moves, on my own key-lookup of every changed line.

Clause-②: no

③ Boundary flags

Dev flags (the report's deviations; open_questions is empty):

  1. Deletion leg run after the rewrite, from committed HEAD — answered: acceptable for a text-only change; the six reds are the readers of these fields and every asserted fragment survives; the pin's own ablation (query-cursor-retired reason reverted → "expected '[P2] data: QueryAST declares 12 members no executor runs — the liveness ledger governs metadata types, not the request surface #4286' to be undefined" red → restored green) is the anti-vacuity proof. Not re-run here.
  2. Census and astdiff scripts rewritten in-container — answered: my independent line-and-key probe (28 files, three prose keys only, 0 non-prose lines, 0 comment lines) reproduces the text-only claim without them.
  3. check:dual-build-cjs-loads NOT MEASURED locally, declared to CI — answered: Build Core hosts it ("Every published require entry point actually loads" → pnpm check:dual-build-cjs-loads) and is success on the head.
  4. /del.pid written at the container's filesystem root — outside the repository and the diff; nothing in the PR carries it. Noted for a person; not a contract matter.
  5. Floor arithmetic (27) — verified: 147 → 174, and the 27 rows are the 27 touched files (above).
  6. Attribution — both branch commits carry the session-URL trailer and the model-free co-author line; the PR body ends with the session-URL footer. Not a contract matter.
  7. origin/main not merged — main has since moved to 1c761c0d71; of the PR's 33 paths only packages/spec/src/migrations/registry.ts moved (ba5927f714, PR feat(spec,cli)!: one stack authoring shape — os validate / os build refuse a default export defineStack did not build #20460, adds stack-config-default-export-unbuilt-refused). A three-way git merge-file of base/head/main registry.ts written into scratch (no repository write) reports 0 conflicts. PR mergeable: true; mergeable_state: unstable is five third-party app check suites (deploy-preview and bot apps, no github-actions among them) queued with 0 runs — every github-actions suite completed success or skipped, combined status success. Regenerate registry.ts on merge as the claim foresaw; the seat's landing call.

Skips on the head: Auto Label ×3, Check PR Size ×2, Packed-tarball smoke ×2, Build Docs, Console Pin Gate — each a roster name in scripts/pm/check-expected-skips.mjs (read, not run); the docs filter is apps/docs/** plus declared content/docs/… paths, not docs/**, so docs/protocol-upgrade-guide.md does not wake Build Docs. All 37 other check-runs success.

Card rulings carried: form D (5749154545) — applied, sampled above; ruling A on surface (5858839916) — no surface site existed in these families and none is touched. Claim boundaries (5882012560) held: no stack- / turso- / cube- entry, no #20234 comment line, no #20513 runtime string. out_of_scope_findings (208 prose sites and 38 short numbers remaining → later stages; 833 comment lines → #20234) are carried, not this PR's. Nothing escalated.

Implemented-by: claude/issue-20233-migrate-meta-tracker-free-stage-7
Reviewed-by: session_01Sfe5YjBLwB9J3y8fvm2xq1

VERDICT: PASS

Adopted and posted by domain:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1) · 2026-09-29T04:06Z · rendered by the seat's at-tier review subagent; its served tier family was read from the subagent transcript before posting.


Generated by Claude Code

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/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants