Repository navigation
Description
epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu
Filing-gate category: ② maintainer-directed task. Maintainer, verbatim (Claude Code session, 2026-11-07), on the seat's proposal to publish the runner as a standalone command-line tool rather than move the scenario machinery into the gallery repository: 「把执行器发布成一个独立的命令行工具,同意」. The same message asked whether it belongs in the os CLI instead. The seat answered no, and this card does not do it. Ruling D on #30291 (verbatim 「同意 D」) already cancelled os lint --eval, keeping scenario scoring out of the customer CLI. This card amends ruling D in one respect only: @objectstack/scenarios becomes a published package (it was private). The cards, runner and scorer stay in this repository. Routing, verbatim: 「能交给车队开发的你不要自己开发」. Epic: objectstack-ai/cloud#3600.
Why
Today running the cards needs a full monorepo checkout, an install and a dependency build (#31161 documents that). External teams and other agent tools (#31159) cannot run a card without cloning the platform. A published CLI gives one entry point. Longer-term, the same tool is how a customer could write acceptance cards for an app an AI built for them; that is a product decision for later and out of scope here.
Ask
- Publish
@objectstack/scenarios(dropprivate: true), versioned with the@objectstack/*release train, with abin(e.g.objectstack-scenarios run …, also vianpx @objectstack/scenarios run …) exposing today'srun-scenariosoptions. - Ship the public cards (
docs/qa/scenarios/*.json) as package data. Never ship anything from the private overlay (objectstack-ai/cloud#3603: held-out and customer-derived cards). Add a packaging test that fails if a card outsidedocs/qa/scenarios/lands in the tarball. - Keep the runner's rules: refuse API-billed logins, default to the published packages (
--packages published, Scenario runner: --packages workspace builds against the workspace's unreleased spec, skills and CLI (default stays published); the exporter refuses workspace records #31147), and the exporter refusesworkspacerecords. - The published entry must load as built JavaScript, not
.ts(the gap @objectstack/scenarios ships .ts-only exports, so a consumer's built entry cannot load./score(ERR_MODULE_NOT_FOUND) or must inline it; give it a minimal unpublished build step and a narrow scorer entry #30915 closed for./score). Check thebinwith a packed-tarball smoke test. - A changeset (
minor, new public package) and a README section for running from npm.
Not in scope: an os subcommand (ruling D stands); customer-facing acceptance cards (needs its own decision card).
Reader: the domain:devx lane seat, from pm:queue. Priority p2: nothing waits on it; the maintainer may raise it.
Activity
objectstack-fleet commentedon Nov 7, 2026
epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu
Priority raised p2 → p1. Maintainer, verbatim (Claude Code session, 2026-11-07): 「31172 31161 改为 p1」. (#31161 already carried p1.)
objectstack-fleet commentedon Nov 7, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit · p1 kept ·
domain:devx· 2026-11-07T15:59Z⛔ Not a claim.
@objectstack/scenariosis published as a standalonenpxCLI, carrying the public cards and never the private overlay. It is not anossubcommand, so ruling D on Scenario library T2b: capability-tag checks in the ported scorer +os lint --evalreads scenario cards #30291 stands except that the package becomes public.domain:devx,area:devpathandpm:queuekept.npm pack --dry-runfile-list check), so a leak is refused rather than shipped.Generated by Claude Code
objectstack-fleet commentedon Nov 7, 2026
domain:devx#3 · os-project-manager · session_01FEkQ5njkh3xbcDN6EtSfw7
Claim: PM loop round 1
Session:
session_01FEkQ5njkh3xbcDN6EtSfw7Account:
os-project-managerBranch:
claude/project-thread-78z461(a project card thread,session_01FEkQ5nGqwL3Ag8M8TdoRiC; the thread can push only its harness branch, a measured platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-31172Domain:
domain:devxSeat:
domain:devx#3File surface:
packages/qa/scenarios/**(package.jsonpublish fields andbin, a thin bin entry over the existing runner CLI, build config, packaging and packed-tarball smoke tests, README); the root.changeset/(31172-*.md, minor); the repo's release/package registries a new published package must appear in, as the gates name them.Container & model:
M,mode:thread,model: default — dispatch-gates --tier: no path-derived mandate,effort: highClause-②: yes
Metadata-protocol: none
Responsibility: n/a — not a defect card; maintainer-directed publication
Thread-read: 6709457749
Premise: holds.
packages/qa/scenarios/package.jsonon main56baf78eisprivate: truewith nobin.Serial constraints cleared: PR #31185 (#31144, same package, in the merge queue) and PR #31188 (#31147,
runner/cli.ts, in review); #31160 (in flight,runner/cli.tsflags). The bin stays a thin wrapper; the dev mergesorigin/mainbefore the PR and again after #31188 lands. A seat contract review (declaration face) is owed on the final head before landing, run in-seat per 「你有 fable ,车道契约复审可以自己做」 (2026-11-07T16:00Z).Order:
pm-orders/devx/order-31172.md(project files), handed to the card thread in its opening message.objectstack-fleet commentedon Nov 7, 2026
domain:devx#3 · os-project-manager · session_01FEkQ5nGqwL3Ag8M8TdoRiC
os-dev-report
{
"issue": 31172,
"status": "done",
"branch": "claude/project-thread-78z461",
"pr": "#31221",
"session": "session_01FEkQ5nGqwL3Ag8M8TdoRiC",
"head": "8ec41a51",
"premise_still_valid": true,
"summary": "@objectstack/scenarios drops private, joins the changesets fixed group (versions with the train, nothing bumped by hand) and ships a bin objectstack-scenarios (bin/objectstack-scenarios.js imports the built dist/bin.js; src/bin.ts dispatches run to the runner CLI's own main with the arguments unchanged, plus help and version). The build copies docs/qa/scenarios/*.json and the capability areas into dist/library (scripts/pack-library.mjs; the package turbo.json adds both dirs to the build inputs), and runner/library.ts locateLibraryRoot reads that copy when the package is not at packages/qa/scenarios of a checkout; cli.ts changes only there (no restructure): out defaults to ./scenario-runs and no framework commit is stamped from npm. A pnpm-pack test allow-lists every JSON in the tarball (manifest + byte-identical open cards and areas), requires origin generic, and smoke-runs the packed bin under plain Node (help, version, the shipped library loads, an API-key login is refused before any scaffold). packages/spec/llms.txt moves 74 to 75 published packages because check:llms-txt derives the count. Owed after #31188 lands (order serial note): merge origin/main again and refuse --packages workspace when locateLibraryRoot answers checkout false, with a smoke case; until then the PR is current with main (merge-tree clean against 66bf5b4, which includes #31185).",
"tests": "On head 8ec41a5: pnpm --filter @objectstack/scenarios typecheck && test under the verify lock: Test Files 25 passed (25), Tests 469 passed (469), VERDICT command-exit 0. New: test/build/packed-tarball.test.ts (8 cases) and test/runner/library.test.ts (6 cases). Ablation 1 (pack-library DIRS widened to docs/qa/platform-checklist, package rebuilt, coverage.json landed in dist/library): packed-tarball 1 failed | 7 passed (the no-other-JSON allow-list); restored blob == HEAD, git diff HEAD empty, package rebuilt (platform-checklist dir holds areas only). Ablation 2 (library.ts real-path comparison replaced by an always-true String(ABL2) check): library.test.ts 1 failed | 5 passed (another workspace read as the checkout); restored blob == HEAD. Both via scripts/ablation-replace.mjs on 2d69cfb. The API-key refusal the smoke pins is existing runner behaviour this diff does not change: not ablated. Lint: eslint packages/qa/scenarios --no-inline-config exit 0.",
"gates": "dispatch-gates --commands on 8ec41a5: 77 commands, all exit 0 (incl. check:changeset-fixed, check:published-files, check:manifest-repository-directory, check:turbo-task-graph, spec check:llms-txt, check:dual-build-cjs-loads after a full build of ./packages/** and ./examples/**: 82/82 tasks, VERDICT 0). --ran: 77 derived accounted for, 77 run, 0 NOT-MEASURED. Beyond the derivation, exit 0: check:published-readme-exports, check:published-readme-links, check:package-naming, check-published-list-mirrors.mjs. First round on 2d69cfb: check:llms-txt exit 1 (count, fixed in c8b7eaf), check:dual-build-cjs-loads exit 3 (prerequisite, before the full build). List: pm-orders/devx/31172-gates-ran.txt. CI check-runs: in_progress at report time (PR just opened).",
"dogfood_battery": "n/a — no
!in the PR title and no (narrowing) arm","files_changed": 14,
"line_budget": "+560 / -23 over 14 files vs origin/main 658d84f",
"deviations": [
"packages/spec/llms.txt (+2/-2) is outside the claimed file surface: check:llms-txt derives the published-package count from the workspace, so publishing this package moves it 74 to 75; named in the PR body.",
"The triage audit asked for a publish-job tarball check; release.yml is not edited (outside the claim). The leak check is the packed-tarball test in Test Core, which runs on every PR and in the merge queue.",
"PR opened on 8ec41a5 (first merge of origin/main); main has since moved (incl. #31185), merge-tree clean. The second merge is owed after #31188 lands, per the order."
],
"mcp_calls": "6 — reads only: issue_read get (1), issue_read get_comments (2), pull_request_read get (2, #31188 and #31185), pull_request_read get_status (1, #31188); no MCP write",
"api_writes": "2 — relay pr_create (fleet-write run 42400365654, read-back identical, no assignees) and this os-dev-report comment via post-stamped",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · noted, not filed — running dist/bin.js directly (node dist/bin.js run) also trips cli.ts self-run guard (argv[1] equals the bundled module URL); the published entry bin/objectstack-scenarios.js is unaffected. Fixing it means touching the guard in cli.ts, which the order rules out."
]
}
Generated by Claude Code
objectstack-fleet commentedon Nov 7, 2026
domain:devx#3 · os-project-manager · session_01FEkQ5nGqwL3Ag8M8TdoRiC
os-dev-report
{
"issue": 31172,
"status": "done",
"branch": "claude/project-thread-78z461",
"pr": "#31221",
"session": "session_01FEkQ5nGqwL3Ag8M8TdoRiC",
"head": "149e988b",
"round": 2,
"premise_still_valid": true,
"summary": "Round 2 on top of report 6711207780. (1) Changeset re-graded minor to patch (9742af0): with Metadata-protocol none the launch-window level rule grades it patch; reproduced the Check Changeset red locally with the PR body as GITHUB_EVENT_PATH and showed it green on patch. (2) CI Test Core timeouts (run 42400730182): root cause, the bin bundled the runner's whole graph (objectql, plugin-sharing, spec; about 1.2 s warm, 8.7 s on a cold container first import), so even help and version paid it. src/bin.ts now imports the runner only for run, and a tsup esbuild plugin (binLoadsBuiltCli) points that import at a separate built entry dist/cli.js: dist/bin.js is 1.5 KB with fs/path/url only, help/version 30 ms. The three run spawn cases get a measured explicit 30 s budget. (3) #31188 merged (86e9ef0) into the branch, no rebase; cli.ts refuses --packages workspace when locateLibraryRoot answers checkout false, before any work dir/build/pack, with a packed-tarball smoke case; README notes it. The direct-run guard trip noted in round 1 is gone (dist/bin.js has no top-level effect).",
"tests": "On head 149e988, after pnpm --filter '@objectstack/scenarios...' build: typecheck && test under the verify lock: Test Files 27 passed (27), Tests 527 passed (527), VERDICT command-exit 0. packed-tarball.test.ts now 10 cases (5.1 s locally, run cases 1.1-1.5 s each, help/version case 123 ms). Ablation 3 (tsup esbuildPlugins emptied: dist/bin.js rebuilt with 19 static @objectstack imports, 196 KB): packed-tarball 1 failed | 8 passed (keeps the runner out of the bin); restored blob == HEAD, rebuilt. Ablation 4 (workspace refusal ANDed with always-false String(ABL4)): rebuilt, ablation-dist-preflight marker present in dist/cli.js and dist/cli.cjs; -t refuses --packages workspace: 1 failed (reached workspace mode, died on fatal: not a git repository); restored blob == HEAD, rebuilt, preflight --absent: absent from 81 files, tree clean. Round-1 ablations 1 and 2 stand. Lint eslint packages/qa/scenarios exit 0.",
"test_budget": "Per test, not per file: the three run spawn cases in packed-tarball.test.ts declare RUN_SPAWN_BUDGET_MS = 30000; readings: 1.1-1.5 s here, 5.7 s and 6.5 s cold on CI Test Core run 42400730182 (vitest 5 s default timed them out), same 30 s-class as built-consumer.test.ts. No file test-budget header: the file reads 5.1 s here, and its CI file reading is NOT MEASURED (the run 42400730182 job log as served holds only its last 5000 lines, which end past the scenarios output). If the next CI run reads the file over 10 s, the header is header-grammar work for the refresh lane or a follow-up push.",
"gates": "dispatch-gates --commands on 149e988: 77 commands, all exit 0 (incl. check-changeset-no-major, check:changeset-fixed, check:published-files, check:turbo-task-graph, spec check:llms-txt, check:dual-build-cjs-loads after a full build 82/82 tasks VERDICT 0). --ran: 77 derived accounted for, 77 run, 0 NOT-MEASURED. Beyond the derivation, exit 0: check:published-readme-exports, check:published-readme-links, check:package-naming, check-published-list-mirrors.mjs. List: pm-orders/devx/31172-gates-ran.txt. merge-tree vs origin/main 733efbd clean. CI check-runs on 149e988: in_progress at report time.",
"dogfood_battery": "n/a — no
!in the PR title and no (narrowing) arm","files_changed": 14,
"line_budget": "+619 / -25 over 14 files vs origin/main (three-dot)",
"deviations": [
"packages/spec/llms.txt (+2/-2), outside the claimed surface: check:llms-txt derives the published-package count (accepted by the seat as same-class fallout).",
"The order said minor; the changeset is patch (Check Changeset level rule under Metadata-protocol none), per the seat note.",
"PR body: not PATCHed by the dev. The round-2 body is at pm-orders/devx/31172-pr-body.md with the seat trailer as its last line, for the seat to apply."
],
"mcp_calls": "9 — reads only: issue_read get (1), issue_read get_comments (2), pull_request_read get (3: #31188, #31185, #31221), pull_request_read get_status (1), get_job_logs (2, job 128488380590); no MCP write",
"api_writes": "3 — relay pr_create (round 1), os-dev-report comment 6711207780 (round 1), this comment",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": []
}
Generated by Claude Code
objectstack-fleet commentedon Nov 7, 2026
domain:devx#3 · os-project-manager · session_01FEkQ5njkh3xbcDN6EtSfw7
Landed 2026-11-07T20:02Z · PR #31221 merged through the merge queue at 2026-11-07T20:01Z, as
fba4c00a636f9ccbfcfeb12d7b5f1d39f067ad71.merged: true, merge commitfba4c00a63, head reviewed149e988b3c(contract review 6712007221 PASS, ACCEPT 6712016348)completedbyFixes #31172State change:⚠️ ); the allow-list in Test Core and Publish Smoke cover it today, so it waits for a maintainer ask.
pm:dispatchedremoved (card closed).@objectstack/scenariosis now a published package with theobjectstack-scenariosbin; its first release goes out with the next changeset version. Next: #31159 (external driver contract), serial behind this PR onrunner/cli.ts, starts now. Not filed: a release-timenpm pack --dry-runguard inrelease.yml(triage