Skip to content

cli: os init -t plugin and os create plugin emit a test script but no test file, so the fresh scaffold's npm test exits 1 with "No test files found" #25175

Closed

Description

@objectstack-fleet

Filing gate ①: a measured defect on the scaffold path, from the out-of-scope finding of #25165's dev (report on #25165, PR #25173). Filed by domain:cli seat 2 (seat post #22648) · os-bill · session session_01AFrKwndmrCLtF5V9hNtrw3. ⛔ Not a claim. Grade: triage's.

Reader, and what they do: the domain:cli seat, in one PR on packages/cli/src/commands/init.ts (TEMPLATES.plugin) and packages/cli/src/commands/create.ts (the plugin scaffold), serial after #25165 (same file).

The reading

Done when

  • A fresh os init -t plugin and a fresh os create plugin scaffold each pass npm test out of the box, by shipping one meaningful starter test (as the blank template does) or by a test script that does not fail on an empty suite; the route and why it is honest are stated in the PR.
  • A pin that a fresh plugin scaffold's npm test exits 0.

Dedupe

objectstack search_issues: "os init plugin npm test No test files found scaffold test script without test file os create plugin vitest exit 1" → 17 hits; the nearest (#25165, #23805, #22912, #20333) concern vitest installs and the blank template's config, none an empty test suite. New.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    and removed on Oct 22, 2026
  2. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · domain:cli seat 2 · p2 · filed by this seat (exception 2: filer-labelled, the lane fits the table, the body carries the filing gate's three answers) · 2026-10-22T07:13Z
    Session: session_01AFrKwndmrCLtF5V9hNtrw3
    Account: os-bill (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-25175-plugin-scaffold-test
    Worktree: objectstack-issue-25175
    Domain: domain:cli
    Seat: domain:cli#2 (seat post #22648)
    File surface (read on origin/main b6e870707; stop on a breach and explain it in the report): packages/cli/src/commands/init.ts (TEMPLATES.plugin only), packages/cli/src/commands/create.ts (the plugin scaffold only), the starter test files those scaffolds emit, their pins, and a changeset for @objectstack/cli.
    Container & model: M, mode:subagent, model: default tier (dispatch-gates.mjs --tier: "no path-derived mandate")
    Clause-②: no
    Basis for the Clause-② line: the plugin scaffolds start to ship a passing test; no accept set or public surface widens.
    Responsibility: this lane's os init -t plugin and os create plugin scaffolds; the platform path that already covers the shape is the create-objectstack blank template, which ships a starter test; it reaches every plugin author whose fresh scaffold's npm test exits 1.
    Thread-read: none
    Serial constraints cleared: #25165 landed (PR #25173, b6e870707), releasing init.ts's SCAFFOLD_VITEST_RANGE region. #25174 (in flight) may touch init.ts's SCAFFOLD_NPM_OVERRIDES region if its measured route is a scaffold override: a different region, ordinary concurrency, whichever lands second merges main. Fold-or-serial with #25123 (p3, SCAFFOLD_ALLOWED_PEER_VERSIONS in the same file): different fix shape, not folded; #25123 is serial after this card. No open PR touches these files (the open PRs' file lists read at 2026-10-22T06:36Z).


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 25175,
    "status": "blocked",
    "branch": "claude/issue-25175-plugin-scaffold-test",
    "pr": "#25196",
    "session": "session_01AFrKwndmrCLtF5V9hNtrw3 — this run's harness-stamped id (Claude-Session trailer on every commit)",
    "premise_still_valid": true,
    "summary": "Delivered the os init -t plugin half as draft PR #25196 (Part of #25175). TEMPLATES.plugin now emits package.test.ts. It imports the package's stack (defineStack's strict parse) and asserts the stack is a plugin that holds every object the src/objects barrel exports. Fresh npm 10 scaffold: npm test exit 0, 1 file, 1 test. A pin runs the emitted test script outside the repo, with a control (no test file means exit 1) and two ablations. BLOCKED on the os create plugin half. Any emitted test file there makes create-plugin-docs-parity.test.ts require one listing line on each of three public pages (content/docs/plugins/index.mdx, content/docs/protocol/kernel/index.mdx, content/docs/protocol/kernel/plugin-spec.mdx). Those pages are outside the dispatched file surface, which says stop on any other breach, so I stopped and did not touch create.ts or the docs. The one PM action: widen the surface to those three pages and send a patch round on this branch and PR. Its options are already measured (open_questions). Premise held: both baselines reproduce exit 1 'No test files found' on npm 10.9.4 with published 18.0.0.",
    "tests": "Head 88a38f3 (branch merged with origin/main f7d7403). (1) Full @objectstack/cli unit tier: pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2 under os-verify-lock, 'Test Files 324 passed (324)', 'Tests 4775 passed (4775)', VERDICT command-exit 0. Integration tier declared to CI (no spawn entry or integration-tier file touched). (2) New pin plus the 16 existing pins that sweep os init and create templates (17 files): 'Test Files 17 passed (17)', 'Tests 268 passed (268)'. New pin cases: shipped-test run 4246 ms, control 389 ms. (3) pnpm --filter @objectstack/cli typecheck exit 0. tsc --noEmit plus check:test-typecheck 'OK — 3 file(s) / 28 error(s) / 6 pinned signature(s) held'. --listFilesOnly shows the new pin is in tsconfig.test.json's program. (4) Ablation through scripts/ablation-replace.mjs, no dist on the path (init.ts imported by relative source specifier). Leg A, emitted key 'package.test.ts' renamed to 'package.ts': red, 'declares a test script and emits no test file: expected 0 to be greater than 0'. Leg B, shipped toBe('plugin') changed to toBe('app'): red, 'package.test.ts > this package is a plugin that hands every object in src/objects to the stack: AssertionError: expected 'plugin' to be 'app''. Each leg restored: blob == HEAD 3dff72ee5d0a and git diff HEAD empty. (5) npm e2e, os init e2e-pkg -t plugin from this branch's bin/run-dev.js, npx -y npm@10 (10.9.4), scratch cache, vitest 4.1.12, spec 18.0.0: npm test exit 0 ('Test Files 1 passed (1)', 736 ms). Baseline with the file removed: exit 1 'No test files found, exiting with code 1'. typecheck, build (dist/objectstack.json), validate and lint all exit 0. (6) The emitted test can fail on a real defect. With the config's objects emptied: 'AssertionError: expected [] to include ...'. With an undeclared manifest key: StackSchemaInvalidError at load. (7) os create plugin, measured only, nothing committed. Baseline npm test exit 1 'No test files found' (script is bare 'vitest'). S1 colocated src/index.test.ts with tsc build: after build, dist/index.test.js is also collected, 'Test Files 2 passed (2)' (vitest 4.1.12 configDefaults.exclude is only node_modules and .git). S2 with tsconfig.build.json excluding tests: dist clean, 1 file, and typecheck catches a planted test type error (TS2322). S3 test/ outside rootDir src: TS6059 under --noEmit too.",
    "gates": "Local, head 88a38f3. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 69 families from merge base f7d7403; I ran all of them plus pnpm check:template-version-sync, each with its exit code captured before any pipe. 70 of 70 end at exit 0. check:scaffold-emission-policy exit 0. check:template-version-sync exit 0. check:dual-build-cjs-loads and check:i18n-coverage first exited 3 (PREREQUISITE NOT MET, packages outside the CLI closure had no dist), then exit 0 once those were built. --ran reconciliation: '69 derived, 69 run, 0 NOT-MEASURED, 0 UNRUN' ('a DERIVED zero — all 69 recorded an exit code and none of them is 3'). CI check-runs on 88a38f3 when read: all in_progress except 'No other open PR may claim the same issue' (success) and the two opt-in jobs (skipped). Families named in_progress: Check Changeset, Lint · ESLint, Lint · repo & tooling gates, Lint · CI, release & engine gates, Lint · docs & code guards, Lint · PM dispatch-gates, Type Check · workspace, Type Check · source gates, Type Check · consumer gates, Type Check · debt ledger, Governed Surface Queue Guard, Scaffold outside the monorepo, install, build (os-create-smoke), Part-of PR must not also close its card. Test Core and Build Core were not listed yet. NOT MEASURED: test:repo (CI's), the dogfood/temporal batteries (main push only).",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm (Clause-②: no)",
    "line_budget": "n/a — the diff touches no skills/** file and no ratcheted ledger (284 added lines across 3 files, under the 3000-line human-merge threshold)",
    "files_changed": [".changeset/25175-plugin-scaffold-test.md", "packages/cli/src/commands/init.ts", "packages/cli/test/scaffold-test-script-passes.test.ts"],
    "deviations": [
    "PR body first line is 'Part of #25175', not the dispatched closing form, because the PR delivers only the os init -t plugin half (os-dev rule for a partial). The seat switches it to the closing form when the create half lands in the patch round.",
    "The os create plugin half is not implemented: stopped on a file-surface breach (three content/docs pages), per the dispatch's 'Stop on any other breach'.",
    "The harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. Commits carry AGENTS.md's model-free pair (Claude-Session plus 'Co-authored-by: Claude'), and the PR carries AGENTS.md's session-URL footer: AGENTS.md takes precedence.",
    "Branch merged origin/main (f7d7403) once before the PR opened (AGENTS §10).",
    "First locked pin run returned queue-timeout 99 (another agent's 930 s CLI unit run held the lock). Re-run when the lock was free: green."
    ],
    "mcp_calls": "0 — no MCP GitHub tool used; reads were gh api REST GETs (issue 25175 and its comments, issue 25165 comments, the PR and its check-runs)",
    "api_writes": "2 relay strokes as objectstack-fleet[bot]. (1) pr_create: POST /repos/objectstack-ai/objectstack/pulls (draft) plus POST /repos//issues/25196/assignees (os-bill), run 39751486047, read back 10458 bytes identical. (2) comment: POST /repos//issues/25175/comments (this report). Each stroke is also one POST /repos/objectstack-ai/objectstack/dispatches under the session token. git push is not a REST write: 6 pushes of this branch. No labels written.",
    "open_questions": [
    {
    "question": "The os create plugin half needs three content/docs pages outside the dispatched surface (create-plugin-docs-parity.test.ts holds their printed file trees equal to the emitted file set). Widen the surface?",
    "options": [
    "A: widen the surface to content/docs/plugins/index.mdx, content/docs/protocol/kernel/index.mdx and content/docs/protocol/kernel/plugin-spec.mdx (one listing line per new file per page) and send a patch round on this branch and PR #25196. The seat flips line 1 to the closing form.",
    "B: land #25196 as Part of #25175 and give the create half its own card."
    ],
    "recommendation": "A. The docs edits are mechanical and forced by an existing pin. One PR keeps the card's two halves and their shared pin together. The create half's design is already measured (next question)."
    },
    {
    "question": "Where should the os create plugin starter test live? Its tsconfig is rootDir 'src' and its build is plain tsc.",
    "options": [
    "S1: src/index.test.ts, tsconfig unchanged. Measured: tsc emits dist/index.test.js and .d.ts, and vitest 4 (default exclude only node_modules and .git) then collects it, 'Test Files 2 passed (2)'.",
    "S2: src/index.test.ts plus tsconfig.build.json (extends ./tsconfig.json, exclude dist, node_modules, src/**/*.test.ts), build and dev scripts 'tsc -p tsconfig.build.json', test script 'vitest run'. Measured: dist holds only index.js and index.d.ts, 1 file collected, typecheck catches a planted test type error (TS2322).",
    "S3: test/index.test.ts. Measured: outside rootDir 'src', so the test escapes typecheck (including it fails TS6059, under --noEmit too).",
    "S4: 'vitest run --passWithNoTests'. Rejected by H2: exit 0 with nothing run."
    ],
    "recommendation": "S2, by the four axes. Business need, measured: a user who builds and then tests gets a doubled suite under S1. Long-term soundness: S2 is the conventional build/typecheck split and keeps dist clean. Preventing AI mistakes: S3 hides type errors in tests and S4 hides an empty suite, and S2 hides neither. Startup scope: S2 costs one extra emitted file (tsconfig.build.json, which also needs a docs listing line), with no new dependency. The test can assert PluginSchema (from @objectstack/spec/kernel, the contract both kernels run at use()) plus name and init, which the loader requires, using only the declared @objectstack/spec."
    }
    ],
    "out_of_scope_findings": [
    "carrier: none · noted, not filed (PR #25196 Acceptance notes): os init without a NAME scaffolds into the current directory and overwrites any existing file at a template path; only the empty wired barrels are written where none exists. package.test.ts joins src/objects/index.ts and the item object in that set. This is a read-only observation with no measured reach. Dedupe words: os init overwrite existing file current directory; writeTemplateSrcFiles overwrite; init no-name scaffold clobber",
    "carrier: none · noted, not filed (PR #25196 Acceptance notes): the new pin file reads about 20 s of wall locally, of which about 15 s is importing init.ts (paid by every os init pin) and about 4.7 s is its tests. The per-file 10 s timing line is report-only."
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: session session_01AFrKwndmrCLtF5V9hNtrw3 · account os-bill · domain:cli seat 2 · 2026-10-22T11:50Z · 因: partial landing (the seat is signing off on the maintainer's order 「当前任务处理完,合并后就下班」) · 去向: pm:queue, unassigned, for the next holder of this lane.

    • Landed: the os init -t plugin half, PR fix(cli): os init -t plugin ships a starter test, so a fresh scaffold's npm test passes #25196 (Part of #25175), merged through the merge queue as 9c431bad3 (2026-10-22T11:38Z; on origin/main). A fresh os init -t plugin scaffold now ships package.test.ts, and its npm test exits 0 on npm 10.
    • Left (the remainder of this card): the os create plugin half. Its npm test still exits 1 "No test files found".
      • It needs a wider file surface than the first dispatch gave: create-plugin-docs-parity.test.ts holds three public pages' printed file trees equal to the emitted file set, so a new emitted test file needs one listing line each on content/docs/plugins/index.mdx, content/docs/protocol/kernel/index.mdx and content/docs/protocol/kernel/plugin-spec.mdx.
      • The dev measured where the starter test should live (report on this card, open_questions): S1 src/index.test.ts with the tsconfig unchanged (tsc then emits the test into dist and vitest collects it twice); S2 the same file plus a tsconfig.build.json that excludes tests (dist clean, one file collected, typecheck still covers the test; recommended); S3 test/ outside rootDir (escapes typecheck); S4 --passWithNoTests (rejected: runs nothing). These are leads for the next dispatch, to re-measure.
    • Resume-from: none (the PR fix(cli): os init -t plugin ships a starter test, so a fresh scaffold's npm test passes #25196 branch carries only the landed half).
    • The PR that finishes it carries Fixes #25175.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: card thread · domain:cli seat 1 (seat post #6024, project run by the Sales account) · p2 · the remainder of this card (the os create plugin half) · 2026-10-22T13:10Z
    Session: session_01QkpbEcZUG5GHxLNpzuuR5y
    Account: os-sales (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-4oxk47 (the harness-pinned branch for this session; it names no issue, so the Duplicate Fix Guard's branch-name hint will not match — this claim is the identity record)
    Worktree: the session's own container checkout (one task per container)
    Domain: domain:cli
    Seat: domain:cli#1 (seat post #6024)
    File surface (read on origin/main 123ff6f; stop on a breach and explain it in the report): packages/cli/src/commands/create.ts (the plugin template only), the starter test file and build tsconfig that template emits, their pins under packages/cli/test/, the three pages create-plugin-docs-parity.test.ts holds equal to the emitted file set (content/docs/plugins/index.mdx, content/docs/protocol/kernel/index.mdx, content/docs/protocol/kernel/plugin-spec.mdx — one listing line per new emitted file, widened per the previous dev's measured open question A), and a changeset for @objectstack/cli.
    Container & model: M, card thread (in-session executor), model: default tier (dispatch-gates.mjs --tier: "no path-derived mandate")
    Clause-②: no
    Basis for the Clause-② line: the os create plugin scaffold starts to ship a passing starter test; no accept set or public surface widens.
    Responsibility: this lane's os create plugin scaffold; the platform path that already covers the shape is the create-objectstack blank template and, since 9c431bad3, os init -t plugin, both of which ship a starter test; it reaches every plugin author whose fresh os create plugin scaffold's npm test exits 1.
    Thread-read: 6340030798
    Serial constraints cleared: the os init -t plugin half landed (9c431bad3); this half does not touch init.ts. Test location re-measured before any choice is committed (the release's S1–S4 leads; S2 recommended there).
    Resume-from: none (the release names none).


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 25175,
    "status": "done",
    "branch": "claude/project-thread-4oxk47",
    "pr": "#25236",
    "session": "session_01QkpbEcZUG5GHxLNpzuuR5y — this run's harness-stamped id (Claude-Session trailer on every commit)",
    "premise_still_valid": true,
    "summary": "Delivered the os create plugin half as draft PR #25236 (Fixes #25175). The plugin template now emits src/index.test.ts (the kernel's load-time checks: name, init, PluginSchema via @objectstack/spec/kernel) and tsconfig.build.json (extends tsconfig.json, excludes src/**/*.test.ts); build/dev compile through it, test is 'vitest run', typecheck stays on tsconfig.json. The three docs listings gained one line per new file. Premise held: main's os create plugin scaffold, npm 10.9.4 with published spec 18.0.0, npm test exits 1 'No test files found'.",
    "tests": "Head 2aed9dd (branch merged with origin/main 03de83b). (1) cli unit tier full: vitest run --project unit --maxWorkers=2, 'Test Files 324 passed (324)', 'Tests 4784 passed (4784)'. Integration tier declared to CI (no spawn entry or integration-tier file touched). (2) pin + create-plugin-docs-parity + create: 'Test Files 3 passed (3)', 'Tests 32 passed (32)'. (3) pnpm --filter @objectstack/cli typecheck exit 0; check:test-typecheck OK. (4) Ablation via scripts/ablation-replace.mjs, each leg restored blob == HEAD and git diff HEAD empty: A build 'tsc' -> red 'the build compiled the starter test into dist/: expected [ index.test.d.ts, index.test.js ] to deeply equal []'; B build config without the test exclude -> same red; C typecheck through tsconfig.build.json -> red 'a type error in the starter test passed typecheck'; D test file key renamed -> 3 cases red; E emitted init renamed start -> red "expected 'undefined' to be 'function'"; F emitted version v0.1.0 -> red, PluginSchema issues non-empty. (5) npm e2e outside the repo, os create plugin e2e-pkg from this branch, npx -y npm@10 (10.9.4), spec 18.0.0, vitest 4.1.12: npm test exit 0 'Test Files 1 passed (1)'; npm run build exit 0, dist = index.d.ts index.js; npm test after build 'Test Files 1 passed (1)'; typecheck exit 0; test file removed -> exit 1 'No test files found'.",
    "gates": "Local, worktree of the branch. dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 97 commands; all run with exit codes captured to a file before any pipe, plus check:template-version-sync and check:scaffold-emission-policy. Final: 99 of 99 exit 0. Four first exited 3 on prerequisites outside the diff (check-plugin-teardown-shape --self-test: pinned fixture commit absent from the shallow clone; check:skill-examples, check:dual-build-cjs-loads, check:i18n-coverage: dist of packages outside the CLI closure) and exit 0 after fetching that commit and a full pnpm build. --ran reconciliation not run (the exit-code file is the record). CI check-runs on the PR: pending at report time.",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm (Clause-②: no)",
    "mcp_calls": "MCP GitHub reads only: issue_read (#25175, comments), pull_request_read (#25196). No MCP write.",
    "api_writes": "Relay strokes as objectstack-fleet[bot]: label-write assign os-sales; post-stamped claim comment 6341601909; label-write +pm:dispatched -pm:queue; pr_create #25236 (draft, assignee os-sales, read back 7554 bytes identical); pr_request_reviewers os-sales; this report comment. git pushes: 2.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · noted, not filed (PR #25236 Acceptance notes): os create's printed 'Next steps' list pnpm install / pnpm build and do not mention pnpm test. Read-only observation, no defect reach.",
    "carrier: none · noted (PR #25236 Acceptance notes): deviation from the card-thread protocol landed in 03de83b while this ran — this thread was spawned by the project coordinator, not a seat, so it wrote its own assignee and Claim (comment 6341601909) and pushes the harness-pinned branch claude/project-thread-4oxk47, recorded in that claim."
    ]
    }


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #25236 comment 6345665936 · domain:cli seat 1 · session session_01CxBKycaiUpA1yGx1XyoGqX · 2026-10-22T16:20Z


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:cli seat 1 · session session_01CxBKycaiUpA1yGx1XyoGqX · 2026-10-22T16:49Z

    reading result
    PR #25236 object merged: true, merge commit 6bc8cc6a7, merged 2026-10-22T16:47:43Z through the merge queue
    origin/main 6bc8cc6a7 is an ancestor of origin/main, single parent (squash)
    queue branch no gh-readonly-queue/main/* head for PR 25236 remains

    State: card closed completed by Fixes #25175; pm:dispatched stripped in this act.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:clipriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions