Skip to content

docs(adr): ADR-0130 — the release artifact is the co-ownership boundary (one artifact, N packages) - #14151

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14144-adr-one-artifact-n-packages
Sep 1, 2026
Merged

docs(adr): ADR-0130 — the release artifact is the co-ownership boundary (one artifact, N packages)#14151
os-zhuang merged 1 commit into
mainfrom
claude/issue-14144-adr-one-artifact-n-packages

Conversation

@os-sam

@os-sam os-sam commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Fixes #14144
Part of #14122 (epic)

Adds docs/adr/0130-release-artifact-as-co-ownership-boundary.md, Status: Proposed. Prose only — one new file, nothing outside docs/adr/**, no implementation code, no schema edits.

What it decides

Compile per package, ship one JSON, keep N manifests inside it, register N packages in dependency-topological order at load time. Eight decision letters:

  • D1 — the release artifact is the co-ownership declaration; the install gate's criterion moves from "same package id" to "co-owners within one artifact".
  • D2 — the ADR-0019 consumer model does not move a letter; the artifact stops at the control plane and must never become the suite D3 removed.
  • D3 — the §5.4 gate relaxation and the §5.6 install-time per-object-name uniqueness check are mechanically inseparable: same PR, plus a gate test asserting the pair, asserting the error code and status (ADR-0112 envelope) rather than a bare throw.
  • D4 — artifact schema gains an optional packages: [...]; manifest is retained and both shapes are read. Forward compatibility rides manifest.engines.protocol. The segmented-loading key position is reserved at schema time, deliberately unimplemented.
  • D5 — topological ordering is a machine acceptance criterion, by reuse of resolvePluginOrder; no second sorter. The pin is behavioural (extension-before-base installs and the extension is in effect), because a permutation assertion passes on an implementation that computes the order and never uses it.
  • D6 — one artifact, one version, with the "no per-module hot-fix" cost stated plainly.
  • D7 — existing single-manifest artifacts register bit-identically through the new path, as an automated test rather than a review judgement.
  • D8 — no manifest owner/publisher field; deferred with a named trigger, aligned to the ADR-0048 2026-08-08 addendum D2.

⛔ No original text of ADR-0019 or ADR-0048 is edited. The boundary is recorded here by cross-reference, per the additive-addendum convention 0048 itself uses.

Governed surface — this PR stays draft

node scripts/pm/check-governed-merges.mjs --test docs/adr/0130-release-artifact-as-co-ownership-boundary.md

governed-surface predicate: 1 of 1 path(s) hit the register (5 surfaces, repo-agnostic).
  GOVERNED — a human merge is the review record for this PR (#9495 regime).
      docs/adr/** x1 — architecture decision records

Verdict: GOVERNED. This PR awaits the maintainer: it stays draft, is never flipped ready, never enqueued, and never has auto-merge armed. The hand-merge is itself the acceptance act for the ADR — Status stays Proposed until then.

Changeset

skip-changeset label applied — no changeset file. The diff publishes nothing from any package: one file, docs/adr/** only. pr-automation.yml reads the label live rather than from the event payload, and the label is applied additively (POST) with a read-back, per that workflow's own recorded size-labeler race.

Verification — all on the final commit 341b9e9

Derived family (node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, 5 families) — all green:

gate verdict
pnpm check:adr-anchors OK (52 anchored file(s) ... 128 decision number(s), each naming one decision or an allowlisted pair; 30918 citation(s) across 3981 file(s) resolve)
pnpm check:doc-authoring 395 files clean · 48 published skill files clean · 14317 customer-facing string(s) ... clean
pnpm --filter @objectstack/lint run check:doc-formula-expressions exit 0
pnpm check:pm-governed-merges 243 assertions self-test pass
node scripts/check-adr-links.mjs 598 relative link destination(s) under docs/adr/ resolve

check:doc-formula-expressions first returned exit 3 = PREREQUISITE NOT MET (@objectstack/formula then @objectstack/lint not built) — not a finding and not a measurement. Both packages were built and the gate re-run to a real exit 0.

Full Lint & Repo Gates job, not just the derived family. The job's 138 steps were harvested from lint.yml and each runnable one executed locally against this commit: 4 are uses: actions (checkout / setup-node / setup-pnpm / cache), 134 are run:, and zero carry an if: — so CI runs every one of them on every PR. 132 of the 134 ran green; the 2 not run are pure CI setup with no local meaning (Get pnpm store directory, which writes $GITHUB_ENV, and Install dependencies / pnpm install --frozen-lockfile, already satisfied in the worktree). That includes ESLint (pnpm lint, repo-wide, exit 0 under the shared verify lock) — no narrowing was taken and none is claimed.

Exit codes were captured before any pipe (redirect, then $?); each verdict above quotes the gate's own printed line, never a bare $?.

Where the proposal's citations did not survive re-verification

Recorded in the ADR's §7 rather than quietly corrected:

Every other anchor was found exactly as described: registry.ts:1456, the installPackage gate at :3575/:3583/:3595, getNamespaceOwners at :1540, unregisterObjectsByPackage at :2679, plugin.ts:405, stack.zod.ts:240/:854/:1759, RESERVED_NAMESPACES at registry.ts:45 with isShareableNamespace at :1116, and ADR-0048's rename-on-install non-goal in all three recorded places.

Open for the maintainer's merge decision

Listed in the ADR's §6: (1) D8's deferral of the owner field — #14122 待决策 ⑤ asked explicitly whether it should land with ADR-0048 addendum D2 instead; (2) whether the ADR-0019 boundary should additionally get a one-line Related entry on 0019 (0019's own text is not rewritten either way); (3) acceptance of D6's "no per-module hot-fix" cost.

Follow-up implementation cards are cut after this record merges, not before — including the Studio package-picker row, which is objectui-side and gets a cross-repo card against that repository linked to the #14122 epic.

Generated by Claude Code


Generated by Claude Code

…ry (one artifact, N packages)

Records the decision chartered on #14144 (epic #14122): compile per package,
ship one JSON, keep N manifests inside it, register N packages in dependency
topological order at load time.

Status: Proposed — governed surface, awaiting the maintainer's hand-merge.

Part of #14122

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015adLit3ZYASJiXwxKG78Wi
@os-zhuang
os-zhuang marked this pull request as ready for review September 1, 2026 09:02
@os-zhuang
os-zhuang requested a review from hotlong as a code owner September 1, 2026 09:02
@os-zhuang
os-zhuang enabled auto-merge September 1, 2026 09:02
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 1, 2026
Merged via the queue into main with commit 682d03b Sep 1, 2026
29 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14144-adr-one-artifact-n-packages branch September 1, 2026 09:21
os-steve pushed a commit that referenced this pull request Sep 5, 2026
… by its landing merge

The record's Status line said "Proposed — awaiting the maintainer's hand-merge,
which is itself the acceptance act". A reader can only reach that line because
the file is on `main`, i.e. because the hand-merge already happened, so the
sentence disproves itself and names an event that can never occur again. It is
also read as a gate: one seat has "re-read the Status line, never assume" in its
standing check-in, which makes it a pause with no end condition.

The line now carries the state and the act only, in the spelling ADR-0125
already uses: the landing merge, its PR, its commit and its date.

Landing reading (the ORIGINAL landing, not the 2026-09-03 anchor migration):
`git log --follow --diff-filter=A` and the REST commit list agree on
`682d03ba7` (2026-09-01, `added` this path), whose message names PR #14151;
`GET /pulls/14151` reports `merged: true`, `base.ref: main`,
`merge_commit_sha: 682d03b...`, `merged_by.login: os-zhuang` — a human
approver, which is the precondition the ruling sets for treating the merge as
the acceptance act.

Part of #15453

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
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/l 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:发布物作为共同所有权边界 —— 一个发布物、物内 N 个包(#14122)

3 participants