docs(adr): retire ADR-0006 D1 by execution — the three retained-project surfaces are renamed (#12867) - #12908
Conversation
…ect` surfaces are renamed (#12867) D2 was pre-registered to reopen at the next SDK/protocol breaking major. The maintainer's 2026-08-28 ruling on the epic card opened that window, so D2 fired and D1's three deliberately-retained surfaces are renamed with no aliases. Adds a second dated addendum recording the retirement, extends the Status-line pointer, and marks D1 in-body as RETIRED while leaving its text intact so the record of why the surfaces were retained stays legible.
4690064 to
9694cf6
Compare
Freshness merge only — no content change of this branch's own. Picks up PR #12917, which stopped packages/spec's namespace tombstone citing the phantom ADR-0006 D4 and so clears the pre-existing check-adr-anchors red that this branch's older base still carried. A workflow rerun could not clear it: a rerun reuses the original merge snapshot, so a new commit on a fresher base is the only thing that moves it.
Freshness merge —
|
| Gate | Exit |
|---|---|
check:adr-anchors |
0 — was 1 |
check:doc-authoring |
0 |
check:pm-governed-merges |
0 |
check-adr-links.mjs |
0 |
check:doc-formula-expressions |
0 |
check:nul-bytes |
0 |
Both anchors legs now pass on their own verdict lines: ✓ check-adr-anchors --self-test: 106 assertions and check-adr-anchors: OK (52 anchored file(s) … 881 decision-letter citation(s) on the anchored surface name a decision the record makes). The remaining 36 unverifiable citations are the soft #9592 note, down from 37 — this ADR's site is the one that left.
⚠️ This PR is no longer a draft, and that was not part of the work above
Flagging rather than reverting, because reverting another actor's ready-flip is not mine to do.
Measured on the timeline:
2026-08-28T10:36:55Z review APPROVED os-zhuang
2026-08-28T10:36:58Z ready_for_review os-zhuang
2026-08-28T13:15:56Z merge commit 2eae99c78 (the freshness merge above)
The flip happened about two and a half hours before the merge push, so pushing did not cause it — a plain push cannot change draft state. The os-zhuang review request that stood earlier is gone because that review was submitted.
Why this matters here specifically: this PR is on a governed surface (docs/adr/**) whose regime is draft-only, human merge, never auto-merge, and its body carries a hard landing constraint — it must not merge before the two rename PRs it records (#12885 and objectstack-ai/cloud#1692, both still parked drafts). The PR is now un-drafted, approved, and MERGEABLE, which is precisely the state that allows it to land early. Merging it ahead of the rename halves would leave ADR-0006 asserting a retirement the code has not performed.
No action taken on the PR state. Over to the epic PM and the maintainer to decide whether to restore draft or hold it by the window instead.
Generated by Claude Code
Fixes #12867
Part of #12865
⛔ Landing constraint — read before touching this PR
Governed surface (
docs/adr/**): DRAFT only, human merge, never un-draft, never arm auto-merge.This PR must land in the SAME coordinated window as the two rename PRs it records, and not before them:
Merging this addendum while either rename PR is still parked leaves the ADR asserting a retirement the code has not performed. That is the one failure mode an ADR recovers worst from, because the next reader trusts the record over the code. If the window slips, this PR waits with the others.
What this is
ADR-0006's first addendum (PR #12736, merged 2026-08-28) recorded D1 — three API surfaces keep the
projectspelling deliberately — and D2, pre-registering the full rename to fire "at the next planned SDK/protocol breaking major". The maintainer's 2026-08-28 ruling on the epic card #12865 opened that window (recorded there verbatim and untranslated: 「作为 epic 卡,处理所有相关任务和开发」), and D2 executed.D2's own closing instruction was to "retire this addendum's D1 in the same release rather than adding an alias to soften it." This PR is that retirement — the record half only; no code rides it.
The three surfaces, and what the executing PRs actually do
Cited by quoted phrase, never line number — the convention D1 set for itself after its own predecessor's line-number anchor went stale. Every claim below was measured against the two PRs' diffs, not copied from the card:
projectsblock becomesenvironments, nested package methods becomeclient.environments.packages.*, no aliases. (PR ADR-0006 D2 (SDK half): rename client.projects.* to client.environments.*, unwrap keys follow the wire, JSDoc names the endpoint (#12866) #12885)project/projectsbecomeenvironment/environmentsat eight emission sites: five inpackages/service-cloud/src/routes/environment-crud.ts, three inpackages/service-cloud/src/routes/environment-lifecycle.ts. Counted from the diff in both directions (5+3 removed, 5+3 added). (cloud PR feat(spec)!: trim ChartTypeSchema to distinctly-renderable families #1692)POST /api/v1/cloud/environments) rather than a server class, because the class D1 named has zero hits in cloud'spackages/service-cloud. Verified independently here by a repo-wide grep of a local cloud checkout: zero hits there too. (PR ADR-0006 D2 (SDK half): rename client.projects.* to client.environments.*, unwrap keys follow the wire, JSDoc names the endpoint (#12866) #12885)The addendum also records a correction that only executing D1 could surface: D1 quoted the SDK's declared create shape as
{ project: any; database: any }, and that declaration was not merely pre-rename but false against the running control plane — the create route never emitted aprojectkey and emits nodatabasekey at all. PR #12885 corrects it to{ environment: any }rather than transliterating it.How the file was edited, and why in three places
Conventions were measured in
docs/adr/, not assumed:## Addendum (2026-08-28, #12867) — …. That dated-heading-with-card-number shape is the dominant convention across the corpus (0019, 0053, 0087 and others carry 4–7 addenda that way).**Partly superseded (…)**,**Extended (…)**).**Config.** RETIRED 2026-08-27 (#11982, …)shape from ADR-0025. D1's body is kept verbatim because it is the record of why the surfaces were retained and what the retention cost, and because D2 was drafted against those exact phrases. An ADR's history stays legible; the marker prevents the section being read in the present tense.New sub-headings are deliberately spelled differently from the first addendum's (
### What this retirement does not change,### Why this rides ADR-0006 rather than a new record) so the two addenda do not generate duplicate anchor slugs.The card asked for a neutral pointer at most on the fourth
project-spelled surface: the addendum gives it one sentence naming #12882 as separately adjudicated and takes no position.Changeset — derived, not copied
No changeset file; the
skip-changesetlabel carries it. Derived from.github/workflows/pr-automation.yml: thechangeset-checkjob has no path-based exemption — every PR needs either a changeset or theskip-changesetlabel (the workflow's own comment notes an empty-frontmatter changeset counts too, and calls it "on par with theskip-changesetlabel"). This PR publishes nothing. The label route also keeps the diff to the single declared file, which the changeset-file route would have breached. Precedent matches: predecessor PR #12736 touched this same ADR alone and carried exactly this label.Gates
Derived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstackon the actual changed path (5 families matched — two more than the dispatch anticipated), pluscheck:nul-bytesfor any edit. Each exit code captured before any pipe; verdicts quoted from each gate's own output.check:doc-authoring✓ doc authoring guard: 392 files clean — no bare metadata literals.check:pm-governed-merges✓ check-governed-merges --self-test: 206 assertionscheck-adr-links.mjs✅ check-adr-links: 571 relative link destination(s) under docs/adr/ resolvecheck:doc-formula-expressions✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 425 files / 1453 TS blocks judged clean(needed@objectstack/formulaand@objectstack/lintbuilt first; the two PREREQUISITE-NOT-MET exits before that measured nothing)check:nul-bytescheck-nul-bytes: OK (scanned 7176 text file(s) … no raw ASCII control bytes)check:adr-anchorsorigin/main— not caused by this PR (see below)check:adr-anchorsis red onmaintodayMeasured, not argued: the gate's output is byte-identical with this branch's file and with
origin/main's version of it restored in place (diffof the two runs is empty). The citing file,packages/spec/src/data/object.zod.ts:1467, is outside this PR's declared single-file surface and is untouched here.This is already filed as #12786, which names this exact site. One thing has changed since that card was measured, and it is worth the triage seat's attention: #12786 recorded ADR-0006 as declaring no decision letters, so the
D4citation scored a soft "cannot verify" note. PR #12736's addendum gave ADR-0006 a real letter index (D1 … D3), which flips that same citation from an advisory note into a hard failing assertion. The gate is red onmainfor every PR until either the citation is respelled or ADR-0006 gains the letter the code claims. Inventing aD4in this addendum was rejected: this card retires D1, it does not decide namespace retirement, and manufacturing a decision letter to green a gate is exactly the defect the gate names.Declared narrowing — verification ran UNLOCKED
scripts/pm/os-verify-lock.shcould not take the shared verify lock on this host: no usableflock. The shared verify lock is declared Linux-only (flockis util-linux, and a stock macOS does not ship it), so the commands were run directly, without the lock — a declared narrowing, not a silent one. No serialization guarantee held for this run, nor for any sibling agent in this container while it ran. (The entry point printed this wording itself and instructed that it be declared here.)Verification base
Branched from
origin/mainat0c2334f6c, with PR #12736's merge commitac35e2a2a7f8c05e28cfab50dd6a0b0406adfdcfverified as an ancestor — the addendum this PR retires is genuinely on the base.Where the gate union ran, and why its readings still apply. The gate union above ran on this branch's pre-rewrite commit
469006493. That commit was afterwards rewritten in place to correct its author identity only (maintainer-directed; content deliberately untouched), so the current head is9694cf67dand469006493no longer resolves on the branch. The readings transfer exactly, and that is mechanically checkable rather than asserted: both commits carry the identical tree0ba6b298c13604057084d577bf95ffe39eed7911and the identical parent0c2334f6c. The gate union therefore ran against byte-for-byte the tree under review now — the rewrite moved commit metadata, not one byte of content.Authored by Claude Code session
session_65d2faee-1ff4-4be8-be28-72b972c539d9, recorded here in prose so the attribution survives edits to this body.Generated by Claude Code