Skip to content

feat(spec,cli)!: retire the ≤16.x retirement kits; the strict unknown-key refusal names the protocol upgrade guide - #26138

Closed
objectstack-fleet[bot] wants to merge 23 commits into
mainfrom
claude/project-thread-q3olv3
Closed

objectstack-fleet[bot] wants to merge 23 commits into
mainfrom
claude/project-thread-q3olv3

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steedos · project thread

Fixes #25767

Clause-②: no (narrowing: a key retired at or below protocol 16.x is refused as a strict unknown key without its own prescription in the error, and os migrate meta --from 16 refuses at the support floor instead of replaying step 17)
Metadata-protocol: narrowed

Tier H — governed path docs/adr/0087-metadata-protocol-upgrade-contract.md (amended in place) and a diff over 3000 lines (generated entries, surface files and ledgers included). Held draft for a GOVERNED_APPROVERS review.

What this PR does

Maintainer ruling on #25767, D2 = A: a retirement kit — the retiredKey() tombstone, its RETIRED_KEYS_BY_MAJOR / RETIRED_DEFS_BY_MAJOR rows, its semantic entry and its D2 conversion — lives through the protocol major after the one it retired in and leaves when the next major is cut. At 18 that keeps the 17.x and 18.x kits and removes everything retired at or below 16.x; 19 repeats the move one major on.

  • Removed (derived from the registry rows and the liveness ledger, not from prose): 50 D2 conversions with retiredAfter at or below 16.x (5 at 15.0.0, 45 at 16.1.0) and their fixtures; 55 tombstones already [RETIRED] at @objectstack/spec@17.0.0 whose container is a strictObject; the 159 major-17 entry files (29 retired-key rows, 53 retired-def rows, 77 semantic entries) and the chain's step 17; 61 [RETIRED] lines of the authorable surface and their 36 liveness-ledger rows.
  • Kept on purpose: 58 same-age tombstones whose container strips unknown keys (mapping.transform, rest-server.requireAuth, connector.rateLimitConfig, book.translations and kin) — deleting one would turn a refusal into a silent strip; the four inline-credential refusals, which are not retirements; the 17.x kits, which leave when 19 is cut.
  • The refusal: a removed key now meets the strict unknown-key refusal, which carries one more sentence after its fix channels and ahead of its history sentence (RETIRED_KEY_UPGRADE_GUIDE_SENTENCE, exported with PROTOCOL_UPGRADE_GUIDE_URL from @objectstack/spec): keys retired before the previous major are no longer prescribed in the error — see the protocol upgrade guide, https://objectstack.ai/docs/protocol-upgrade. The strictObject 的 history 句夹在「哪个键错了」与「该写什么」之间,在单行 error 显示位上把修法推到 222 字符之后(#5762 实测) #5955 "history last" order is unchanged.
  • The floor: MIGRATION_SUPPORT_FLOOR is 17; os migrate meta --from 16 and below answer MigrationFloorError, whose message names the floor and the guide, and rewrite nothing. packages/cli examples, pins and fixtures follow the floor.
  • The deletion gate: check:authorable-surface proof 1 ages a tombstone one major (was two). A deleted [RETIRED] line is dated by an exact registry row or, new, by the previous major's release tag (@objectstack/spec@17.0.0 here): a line already [RETIRED] on the surface at that tag was retired before that cut. The tag is immutable, so neither a row a PR writes nor one it deletes moves the clock; when the tag cannot be read the gate dates by the registry alone and says so. No gate was added.
  • The paper trail: ADR-0087 amended in place ("never deleted" / "permanent" / "forever" now read "one major past retirement"), the same permanence text in registry.ts.template's docblock, docs/protocol-upgrade-guide.md says where an aged-out kit's prescription lives (the release that carried it), content/docs/upgrading.mdx and the generated references follow, one changeset (minor for spec and cli, patch for lint and metadata-core).

Acceptance notes (read before approving)

  1. 17.x load-path kits are rows, not steps. 17 conversions dated retiredAfter: 17.7.0 (datasource-driver-mongo-to-mongodb, retry-policy-converged, the flow-node aliases, sharing-rule-access-level-full-to-edit, …) stay registered for the data-at-rest seams (stored-row rehydration, the artifact door), but their chain step (17) is below the floor: os migrate meta --from 17 does not replay them. This is the template's own rule ("a step the floor no longer reaches retires"), the same move that retired steps 11–16 at the first floor move; their prescriptions already name the hand edit. Three protocol-18 semantic entries (spec(conversions): eight ADR-0087 D2 conversions stay on the 18 load path after #23487 — five families each need a ruling before they can retire #23543 F1/F2/F3: the mongo alias, the flow sibling-block lifts, the job retry default) declared a conversionIds link to one of those step-17 conversions and promised that os migrate meta lists the edit; the link is dropped and the prose names the hand edit, the shape the F4/F5 entries already have for protocol-11/15 conversions. The chain is one hop now (18) and stays one hop under the one-major rule; the cli report-order pin counts hops off the floor, and a new pin refuses a link to a conversion the floor does not reach.
  2. Stored rows still in a ≤16.x shape are no longer rewritten at read; canonicalize once with os migrate meta --stored --apply on 18.1 or earlier. app-hidden-to-unpublished is among the removed conversions, so a pre-split hidden: true app row is no longer rewritten by any seam; the artifact door's refusal of it by id is removed as moot (@objectstack/metadata-core).
  3. ADR-0104 data-migration advice is unreachable from the command. pendingDataMigrations keys on a run crossing into 17; no run does now. The field stays in the JSON ([]) and the code stays; the cli e2e pins only the silence. A ruling on deleting it is a residual on the card.
  4. Unknown-key guidance tables are untouched. TOOL_RETIRED_KEY_GUIDANCE, CAPABILITIES_RETIRED_KEY_GUIDANCE, RETIRED_DATASOURCE_BLOCKS, JOB_ID_RETIRED, the app AREA_* aliases and kin are not ledger tombstones (no row, no entry); their house sentence is respelled to name the floor. Whether they age out with the kits is a residual on the card.
  5. Fuzzy "Did you mean" can now point an aged-out key at a near spelling (retryDelayMs → maxRetryDelayMs, aria → areas); the guide sentence follows in the same message.
  6. Tag offline: the gate's tag proof reads git show @objectstack/spec@17.0.0:…; a checkout without the tag dates by the registry alone and prints that it did.
  7. No live ≤16.x reader found. Measured at 963e504cf5: no examples/**, ui/ or hotcrm source writes a removed key (the ui/ hits are the console's own same-named props and type mirrors).

File surface beyond the claim

The claim named packages/spec/src/conversions/registry.ts, the *.zod.ts tombstone files, suggestions.zod.ts, registry.ts.template, cli/.../meta.ts, ADR-0087, the releases page and one changeset. The diff also touches, each as a consequence of the removal and nothing more:

  • packages/spec/src/migrations/entries/** (159 major-17 entry files deleted), chain.ts (floor + guide link in the error), shared/protocol-upgrade-guide.ts (new, the sentence and URL), shared/retired-key.ts (docblock), scripts/build-schemas.ts + scripts/lib/renamed-defs.ts (the one-major gate), the generated authorable-surface/*.json, api-surface/shared.json, export-origins/shared.json, liveness/*.json + state-counts/*.md, content/docs/references/** (all by the generators; check:generated is the proof).
  • Spec, cli, lint and metadata-core tests whose pins named a removed kit (rewritten to the strict refusal + guide, or re-targeted to a surviving 17.x/18.x kit); packages/lint/src/validate-*.ts and packages/metadata-core/src/*.ts where a removed key or conversion id was read. The lint's field-rule walk no longer reads conditionalRequired (its tombstone left FieldSchema), its liveness pin for the dashboard walk rides the refreshInterval row, and the ADR-0032 dispatch-key tests accept the script contract's per-key refusals beside the lint's own prescription.
  • docs/qa/platform-checklist/areas/ai.json: one lost anchor (skill.zod.ts#triggerPhrases) re-pointed, revision 7.
  • docs/adr/0072-reference-scope-and-resolvability.md and docs/adr/0142-ownership-queue-membership-claim-and-assignment-rules.md: one symbol anchor each named a removed tombstone (flow.zod.ts#outputSchema) or a removed major-17 entry; re-pointed to the file / to prose, no other change. scripts/check-spec-docblock-symbol-anchors.mjs: the one CENSUS_RESIDUAL row whose citation left with a removed conversion's docblock is deleted, as the gate asks.
  • packages/cli/test/package-owned-command-readers.test.ts: the [finding] cli(serve): os serve resolves capability providers from a multi-package artifact's top-level requires only — a package's requires: ['automation'] is not loaded at boot #22288 proof that os migrate meta reads every package's body rode the ADR-0104 listing, unreachable now; it rides a retired key on the service package's object instead, in a fixture pair of its own.
  • .claude/skills/spec-property-retirement/SKILL.md: the aging clock and the second dating source, +4 lines (file 337 → 341, pack 1104 → 1108).
  • Releases page: content/docs/releases/ is release-owned, so the "16 and below: refusal + link" note lives in the changeset (which the release notes are cut from), content/docs/upgrading.mdx and the upgrade guide.

维护者速读(草稿)

改了什么。 按你在 #25767 的裁决(D2 = A):退役套件只活到退役所在 major 的下一个 major。本 PR 在 18 上删掉所有 ≤16.x 退役的套件:50 个 D2 conversion、55 个墓碑、159 个 17 号 migration 条目和链上的第 17 步;被删的键现在由 strict 容器当未知键拒绝,错误里多一句指向升级指南(https://objectstack.ai/docs/protocol-upgrade),处方不再内嵌。os migrate meta 的支持底线从 16 升到 17,--from 16 直接拒绝并给链接。ADR-0087 原地修订,门禁的老化时钟从两个 major 改为一个,不新增门禁。

为什么改。 每个 major 都在累积墓碑和 conversion(17 号条目就有 159 个文件),它们既占 spec 体积也占每次升级的审阅面;业务上,升级者真正需要的是「我这把键该改成什么」,这句话放在升级指南和当时的 release notes 里就够了,不必让每个 strict schema 永远背着。

风险与代价(含回滚)。 ① 还停在 16 方言的源码不再拿到逐键处方,只拿到未知键拒绝 + 链接;它需要先在 ≤18.1 的 cli 上跑一次 os migrate meta --from 16。② sys_metadata 里仍是 ≤16.x 形状的行不再在读取时改写,要在 ≤18.1 上用 --stored --apply 规范化一次。③ 17.7.0 从加载路径退役的 17 个 conversion 没有可重放的步,靠处方手改(模板本身的规则)。④ ADR-0104 的数据迁移提示从命令里不可达了,代码留着待裁。回滚:revert 本 PR 即恢复全部套件与第 17 步;没有数据写入,没有不可逆动作。

席位意见。 (留空,席位定稿)

你要做的。 作为 GOVERNED_APPROVERS 批准本 PR(Tier H:ADR 原地修订 + >3000 行),或指出不认可的点;另有两个残留问题在卡片上等你一句话(guidance 表是否随套件老化;pendingDataMigrations 是否删除)。


Generated by Claude Code

…the upgrade guide (#25767) [wip]

Work in progress, paused on maintainer instruction (token budget); not yet
gate-green. Done so far:

- conversions/registry.ts: the 50 retiredAfter-≤16.x conversions and their
  retired-key / retired-def tables are removed; chain floor rises 16 → 17
  (MIGRATION_SUPPORT_FLOOR), MigrationFloorError names the upgrade guide.
- 55 ≤16.x tombstones on strict containers deleted; retiredKey() tombstones
  on non-strict containers kept (a delete would strip silently).
- shared/protocol-upgrade-guide.ts: RETIRED_KEY_UPGRADE_GUIDE_SENTENCE,
  emitted by the strict unknown-key refusal after its fix channels and
  ahead of the history sentence (#5955 order).
- build-schemas.ts tombstone-age gate (registry row or previous-major tag
  proof); migrations registry.ts.template permanence docblock.
- ADR-0087 amendment, upgrade guide page, changeset; cli migrate meta
  support floor.
- Test pins rewritten for ai, automation, conversions, data, kernel,
  migrations, shared, security and most of ui.

Left: ui/view*, ui/dashboard*, scripts liveness pins; full spec test run;
cli floor-17 pins; dispatch gates; PR body and report.

Claude-Session: https://claude.ai/code/session_01H37vtTJRVBf1LkyYNW5yfo
Co-authored-by: Claude <noreply@anthropic.com>
…-key refusal names the protocol upgrade guide

Maintainer ruling on #25767 (D2 = A): a retirement kit lives through the
protocol major after the one it retired in and leaves when the next major
is cut. At 18 that removes everything retired at or below 16.x — 50 D2
conversions and their fixtures, 55 tombstones on strict containers, the
159 major-17 migration entries and the chain's step 17 — and keeps the
17.x and 18.x kits for 19 to repeat the move.

- A removed key meets the strict unknown-key refusal, which now carries
  one more sentence after its fix channels and before the history
  sentence: keys retired before the previous major are no longer
  prescribed here — see the protocol upgrade guide
  (`RETIRED_KEY_UPGRADE_GUIDE_SENTENCE`, `PROTOCOL_UPGRADE_GUIDE_URL`).
- `MIGRATION_SUPPORT_FLOOR` is 17: `os migrate meta --from 16` and below
  answer `MigrationFloorError`, naming the floor and the guide; the chain
  is one hop (18). The 17.7.0 load-path conversions stay registered for
  the data-at-rest seams but have no replayable step; the three
  protocol-18 entries that linked one drop the link and name the hand
  edit (the F4/F5 shape).
- `check:authorable-surface` ages a tombstone one major, dating a deleted
  `[RETIRED]` line by a registry row or by the previous major's release
  tag; no gate is added.
- ADR-0087 amended in place; the template, the upgrade guide, the
  retirement skill and one changeset follow. Spec, cli, lint and
  metadata-core tests re-pinned to the refusal or to surviving kits.

Claude-Session: https://claude.ai/code/session_01H37vtTJRVBf1LkyYNW5yfo
Co-authored-by: Claude <noreply@anthropic.com>
Brings in the 84 commits main gained since the branch base. Source files
merged without a text conflict; the merge driver deferred eleven
generator-owned artifacts (authorable-surface ui/security, the permission
liveness state-counts page, eight reference pages), regenerated here from
the merged tree with the spec generators, not by hand.

Claude-Session: https://claude.ai/code/session_01H37vtTJRVBf1LkyYNW5yfo
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Maintainer ruling relayed: B, and it ships in 18.2 · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-26T14:12Z

⛔ Not a review, ⛔ not a claim. A relay of the maintainer's word for the holder of this PR and for the 18.2.0 release owner.

The maintainer's words (triage thread, 2026-10-26, verbatim): 「B,进 18.2」, answering two questions. Is a customer's ≤16.x metadata project still upgradeable after this PR? It is, through @objectstack/cli@18.1.0. And should the path be made prominent (B) and land in 18.2.0? Yes to both.

What B asks of this PR (text only, no code)

Put one prominent block, "Upgrading from protocol 16 or earlier", in two places. The changeset is one, because the release notes are cut from it, so it lands at the top of the 18.2.0 notes. The top of docs/protocol-upgrade-guide.md (or the protocol-18 page) is the other. The block carries, in this order:

  1. Source metadata project: run the first hop on 18.1's CLI, the last release whose floor is 16:
    npx @objectstack/cli@18.1.0 migrate meta --from 16
    npx @objectstack/cli@18.1.0 migrate meta --from 16 --apply
    Work the to-do list it prints, then move the dependencies to 18.2 and run os migrate meta --from 17, os validate and os build.
  2. Stored metadata (sys_metadata, Studio-authored), before the runtime moves:
    npx @objectstack/cli@18.1.0 migrate meta --stored --apply
    Say plainly that this must run before the deployment's image or dependencies move to 18.2. 18.2 no longer rewrites a ≤16.x row at read, so a row left behind is refused by the strict parse until it is migrated.
  3. One line on what 18.2 does if step 1 is skipped: --from 16 refuses with MigrationFloorError and rewrites nothing, and a ≤16.x key meets the strict unknown-key refusal with the guide link.

content/docs/upgrading.mdx already carries this at its floor note (around :242–251). B makes it the first thing a reader of the 18.2.0 notes sees.

"Ships in 18.2"

  • This PR lands before the 18.2.0 Version PR (chore: version packages #25640) is merged, so its changeset (spec and cli minor) is in that release. Tier H as stated, so the maintainer's review and landing apply.
  • For the release owner: 18.2.0 is the first release in which a ≤16.x project must pass through 18.1. The B block is that release's upgrade note.

Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review October 26, 2026 14:14
@os-zhuang
os-zhuang enabled auto-merge October 26, 2026 14:14
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Addendum to the B block: lead with "one major at a time" · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-26T14:16Z

⛔ Not a review, ⛔ not a claim. This refines the relay above with the maintainer's follow-up (triage thread, 2026-10-26, verbatim): 「我先用 v17 的升级工具,然后再用 v18的升级工具,这个是通常能理解的流程吧」.

Verified on the release tag: @objectstack/cli@17.7.0 (published on npm) has MIGRATION_SUPPORT_FLOOR = 16 (packages/spec/src/migrations/registry.ts:79) and carries migrate meta --stored. So the stepwise path works as the maintainer describes, and it is the one readers already expect.

So the B block leads with it, and the 18.1 one-shot follows as an alternative:

  1. One major at a time (the default, and the rule that generalizes to 19):
    npx @objectstack/cli@17.7.0 migrate meta --from 16 --apply   # 16 → 17
    npx @objectstack/cli@17.7.0 migrate meta --stored --apply    # stored rows, before the runtime moves
    # move the dependencies / image to 18.2, then
    os migrate meta --from 17 --apply                             # 17 → 18
    os validate && os build
  2. Alternative: @objectstack/cli@18.1.0 still runs --from 16 through both hops in one command.
  3. Unchanged: stored sys_metadata rows are migrated before the deployment's runtime moves to 18.2, and the line on what 18.2 does when step 1 is skipped stays.

The block can then state the general rule once: to upgrade across several majors, run each major's CLI in turn. A major's CLI carries the steps for itself and the major before it. That matches this PR's one-major retirement rule, so the same sentence stays true at 19.


Generated by Claude Code

…e 17.x kits, not the retired ≤16.x ones

The ≤16.x retirement kits left the registry in the previous commit, and
two suites still rode them as fixtures:

- packages/metadata-protocol's stored-row seams (migrateStoredMetadata,
  getMetaItem(s), loadMetaFromDb, the residue re-save and the
  non-canonical-type control) used the `conditionalRequired` →
  `requiredWhen` field rename and the action `execute` → `target` alias as
  the legacy shape the stored seam keeps lowering. Those conversions are
  gone, so the rows now carry the 17.2.0 `reference_to` → `reference`
  rename (`field-reference-to-alias`) and the 17.4.0 `aria` removal
  (`action-aria-removed`), both still registered for the data-at-rest
  seams; the pins read the same notices, rewrites, checksums and report
  lines as before, on the surviving kit.
- packages/lint's object-door field-rule test listed `conditionalRequired`
  among the slots the build's expression walk judges; the walk no longer
  reads it (its tombstone aged out of `FieldSchema`, so the key is a strict
  unknown key), and the row is dropped with the docblock saying why.

Claude-Session: https://claude.ai/code/session_01H37vtTJRVBf1LkyYNW5yfo
Co-authored-by: Claude <noreply@anthropic.com>
…ns on the retired ≤16.x kits ride 17.x kits or the strict refusal

Running every package whose sources read the conversion registry in full
found the rest of the pins that rode a kit the previous commits removed:

- packages/metadata-protocol: the served-schema property counts (#17501)
  move down by exactly the top-level tombstones that left each shape
  (action 3, agent 2, app 8, dashboard 2, field 1, flow 2, skill 1); the
  #17502 repeater-row pin moves from the dashboard widget row, which has no
  tombstone left, to the page component row (`visibility`, `responsive`,
  17.x kits), with the dashboard keeping its depth pin through
  `refreshInterval` and the widget `chartConfig`; the aged-out widget
  column is pinned as the strict refusal it is now; the #21982 fallback
  pin rides `errorHandling.retryDelayMs` (`retry-policy-converged`, 17.7.0)
  instead of `flow.active`, and `flow.active` is pinned refused on both
  hosts, naming the upgrade guide.
- packages/services/service-automation: the script `actionType` stubs are
  refused at registration as unknown keys naming the guide (nothing strips
  them on rehydration any more), the fault-edge guard rides the bare
  contract, and the wait-node round trip holds the `timeout` guidance
  channel, with the aged-out `timeoutMs` pinned as the strict refusal.
- packages/objectql: the rule validator pin shows the chain no longer
  lowers the aged-out `conditionalRequired` alias and enforces the rule on
  the canonical `requiredWhen` only.

Claude-Session: https://claude.ai/code/session_01H37vtTJRVBf1LkyYNW5yfo
Co-authored-by: Claude <noreply@anthropic.com>
…-seam pins ride the 17.x kits; the aged-out ≤16.x spellings are pinned as strict refusals

The two remaining consumer suites of the conversion registry carried
fixtures in the ≤16.x dialect the previous commits retired:

- packages/runtime: the #12892 two-reader harness and the two real-boot
  files (the security registrar, the #14491 seeder declaration copy)
  wrote the stack's `roles`, an RLS `priority` and a `sharedWith.type:
  'role'` recipient, each governed by a kit that left the registry. The
  fixtures now write `positions`, no `priority` and a `position`
  recipient; the conversion axis is measured on the 17.x kits that still
  reach the security collections (the `allowRestore` / `allowPurge`
  grant bits, `accessLevel: 'full'`); and a new harness pin shows the
  door refusing each aged-out spelling outright — a strict unknown key
  naming the upgrade guide, an invalid recipient option. The #3878
  analytics-entry pins expect `query` refused as a strict unknown key
  naming the guide instead of the envelope's per-key prescription.
- packages/services/service-datasource: the #4456 restore-seam pin shows
  what the seam replays now — the 17.7.0 `mongo` → `mongodb` driver
  alias — and that a row still in the ≤16.x config spelling (`file`,
  `connectionString` / `user`, `uri`) is served as stored: the row the
  ruling sends through `os migrate meta --stored --apply` on 18.1 or
  earlier.

Claude-Session: https://claude.ai/code/session_01H37vtTJRVBf1LkyYNW5yfo
Co-authored-by: Claude <noreply@anthropic.com>
…6 or earlier" — one major at a time, stored rows before the runtime moves

The maintainer's ruling relayed on the PR (B, ships in 18.2): make the
path a ≤16.x project takes prominent, text only. One block, in the two
places the ruling names — the changeset, because the 18.2.0 release
notes are cut from it, and the top of docs/protocol-upgrade-guide.md:

- the default, one major at a time: `@objectstack/cli@17.7.0 migrate
  meta --from 16 --apply`, its `--stored --apply` for the sys_metadata
  rows, then the move to 18.2 and `os migrate meta --from 17 --apply`,
  `os validate`, `os build` — and the rule it follows, each major's CLI
  in turn, which holds at 19;
- the one-shot alternative on `@objectstack/cli@18.1.0`, the last
  release whose floor is 16;
- stored rows are migrated before the deployment's image or
  dependencies move to 18.2, since 18.2 no longer rewrites a ≤16.x row
  at read;
- what 18.2 does when the first hop is skipped: `--from 16` refuses with
  MigrationFloorError and rewrites nothing, and a ≤16.x key meets the
  strict unknown-key refusal with the guide link.

No code and no generated file changes; content/docs/upgrading.mdx keeps
its floor callout, which names the 18.1 path as the alternative does.

Claude-Session: https://claude.ai/code/session_01H37vtTJRVBf1LkyYNW5yfo
Co-authored-by: Claude <noreply@anthropic.com>
Brings in the 40 commits main gained since the previous merge. One text
conflict, in the #17501 served-schema property-count pin: main moved
`object` 47 → 48 for the `sharing` block (#25760) while this branch had
re-derived every count without the top-level tombstones that left each
shape; resolved as the branch's counts with `object` at 48. The merge
driver deferred four generator-owned artifacts (the data authorable
surface and three reference pages), regenerated here from the merged tree
with the spec generators, not by hand.

Claude-Session: https://claude.ai/code/session_01H37vtTJRVBf1LkyYNW5yfo
Co-authored-by: Claude <noreply@anthropic.com>
…the spec keys that aged out at 18.2

The re-review of 2718c3c found the console's `ListViewSchema` twin built
like the App and Dashboard twins this PR already fixed: `BaseSchema`
(`.passthrough()`) plus the spec list view's members by reference. The five
list view tombstones that aged out of the spec at 18.2 (`striped`,
`bordered`, `virtualScroll`, `responsive`, `performance`) left the
projection with no refusal of their own, so an authored `striped: true`
parsed green and was kept. Each is now an `agedOutSpecKeyRefusal` arm on
the twin. The TS face is derived from the twin (`ListViewInferred`), so
each key is `?: undefined` there with no hand-kept member; the page
`list-view` node's `properties` bag reads the twin's shape and refuses the
five too, and its flat spelling gets the row's own retirement.

A parse census of the other removed component tombstones found three more
flat spellings kept in silence on public-block arms: `page:header` `icon`,
`page:card` `actions` and `record:details` `layout`. `flatPropRefusals`
reads the spec row's key set, and the row no longer carries the name, so
`BaseSchema` kept a flat value. Each arm now declares the console's own
refusal; the bag spelling was already refused by the strict row.

Pins: list-view-aged-out-spec-keys-25767 (twin, bag, flat, TS face) and
public-block-aged-out-spec-keys-25767 (flat, bag), each with the spec's
own unknown-key verdict as the control.

Claude-Session: https://claude.ai/code/session_018wdyGVjfpxCUwq2UMrZkwi
Co-authored-by: Claude <noreply@anthropic.com>
… as their own category

`list-view-spec-parity`'s rogue-key check read the five new
`agedOutSpecKeyRefusal` arms as objectui-only fields. They are neither a
sanctioned local extension nor a spec member: a fifth category,
`AGED_OUT_SPEC_REFUSALS`, checked like `HANDLER_KEY_REFUSALS` — each member
must be declared on the arm, refuse every value, and be undeclared by the
spec, so the set cannot park a live field.

Claude-Session: https://claude.ai/code/session_018wdyGVjfpxCUwq2UMrZkwi
Co-authored-by: Claude <noreply@anthropic.com>
…rge of main

`node scripts/gen-sdui-manifest-node.mjs` over the merged tree: the
manifest itself is unchanged (sha256 1f6e1ccb925a…, 106 components); the
core and types records move with main's sources and this round's
ui/packages/types edits.

Claude-Session: https://claude.ai/code/session_018wdyGVjfpxCUwq2UMrZkwi
Co-authored-by: Claude <noreply@anthropic.com>
…w keys again

`ObjectView.relayRungCensus-7559` reads every `ListViewSchema` member and
asks for a relay rung or a declared absence. The five list view keys whose
spec tombstones aged out at 18.2 had left that shape, so their `unread`
rows were dropped; the twin now declares each as its own refusal
(`agedOutSpecKeyRefusal`), which makes them members again. They return as
`unread`, each reason naming the age-out and the refusal: an authored
value never parses, so there is nothing for a rung to relay. CI's
Test UI (15/16) on 045298a was red on exactly this.

Claude-Session: https://claude.ai/code/session_018wdyGVjfpxCUwq2UMrZkwi
Co-authored-by: Claude <noreply@anthropic.com>
# Conflicts:
#	scripts/sdui-manifest.sources/core.json
#	scripts/sdui-manifest.sources/types.json
…ide; the branch's aged-out data.json lines stay deleted

Main moved packages/spec/authorable-surface/data.json (Seed files rows) and two
reference pages; the merge took main's side and these are the regenerated
results. Field:conditionalRequired, Index:partial and Index:type stay deleted:
they aged out on this branch (objectstack#25767).

Claude-Session: https://claude.ai/code/session_018wdyGVjfpxCUwq2UMrZkwi
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Closing as superseded · domain:spec seat 2 · session session_01RyMY3prh9GRva1Tt37Di3i

The maintainer amended #25767's scope on 2026-10-27, recorded in ruling 6434038284 (「同意」 04:39Z). Part 1 is kept: retirement kits age out one major after they retired. Part 2 is withdrawn: the migration chain stays replayable down to floor 16, and step 17 with its 159 entries stays. Release moves to 18.3.

As adopted with the ruling, this PR closes unmerged. Its scope has halved, and it carries two FAIL contract-review records plus an APPROVED review on an earlier head, so it should not land on that approval. The reworked change comes from the same branch (claude/project-thread-q3olv3) as a new draft PR with Supersedes #26138 and Fixes #25767, and it gets a fresh contract review and a fresh maintainer approval. Head at close: 0a482d6898.

zhuangjianguo pushed a commit that referenced this pull request Oct 27, 2026
…s `username` again

The rework restored this file to main and lost #26138's c61ede6. Test
Core 4/8 failed audit-mail-bodies.archive case 7 at cd60de5: the
fixture's postgres archive carried `user`, the pre-17 spelling of
`username`. The `datasource-config-driver-key-aliases` conversion that
rewrote it at artifact load aged out with its kit, so the strict config
door refuses the key and the command never reaches the not-connected
archive the case pins. The fixture spells the live key.

A census of packages/cli for the other spellings that conversion and the
removed datasource conversions carried (sqlite file/database, postgres and
mysql connectionString, mongo uri, inert blocks, capabilities, readReplicas,
connector rateLimit) finds no other datasource declaration that uses one.

Claude-Session: https://claude.ai/code/session_018wdyGVjfpxCUwq2UMrZkwi
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

3 participants