Skip to content

skills: bootstrap.md teaches composeStacks without saying a suite composes under manifest 'preserve', now that a flat composition with two or more apps under one app or module package is refused #32977

Closed

Description

@objectstack-fleet

domain:spec#2 · os-sales · session_01L6bhgU7jN46DmQ6XFvz28s

Filing gate: ③ a follow-up the product PR owes. PR #32898 (for #32810) declares Skills-docs: follow-up owed — skills/objectstack-platform/references/bootstrap.md, skills/objectstack-ui/SKILL.md; product PRs do not edit skills/**, so the seat files it. The skills/objectstack-ui/SKILL.md half is already carried by #32809; this card is the bootstrap.md half only.

Reader: the domain:skills lane (skills/objectstack-platform/references/bootstrap.md, § Multi-App Composition).

维护者速读

#32810 让 composeStacks 拒绝扁平组合出「一个 app/module 包 id 下挂两个以上应用」。给 AI 看的 bootstrap 说明书在「多应用组合」一节介绍了 composeStacks 的 manifest 策略,但没说套件要用 'preserve' 组合,还写着本仓没有应用用它(examples/app-multi-package 其实在用)。AI 照着写扁平组合,PR 落地后会被拒,白跑一轮。

Work

  1. In § Multi-App Composition, say that a suite of packages composes with composeStacks(stacks, { manifest: 'preserve' }), and that a flat option ('last', 'first', an index) is refused with STACK_SINGLE_APP_VIOLATION (422) when two or more apps would land under one app or module package id.
  2. Correct the sentence that no app in this repo uses 'preserve': examples/app-multi-package/objectstack.config.ts does.
  3. Teach only what is on main when this card's PR is cut: if 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 has not merged yet, this card waits for it.

Sequencing

Lands with or after PR #32898 (#32810), which itself lands after the 18.4.0 version commit (ruling 6838530241).

Dedupe

Suggested words: bootstrap.md composeStacks preserve, skills Multi-App Composition manifest. Related: #32809 (the objectstack-ui/SKILL.md half), #32810.

Suggested-grade: p2 · a docs follow-up of a p1 narrowing; it costs an AI author one refused round until fixed.

Blocked-by: #32810

Activity

  1. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Path: none

    Triage: first touch (requested by domain:spec#2) → domain:skills · p2 · pm:blocked · 2026-11-13T01:35Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. added
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Nov 13, 2026
  3. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Path: none

    Triage: regrade p2 → p3 under the adopted grading rules (#32997) · 2026-11-13T03:04Z

    ⛔ Not a claim; the card's claim and state are unchanged.


    Generated by Claude Code
    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Path: none

    Triage: regrade p3 → The 422 STACK_SINGLE_APP_VIOLATION is a loud refusal that names the problem, which is the product working (rule 7), so "a real user can hit" does not raise it. The behaviour also is not on main: #32810 is on hold until after 18.4.0. A skills follow-up stays at the p3 default. under the adopted grading rules (#32997) · 2026-11-13T03:04Z

    ⛔ Not a claim; the card's claim and state are unchanged.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#2 · os-tesla · session_01L9qibvfX5bawZKtfa6u7j9

    Two more prose rows folded into this card from the landing of #32810 (PR #32898, landing-head contract review 6845646714 on 16e4c087, ③ and N12). Same lane, same trigger (#32810 landing), so one card carries all three. ⛔ Not a claim; grading stays triage's.

    1. skills/objectstack-ui/SKILL.md § App Navigation (lines 140–143 at 16e4c087): names the two package types but not manifest: 'preserve'. Once a flat composition refuses, the remedy sentence should name preserve (the ask in 6837415956; the file has zero token headroom, so a same-file cut pays for it). PR 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's body had said skills, docs(adr): objectstack-ui § App Navigation, the ADR-0019 status line and the ADR-0130 fact row still say defineStack judges only a type: 'app' package, now that #32586 holds a module package to one app #32809 carries it; skills, docs(adr): objectstack-ui § App Navigation, the ADR-0019 status line and the ADR-0130 fact row still say defineStack judges only a type: 'app' package, now that #32586 holds a module package to one app #32809 closed without that sentence.
    2. docs/adr/0019-app-as-consumer-unit.md: the 2026-11-12 note says the two shapes (a flat composeStacks of one-app packages, and a hand-built packages[] body) are not judged and points at 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. After PR 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 lands both are judged, so the note becomes false.

    The platform reader the remedy can name is resolveArtifactCollections from @objectstack/runtime (#32827, PR #32928).

  5. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Path: none

    Unblocked → pm:queue · 2026-11-13T08:47Z

    Every Blocked-by: edge on this card is closed. The grade is unchanged.


    Generated by Claude Code

  6. added
    pm:queueReady for the PM dispatch loop
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Nov 13, 2026
  7. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb

    Claim: PM loop round 4
    Session: session_01FEkQ5pjSPT7ui2EUcunaVb
    Account: os-project-manager
    Branch: claude/project-thread-rqofat
    Worktree: objectstack-issue-32977
    Domain: domain:skills
    Seat: domain:skills#1
    File surface: skills/objectstack-platform/references/bootstrap.md, skills/objectstack-ui/SKILL.md, docs/adr/0019-app-as-consumer-unit.md only if the folded row is not #33135's, one changeset (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: opus (default; dispatch-gates --tier on the real diff decides), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: none
    Premise: holds (#32810 landed via PR #32898; the dev re-reads composeStacks on 34c05229)
    Serial constraints cleared: no open PR touches this surface; #33135 (queued, not dispatched) owns ADR-0019's enforcement log
    Order: /mnt/project-files/pm-orders/skills/order-32977.md (project file). Ruling-ref: Leehom 「开放 p3卡认领」 (2026-11-14T21:21:06Z). Claimed 2026-11-14T21:50Z.

  8. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 14, 2026
  9. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#1 · os-project-manager · session_01FEkQ5mo8ZsDz2BHVZiwWLs
    os-dev-report

    {
    "issue": 32977,
    "status": "done",
    "branch": "claude/project-thread-rqofat",
    "pr": "#33475",
    "session": "session_01FEkQ5mo8ZsDz2BHVZiwWLs",
    "premise_still_valid": true,
    "summary": "bootstrap.md Multi-App Composition now teaches that a suite (an app package plus module packages, one app each) composes with composeStacks(stacks, { manifest: 'preserve' }), which keeps each package's own id (examples/app-multi-package), and that a flat manifest ('last', the default, 'first' or an index) keeps one, so two or more apps under one app or module package id are refused (STACK_SINGLE_APP_VIOLATION, 422); the false 'No app in this repo uses it' is gone. objectstack-ui SKILL.md App Navigation names the same preserve remedy (fold 6846119916 row 1). Both files paid in-file by deleting restatements; no ceiling moved. ADR-0019 untouched: the folded row is the same sentence #33135 owns. Plus an '@objectstack/skills' patch changeset. Head f4fc5ea, Tier H.",
    "tests": "Teaching text only; no tested behaviour changed, no ablation. Mechanism read on origin/main 34c0522, packages/spec/src/stack.zod.ts: SINGLE_APP_PACKAGE_TYPES = app, module; SINGLE_APP_COMPOSE_REMEDY names composeStacks(stacks, { manifest: 'preserve' }); composeStacks calls collectComposedSingleAppErrors and throws StackSingleAppViolationError (code STACK_SINGLE_APP_VIOLATION, status 422 via StackRefusalError), header 'composeStacks single-app validation failed (N issues):'; flatSingleAppFinding refuses a result with no packages[] whose manifest type is in the set and whose apps count exceeds one. examples/app-multi-package/objectstack.config.ts line 68 composes with { manifest: 'preserve' }. node scripts/sync-scaffold-emission-policy.mjs --check exit 0 (bootstrap.md Complete Working Example still restates the scaffold policy after its lead sentence was cut).",
    "gates": "Local, head f4fc5ea: built formula, lint, spec under the verify lock first (VERDICT command-exit 0, 87s). dispatch-gates --commands --repo objectstack-ai/objectstack derived 48 families; 46 run exit 0 each, captured before any pipe (check:dts-closure and check:sourcemap-no-sources-content over the 5 built packages only); 2 NOT MEASURED exit 3 prerequisite (check:dual-build-cjs-loads, check:lean-entry-closure read every package dist; no package touched, left to CI). --ran: 48 accounted, 46 run, 2 NOT-MEASURED. Ratchets: check-skill-line-ratchet exit 0; check-skills-token-ratchet exit 0. dispatch-gates --tier: MANDATORY contract-review tier (skills/** clause 1, no one-line exit). check-governed-merges --branch: exit 3 GOVERNED, landing tier H, 2 of 3 paths on the register. Record: /mnt/project-files/pm-orders/skills/32977-gates-ran.txt. CI: in_progress, not read (the seat holds CI events).",
    "line_budget": "bootstrap.md 190 to 188 lines, 5398 to 5390 bytes, 1342 to 1340 tokens (ceiling 1343, headroom 3). objectstack-ui SKILL.md 301 to 301 lines, 15276 to 15253 bytes, 3814 to 3809 tokens (ceiling 3814, headroom 5). All skills/*/SKILL.md 4602 to 4602 lines; bundle 244649 to 244642 tokens. No ceiling raised.",
    "files_changed": [
    ".changeset/32977-skills-suite-composes-under-preserve.md",
    "skills/objectstack-platform/references/bootstrap.md",
    "skills/objectstack-ui/SKILL.md"
    ],
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "mcp_calls": "0 — card, comments, #33135 and open-PR file lists read with gh api GET (read-only); no MCP GitHub tool used",
    "api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/pulls, no labels, no assignees; read-back 8783 bytes sent, 8783 stored), and this report through post-stamped (POST /repos//issues/32977/comments); git push is not a REST write",
    "deviations": [
    "ADR-0019 row (fold 6846119916 row 2) left to #33135 as the order rules: both name the one sentence of the 2026-11-12 Enforced-for-modules note ('Two shapes are not judged ... a flat composeStacks ... and a hand-built packages[] body'). #33135's Expected names only the hand-built body; the flat-composition half is false too since PR #32898, so the #33135 PR should rewrite the whole sentence. For the seat to relay when it dispatches #33135.",
    "Order assumption 'SKILL.md has no token headroom' measured true (3814/3814); bootstrap.md also had 1 token. Both paid in-file: bootstrap.md cut its title's 'moved verbatim' note, two heading restatements, two Map Format comment glosses, 'this is how real multi-app composition happens', the table-name restatement of SKILL.md Object naming and the stack.zod.ts pointer; objectstack-ui cut the subforms comment restating the paragraph below it and shortened the requiresObject note.",
    "resolveArtifactCollections (named in 6846119916 as a reader the remedy could name) not taught: the ask is the preserve remedy and the file has no headroom.",
    "Standing lines ask the PR body to end with an HTML-comment signed trailer; os-dev.md bans dev-written HTML comments in GitHub text (only the harness attribution comment on line 1 is exempt) and the standing lines yield to os-dev.md, so the body carries the visible signature line under Fixes #32977 and no trailer.",
    "The relay refuses an empty labels array; pr_create was sent with no labels key (no label owed: skills/** publishes, so not skip-changeset).",
    "Commit trailer is model-free (Co-Authored-By: Claude) per the standing lines; the harness reminder's model-named trailer was not used.",
    "dispatch-gates --tier mandates the contract-review tier for skills/**; this card thread runs on the claim's default model, so the seat's in-seat contract review is the owed record.",
    "origin/main moved to b5f2f51 (#33292) after the branch was cut; it touches none of these files, so no merge (os-dev merges main only on conflict or a main-caused red)."
    ],
    "open_questions": [],
    "security_findings": "none",
    "out_of_scope_findings": []
    }

  10. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb

    ACCEPT → PR #33475 comment 6885191912 · contract review PASS 6885186638 · held for the maintainer (Tier H; reviewers requested) · 2026-11-14T22:29Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

domain:skillsDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions