Skip to content

docs(adr): retire ADR-0006 D1 by execution — the three retained-project surfaces are renamed (#12867) - #12908

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-12867-adr0006-d1-retirement-addendum
Aug 28, 2026
Merged

docs(adr): retire ADR-0006 D1 by execution — the three retained-project surfaces are renamed (#12867)#12908
os-zhuang merged 2 commits into
mainfrom
claude/issue-12867-adr0006-d1-retirement-addendum

Conversation

@hotlong

@hotlong hotlong commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

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 project spelling 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:

  1. SDK method namespaceprojects block becomes environments, nested package methods become client.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)
  2. Control-plane response keysproject / projects become environment / environments at eight emission sites: five in packages/service-cloud/src/routes/environment-crud.ts, three in packages/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)
  3. The JSDoc sentence — now names the endpoint (POST /api/v1/cloud/environments) rather than a server class, because the class D1 named has zero hits in cloud's packages/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 a project key and emits no database key 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:

  • New addendum appended after the first, heading ## 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).
  • Status line extended, not rewritten — the pattern ADR-0053 uses to carry several addendum pointers on one Status line (**Partly superseded (…)**, **Extended (…)**).
  • D1 marked RETIRED in place with a one-line block quote, its text left otherwise untouched — the **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-changeset label carries it. Derived from .github/workflows/pr-automation.yml: the changeset-check job has no path-based exemption — every PR needs either a changeset or the skip-changeset label (the workflow's own comment notes an empty-frontmatter changeset counts too, and calls it "on par with the skip-changeset label"). 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/objectstack on the actual changed path (5 families matched — two more than the dispatch anticipated), plus check:nul-bytes for any edit. Each exit code captured before any pipe; verdicts quoted from each gate's own output.

Gate Result
check:doc-authoring ✓ doc authoring guard: 392 files clean — no bare metadata literals.
check:pm-governed-merges ✓ check-governed-merges --self-test: 206 assertions
check-adr-links.mjs ✅ check-adr-links: 571 relative link destination(s) under docs/adr/ resolve
check:doc-formula-expressions ✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 425 files / 1453 TS blocks judged clean (needed @objectstack/formula and @objectstack/lint built first; the two PREREQUISITE-NOT-MET exits before that measured nothing)
check:nul-bytes check-nul-bytes: OK (scanned 7176 text file(s) … no raw ASCII control bytes)
check:adr-anchors RED, and pre-existing on origin/main — not caused by this PR (see below)

check:adr-anchors is red on main today

• ADR-0006 D4 is cited by 1 file(s), but ADR-0006 declares no D4 —
    it decides: D1, D1.1, D1.2, D1.3, D2, D3
    packages/spec/src/data/object.zod.ts

Measured, 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 (diff of 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 D4 citation 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 on main for every PR until either the citation is respelled or ADR-0006 gains the letter the code claims. Inventing a D4 in 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.sh could not take the shared verify lock on this host: no usable flock. The shared verify lock is declared Linux-only (flock is 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/main at 0c2334f6c, with PR #12736's merge commit ac35e2a2a7f8c05e28cfab50dd6a0b0406adfdcf verified 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 is 9694cf67d and 469006493 no longer resolves on the branch. The readings transfer exactly, and that is mechanically checkable rather than asserted: both commits carry the identical tree 0ba6b298c13604057084d577bf95ffe39eed7911 and the identical parent 0c2334f6c. 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

…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.
@os-zhuang
os-zhuang force-pushed the claude/issue-12867-adr0006-d1-retirement-addendum branch from 4690064 to 9694cf6 Compare August 28, 2026 08:16
@os-zhuang
os-zhuang marked this pull request as ready for review August 28, 2026 10:36
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.
@hotlong

hotlong commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

Freshness merge — check:adr-anchors red is cleared

Merged origin/main into this branch (normal merge commit, normal push — no rebase, no force). Merge commit 2eae99c78, parents 9694cf67d + 33b52fe0b.

Why a merge rather than a workflow rerun. The red was the phantom-ADR-0006 D4 assertion, pre-existing on this branch's older base. PR #12917 removed that citation on main at 09:18Z, but a workflow rerun reuses the original merge snapshot, so only a new commit on a fresher base can move the verdict.

This branch's own content is unchanged by the merge — the ADR file's blob id is 7ba992b73e2b15585df76f411dd6fc209cc6bac0 both before and after, and the branch's own diff against the new base is still exactly one file, +131/-1.

Gate union re-derived and re-run on the merged head 2eae99c78, all six green (exit codes captured before any pipe):

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

@os-zhuang
os-zhuang added this pull request to the merge queue Aug 28, 2026
Merged via the queue into main with commit abeb566 Aug 28, 2026
25 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-12867-adr0006-d1-retirement-addendum branch August 28, 2026 14:15
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/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ADR-0006 D1 retirement addendum: record that D2 executed and the three retained-project surfaces are renamed

2 participants