Skip to content

feat(01KVS2MG): Authoring refuses a story whose vitest target cannot resolve to a runnable package#440

Merged
jackmcintyre merged 1 commit into
mainfrom
feat/01KVS2MG-unresolvable-test-target
Jun 23, 2026
Merged

feat(01KVS2MG): Authoring refuses a story whose vitest target cannot resolve to a runnable package#440
jackmcintyre merged 1 commit into
mainfrom
feat/01KVS2MG-unresolvable-test-target

Conversation

@jackmcintyre

Copy link
Copy Markdown
Owner

What

Authoring and scan-time planning-discipline now refuse a story whose vitest: verification target cannot resolve to a runnable package — catching wrong-path test markers BEFORE a build is wasted.

The validator already existence-checked cited sources and artifact: targets, but vitest: targets were only shape-checked (isRunnableTestTarget). That left a gap: a wrong-prefix target like mcp-server/tests/x.test.ts (instead of plugins/flow/mcp-server/tests/x.test.ts) is a perfectly valid shape but has no package above it, so the build/review round was doomed yet still started.

How

  • Extracted findPackageRoot (and its workspace helpers hasLocalVitest, findVitestInWorkspaceMembers, findWorkspaceYamlInSubtree) from tools/run-reviewer-session.ts into a new shared lib lib/find-package-root.ts. run-reviewer-session.ts now imports and re-exports findPackageRoot by name, so existing callers (and an upcoming story) keep their import path. The review-time vitest check and the new author/scan-time check now share one walk and cannot diverge.
  • discipline-resolvability.ts runs the shared findPackageRoot walk after the existing shape check, for each vitest: target. On no package root, it pushes a new unresolvable-test-target violation naming the offending target. This validator backs both author time (writeNativeStory) and scan time (scanSources).
  • New unresolvable-test-target code added to the DisciplineViolationReason union.

Acceptance criteria

  • AC1 — a wrong-prefix / no-package vitest: target is refused with unresolvable-test-target naming the target; nothing is written/materialised (the gate throws before any build). Covered by the new resolvability tests in discipline-runnable-test-kind.test.ts.
  • AC2 — a not-yet-existing test file under a real package PASSES: the check verifies a package resolves, NOT that the test file already exists (preserves the build-creates-it intent). Explicitly tested (the target file is stat-confirmed absent, yet zero violations).
  • AC3 — a shape-invalid target (not under __tests__/, not .test/.spec) still fails with the EXISTING non-runnable-test-target violation, and the new resolvability check does NOT double-report. No regression.

Test / build

  • Target test green: src/validators/__tests__/discipline-runnable-test-kind.test.ts (27 tests).
  • Full suite green: 3788 passed / 251 files. Fixtures across the suite that author/scan a fresh native story with a shape-valid vitest target now seed a workspace-root package.json so the target resolves (the real monorepo always has one).
  • Coverage: overall line 86.12% ≥ 86% gate.
  • Rebuilt the committed dist bundle (dist/index.js, dist/cli.js) — no drift.
  • Lint + typecheck clean. No .flow/state/** touched.

https://claude.ai/code/session_01E5VyKQMGJSL6fRfRmCzuvs

…le package

Authoring and scan-time discipline now reject a story whose vitest
verification target has no package.json between it and the repo root
(e.g. a wrong-prefix `mcp-server/tests/x.test.ts` instead of
`plugins/flow/mcp-server/tests/x.test.ts`), with a new
`unresolvable-test-target` violation that names the offending target —
before any build is wasted.

- Extract findPackageRoot (and its workspace helpers) from
  tools/run-reviewer-session.ts into lib/find-package-root.ts so the
  author/scan-time check and the review-time vitest check share ONE walk
  and cannot diverge. run-reviewer-session.ts re-exports findPackageRoot
  so it stays importable by name.
- discipline-resolvability.ts runs the shared walk after the existing
  shape check; the test FILE need not exist (the build creates it), only
  an enclosing package must resolve — so a not-yet-existing test file
  under a real package still passes.
- Existing non-runnable-test-target shape check and artifact/cited-source
  existence checks unchanged (no regression).
- Tests cover: wrong-prefix refusal, not-yet-existing-file pass,
  shape-invalid still non-runnable-test-target. Fixtures across the suite
  seed a workspace-root package.json so shape-valid vitest targets resolve.
- Rebuilt committed dist bundle.

Claude-Session: https://claude.ai/code/session_01E5VyKQMGJSL6fRfRmCzuvs
@jackmcintyre jackmcintyre merged commit 5183a14 into main Jun 23, 2026
1 check passed
@jackmcintyre jackmcintyre deleted the feat/01KVS2MG-unresolvable-test-target branch June 23, 2026 22:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant