Repository navigation
fix(spec): re-anchor the authorable-surface anchor so an offline, tagless spec build passes (#27015) - #27020
Conversation
…bstone age-out (#27015) The committed anchor sat at 85c6d76, before dbf7e04 (#26599) aged the <=16.x retirement kits out. A build that cannot reach origin/main anchors on this file, and then has to date the 38 deleted tombstone lines through the @objectstack/spec@17.0.0 release tag. An offline, tagless clone cannot read that tag, so `@objectstack/spec#build` failed there (the cloud EE image check). Re-anchored with `pnpm --filter @objectstack/spec gen:authorable-surface-base` at 7eb613c, which carries those deletions in its own surface. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QUs3Bshfmr8srPY21BVS4u
…aged-out deletion (#27015) Reads only committed files, as an offline build does: the anchor's [RETIRED] lines that the live surface has dropped, in a def still on the surface, must each be dated by RETIRED_KEYS_BY_MAJOR. A line only the @objectstack/spec@<major-1>.0.0 tag can date is one a build with no route to origin/main refuses. Red at the previous anchor 85c6d76 (45 lines, the 38 the offline gate refused plus 7 it proves unreachable), green at 7eb613c. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QUs3Bshfmr8srPY21BVS4u
|
Seat review · Faces. Neither file is a published schema: Read:
Landing: ready + auto-merge once every check on the head is green. The driving thread reports green, then the seat arms. After it lands, cloud#3340 moves its pin to a commit carrying both this fix and #27011. Generated by Claude Code |
…26599 aged out (#27015) `ui/PageCardProps:body` left the live authorable surface in #26599 and stayed authorable in the self-test only through the stale anchor. With the anchor re-anchored, the case named a key neither side carries. The specimen is now `ui/Dashboard:refreshInterval`, a 18.x tombstone that is on the live ratchet until major 20. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QUs3Bshfmr8srPY21BVS4u
📓 Docs Drift Check
What this run could not see
Coarse fallback — 147 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
|
Seat delta ACCEPT · The delta since the ACCEPT at Every check run on the head has concluded: 37 success, 13 skipped by path filter, and 1 cancelled Landing: ready + auto-merge. Generated by Claude Code |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40619952219 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
Queue ejection on run 40619952219 is not this PR's. Read 2026-10-28T02:39Z. Failing check: Why it is not this PR's: this diff touches Fix: none exists yet. The case inserts Until that lands, a re-queue of this PR can only pass if the shard happens to be lightly loaded. Generated by Claude Code |
…ix for #27037) The case seeds RELATION_FILTER_ID_CAP (1,000) rows and deletes 1,001: 2.3 s alone, past the default 5 s on a loaded full-suite queue shard, which ejected #26960, #27011 and #27020 (#27037). The slowdown itself is #27004's (since #26930 a 1,001-row predicate delete is about 18x slower); this only budgets for it. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QUs3Bshfmr8srPY21BVS4u
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40621681807 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
Seat delta ACCEPT · The delta since Landing: ready + auto-merge once the PR checks on this head are green. Generated by Claude Code |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40633845705 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
Queue ejection on run 40633845705 is not this PR's either. Read 2026-10-28T05:04Z. Failing check: Why it is not this PR's: this diff touches Fix: none exists yet. The #27037 budget this PR carries already held in this build (Test Core 8/8 did not fail). This is a second, independent load-sensitive case: a scaffold that writes a project tree in a 30 s budget on a loaded full-suite shard. Not porting another budget here unasked; it is the queue owner's call whether to re-queue or budget it. Generated by Claude Code |
…ix for #27037) The case seeds RELATION_FILTER_ID_CAP (1,000) rows and deletes 1,001: 2.3 s alone, past the default 5 s on a loaded full-suite queue shard, which ejected #26960, #27011 and #27020 (#27037). The slowdown itself is #27004's (since #26930 a 1,001-row predicate delete is about 18x slower); this only budgets for it. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QUs3Bshfmr8srPY21BVS4u (cherry picked from commit 6674ba8)
Fixes #27015
What changes
packages/spec/authorable-surface.base.jsonis re-anchored from85c6d76ec42ato7eb613c39f(7,982 keys), withpnpm --filter @objectstack/spec gen:authorable-surface-base, in a commit of its own.packages/spec/scripts/authorable-surface-base.currency.pin.test.ts: reading only committed files, as an offline build does, every[RETIRED]line the anchor records that the live surface has dropped (in a def still on the surface) must be dated byRETIRED_KEYS_BY_MAJOR. A line only the@objectstack/spec@<major-1>.0.0tag can date fails the pin, with the re-anchor command, and the in-PR alternative (an exact retired-key entry), in the message.scripts/docs-audit/affected-docs.mjsself-test: the live-ratchet tombstone specimenui/PageCardProps:bodyaged out in feat(spec)!: retirement kits whose conversion retired at or below 16.x age out; the strict unknown-key refusal names the protocol upgrade guide #26599 and was passing only through the stale anchor; it is nowui/Dashboard:refreshInterval, a 18.x tombstone (Flag docs affected by code changeswas red on the first head).6674ba8e09):packages/rest/src/data-nested-object-door.test.ts, "the cap" case gets an explicit30_000ms budget. It seeds 1,000 rows and deletes 1,001; that takes 2.3 s alone, and twice ran past the default 5 s on a loaded full-suite queue shard, ejecting this PR (queue runs 40619952219, 40621681807). The slowdown itself stays with objectql: since #26930 a predicate delete walks every matched row one by one; 1,001 rows cost ~1.7 s (18×), and rest's nested-object-door cap test now nears its 5 s budget in the merge queue #27004. Budget only, no behaviour change.Why
#26599 (
dbf7e04adf) aged the 16.x-and-older kits out and deleted their tombstone lines. Online, the deletion gate (#4650) dates 38 of them through the@objectstack/spec@17.0.0release tag (#25767). A build with no route to origin/main anchors on the committedauthorable-surface.base.jsoninstead, which still sat at85c6d76ec42a, before that deletion. It cannot read or fetch the tag either, so it refused all 38 lines and@objectstack/spec#buildfailed. That is the cloud EE image check (verify-objectos-ee-image.ymlbuilds the framework layer offline), which blocks cloud's pin round on cloud#3340.Reproduced at
7eb613c39fin a depth-1 clone with no tags and no remote (pnpm --filter @objectstack/spec gen:schema):85c6d76ec42a, no tag@objectstack/spec@17.0.0fetchedOption 2 (date a tombstone offline without the tag) is not in this PR; it needs a design call. The 17.0.0 tag (
56724c5005) is older than the old anchor, so a[RETIRED]mark in the anchor does not by itself prove the line predates the cut. An offline dating source would mean committing the tag's retired set in-tree (a field the re-anchor writes, or a separate snapshot) and verifying it against the tag wherever origin is reachable, the way the anchor itself is verified (#5235). That changes the gate's trust model, which today trusts the tag because a PR cannot write it.The pin is deliberately stricter than the gate on one shape: a tombstone in a def still on the surface but unreachable from the metadata roots (proof 2) also counts, since only the generator's Zod graph can tell reachability. At the old anchor the pin reports 45 lines: the 38 the offline gate refused plus 7 it proves unreachable. It errs toward a re-anchor, never toward a broken offline build. A PR that ages out tag-dated tombstones will now see this pin red on its own diff; its remedy there is an exact
src/migrations/entries/retired-keys/entry per key (check (b2) accepts a row for an aged-out key), or a re-anchor once the deletion is on main.Verification
7eb613c39f).7eb613c39f; red at the previous anchor (45 lines listed).pnpm --filter @objectstack/spec check:authorable-surface: exit 0 online.node scripts/docs-audit/check-affected-docs.mjs: exit 0; the spec tests that read the anchor (7 retirement tests,renamed-defs,check-generated-ledger, the new pin): 142/142.check:scripts-typecheck,check:test-typecheck,check:cross-package-test-inputs,check:test-source-alias,check:agent-test-spelling,check:shard-attestation: all exit 0. ESLint on the new file: clean.@objectstack/spectarball (filesholds neither), so this PR publishes nothing;skip-changeset.Clause-②: no
Metadata-protocol: none
Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01QUs3Bshfmr8srPY21BVS4u