Skip to content

docs(adr-0146): D8 item 3 names the whole-deployment export GET /packages/export, the per-package exports composed unchanged, the pair after its base - #29830

Merged
os-zhuang merged 2 commits into
mainfrom
claude/project-thread-kr1zkm
Nov 3, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/project-thread-kr1zkm

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread
Fixes #29802

Clause-②: no
Metadata-protocol: none

维护者速读

What changes

One sentence in ADR-0146 D8 item 3, after the two per-package routes it already names: the whole-deployment export GET /packages/export (#28914) composes those per-package exports unchanged — every installed package the deployment's own code does not register, each entry exactly what its own GET /packages/:id/export answers, in ADR-0141 D5's hydrate order, so a .custom pair comes after its base when both are listed, and the pair of a code-registered base (item 1's code package) is exported alone, that base travelling with the deployment's code and not with the bundle — and adds no reading of its own, with the two symbols anchored (packages/runtime/src/domains/packages.ts#assemblePackageExportBundle, packages/spec/src/api/package-lifecycle.zod.ts#PackageExportBundleSchema). Refs gains a dated entry naming #29802, this PR, #29755 and #28914. No code, no schema, no other ADR. The second commit answers the contract review's two should-fixes (6597286611): the pair-after-base clause now says when it holds and what happens to the pair of a code-registered base (the PackageExportBundleSchema docblock's "a pair of a code base is still exported"), and the Refs entry names this PR beside the card, as the #29791 entry does.

Item 3 rather than a Refs-only entry: the card's reach is a reader of D8 learning which export carries a paired override, and item 3 is where the two per-package routes are named; a Refs entry is provenance, not where that reader looks. The sentence states what the code already does and decides nothing new, so there is no **Amended in place** entry on the Status line — the file's own convention (kept by #29791) reserves that for rulings that change a decision; the dated Refs entry is the provenance, in the shape #29791's entry set.

Why

Measured on origin/main b0ef25f5 before writing:

  • assemblePackageExportBundle (packages/runtime/src/domains/packages.ts, declaration at line 3616, docblock from line 3598): skips every registry row whose source is code, lists the rest once, orders them with orderHydrationBatch (packages/core/src/hydration-order.ts, ADR-0141 D5's one sorter) over declaredDependencyIds(row.manifest) (packages/core/src/artifact-packages.ts), and pushes, per id, the answer of assemblePackageManifest(deps, id, registry, context) — the same call with the same arguments the per-package route GET /packages/:id/export serves at line 2599 (deps.success(manifest)). Nothing is assembled, cleaned or redacted a second way; a package whose export cannot be assembled fails the whole read.
  • PackageExportBundleSchema (packages/spec/src/api/package-lifecycle.zod.ts, line 332): its packages description says each entry is "as GET /packages/:id/export answers it, dependencies first … so a .custom pair comes after its base"; the docblock's One producer section says the same.
  • ADR-0146 D3 has the pair declare its base in manifest.dependencies, so the sorter places the pair after its base whenever both are listed; ADR-0141 D5's Decided paragraph is the hydrate order the sorter implements.
  • ADR-0146 D8 items 2 and 3 (as clarified by docs(adr-0146): D8 item 2 names the pair's export, GET /packages/X.custom/export, never the base's #29791) name only GET /packages/X.custom/export and GET /packages/X/export; nothing in the record contradicts the bundle, and nothing names it. The premise holds.

Tests

Docs-only; no test changes and no ablation (a documentation edit is not ablated). The derived gate families ran locally at the pushed head (Verification).

Acceptance notes

  • skip-changeset: docs/adr/** publishes nothing (the fast lane of the changeset rule); the label rides pr_create.
  • pnpm lint is the repo-wide eslint scan CI owns; the diff has no lintable source, and the docs/adr families the derivation names ran locally instead (Verification).

Verification

Head 65f1b7ce on origin/main b0ef25f5: two commits (the second answers the contract review's should-fixes), one file, +13/−2. The same 21 derived gates ran at both heads, 42951327 and 65f1b7ce, with the same verdicts.

  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 21 commands (13 by path, 8 whole-tree). All 21 ran from the worktree at each head with the exit code captured before any pipe: 21 exit 0, 0 non-zero, both times.
  • Prerequisite for check:doc-formula-expressions: @objectstack/formula and @objectstack/lint built under the verify lock — os-verify-lock: VERDICT command-exit 0 · held the lock 163s at the first head, a turbo cache hit (4 cached, lock held 6 s) at the second.
  • node scripts/pm/dispatch-gates.mjs --ran ran-all.list --repo objectstack-ai/objectstack: Run reconciliation — 21 derived, 21 run, 0 NOT-MEASURED, 0 UNRUN. (exit 0), at both heads.
  • check:adr-symbol-anchors counts: origin/main b0ef25f5 answers 3050 anchors, 735 symbol (708 declaration); each head answers 3052 anchors, 737 symbol (710 declaration) — the two new path#symbol anchors resolve at their declaration sites.
  • --tier: the mandated tier for docs/adr/** holds (recorded on the claim's Container & model line); changed lines 15 vs the human-merge threshold 3000: under.

Exit 0: check-adr-links (+ --self-test), check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, ci/plan-test-core-shards --self-test, lint check:doc-formula-expressions, check:adr-anchors, check:adr-index, check:adr-symbol-anchors, check:ci-filter-parity, check:closed-ceremony-text, check:cross-package-test-inputs, check:doc-authoring, check:driver-memory-census, check:gitlink-declared, check:nul-bytes, check:pm-governed-merges, check:pm-prior-rulings, check:refd-timer-probe, check:watch-hint-literal.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (untouched)
  • 2. Every name I added uses the casing for its kind. (no names added)
  • 3. No formatter ran; pnpm lint passes. (the CI-owned repo scan; the derived docs/adr families ran locally)
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. (publishes nothing: skip-changeset; both lines above)
  • 6. packages/spec touched: its generated artifacts are regenerated and committed. (untouched)
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English. (the 维护者速读 block is the dispatch contract's maintainer digest)
  • The Before Submitting list in CONTRIBUTING.md is done.

Generated by Claude Code

…kages/export, as the per-package exports composed unchanged, the pair after its base

One sentence in D8 item 3 and one dated Refs entry. No code, no schema,
no other ADR.

Claude-Session: https://claude.ai/code/session_01JQwxbZL4zwPNbxQsb6VsoU
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Nov 3, 2026
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Nov 3, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#2 · os-warren · session_01JQwxbXKRzgnVvjzxaYxLUf

Contract-review-claim: session_01JQwxbXKRzgnVvjzxaYxLUf · head 4295132 · 2026-11-03T06:37Z

Face: ADR (docs/adr/0146-studio-designs-setup-administers-one-editor-per-item-paired-customize-package.md, D8 item 3 plus a dated Refs entry; Tier H), at CONTRACT_REVIEW_TIER by the seat's at-tier reviewer.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#2 · os-warren · session_01JQwxbXKRzgnVvjzxaYxLUf

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 42951327fe992ee52247491260c7654e55a6dbf6
Local-runs: none
Scope: docs/adr/0146-studio-designs-setup-administers-one-editor-per-item-paired-customize-package.md + packages/runtime/src/domains/packages.ts, packages/spec/src/api/package-lifecycle.zod.ts, packages/core/src/hydration-order.ts, packages/core/src/artifact-packages.ts, packages/spec/src/kernel/package-registry.zod.ts, docs/adr/0141-inter-app-dependency-declared-checked-before-install.md, packages/client/src/index.ts, packages/cli/src/commands/package/export.ts

PR #29830 (card #29802) at 42951327, one commit on origin/main b0ef25f5 (merge-base; origin/main has since moved one commit, #28903, which does not touch any file in scope). One file, +10/−2: one sentence in ADR-0146 D8 item 3 and one dated Refs entry. The face is rules (docs/adr/**, a governed path), so the whole diff is the hits set; there is no lane-seat remainder. Inputs read: the card body and all three comments (triage 6596568396, claim 6596863611, os-dev-report 6597153981), the PR body and file list, the net diff, the check-runs on the head, and the cited code on origin/main.

Check-runs on the head at the time of this record: every non-skipped run has completed success except Test Core (1/8), still in_progress. The gate families this diff derives are green in CI: Check Documentation Links (check-adr-links), Lint · repo & tooling gates (check:adr-anchors, check:adr-index, check:doc-authoring), Lint · docs & code guards (check:adr-symbol-anchors), Lint & Repo Gates, Check Changeset, Governed Surface Queue Guard, PR-body guards.

① Derived judgments

② Semver level

skip-changeset is right: docs/adr/** publishes nothing, the label is on the PR, and Check Changeset is green. The PR body carries Clause-②: no with no arm, which matches the tree: nothing widens, nothing narrows, and a tree with no changeset carries no narrowing declaration. Metadata-protocol: none is right (the protocol is untouched). The tier is decided by the governed path (rules face), not by the Clause-② line.

③ Boundary flags

open_questions is empty. The os-dev-report lists five deviations; each answered:

  1. Post-create assignees/reviewers skipped — consistent with the order (no GitHub MCP, no reviewer request); the PR shows none. Answered: the seat's landing path owns it.
  2. Commit trailer carries the model-free pair — verified on the commit: Claude-Session: https://claude.ai/code/session_01JQwxbZL4zwPNbxQsb6VsoU and Co-authored-by: Claude with the noreply@anthropic.com address, the pair AGENTS.md (line 446) requires. Answered.
  3. No PR-activity subscription or CI wait — the seat owns review and landing; every derived family is now green on the head (above). Answered.
  4. Refs entry names docs(adr): ADR-0146 D8 names the whole-deployment export GET /packages/export (each package's own export, the pair after its base) #29802, feat(runtime,client,cli): export a deployment's whole ontology as installable packages in one read (GET /packages/export, os package export) #29755 and packages: a tenant exports its whole ontology — every installed package, its .custom pair and environment customizations — as installable packages for the open runtime (os package export + the read it calls) #28914, not this PR — carried into ④ as should-fix 2; the dev offered the rework round for it.
  5. Worktree removed after the report — procedural; rework re-creates it from the branch. Answered.

Security findings: none, and none owed by a docs-only diff. Out-of-scope findings: none reported, none found.

④ Design judgment

docs/adr/0146-…md, D8 item 3 — the sentence, clause by clause against the live tree.

  • "composes those per-package exports unchanged" — holds. assemblePackageExportBundle pushes, per id, assemblePackageManifest(deps, id, registry, context): the same function with the same four arguments the per-package route GET /packages/:id/export serves (deps.success(manifest)), and the docblock's ⛔ forbids assembling, cleaning or redacting a second way.
  • "every installed package the deployment's own code does not register" — holds. The loop is if (row?.source === 'code') continue;; source is required on InstalledPackageSchema and InstalledPackageSourceSchema defines code as "registered by the deployment's own code". The gloss is the schema description's own and client.packages.exportAll()'s docblock's.
  • "each entry exactly what its own GET /packages/:id/export answers" — holds, as above. The bundle door adds a closed-query refusal the per-package door does not have; that is a door rule, not an entry difference.
  • "in ADR-0141 D5's hydrate order" — holds. The bundle sorts with orderHydrationBatch (packages/core/src/hydration-order.ts, whose header is "ADR-0141 D5 — the order a boot hydrates its installed packages in") over declaredDependencyIds(row.manifest) (the keys of manifest.dependencies); ADR-0141 D5's Decided paragraph is exactly that: both hydrate paths order their batch by manifest.dependencies through resolvePluginOrder, declared ids as optional edges, a cycle degrading to source order.
  • "so a .custom pair comes after its base" — holds when both are in the bundle: ADR-0146 D3 has the pair declare its base in manifest.dependencies, which is the one edge the sorter reads. See should-fix 1 for the case the sentence leaves to inference.
  • "adds no reading of its own" — holds in D8's vocabulary ("one effective read"; a reading is a resolution of an item's content): the docblock's ⛔ is exactly that no item is resolved a second way. The bundle's one act of its own is listing the registry rows, which is not a reading of any item.
  • The two anchors — both resolve at declaration sites (①).

Against the first consumer. os package export (packages/cli/src/commands/package/export.ts) reads client.packages.exportAll() and writes one numbered directory per entry in the read's order, "and this command never re-sorts it"; exportAll's docblock says the same ("dependencies first, so a .custom pair follows its base… never re-sort them"). The order clause the sentence states is the one the consumer relies on, so the ADR, the schema, the runtime and the consumer now say one thing.

Against the execution plan. ADR-0146's Rollout lists the N-numbered cards of epic #28236; #28914 is not one of them and the sentence cites it as landed, deciding nothing, so no rollout row is owed and "this record declares; it implements nothing" is not strained. The sentence is consistent with item 2's "⛔ never GET /packages/X/export" and with Decided here #5 ("travels in the pair's export, never the base's"): the bundle carries both entries, the base's unchanged and the pair's with its overrides block, which is exactly item 3's split applied entry by entry. D8's "five reads" framing survives because the bundle is composition, not a sixth resolution.

Attempts to break it that found nothing. The error path (a package whose export cannot be assembled fails the whole read) is not claimed either way by the sentence and is the schema's rule; a D8 reader is not asking it. Disabled packages are "installed" in the registry sense and the sentence says nothing that excludes them. The bare (#28914) follows the body's own style ((#28238, N-03), (#28241, N-27)); GET /packages/:id/export is the form lines 97 and 195 already use. Two Refs lines exceed 120 columns, as link-bearing Refs lines already do across the file (136 such lines on main); check:doc-authoring is green.

Findings.

No must-fix. The change holds against the code it cites, the schema it mirrors, the consumer that reads the bundle, and the ADR's own conventions.

Implemented-by: claude/project-thread-kr1zkm
Reviewed-by: at-tier reviewer for session_01JQwxbXKRzgnVvjzxaYxLUf

VERDICT: PASS


Generated by Claude Code

…Refs entry names PR #29830

Contract review should-fixes (6597286611): the pair-after-base clause holds
when both are listed, and the pair of a code-registered base is exported
alone, its base travelling with the code; the dated Refs entry names the
PR beside the card, as the #29791 entry does.

Claude-Session: https://claude.ai/code/session_01JQwxbZL4zwPNbxQsb6VsoU
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#2 · os-warren · session_01JQwxbXKRzgnVvjzxaYxLUf

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 65f1b7cea7704e9d3a9ade70bc3c3898eab111c4
Local-runs: none
Scope: docs/adr/0146-studio-designs-setup-administers-one-editor-per-item-paired-customize-package.md + packages/runtime/src/domains/packages.ts, packages/spec/src/api/package-lifecycle.zod.ts, packages/core/src/hydration-order.ts, packages/core/src/artifact-packages.ts, packages/spec/src/kernel/package-registry.zod.ts, docs/adr/0141-inter-app-dependency-declared-checked-before-install.md, packages/client/src/index.ts, packages/cli/src/commands/package/export.ts

Delta record on PR #29830 (card #29802), building on the PASS record 6597286611 on 42951327. The new head 65f1b7ce is a fast-forward of that head on origin/claude/project-thread-kr1zkm (one commit added, 42951327 an ancestor), on the same merge-base b0ef25f5. The inter-head diff (git diff 42951327 65f1b7ce) is one file, +5/−2, and touches exactly the two should-fix sites of the prior record; the net diff against main is one file, +13/−2. Everything the prior record judged and did not name below stands unchanged on this head: the face (rules, docs/adr/**), the hits set, the scope, the absence of a lane-seat remainder, and the inputs read (the card body and its three comments, the PR body and file list, the net diff, the check-runs on the head, and the cited code on origin/main). No comment has been added to the card since the os-dev-report 6597153981; the PR carries the claim 6597183624 and the prior record 6597286611.

Check-runs on 65f1b7ce at the time of this record: 45 runs, 26 completed/success, 19 completed/skipped, none in progress and none failed. Every family the diff derives is green: Check Documentation Links (check-adr-links), Lint · repo & tooling gates (check:adr-anchors, check:adr-index, check:doc-authoring), Lint · docs & code guards (check:adr-symbol-anchors), Lint & Repo Gates, Governed Surface Queue Guard, PR-body guards, and Test Core (1/8) (in progress on the prior head) has completed success. Check Changeset reads skipped on both of this head's runs where the prior head's opened run read success: the job's own comment names the skip-changeset label as its fast-path exemption, read off the event's label snapshot; on the opened run the label was not yet in that snapshot, so the job ran and passed on its authority half, and on this head's synchronize runs the label is in the snapshot, so the job is exempt. Skipped here is "no release declared", not a gate that did not answer.

① Derived judgments

② Semver level

Unchanged: docs/adr/** publishes nothing, skip-changeset is on the PR, the PR body carries Clause-②: no with no arm and Metadata-protocol: none, and the tree carries no changeset and no narrowing declaration. Check Changeset is skipped on this head by the label exemption (above), which is the same verdict the prior head's success gave: no changeset owed.

③ Boundary flags

No new flag. The rework carries no os-dev-report on the card yet; the commit message names the prior record's two should-fixes as what it answers, and the tree confirms both (④). Of the prior record's five dev deviations, deviation 4 (the Refs entry not naming this PR) is now resolved in the tree; the other four stand answered as before. The new commit's trailer carries the model-free pair AGENTS.md requires (Claude-Session: URL and Co-authored-by: Claude with the noreply@anthropic.com address). open_questions remains empty; security findings none, none owed.

④ Design judgment

docs/adr/0146-…md, D8 item 3 — the reworked clause against the live tree. The sentence now reads "…in ADR-0141 D5's hydrate order, so a .custom pair comes after its base when both are listed, and the pair of a code-registered base (item 1's code package) is exported alone, that base travelling with the deployment's code and not with the bundle — and adds no reading of its own".

  • "comes after its base when both are listed" — holds. assemblePackageExportBundle sorts with orderHydrationBatch over declaredDependencyIds(row.manifest), and the sorter's one rule (hydration-order.ts; ADR-0141 D5's Decided paragraph) is that a declared id names an edge only when it names a node of the batch: "an id absent from the batch is not an edge". The pair's manifest.dependencies names its base (D3), so the edge exists exactly when both are listed.
  • "the pair of a code-registered base … is exported alone" — holds. The loop skips row?.source === 'code' and nothing else; the pair is an authored row (the D3 ensure door creates it), so it is listed while its code base is not. The PackageExportBundleSchema docblock says it in so many words: "A pair of a code base is still exported."
  • "that base travelling with the deployment's code and not with the bundle" — holds, near-verbatim from both cited sources: the runtime docblock ("A code row is registered by the deployment's own code and travels with it, never with the bundle") and the schema docblock ("so it travels with that code and not with the bundle: an install of the bundle never re-installs it").
  • "(item 1's code package)" — apt (①): it ties the bundle's exclusion to the ADR's own worked case, which is what the prior should-fix asked for.
  • The rest of the sentence is byte-identical to the judged head, and the prior ④ reading of it (composition unchanged, the source gloss, the same producer, ADR-0141 D5's order, no reading of its own, the two anchors) stands.

Against the first consumer and the execution plan. Unchanged: os package export writes the entries in the read's order and never re-sorts, and the clause now tells its reader that a code-registered base will not be among them, which is exactly what that consumer prints a directory for and what it does not. No rollout row is owed; nothing is decided.

Attempts to break the rework that found nothing. "Exported alone" could be read in isolation as "the only entry", but the clause that follows ("that base travelling with the deployment's code and not with the bundle") fixes the sense as "without its base", and the preceding "every installed package the deployment's own code does not register" already says other packages are listed. The clause adds no second rule for the code case; it restates the one exclusion. Line lengths of the rewrapped sentence are 61–114 columns; the Refs lines keep the file's link-bearing shape (check:doc-authoring green).

Findings. The prior record's should-fix 1 (the pair-after-base clause left the code-registered base to inference) and should-fix 2 (the Refs entry did not name this PR) are both answered in the tree. No new finding; no must-fix.

Implemented-by: claude/project-thread-kr1zkm
Reviewed-by: at-tier reviewer for session_01JQwxbXKRzgnVvjzxaYxLUf

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#2 · os-warren · session_01JQwxbXKRzgnVvjzxaYxLUf

维护者速读

席位核对

ACCEPT · domain:server#2 · head 65f1b7cea7704e9d3a9ade70bc3c3898eab111c4 · 2026-11-03T07:04Z · contract review of record at CONTRACT_REVIEW_TIER (rules face): PASS 6597286611 on 42951327, delta PASS 6597553576 on this head, by an independent at-tier subagent adopted by this seat

  1. Shape: base main, Fixes #29802, Clause-②: no, Metadata-protocol: none, skip-changeset (nothing published). Net diff 1 file, +13/−2 (docs/adr/0146-…md: one sentence in D8 item 3, one dated Refs entry). GOVERNED (check-governed-merges --pr 29830, docs/adr/** 1 of 1 path): landing tier H.
  2. Premise measured: assemblePackageExportBundle skips only source === 'code' rows and orders by orderHydrationBatch over declared dependencies (ADR-0141 D5), pushing the same assemblePackageManifest answer the per-package route serves; the PackageExportBundleSchema docblock says a pair of a code base is still exported. Both new path#symbol anchors resolve (review ①, both rounds).
  3. Gates on this head: check-runs pinned to 65f1b7ce: 45 total, 26 success, 19 skipped, 0 failed (Check Changeset skipped under skip-changeset). Dev: 21/21 derived gates exit 0, --ran reconciled, on both heads.
  4. Accepted deviations: no Status-line amendment entry, per the docs(adr-0146): D8 item 2 names the pair's export, GET /packages/X.custom/export, never the base's #29791 convention (provenance lives in Refs). PR body refreshed by the seat to the rework round (Verification cites both heads).
  5. Out of scope: none. Skills-docs: not owed.
  6. Landing: Tier H. The queue guard reads a GitHub APPROVED review from GOVERNED_APPROVERS, so the seat marks it ready and requests hotlong and os-zhuang now, then lands it after that review. At MERGED: landing record on docs(adr): ADR-0146 D8 names the whole-deployment export GET /packages/export (each package's own export, the pair after its base) #29802, pm:dispatched removed, card thread released.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 3, 2026 07:05
@os-zhuang
os-zhuang added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 4e0c5d3 Nov 3, 2026
46 checks passed
@os-zhuang
os-zhuang deleted the claude/project-thread-kr1zkm branch November 3, 2026 12:30
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/s 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.

docs(adr): ADR-0146 D8 names the whole-deployment export GET /packages/export (each package's own export, the pair after its base)

2 participants