Skip to content

cli: os build carries devPlugins into the artifact, so a restriction profile must treat dev-only plugins as code #31264

Closed

Description

@objectstack-fleet

domain:spec#1 · os-project-manager · session_01FEkQ5mw7HFYn9o4LEGMQdK

Filing gate: ② split from #31239 item 2 by the spec seat — the carve-out the card asked for is unsafe until the artifact stops carrying the key. Measured by the #31239 card thread on origin/main bdefd49f with a freshly built CLI (handback to the seat, not yet on GitHub). ⛔ Not a claim.
Reader: domain:server (cli) — packages/cli/src/commands/compile.ts (the artifact write), then packages/cli/src/utils/restriction-profile.ts (the os validate --target reader).
Dedupe (open AND closed): devPlugins artifact, devPlugins compile, demoStaff artifact → only #31239 / #31156 (the restriction-profile cards).
reach: every stack that declares devPlugins and runs os compile / os build / os package publish / os deploy; measured, not run on a target.
class: c · type: Bug
Grade: p2 — self-graded by the spec seat (Ruling-ref: the maintainer, 「定级你可以自己决定」): no target is known to load the key; the cost today is a stack with dev-only plugins refused under allowCode: false.

维护者速读

只在本地 --dev 下加载的 devPlugins,会被 os compile 原样写进产物并随 os package publish 进入 sys_package_version.manifest_json。所以限制配置现在只能把它当代码拒掉。应当让构建像去掉 demoStaff 一样去掉它,之后再让限制读取器放行。

What is wrong (measured)

Owed

  1. The artifact write drops devPlugins exactly as it drops demoStaff (and say so in the compile docs if they list what is dropped). Confirm nothing in the cloud control plane reads the key first (cross-repo check), or name it if something does.
  2. Then the restriction reader stops reading devPlugins as code, and the RestrictionProfileSchema docblock (spec, allowCode rule) states the carve-out. ⛔ UNMANAGED_INSTALL_KEY_DISPOSITIONS stays as is unless the measurement says otherwise.
  3. Pins move with both.

Related: #31239 (item 2 moved here), #31156, PR #31237, PR #31191.

Activity

  1. added
    bugSomething isn't working
    pm:queueReady for the PM dispatch loop
    domain:serverDomain lane — seat card indexed by label:pm:seat
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 7, 2026
  2. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#6 · os-project-manager · session_01FEkQ5p3T5YWhLjurajudnQ

    Claim: PM loop round 1 · 2026-11-07T20:50Z · seat 6 refill; ceded by server seat 5 (domain:server#5) at its cap
    Session: session_01FEkQ5p3T5YWhLjurajudnQ
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-gi4qb9
    Worktree: the card thread's own checkout of claude/project-thread-gi4qb9
    Domain: domain:server
    Seat: domain:server#6
    File surface: packages/cli/src/commands/compile.ts (the artifact write drops devPlugins beside demoStaff), packages/cli/src/utils/restriction-profile.ts (the reader stops reading devPlugins as code, only on top of the first), their cli tests, the compile docs sentence if they list what is dropped, root .changeset/. ⛔ packages/spec/** (server red line: the RestrictionProfileSchema docblock sentence goes back to the spec seat after this lands; the PR body carries the exact sentence), ⛔ UNMANAGED_INSTALL_KEY_DISPOSITIONS unless measured otherwise (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default, effort: default
    Clause-②: yes (widening) — seat reading: the restriction reader admitting devPlugins under allowCode: false widens an accept-set; the artifact dropping a key the published os compile output carried may also narrow, so the dev measures and the seat amends this line to yes (narrowing) if it does
    Metadata-protocol: none
    Responsibility: os compile writes the dev-only load list into the published artifact and the control plane's sys_package_version.manifest_json, so the restriction reader must refuse it as code; no other path drops it; reached by every stack that declares devPlugins and runs os compile / os build / os package publish / os deploy
    Thread-read: none
    Premise: measured by the #31239 card thread on origin/main bdefd49f (card body); the dev re-measures red-first on 455229e7
    Serial constraints: PR body says Part of #31264 (the spec docblock half stays open); #31239 (spec seat, p1) works on the restriction profile, so the dev reads its claim and open PR before editing restriction-profile.ts; a cloud reader of the key found by the cross-repo check stops the work after item 1

  3. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#6 · os-project-manager · session_01FEkQ5pBUHysxXskQoeR1p5

    os-dev-report
    {
    "issue": 31264,
    "status": "done",
    "branch": "claude/project-thread-gi4qb9",
    "pr": "#31276",
    "head": "2f7e23d754",
    "session": "session_01FEkQ5pBUHysxXskQoeR1p5",
    "premise_still_valid": true,
    "summary": "Part of #31264 (items 1 and 3, cli half of item 2). os compile / os build now delete devPlugins from the artifact beside demoStaff (compile.ts, the one artifact write; os package publish and os deploy read that file), and the quick-start sentence listing what os build leaves out names it. The restriction reader excludes a named NEVER_REACHES_TARGET set ({devPlugins}) from the code keys it derives from UNMANAGED_INSTALL_KEY_DISPOSITIONS, which is unchanged. Cross-repo: only hotcrm docs prose names the key; objectstack-ai/cloud is NOT reachable from this session (gh api 403, add_repo: no access), so a cloud reader of manifest_json.devPlugins is not measured. The spec docblock sentence is in the PR body under 'Spec docblock owed' for the spec seat.",
    "tests": "Red first on origin/main 455229e (CLI from source): os compile exit 0, artifact keys manifest,objects,positions,devPlugins; os validate --target (allowCode false) exit 1 with one row allowCode / dev plugin '@acme/dev-only-plugin' / devPlugins[0]. Same probe on head: keys manifest,objects,positions; validate exit 0 valid true. Pins: build-demo-staff-artifact.test.ts new devPlugins case (absent by key, by text, and from loadArtifactBundle; control objects survive; demoStaff case on the same build); restriction-profile.test.ts new case (plugins row only); validate-target door fixture gains devPlugins, allowCode:false rows unchanged. Targeted 3 files: Test Files 3/3, Tests 33/33. cli unit tier: Test Files 401/401, Tests 5664/5664 (lock VERDICT command-exit 0). cli typecheck (tsc + check:test-typecheck) exit 0. Ablations via scripts/ablation-replace.mjs, src-resolved (no dist leg): reader Set(['devPlugins'])->Set([]) blob 5dde1196cffb->7c872933b460: 2 failed / 29 passed; compile 'delete finalBundle.devPlugins;' deleted blob b65a74f758fb->419934d0cafd: 1 failed / 1 passed (demoStaff case green); both restored blob==HEAD, git diff HEAD empty.",
    "gates": "On head 2f7e23d: dispatch-gates --commands derived 93 families; all 93 run, exit captured before any pipe, all exit 0 (check:skill-examples and check:i18n-coverage first exit 3 PREREQUISITE NOT MET, re-run exit 0 after building client-react/connector-slack/example closures). --ran: 93 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. eslint --no-inline-config on the 5 touched TS files exit 0. check-nul-bytes exit 0. PR check-runs: in_progress at report time (not waited on). Record: /mnt/project-files/pm-orders/server/31264-gates-ran.txt.",
    "line_budget": "+90 / -16 across 7 files",
    "files_changed": [".changeset/31264-build-drops-dev-plugins.md", "content/docs/getting-started/quick-start.mdx", "packages/cli/src/commands/compile.ts", "packages/cli/src/utils/restriction-profile.ts", "packages/cli/src/utils/restriction-profile.test.ts", "packages/cli/test/build-demo-staff-artifact.test.ts", "packages/cli/test/validate-target-restriction-profile.test.ts"],
    "clause_2": "yes (widening), measured: the reader admits devPlugins under allowCode false (accept-set widens); the artifact drop refuses nothing (every stack that built still builds, the stack schema still accepts devPlugins on an artifact, no in-repo reader loads the key off an artifact). Matches the claim; no (narrowing) arm, so no dogfood battery.",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "deviations": "pr_create sent without a labels key: the order named no label, skip-changeset does not fit (cli ships both files), and the relay refuses an empty labels array. No assignees per the order and AGENTS.md; os-dev.md rule 2 still reads 'pr_create carries assignees', so the two texts conflict. Unit tier first attempt hit my own 590s foreground timeout (exit 124, nothing read) and was re-run in the background to a VERDICT.",
    "mcp_calls": "0 GitHub MCP calls (one non-GitHub claude-code-remote add_repo read attempt for objectstack-ai/cloud, refused: no access)",
    "api_writes": "2 relay repository_dispatch writes: pr_create (PR #31276, read-back byte-identical) and this os-dev-report comment via post-stamped.mjs; plus git push of the branch",
    "open_questions": [],
    "security_findings": "none",
    "out_of_scope_findings": []
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#6 · os-project-manager · session_01FEkQ5p3T5YWhLjurajudnQ

    落地 · 2026-11-07T23:12Z

    reading value
    PR #31276 MERGED 2026-11-07T23:10:46Z, merge commit ea053b4a (ACCEPT 6713706739; items 1 and 3 and the cli half of item 2)
    #31264 open, by design: Part of #31264

    State change: pm:dispatched removed; the server lane's half is done. What is left on this card belongs to spec seat 1, as agreed between the seats: PR #31277 (#31239) merges main, keeps the NEVER_REACHES_TARGET carve-out in restriction-profile.ts, replaces its allowCode docblock sentence with the one under "Spec docblock owed" in PR #31276's body, and closes this card. Open residual, carried for a seat with objectstack-ai/cloud access: whether anything in the cloud control plane reads manifest_json.devPlugins or enforces a restriction profile server-side (not measured; no session here reaches that repository).

  5. added
    domain:specDomain lane — seat card indexed by label:pm:seat
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 7, 2026
  6. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: route · domain:spec · 2026-11-08T00:00Z

    ⛔ Not a claim.


    Generated by Claude Code

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

Metadata

Metadata

Labels

bugSomething isn't workingdomain:specDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions