Skip to content

docs(adr): ADR-0070 D2 amended — a type: module sub-package of an installed app may be disabled, not authored into, by an admin (#28285) - #28430

Merged
os-zhuang merged 1 commit into
mainfrom
claude/project-thread-a2g9zi
Oct 31, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/project-thread-a2g9zi

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Leehom · project thread

domain:server#2 · os-project-manager · session_01FEkQ5nCt4UPJjChW4GyQxQ

Fixes #28285

Clause-②: no — governed prose only; no accept set, refusal or served shape moves here. The behaviour the note records shipped in PR #28308 (7abe151b), which declared its own yes (widening).
Metadata-protocol: none

维护者速读

  • 改了什么:在 ADR-0070 的 D2 下加一条带日期的修订说明,并在 Status 行加同日期的指针:已安装应用下的 type: module 子包可以被管理员停用(不是写入)。说明按代码实际行为写:停用门读取的归属判据(模块包的 manifest.dependencies 直接声明一个已安装的 type: app 包,自身 scope 不是 system/cloud)、写入仍拒绝(isWritablePackage 不变)、导航折叠丢弃已停用包的贡献、其记录触发流程在进程内写入时也不派发。
  • 为什么改:packages: an admin cannot disable a type:module sub-package of an installed app (422 WRITABLE_PACKAGE_REQUIRED), and a disabled package's nav contributions stay in the app #28117 第 6 项,裁决「大包 + 设置里启用模块」/「同意」(2026-10-30);代码已随 PR feat(runtime): an admin can disable a type:module package of an installed app; its nav contributions and record-change flows stop (#28117) #28308 合入 main,决策记录要跟上代码。
  • 风险与回滚:零运行时风险,只改一份决策记录;回滚即 revert。ADR-0146 覆盖的是 D3/D5,D2 不在其列,本修订与之不冲突。
  • 先看:docs/adr/0070-package-first-authoring.md 的 D2 修订块(一个引用段);Status 行末尾的指针。
  • 两分钟验证:pnpm check:adr-symbol-anchors,预期全部锚点解析(本次新增 5 个符号锚);再把 D2 修订块与 packages/runtime/src/domains/packages.ts 里 isDisableableAppModule 的注释对照。
  • 需要你做的:Tier H(docs/adr/**):你的 approve 或亲手合并。另有一个未决问题不在本 PR 内:应用自己的 hook 在进程内读写已停用模块的对象要不要拒绝(决策函 6538936519),修订块只把它记为未决。

What changes

One file, docs/adr/0070-package-first-authoring.md:

  1. An amendment note under D2, in the registry's dated > **Amended …** form (the form ADR-0087 and ADR-0005 use), recording the maintainer's ruling of 2026-10-30 verbatim and untranslated (「大包 + 设置里启用模块」, then 「同意」) and what shipped in PR feat(runtime): an admin can disable a type:module package of an installed app; its nav contributions and record-change flows stop (#28117) #28308 (7abe151b):
  2. A dated pointer on the Status line, the form ADR-0146's "Status-line pointers" section fixes for an amended record (· **Amended** (date, …) — clause; see the amendment note under D2). Nothing else on the Status line moves; D3–D6 are untouched.

ADR-0146 check. Its supersession of ADR-0070 covers D3's prompt and D5's destination for the paired case, and its pointer on ADR-0070's Status line says "D1, D2, D4 and D6 stand". D2 is not the superseded part, so the amendment stands beside ADR-0146 and this PR touches no other record.

Five symbol anchors are new, all resolving (check:adr-symbol-anchors below): packages/runtime/src/domains/packages.ts#isDisableableAppModule, packages/metadata-protocol/src/package-writability.ts#isWritablePackage, packages/spec/src/api/package-api-assembled.zod.ts#SERVED_ROW_VERDICTS, packages/objectql/src/registry.ts#applyNavContributions, packages/triggers/trigger-record-change/src/record-change-trigger.ts#RecordChangeTrigger.

Tests

None: a decision record, no tested behaviour changes, so no ablation. The gates that read docs/adr/** are the verification.

Acceptance notes

  • Governed surface. node scripts/pm/check-governed-merges.mjs --test docs/adr/0070-package-first-authoring.md answers exit 3: "⛔ GOVERNED — a human merge is the review record for this PR (governance: human merge IS the review record for governed surfaces — retire the per-PR ADR approval check, add a report-only post-merge audit #9495 regime) … ⚖️ landing tier: H(人合) — the maintainer's hand, or an authorized APPROVED review (GOVERNED_APPROVERS) and then the owning seat lands it. docs/adr/** ×1". This PR stays draft; no seat readies, queues or arms it.
  • Model tier. dispatch-gates.mjs --tier on the path: "Model tier — MANDATORY: claude-fable-5-1 … the same order fixes the effort floor at xhigh". This session ran at claude-fable-5-1, effort xhigh (the session record).
  • skip-changeset rides the create: docs/adr/** publishes nothing (fast track).
  • The generated ADR index docs/adr/README.md is current after the edit (node scripts/adr-index.mjs --check: "OK — docs/adr/README.md is current and every record parsed"), so it is not touched.
  • Not here, by the order: the in-process access decision (letter 6538936519), the Console half (Packages page: offer Enable / Disable on a suite's type:module rows once the server allows disabling them #28118), D4–D6.
  • Lint. pnpm exec eslint --no-inline-config docs/adr/0070-package-first-authoring.md exits 0 with "File ignored because no matching configuration was supplied": Markdown is outside the eslint config, and the doc gates below are the style authority for this path.
  • The PR body's first two lines are the harness attribution block the project requires; the seat signature follows it.

Verification

Gates from node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on this diff (21 commands), each run on head c2b0e3ad with its exit code captured before any pipe:

# Gate Exit
1 node scripts/check-adr-links.mjs 0
2 node scripts/check-adr-links.mjs --self-test 0
3 node scripts/check-closing-keyword-parity.mjs 0
4 node scripts/check-closing-keyword-parity.mjs --self-test 0
5 node scripts/check-comment-mask-corpus.mjs 0
6 node scripts/ci/plan-test-core-shards.mjs --self-test 0
7 pnpm --filter @objectstack/lint run check:doc-formula-expressions 0
8 pnpm check:adr-anchors 0
9 pnpm check:adr-index 0
10 pnpm check:adr-symbol-anchors 0
11 pnpm check:ci-filter-parity 0
12 pnpm check:closed-ceremony-text 0
13 pnpm check:cross-package-test-inputs 0
14 pnpm check:doc-authoring 0
15 pnpm check:driver-memory-census 0
16 pnpm check:gitlink-declared 0
17 pnpm check:nul-bytes 0
18 pnpm check:pm-governed-merges 0
19 pnpm check:pm-prior-rulings 0
20 pnpm check:refd-timer-probe 0
21 pnpm check:watch-hint-literal 0

dispatch-gates --ran: "21 derived famil(ies) accounted for — 21 run, 0 NOT-MEASURED (a DERIVED zero — all 21 recorded an exit code and none of them is 3)". The first pass recorded exit 3 (PREREQUISITE NOT MET: @objectstack/formula and @objectstack/lint not built) on check:doc-formula-expressions; after pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint under the verify lock (VERDICT command-exit 0, 1m36s) the gate ran and exited 0, and the record above carries that run.

Readings quoted from the gate logs
  • node scripts/check-adr-links.mjs → ✅ check-adr-links: 962 relative link destination(s) under docs/adr/ resolve
  • node scripts/check-adr-links.mjs --self-test → ✅ check-adr-links --self-test: discrimination, census, ADR-0046 pin and baseline staleness all verified
  • node scripts/check-closing-keyword-parity.mjs → check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators; sweep found 5 file(s) carrying the grammar across 23186 tracked file(s), all registered).
  • node scripts/check-closing-keyword-parity.mjs --self-test → ✓ check-closing-keyword-parity --self-test: 40 assertions, 5 mutations of the shipped parsers each driven to red.
  • node scripts/check-comment-mask-corpus.mjs → ✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 19531 files, 0 disagree, 0 unparseable, 186.4s (comparator self-test: 26 cases pass).
  • node scripts/ci/plan-test-core-shards.mjs --self-test → ✓ plan-test-core-shards self-test: 23 case(s) across 5 batteries.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions (rerun after the build) → ✓ check:doc-formula-expressions (field-level *When, The os:check fence type-checks a visibleWhen CEL string as string — any predicate text passes, including calls to functions that exist nowhere #11407): 15 predicate(s) on a statically determinable field layer judged clean; 12 skipped as undeterminable.
  • pnpm check:adr-anchors → check-adr-anchors: OK (95 anchored file(s), every governing ADR still referenced; 142 decision number(s), each naming one decision or an allowlisted pair; 62056 citation(s) across 8887 file(s) resolve, 37 of them stem-qualified to one record; 2025 decision-let
  • pnpm check:adr-index → adr-index --report: OK — docs/adr/README.md is current, every record parsed, self-test 46 assertions green. Report-only: this line never reds the step.
  • pnpm check:adr-symbol-anchors → ✅ check-adr-symbol-anchors: 2952 anchors across 148 records resolve — 691 symbol (663 declaration, 28 literal), 2214 file-level, 47 cross-repo, 6 exempt, 31 continuation. 0 line anchors survive in the path-anchored, backticked continuation, fenced comment head
  • pnpm check:ci-filter-parity → OK: all 8 root input(s) of test / test:repo in turbo.json are covered by core or crosspkg, which the test job's if: reads.
  • pnpm check:closed-ceremony-text → ✓ check-closed-ceremony-text: 5537 shipped file(s) read; none says the ownership ceremony is closed.
  • pnpm check:cross-package-test-inputs → OK: 31 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob (6 of them on a split "test:repo" task); 13 walked root(s) judged, 3 on ACCEPTED_WALK_RADII; 4061 test file(s) import a workspace sibling by bare specifier over
  • pnpm check:doc-authoring → ✓ doc authoring guard: sibling-package prose ids hold the baseline — 0 pinned site(s) across 0 file(s), 116712 string(s) read in 1627 parsed source(s) (seen floor 40000 strings / 600 sources), no growth, no burn-down unrecorded.
  • pnpm check:driver-memory-census → check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live, and every ruled file states "driver-memory census in undeclared-field-write-driver-split.integration.test.ts is stale — a second packages/runtime test consumer (#6468) is outside #5704's "in this one place" ruling #6664 census: 2 ruled consumers". This gate polices the census, never investment.
  • pnpm check:gitlink-declared → check-gitlink-declared: OK (23186 index entries -- 0 gitlink(s) at mode 160000; no .gitmodules in the index, so nothing is declared; nothing to declare).
  • pnpm check:nul-bytes → check-nul-bytes: OK (scanned 23087 text file(s) -- 23087 tracked, 0 untracked-not-ignored; skipped 99 binary; no raw ASCII control bytes).
  • pnpm check:pm-governed-merges → ✓ check-governed-merges --self-test: 537 assertions (the unified governed predicate + near misses, subject→PR spellings, window parsing, the finding(check-governed-merges): the merge queue's build-to-land skew can put a governed landing BELOW a round's --since boundary, where it is silently absent from the audit list #12633 landing window — the QS-7 regression pin in both directions, the topological close beyond the budget, the unprov
  • pnpm check:pm-prior-rulings → ✓ check-prior-rulings self-test: 155 cases pass (term derivation with its length floor, stopwords and code-span splitting; the governing-text carrier in both measured shapes plus the absent case that is 23 of 27 on the live board; the backticked-CLAUSE and lea
  • pnpm check:refd-timer-probe → OK check-refd-timer-probe: 19525 source file(s) swept; the process-global timer probe is read in packages/qa/refd-timer-testkit/src/index.ts and nowhere else.
  • pnpm check:watch-hint-literal → ✓ check-watch-hint-literal: 75 declaration(s) across 4 rostered name(s) -- ROOT_DIR_WATCH_HINTS 49, ROOT_FILE_WATCH_HINTS 14, ROOT_WATCH_HINTS 3, DECLARED_WATCH_HINTS 9 -- every one an array of quoted literals inside its own statement, all 188 of those literal

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (packages/spec untouched.)
  • 2. Every name I added uses the casing for its kind. (No names added.)
  • 3. No formatter ran; pnpm lint scoped to the file is ignored by config (exit 0, see Acceptance notes).
  • 4. One issue, one branch off an up-to-date main (5da3a8ce), one pull request.
  • 5. A change that publishes carries a changeset: nothing publishes (skip-changeset); both declaration lines are filled in above.
  • 6. packages/spec touched: n/a.
  • 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 required Chinese summary; the ruling is quoted verbatim).
  • The Before Submitting list in CONTRIBUTING.md is done.

Generated by Claude Code

…sub-package of an installed app

Records the maintainer's ruling of 2026-10-30 (「大包 + 设置里启用模块」, then
「同意」) as a dated amendment note under D2, naming the tie the disable door
reads as shipped: a type: module package whose manifest.dependencies directly
names an installed type: app package, not system/cloud scoped. Authoring stays
refused (isWritablePackage unchanged), the navigation fold drops a disabled
package's contributions, and its record-change flows are withheld for
in-process writes. The in-process access question is recorded as open. The
Status line carries the dated pointer the registry's convention requires.

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

Copy link
Copy Markdown
Contributor Author

domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: c2b0e3ad1b7bc4170352cda80eb5953676715c63
Local-runs: none
Scope: docs/adr/0070-package-first-authoring.md + packages/runtime/src/domains/packages.ts, packages/metadata-protocol/src/package-writability.ts, packages/spec/src/api/package-api-assembled.zod.ts, packages/objectql/src/registry.ts, packages/triggers/trigger-record-change/src/record-change-trigger.ts, packages/core/src/artifact-packages.ts, packages/metadata-protocol/src/protocol.ts, packages/runtime/src/domains/packages-disable-app-module.test.ts, content/docs/deployment/marketplace-handbook.mdx, docs/adr/0146-studio-designs-setup-administers-one-editor-per-item-paired-customize-package.md, docs/adr/0141-inter-app-dependency-declared-checked-before-install.md (all read on main at ea1751be, which carries PR #28308's merge 7abe151b)

Inputs read: card #28285 (body, triage, unblock, claim, dev report 6545434096); parent #28117 (ruling record in the body, scope addendum 6523684730, decision letter 6538936519, landing record, director batch note); PR #28430 body, file list, net diff against main and the check-runs on the head; PR #28308 (merged, file list); issue #28318 (the disableable key) and #28118 (the Console half). The dispatch order was read for the seat's rulings only; nothing below rests on its conclusions.

① Derived judgments

  • Accept set: nothing moves. One file, docs/adr/0070-package-first-authoring.md, +3/−1. No packages/spec/src/**, no runtime, no skills, no changeset. The diff publishes no key, refusal or served shape; the behaviour it records is already on main from PR feat(runtime): an admin can disable a type:module package of an installed app; its nav contributions and record-change flows stop (#28117) #28308 (7abe151b), which carried its own yes (widening). Right.
  • Governed face: one hit. docs/adr/** is the governed rules text, so the PR is Tier H and the review is owed at CONTRACT_REVIEW_TIER. The PR is draft with no auto-merge and no readiness, as the Tier H line requires. Right.
  • Public surface of the ADR: two edits, both additive. (a) A dated · **Amended** (…) pointer appended to the Status line, after ADR-0146's Superseded in part pointer, leaving that pointer and its "D1, D2, D4 and D6 stand" sentence untouched. (b) One blockquote > **Amended … —** … note under D2, after D2's predicate sentence and before D3's heading. D1, D3–D6, Consequences, Open questions and Rollout are untouched. Right.
  • Symbol anchors: five new, all resolve on main. packages/runtime/src/domains/packages.ts#isDisableableAppModule (module-level function), packages/metadata-protocol/src/package-writability.ts#isWritablePackage (exported), packages/spec/src/api/package-api-assembled.zod.ts#SERVED_ROW_VERDICTS (module const), packages/objectql/src/registry.ts#applyNavContributions (public method), packages/triggers/trigger-record-change/src/record-change-trigger.ts#RecordChangeTrigger (exported class). Each declaration found by reading the file; the "Lint & Repo Gates" check-run on the head is green. Right.
  • Issue links: #28117 and PR #28308 as absolute GitHub links, the form the Status-line precedents use (ADR-0035, ADR-0043). Right.

② Semver level

  • skip-changeset is stored on the PR with documentation and size/xs; docs/adr/** publishes nothing, so no changeset is owed. Right.
  • Body declarations: Clause-②: no (prose only, no narrowing arm) and Metadata-protocol: none (packages/spec untouched). Both match the diff.
  • Check-runs on the head at this read: Lint & Repo Gates, Test UI, Dogfood Regression Gate, Plan Test Core shards, Auto Label all green; Test Core (1/8) still in progress, nothing red. The landing seat reads it green before the Tier H hand-off; a docs-only tree cannot have changed its inputs.

③ Boundary flags

④ Design judgment

The amendment note, sentence by sentence against main.

  1. Ruling and its three defaults (suite as one artifact, admin switches per environment, "disabled" has one meaning: hidden, refused on the data plane, data kept) — verbatim from the packages: an admin cannot disable a type:module sub-package of an installed app (422 WRITABLE_PACKAGE_REQUIRED), and a disabled package's nav contributions stay in the app #28117 ruling record. Holds.
  2. "Read-only above means may not be authored into; it does not mean may not be switched off." — D2's own text says "Read-only. New items may not be authored into them", and isWritablePackage's doc and isDisableableAppModule's doc both spell writable as "may author into". Holds.
  3. The door reads one exemption before the writability check, isDisableableAppModule. — PATCH /packages/:id/disable on main runs isDisableablePackage(qlService, id) ? null : requireWritablePackage(deps, qlService, id, 'disable'), and isDisableablePackage evaluates isDisableableAppModule first, then isWritablePackage. Holds; the note names isDisableablePackage indirectly as "the predicate the door asks" in the served-verdict sentence, so a reader reaches the real symbol.
  4. The tie, as shipped: manifest.type === 'module'; manifest.dependencies directly naming a package installed here whose manifest.type === 'app'; own manifest.scope not system/cloud. — isDisableableAppModule reads exactly these three from the registry row (declaredDependencyIds returns the keys of the dependencies record, ADR-0141 D1's declaration, so "directly" is right; "installed here" is registry.getPackage(dependency) answering a row; the scope list is READ_ONLY_PACKAGE_SCOPES). The self-exclusion dependency !== id is an implementation guard the note need not state. "Both install paths leave it on the registry row" is pinned in packages-disable-app-module.test.ts for code and marketplace. Holds.
  5. "Everything else answers the door as before." — the door falls through to requireWritablePackage for the app itself, plugins, drivers, orphan modules and platform-scope modules; the enable door is unchanged. Holds.
  6. isWritablePackage unchanged; edit, publish, revert, delete and overwrite still 422 WRITABLE_PACKAGE_REQUIRED. — package-writability.ts is not in PR feat(runtime): an admin can disable a type:module package of an installed app; its nav contributions and record-change flows stop (#28117) #28308's file list and reads as before; every other package door (install/overwrite, publish, revert, adopt, edit, delete) asks requireWritablePackage alone. Holds.
  7. The verdict is served beside it as disableable, computed by the predicate the door asks. — withDisableableVerdict calls isDisableablePackage; SERVED_ROW_VERDICTS declares disableable beside writable and forbids deriving one from the other. Holds.
  8. While disabled: 404 OBJECT_PACKAGE_DISABLED on the data plane and by-name reads; the nav fold drops its contributions; record-change flows withheld for in-process writes too. — assertObjectRegistered in protocol.ts and the by-name read answer that code; applyNavContributions skips a contribution whose packageId is disabled, per read, before the group lookup; RecordChangeTrigger returns before dispatch when registry.isObjectPackageDisabled(written) is true, per write. "Too" is right: a data-plane write never reaches the trigger (it is refused first), so the withholding is what the in-process path meets. Holds.
  9. Enable restores all three; the data was never touched. — all three checks are asked per request and nothing is cached or deleted; the test pins the restore. Holds.
  10. Not decided here: in-process ctx.api access; today served, pinned and documented; with the maintainer as letter 6538936519. — pinned in packages-disable-app-module.test.ts (the addendum-6523684730 describe block), documented in marketplace-handbook.mdx ("What your app's own code meets"), and the letter is open on packages: an admin cannot disable a type:module sub-package of an installed app (422 WRITABLE_PACKAGE_REQUIRED), and a disabled package's nav contributions stay in the app #28117. The note takes no side. Holds, and it is the sentence the order forbade from being settled.

ADR-0146 supersession. Its supersede table row for ADR-0070 names D3 (select-or-create a base first) and D5 (retire the stopgaps) for the paired case only, and its pointer on ADR-0070's Status line says "D1, D2, D4 and D6 stand". D2 is not superseded, so an amendment under D2 sits beside ADR-0146. Its D3 pair package (a base's customize package) is a project-scope writable base, never a type: module, so the exemption does not reach it; ADR-0141's open item on dependents of a disabled package is not claimed. No conflict.

Status-line form. The repo marks an amendment on the Status line as · **Amended** (date, #card — clause) (ADR-0035, ADR-0043, ADR-0045, ADR-0017) and in the body as a dated > **Amended … —** … blockquote (ADR-0005, ADR-0035, ADR-0048, ADR-0087); ADR-0146's "Status-line pointers" section fixes the Status line as the one place for the pointer. The PR follows both; the pointer says which clause changed and where the note is, and the generated index is reported current.

First consumers, and does the text help them. (a) #28118, the Console half (Packages page Enable/Disable on module rows): the note names disableable as the served key and the spec symbol, and says writable stays false for a module, which is the one mistake that page could make. (b) A client refused at the disable door: the 422 body's docs: field points at this ADR, and the note is now the sentence telling them which packages the door accepts. (c) The HotCRM tolerance card and any later ADR PR after letter 6538936519: the last sentence is the exact place to amend. Execution plan: none owed; the code shipped first and the record follows it, as the card required.

Findings.

Implemented-by: claude/project-thread-a2g9zi
Reviewed-by: session_0186vfjHHMsRXC9EUT9hTFMo

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo

席位核对

ACCEPT · domain:server seat 2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo · 2026-10-31T15:40Z · head c2b0e3ad · #28285

The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」. This PR is Tier H: that authorisation does not reach it. It stays draft until the maintainer approves.

  1. Shape:
    • A draft against main with no assignees, Fixes #28285, labelled skip-changeset (an ADR edit ships in no package).
    • check-governed-merges --pr 28430 reads ⛔ GOVERNED, docs/adr/** ×1, 4 changed lines. Landing tier H(人合).
    • The claim (6545211287) names this PR's branch, claude/project-thread-a2g9zi.
  2. Against the order:
  3. Contract review: owed at CONTRACT_REVIEW_TIER (governed rules text). PASS on this head, 6545514720. One should-fix, not blocking: the Status pointer's "then" could read as both quoted phrases being from one day; the date it gives is the ruling's.
  4. Gates:
    • Locally, the dev ran 21 derived families, every one exit 0.
    • CI on head c2b0e3ad: 26 success, 25 skipped, 0 red. The state is clean.
  5. Overlap: no other open PR touches docs/adr/0070-package-first-authoring.md.
  6. Next:
    • ⛔ No seat flips it ready, enqueues it or arms auto-merge. The maintainer's approval (or merge) is the review record.
    • After it merges, the landing record goes on the card and the claim is released.

Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review October 31, 2026 20:41
@os-zhuang
os-zhuang enabled auto-merge October 31, 2026 20:41
@os-zhuang
os-zhuang added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit 8e6acf4 Oct 31, 2026
52 checks passed
@os-zhuang
os-zhuang deleted the claude/project-thread-a2g9zi branch October 31, 2026 21:03
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/xs 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-0070 D2 addendum — a type: module sub-package of an installed app may be disabled by an admin (#28117 item 6)

2 participants