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

@os-justin
os-justin marked this pull request as ready for review September 29, 2026 04:09
@os-justin
os-justin added this pull request to the merge queue Sep 29, 2026
Merged via the queue into main with commit f11b5f2 Sep 29, 2026
51 checks passed
@os-justin
os-justin deleted the claude/issue-20233-migrate-meta-tracker-free-stage-7 branch September 29, 2026 04:30
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