Skip to content

spec: 14 retiredKey() tombstones again prescribe @objectstack/spec 18, a version that will not contain the change — #4350 recurring with no gate behind its fix #18040

Description

@zhuangjianguo

Filed by the epic PM for #15939 (session_015c5G6TmpMKgnusmTpD7Ntt) as a surrounding finding. ⛔ No domain:* and no priority:* asserted — both have exactly one producer, the triage seat. ⚠️ Triage's first touch is owed before this can be dispatched.

Surfaced by the at-tier contract review of PR #18016 and verified independently on origin/main, 2026-09-13T14:29Z.

This is a recurrence, not a new defect

#4350 filed exactly this in July — 「十处墓碑文案写着「removed in @objectstack/spec 18」,而这些键随 17.0.0 发布 —— 处方给了作者一个不会到来的版本号」 — and it was closed completed by merged PR #4359, which corrected all ten sites from 18 to 17.

⚠️ #4350 also recorded that the wrong number caused real downstream harm: objectui#3101 scheduled its own cleanup against "the PR that takes @objectstack/spec to 18" — an event that was never going to arrive.

There are 14 again. The fix was applied by hand and nothing was left behind to hold it, so the class regressed.

The 14, measured

⚠️ Measure with concatenated string literals joined first — the phrase spans a '…' + '…' break, so a single-line grep returns a false zero. That is why this went unnoticed:

git ls-tree -r --name-only origin/main -- packages/spec/src | grep -E '\.ts$' | while read f; do
  git show "origin/main:$f" | tr '\n' ' ' | sed "s/' *+ *'//g" | grep -o -E "@objectstack/spec 18"
done | wc -l
file count
packages/spec/src/kernel/plugin-lifecycle-advanced.zod.ts 5
packages/spec/src/system/disaster-recovery.zod.ts 2
packages/spec/src/system/cache.zod.ts 2
packages/spec/src/api/export.zod.ts 2
packages/spec/src/ui/view.zod.ts 1
packages/spec/src/integration/connector.zod.ts 1
packages/spec/src/automation/execution.zod.ts 1
total 14

Lit control on the same corpus and method: 88 files say @objectstack/spec 17; tree-wide the split is 238 tombstones saying 17 against these 14. Dark control 0.

Why 17 is the right number

Established independently by the at-tier review, from primary sources rather than from the majority:

  • retiredKey()'s own docblock says the guidance names "the version that removed it", and its worked example is 17.0.0a package version.
  • The package is at 17.4.0 with 37 pending minor changesets and 0 major, so every one of these tombstones first refuses in 17.5.0. A reader who hits one is on 17.x, and "18" names a version that does not exist.
  • PROTOCOL_VERSION is pinned in lockstep with the package major (protocol-version.test.ts), so it cannot be moved to 18 unilaterally either.
  • MigrationStep.major is documented as "the protocol major this step migrates into" — a different axis by design. RETIRED_KEYS_BY_MAJOR[18] being 18 is correct and is not evidence that the prose should say 18. Conflating the two axes is the whole error.

This reproduces #4350's own reasoning, which reached 17 by the same route in July.

Scope note: 5 of the 14 are days old

plugin-lifecycle-advanced.zod.ts's five arrived with PR #17986 (#17780), part of the #15939 epic, merged 2026-09-13. That file is internally mixed — its own HEALTH_CHECK_INTERVAL_RETIRED says 17 — so the round followed the half it happened to read. ⇒ the class is not static; it is actively growing, which is the argument for a gate rather than a second hand-sweep.

For the record: the same defect was caught before landing on the epic's last card (#17785 / PR #18016) and corrected there, so the epic's remaining cards are clean. Only #17986's five got through.

Suggested shape — enforce-or-remove, not a third hand-sweep

  1. Correct the 14. Mechanical: the number, nothing else.
  2. Add the gate fix(spec)!: 退役处方指向 protocol 17 —— 这趟车真正会发的 major (#4350) #4359 did not. A rule that a retiredKey() prescription may not name a package major greater than package.json's current major is checkable from the tree alone and needs no release knowledge. ⚠️ It must join the concatenated literals before matching, or it will read the same false zero this defect has been hiding behind since July.

⇒ Without step 2 this is the third occurrence waiting to happen. Recorded as declared ≠ enforced: the rule is real, was ruled on in #4350, and has nothing holding it.

Dedupe

search_issues over this repo for the tombstone-version shape ⇒ 7 results, 0 open. #4350 is the direct predecessor (closed completed by #4359). #16277, #15437, #15332 are adjacent version-prose defects on other surfaces; #12772, #6914, #7062 are other tombstone-content classes. ⚠️ Declared limit: semantic search, not an exhaustive title enumeration.

Refs: #4350 (predecessor) · PR #4359 (its fix) · objectui#3101 (the downstream harm it recorded) · PR #17986 (source of 5 of the 14) · #15939 (the epic that surfaced the recurrence)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions