Problem Statement
PR #633 introduced the first Node/TypeScript application (Vite/esbuild + Vitest) under src/500-application/: 516-chat-with-your-factory. The app already ships Vitest with the @vitest/coverage-v8 provider and passing unit tests, but nothing in CI runs those tests, enforces them, or reports coverage to Codecov.
Rust crates in the same folder have a complete coverage + registration + enforcement contract (see .github/instructions/rust-crate-registration.instructions.md). Node/Vite apps have no equivalent, so unit tests can silently rot and coverage is invisible. This gap will repeat for every future Node/Vite app unless a shared baseline is established.
Current State (gap analysis)
| Concern |
Rust (exists) |
Node/Vite (missing) |
| Test + coverage runner in CI |
rust-tests.yml matrix runs cargo llvm-cov → Codecov (flags: rust) |
No workflow runs npm test / vitest --coverage for 500-application apps (docusaurus-tests.yml is docs-only) |
| PR gating / change detection |
rust-tests gated by changesInRust from scripts/build/Detect-Folder-Changes.ps1 |
application-matrix-builds.yml only builds Docker images; never runs unit tests/coverage |
| Codecov flag + paths |
codecov.yml has flags.rust.paths + project/patch status |
No js/node flag, paths, or coverage status; 516 not registered |
| Registration enforcement |
validate-rust-registration.yml + Validate-RustCrateRegistration.ps1 |
No equivalent gate for Node packages |
| Authoring docs / instructions |
rust-crate-registration.instructions.md |
No instruction file for registering a Node app |
What 516 already has (local only)
test, test:watch, test:coverage scripts and @vitest/coverage-v8 in package.json
- A
vitest.config.ts with a v8 coverage provider (default text reporter only — no Cobertura/lcov output)
- At least one real test:
src/server/factoryTool.test.ts
Proposed Solution
Build a generic baseline for all Vite/Node apps under src/500-application/, not a one-off for 516.
-
Reusable Node test/coverage workflow (e.g. .github/workflows/node-tests.yml)
- Matrix over registered Node packages under
src/500-application/
npm ci → npm run test:coverage → upload Cobertura/lcov to Codecov under a new js (or node) flag
- Standardize a coverage reporter (Cobertura/lcov) in each app's
vitest.config.ts (516 currently emits only the default text reporter) and a consistent test:coverage script convention
-
PR gating in pr-validation.yml
- Add a
changesInNode-style output to scripts/build/Detect-Folder-Changes.ps1 so the workflow runs only when Node app files (or the workflow/codecov config) change
-
Codecov registration in codecov.yml
- Add
flags.js with per-app paths, plus coverage.status.project/patch entries, or an explicit ignore opt-out path — matching the Rust flag model
-
Registration enforcement gate
- New validator workflow + script (mirroring
Validate-RustCrateRegistration.ps1) that fails a PR when a Vite/Node app under src/500-application/ is neither fully registered (workflow matrix + codecov flag) nor explicitly opted out
-
Authoring instructions
- New
node-package-registration.instructions.md with applyTo: **/src/500-application/**/package.json (+ workflow/codecov globs), documenting the registration/opt-out contract, analogous to the Rust instructions
Benefits
- Node/Vite apps get the same coverage visibility and enforcement guarantees as Rust crates
- Prevents silent test rot and untracked coverage as more Node apps land under
src/500-application/
- Establishes a documented, self-service registration path for future app authors
Acceptance Criteria
Notes / Open Questions
- Flag naming: reuse
js to align with the existing fuzz-js-* scheme, or use node?
- Node version: standardize on
24 (used across existing workflows) vs. per-app engines
- Should coverage thresholds start
informational: true (like Rust patch) to avoid blocking early adopters?
Related Issues
Problem Statement
PR #633 introduced the first Node/TypeScript application (Vite/esbuild + Vitest) under
src/500-application/:516-chat-with-your-factory. The app already ships Vitest with the@vitest/coverage-v8provider and passing unit tests, but nothing in CI runs those tests, enforces them, or reports coverage to Codecov.Rust crates in the same folder have a complete coverage + registration + enforcement contract (see
.github/instructions/rust-crate-registration.instructions.md). Node/Vite apps have no equivalent, so unit tests can silently rot and coverage is invisible. This gap will repeat for every future Node/Vite app unless a shared baseline is established.Current State (gap analysis)
rust-tests.ymlmatrix runscargo llvm-cov→ Codecov (flags: rust)npm test/vitest --coveragefor500-applicationapps (docusaurus-tests.ymlis docs-only)rust-testsgated bychangesInRustfromscripts/build/Detect-Folder-Changes.ps1application-matrix-builds.ymlonly builds Docker images; never runs unit tests/coveragecodecov.ymlhasflags.rust.paths+ project/patch statusjs/nodeflag, paths, or coverage status; 516 not registeredvalidate-rust-registration.yml+Validate-RustCrateRegistration.ps1rust-crate-registration.instructions.mdWhat 516 already has (local only)
test,test:watch,test:coveragescripts and@vitest/coverage-v8inpackage.jsonvitest.config.tswith av8coverage provider (default text reporter only — no Cobertura/lcov output)src/server/factoryTool.test.tsProposed Solution
Build a generic baseline for all Vite/Node apps under
src/500-application/, not a one-off for 516.Reusable Node test/coverage workflow (e.g.
.github/workflows/node-tests.yml)src/500-application/npm ci→npm run test:coverage→ upload Cobertura/lcov to Codecov under a newjs(ornode) flagvitest.config.ts(516 currently emits only the default text reporter) and a consistenttest:coveragescript conventionPR gating in
pr-validation.ymlchangesInNode-style output toscripts/build/Detect-Folder-Changes.ps1so the workflow runs only when Node app files (or the workflow/codecov config) changeCodecov registration in
codecov.ymlflags.jswith per-apppaths, pluscoverage.status.project/patchentries, or an explicitignoreopt-out path — matching the Rust flag modelRegistration enforcement gate
Validate-RustCrateRegistration.ps1) that fails a PR when a Vite/Node app undersrc/500-application/is neither fully registered (workflow matrix + codecov flag) nor explicitly opted outAuthoring instructions
node-package-registration.instructions.mdwithapplyTo: **/src/500-application/**/package.json(+ workflow/codecov globs), documenting the registration/opt-out contract, analogous to the Rust instructionsBenefits
src/500-application/Acceptance Criteria
vitestwith coverage for registered apps and uploads to Codecov under a dedicated flag516-chat-with-your-factoryis registered and reporting coverage as the first consumerDetect-Folder-Changes.ps1codecov.ymlhas a Node/JS flag with paths + project/patch status (and an opt-out path)test:coveragescript + coverage reporter convention is documented for new appsNotes / Open Questions
jsto align with the existingfuzz-js-*scheme, or usenode?24(used across existing workflows) vs. per-appenginesinformational: true(like Rustpatch) to avoid blocking early adopters?Related Issues
ci(coverage): enforce 80% coverage thresholds across all language stacks). ci(coverage): enforce 80% coverage thresholds across all language stacks #175 assumes vitest coverage is already produced and uploaded for JS/TS code, which does not yet exist forsrc/500-application/Node apps. Recommend tracking this as a dependency of ci(coverage): enforce 80% coverage thresholds across all language stacks #175.add coverage thresholds to frontend vitest configuration, closed) covereddocs/docusaurus JS only — no overlap.-corecrates from WASM operators) are the Rust-side precedent this issue mirrors — no functional overlap.docs(testing): update testing-validation.md) is documentation-only and would consume the conventions this issue establishes.