Repository navigation
docs(adr): ADR-0019 records that a flat composeStacks and a packages[] body are judged since 2026-11-13 - #33502
objectstack-fleet[bot] wants to merge 2 commits into
Conversation
…ies are judged since 2026-11-13 The 2026-11-12 enforcement note said a flat composeStacks and a hand-built packages[] body are not judged. Both are judged on main: composeStacks refuses a flat composition that puts two or more apps under one app or module package id, and strict defineStack judges single-app and namespace prefix per package body with residual top-level items against the manifest. The note's sentence is now the reading at its date, a dated note records the three merges, and the Status line names them. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5obDWQ7NdtH2f9iZXC
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: Inputs read: card #33135 body and all four comments (triage 6859219233, seat scope note 6884985712, claim 6885232502, os-dev-report 6885394481); PR #33502 body, file list (one file, +40 / -4) and net diff; the check-runs on this head. Base drift: Check-runs on this head at render time: 53 completed, 27 success and 26 skipped. None failed and none is pending. The last to finish were Test Core (1/8) and the three Type Check runs (workspace, consumer gates, debt ledger), all success. The derived gate families answer green. ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Findings:
No must-fix. S1 and S2 earn a delta review of their fix. Both, and the nits, sit on the prose face (this ADR), so fixing them moves the head on this file only. Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-14T22:58Z · isolated sub-agent at CONTRACT_REVIEW_TIER · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
…eStacks merge and narrows what stays unjudged Per-body judging at strict defineStack came with the composeStacks merge; the later merge changed only how the top level is counted. A stack with no manifest still has its bodies judged, and composeStacks re-judges a strict: false input only by the single-app rule, with two or more inputs. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5obDWQ7NdtH2f9iZXC
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: Inputs read: the earlier record (PR #33502 comment 6885553305, PASS on Check-runs on this head at render time: 48 completed, 26 success and 22 skipped. None failed and none is pending. Test Core (1/8), Lint & Repo Gates, Lint · repo & tooling gates and Lint · docs & code guards finished last, all success. The derived gate families answer green. Delta
① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
New findings:
No must-fix and no should-fix. S1 and S2 are fixed, N1 and N2 are fixed, and N3 and N4 stand as accepted. N5 and N6 are nits and end the round. Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-14T23:22Z · isolated sub-agent at CONTRACT_REVIEW_TIER · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb 维护者速读
席位核对Verdict: ACCEPT, held for the maintainer · head
|
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Correction: contract-review tierThe contract-review record(s) 6885553305, 6885829992 on this PR say The seat re-runs the review at |
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: At-tier re-review. The two earlier records on this PR (6885553305 on Inputs read: card #33135 body and its five comments (triage 6859219233, seat scope note 6884985712, claim 6885232502, os-dev-report 6885394481, the seat's ACCEPT line 6885845907); PR #33502 body, file list (one file) and the net diff against Check-runs on this head: 53 completed, 26 success and 27 skipped, none failed, none pending. Lint & Repo Gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · PM dispatch-gates, Check Documentation Links, Governed Surface Queue Guard, the PR-body guards, Test Core (1/8) and the Type Check runs are all success. The derived gate families answer green. ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Status line. "the same rule on a flat The 2026-11-12 note. "At this merge the check read one #32898 bullet.
#33074 bullet. The #33122 bullet. Closing paragraph.
Attempts to break it that did not: a Findings:
No must-fix and no should-fix. The four nits sit on the prose face; they may be fixed there, left as accepted deviations, or carried to a follow-up card. They end the round. Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-15T00:41Z · isolated sub-agent at CONTRACT_REVIEW_TIER (served model verified by the seat) · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
Requested by Leehom · project thread
Fixes #33135
domain:skills#1 · os-project-manager · session_01FEkQ5obDWQ7NdtH2f9iZXC
Clause-②: no
Metadata-protocol: none
维护者速读
composeStacks,和手工拼的packages[]包体」。这句改成当日的读数(过去时),并在其后新增一段「自 2026-11-13 起,组合与packages[]包体都受检查」,逐条写明 feat(spec)!: composeStacks refuses a flat composition that puts two or more apps under one app or module package id, and every packages[] body is held to one app #32898、feat(spec)!: strict defineStack judges a packages[] stack per body and counts only the top-level apps no body declares against its manifest #33074、feat(spec)!: strict defineStack judges a packages[] stack's namespace prefixes per body and its top level by the residual rule #33122 三次合并各自检查了什么;状态行的「已落地」也补上这三次合并及其提交号。main上都已不成立:扁平组合把两个以上应用放到同一个 app/module 包名下会被拒(STACK_SINGLE_APP_VIOLATION,422),手工拼的包体也按包分别检查单应用和命名空间前缀。照着旧文字读的作者或 AI 会以为这些形状不受检查。docs/adr/0019-app-as-consumer-unit.mdD3 修订说明下的「Enforced for compositions andpackages[]bodies since 2026-11-13」一段;再看第 3 行状态行新增的那半句。pnpm check:adr-symbol-anchors,预期 exit 0、「anchors across 156 records resolve」。docs/adr/**):请批准或合并。What changes
docs/adr/0019-app-as-consumer-unit.md, D3, the 2026-11-12 note "Enforced for modules since 2026-11-12". Its sentence "The check reads onedefineStackcall. Two shapes are not judged (spec: a flat composeStacks (default manifest 'last') of packages with one app each yields one package id with several apps, and no door refuses it (the single-app rule of ADR-0019 D3 as amended) #32810): a flatcomposeStacks… and a hand-builtpackages[]body." is rewritten as the reading at that merge, in the past tense, and points to the next paragraph: "At this merge the check read onedefineStackcall, and two shapes were not judged (spec: a flat composeStacks (default manifest 'last') of packages with one app each yields one package id with several apps, and no door refuses it (the single-app rule of ADR-0019 D3 as amended) #32810): … Both are judged since 2026-11-13; see the next paragraph." The rest of that paragraph is unchanged.packages[]bodies since 2026-11-13.", following the file's own convention (the 2026-11-12 note keeps the paragraph before it "as written" and adds a dated note). One bullet per merge:0b23b2a0c4):composeStacksrefuses a flat composition ('last','first'or an index) whose kept manifest is anappormodulepackage and that brings two or more apps,STACK_SINGLE_APP_VIOLATION(422), naming each app and its input; the remedy ismanifest: 'preserve'; everypackages[]body of a composition is held to one app; a one-input composition is handed back unjudged.2c98485db5): changes only how strictdefineStackcounts the top level of apackages[]stack. Before, every top-level app counted againstmanifest.id; since, the residual rule feat(spec)!: composeStacks refuses a flat composition that puts two or more apps under one app or module package id, and every packages[] body is held to one app #32898 gavecomposeStacks(top-level apps no body declares count againstmanifest.idbeside that id's own body). Bodies are judged as before, per body since feat(spec)!: composeStacks refuses a flat composition that puts two or more apps under one app or module package id, and every packages[] body is held to one app #32898.5b2ec820c8): strictdefineStackjudges namespace prefixes per body against the body's own namespace, residual top-level objects againstmanifest.namespace,STACK_NAMESPACE_PREFIX_INVALID; a body with no namespace is not judged.defineStack(other package types, no manifest,strict: false, the last now judged atcomposeStacks), and the placement sentence, which stands (measured, below).composeStacksand on everypackages[]body (feat(spec)!: composeStacks refuses a flat composition that puts two or more apps under one app or module package id, and every packages[] body is held to one app #32898, merged 2026-11-13 as0b23b2a0c4; feat(spec)!: strict defineStack judges a packages[] stack per body and counts only the top-level apps no body declares against its manifest #33074, merged 2026-11-13 as2c98485db5), and the namespace-prefix rule judged perpackages[]body (feat(spec)!: strict defineStack judges a packages[] stack's namespace prefixes per body and its top level by the residual rule #33122, merged 2026-11-13 as5b2ec820c8)."skills/**(PR docs(skills): a suite composes under manifest preserve; a flat composition of two apps under one package is refused #33475 teaches the flat-compose fact there).Why
Read on
origin/mainb392ff7b, not from the card:packages/spec/src/stack.zod.ts:collectComposedSingleAppErrorsandflatSingleAppFinding(flat result: every app counts against the one kept manifest),SINGLE_APP_PACKAGE_TYPES=app,module,SINGLE_APP_COMPOSE_REMEDY(namesmanifest: 'preserve'),collectPackageBodySingleAppErrors(each body by its owntype,id,apps),validateSingleAppandresidualSingleAppFinding(one judge for both doors),namespacePrefixErrors(per body, residual top level),composeStacks'stacks.length === 1early return.examples/app-multi-package/objectstack.config.tscomposes withmanifest: 'preserve'.Attribution per PR, read from each merge commit's tree:
residualSingleAppFinding,flatSingleAppFindingandcollectPackageBodySingleAppErrorsexist at0b23b2a0c4(feat(spec)!: composeStacks refuses a flat composition that puts two or more apps under one app or module package id, and every packages[] body is held to one app #32898), wherevalidateSingleAppdoes not call the residual judge; it does at2c98485db5(feat(spec)!: strict defineStack judges a packages[] stack per body and counts only the top-level apps no body declares against its manifest #33074);namespacePrefixErrorsfirst exists at5b2ec820c8(feat(spec)!: strict defineStack judges a packages[] stack's namespace prefixes per body and its top level by the residual rule #33122).Each merge commit is an ancestor of
origin/main(git merge-base --is-ancestor, exit 0 for all three, after deepening the shallow clone).One probe against
packages/spec/distbuilt fromb392ff7b, not kept as a test:composeStacks(default'last') of two module stacks with one app eachSTACK_SINGLE_APP_VIOLATION422manifest: 'preserve'packages[]body (module) with two apps,defineStackSTACK_SINGLE_APP_VIOLATION422svc, objectcrm_caseSTACK_NAMESPACE_PREFIX_INVALID422svc_casecrm_casedefineStackand'preserve'composeThe placement sentence therefore stands, as the order asked to measure.
Ruling: Leehom 2026-11-14T21:21:06Z 「开放 p3卡认领」 (p3 cards open for claiming); scope widened to both halves by the skills seat's note 6884985712 on the card.
Acceptance notes
Verification
Head
691fe886(round 1, after contract review 6885553305; round 0 wasc72ef404), baseorigin/mainb392ff7b.Derived gates: 21 derived, 21 run, all exit 0
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 21 families for the one path. Each ran on headc72ef404(round 0) and again on691fe886, 21 of 21 exit 0 (33135-gates-ran-r1.txt) with its exit code captured before any pipe, after building@objectstack/lint...under the verify lock (VERDICT command-exit 0, 86s):check-adr-links(scan and--self-test),check-closing-keyword-parity(scan and--self-test),check-comment-mask-corpus,plan-test-core-shards --self-test,@objectstack/lint check:doc-formula-expressions,check:adr-anchors,check:adr-index,check:adr-symbol-anchors("3594 anchors across 156 records resolve"),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.--ranreconciliation: "21 derived famil(ies) accounted for — 21 run, 0 NOT-MEASURED".#flatSingleAppFinding,#SINGLE_APP_COMPOSE_REMEDY,#collectPackageBodySingleAppErrors,#validateSingleApp,#residualSingleAppFinding,#namespacePrefixErrors) are not judged bycheck:adr-symbol-anchors(that spelling is off in this corpus); each was found bygrepas a declaration inpackages/spec/src/stack.zod.tsonb392ff7b.Tier and governed readings
dispatch-gates --tier: MANDATORY contract-review tier fordocs/adr/**; no one-line exit for this surface. This thread ran at the claim's default model; the seat's in-seat contract review is the owed record.node scripts/pm/check-governed-merges.mjs --branch claude/project-thread-bd7546: GOVERNED, landing tier H (人合),docs/adr/**x1. Size +50 / -4, under the 3000 threshold.node scripts/pm/check-skill-line-ratchet.mjs: exit 0 (no skill file touched). No changeset:docs/adr/**ships in no package (skip-changeset).🤖 Generated with Claude Code
https://claude.ai/code/session_01FEkQ5obDWQ7NdtH2f9iZXC