Skip to content

Commit c603de7

Browse files
jobordujoborduclaude
authored
fix(roadmap/health): parse checklist phase format; collapse W007 spam (F8, F3) (#243)
* fix(roadmap/health): parse checklist phase format; collapse W007 spam (F8, F3) F8 — `nf-tools roadmap analyze` returned zero phases on a ROADMAP using the checklist format (`- [x] Phase 54: Title`). The phasePattern regexes (in cmdRoadmapAnalyze, cmdValidateHealth, cmdValidateConsistency, comparePhaseVersions) only matched `## Phase` headings or **bold** checklist items, never a plain `- [x] Phase N:`. Widened the shared prefix to accept the unbolded checklist form; heading and bold forms still match. F3 — because the parser found nothing, `validate health` flagged every on-disk phase as W007 ("exists on disk but not in ROADMAP"), one warning each → dozens of duplicates pinning /nf:health at DEGRADED. The regex fix populates roadmapPhases so phases that ARE in the roadmap stop being flagged, and the remaining genuine orphans now collapse into ONE actionable W007 pointing at /nf:cleanup. New bin/roadmap-health-parser.test.cjs (behavioral, wired into test:ci): checklist ROADMAP yields phases; heading/bold still parse; orphans collapse to one W007. nf-tools.test.cjs still 188/188. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(roadmap/health): widen the 4th parser site + correct changelog (review) Copilot on #243: my replace_all used a 4-space-indented old_string, so the 2-space-indented phasePattern in cmdValidateConsistency (line ~3784) was NEVER widened — it still required a heading or bold checklist item. Now widened to match the unbolded `- [x] Phase N:` form like the other three. Corrected the CHANGELOG to name the actual four call sites (cmdRoadmapAnalyze, cmdPhaseComplete's ROADMAP fallback, cmdValidateConsistency, cmdValidateHealth) — the prior note wrongly listed comparePhaseVersions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: jobordu <jonathan@jonathanborduas.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 880e309 commit c603de7

4 files changed

Lines changed: 104 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
77
## [Unreleased]
88

99
### Fixed
10+
- fix(roadmap/health): `/nf:roadmap analyze` returned **zero** phases on a ROADMAP that uses the checklist phase format (`- [x] Phase 54: Title`), and `/nf:health` then flooded its report with one **W007** per orphan phase — pinning it permanently at DEGRADED. The phase-extraction regexes (in `cmdRoadmapAnalyze`, `cmdPhaseComplete`'s ROADMAP fallback, `cmdValidateConsistency`, and `cmdValidateHealth`) only matched `## Phase` headings or **bold** checklist items, never a plain `- [x] Phase N:`. Widened the shared prefix to accept the unbolded checklist form (heading and bold forms still match). Because the parser now finds the roadmap's phases, the bogus W007s disappear; and the on-disk-but-not-in-ROADMAP check now **collapses** its remaining orphans into a single actionable W007 (`N phase(s) … : 50, 51, … — run /nf:cleanup`) instead of one warning each. New `bin/roadmap-health-parser.test.cjs` (behavioral, wired into `test:ci`): a checklist-format ROADMAP yields phases; heading/bold forms still parse; multiple orphans collapse to one W007. Found by dogfooding `/nf:roadmap analyze` and `/nf:health`.
1011
- fix(skills): three dogfooding papercuts. (1) `/nf:session-insights` — `observe-handler-session-insights.cjs` emitted issues with no `category` field, but the skill's renderer groups output "by category", so the grouping silently fell back to ungrouped. Each of the 5 issue types now sets a `category` matching the renderer's groups (Tool Failures / Long Sessions / Circuit Breaker / File Churn / Hook Failures). (2) `/nf:reapply-patches` showed "Current version: {read VERSION file}", but there is no top-level VERSION file (version lives in package.json) — now reads from package.json. (3) `/nf:link-daintree` (renamed from link-canopy) still printed "LINK CANOPY" banners and told users to "re-run /nf:link-canopy", a command that no longer exists — banners → "LINK DAINTREE", command refs → `/nf:link-daintree` (the canopy-app *legacy install path* fallback is intentional and left intact). New `bin/skill-papercut-sweep.test.cjs` (wired into `test:ci`) cross-checks the handler's category set against the renderer's group list and scan-guards the other two.
1112
- fix(formal-test-sync): `/nf:formal-test-sync`'s "safe" modes were not safe. (1) There was no `--help` guard, so `--help` (and any unrecognized flag) fell through to the **default full sync** — which generates stub files and writes `formal-test-sync-report.json` + `unit-test-coverage.json`. Just asking for usage mutated `.planning/formal/`. `--help`/`-h` now print usage and exit 0 with no analysis and no writes. (2) `--dry-run` is documented "no writes" but only gated the stub *files* — it still wrote the report + sidecar JSONs every run. `--dry-run` now skips those writes too (it still computes and shows what *would* be generated). `--report-only` (already correctly read-only) and the default write path are unchanged. New `bin/formal-test-sync-safety.test.cjs` runs the real script against a throwaway `--project-root` and asserts exactly which files each mode writes (wired into `test:ci`). Found by dogfooding `/nf:formal-test-sync`. (The earlier hypothesis that `extract-annotations.cjs` mutates was wrong — it is read-only.)
1213
- fix(skills): two thin-wrapper command bugs found by dogfooding. (1) `/nf:update`'s post-update step ran `node bin/migrate-planning.cjs --project-root=$(pwd)`, but `migrate-planning.cjs` only parses `--root <dir>` — the unrecognized flag was ignored and the layout migration silently ran against the default root instead of the project. Now passes `--root "$(pwd)"` (matching the workflow source). (2) `/nf:queue` wrote the task with `printf '%s' '$ARGUMENTS'`; any task text containing a single quote (e.g. `"it's"`) broke the surrounding single-quote and mangled or truncated the queued command. Now writes via a quoted heredoc so the task round-trips verbatim. New `bin/skill-command-correctness.test.cjs` — behavioral (runs the extracted queue.md bash with a quote-containing task and asserts an exact round-trip) + flag-correctness guard (wired into `test:ci`).

bin/roadmap-health-parser.test.cjs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
'use strict';
2+
// bin/roadmap-health-parser.test.cjs
3+
// Guards F8 + F3 (dogfooding):
4+
// F8 — `nf-tools roadmap analyze` returned ZERO phases on a ROADMAP that uses the
5+
// checklist phase format (`- [x] Phase N: Title`). The phasePattern regexes
6+
// only matched `## Phase` headings or **bold** checklist items, never a plain
7+
// `- [x] Phase N:`. Same blind spot in cmdValidateHealth/Consistency/compare.
8+
// F3 — `nf-tools validate health` emitted ONE W007 per orphan phase (dozens),
9+
// pinning /nf:health at DEGRADED. The orphans are now collapsed into a single
10+
// actionable W007.
11+
12+
const { describe, it } = require('node:test');
13+
const assert = require('node:assert/strict');
14+
const fs = require('fs');
15+
const os = require('os');
16+
const path = require('path');
17+
const { execFileSync } = require('child_process');
18+
19+
const TOOLS = path.join(__dirname, '..', 'core', 'bin', 'nf-tools.cjs');
20+
21+
function runTool(args, cwd) {
22+
const out = execFileSync('node', [TOOLS, ...args], { cwd, encoding: 'utf8' });
23+
return JSON.parse(out);
24+
}
25+
26+
function tmpProject() {
27+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'nf-rmhp-'));
28+
fs.mkdirSync(path.join(dir, '.planning', 'phases'), { recursive: true });
29+
return dir;
30+
}
31+
32+
describe('F8 — roadmap analyze parses the checklist phase format', () => {
33+
it('extracts phases from `- [x] Phase N: Title` lines', () => {
34+
const dir = tmpProject();
35+
try {
36+
fs.writeFileSync(path.join(dir, '.planning', 'ROADMAP.md'),
37+
'# Roadmap\n\n<details>\n<summary>Done</summary>\n\n' +
38+
'- [x] Phase 54: XML Context Packer (2/2 plans)\n' +
39+
'- [x] Phase 55: Hotspot Detection (2/2 plans)\n' +
40+
'- [ ] Phase 56: Co-Change (0/1 plan)\n</details>\n');
41+
const d = runTool(['roadmap', 'analyze'], dir);
42+
assert.equal(d.phase_count, 3, 'all three checklist phases must be parsed');
43+
const nums = d.phases.map(p => String(p.number));
44+
assert.deepEqual(nums.sort(), ['54', '55', '56']);
45+
} finally {
46+
fs.rmSync(dir, { recursive: true, force: true });
47+
}
48+
});
49+
50+
it('still parses heading and bold-checklist forms (no regression)', () => {
51+
const dir = tmpProject();
52+
try {
53+
fs.writeFileSync(path.join(dir, '.planning', 'ROADMAP.md'),
54+
'# Roadmap\n\n## Phase 1: Heading Form\n\n- [ ] **Phase 2: Bold Form**\n');
55+
const d = runTool(['roadmap', 'analyze'], dir);
56+
assert.equal(d.phase_count, 2, 'heading + bold forms must still match');
57+
} finally {
58+
fs.rmSync(dir, { recursive: true, force: true });
59+
}
60+
});
61+
});
62+
63+
describe('F3 — health collapses orphan-phase W007s into one', () => {
64+
it('emits a single W007 listing every orphan, not one per phase', () => {
65+
const dir = tmpProject();
66+
try {
67+
// ROADMAP knows only Phase 1; phases 50/51/52 exist on disk → 3 orphans.
68+
fs.writeFileSync(path.join(dir, '.planning', 'ROADMAP.md'),
69+
'# Roadmap\n\n- [ ] Phase 1: Known\n');
70+
for (const n of ['50-old', '51-old', '52-old']) {
71+
fs.mkdirSync(path.join(dir, '.planning', 'phases', n), { recursive: true });
72+
}
73+
const d = runTool(['validate', 'health', '--json'], dir);
74+
const all = d.issues || d.warnings || d.checks || [];
75+
const w007 = all.filter(i => i && i.code === 'W007');
76+
assert.equal(w007.length, 1, 'orphans must collapse into exactly one W007');
77+
const msg = w007[0].message || w007[0].msg || '';
78+
assert.ok(/50/.test(msg) && /51/.test(msg) && /52/.test(msg),
79+
'the single W007 must enumerate all orphan phases');
80+
} finally {
81+
fs.rmSync(dir, { recursive: true, force: true });
82+
}
83+
});
84+
});

core/bin/nf-tools.cjs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2723,7 +2723,7 @@ function cmdRoadmapAnalyze(cwd, raw) {
27232723
const phasesDir = path.join(cwd, '.planning', 'phases');
27242724

27252725
// Extract all phase headings: ## Phase N: Name or ### Phase N: Name (integer or milestone-scoped)
2726-
const phasePattern = /#{2,4}\s*Phase\s+(v\d+\.\d+-\d+(?:\.\d+)?|\d+(?:\.\d+)?)\s*:\s*([^\n]+)/gi;
2726+
const phasePattern = /(?:#{2,4}\s*|[-*]\s+\[[^\]]\]\s+(?:\*{1,2}\s*)?)Phase\s+(v\d+\.\d+-\d+(?:\.\d+)?|\d+(?:\.\d+)?)\s*:\s*([^\n]+)/gi;
27272727
const phases = [];
27282728
let match;
27292729

@@ -3549,7 +3549,7 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
35493549
// Fallback: check ROADMAP.md for phases not yet on disk
35503550
if (isLastPhase && fs.existsSync(roadmapPath)) {
35513551
const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
3552-
const phasePattern = /#{2,4}\s*Phase\s+(v\d+\.\d+-\d+(?:\.\d+)?|\d+(?:\.\d+)?)\s*:\s*([^\n]+)/gi;
3552+
const phasePattern = /(?:#{2,4}\s*|[-*]\s+\[[^\]]\]\s+(?:\*{1,2}\s*)?)Phase\s+(v\d+\.\d+-\d+(?:\.\d+)?|\d+(?:\.\d+)?)\s*:\s*([^\n]+)/gi;
35533553
let pm;
35543554
while ((pm = phasePattern.exec(roadmapContent)) !== null) {
35553555
if (comparePhaseVersions(pm[1], phaseNum) > 0) {
@@ -3781,7 +3781,7 @@ function cmdValidateConsistency(cwd, raw) {
37813781

37823782
// Extract phases from ROADMAP
37833783
const roadmapPhases = new Set();
3784-
const phasePattern = /(?:#{2,4}|[-*]\s+\[[^\]]\]\s+\*{1,2})\s*Phase\s+(v\d+\.\d+-\d{2}(?:\.\d+)?|\d+(?:\.\d+)?)\s*:/gi;
3784+
const phasePattern = /(?:#{2,4}\s*|[-*]\s+\[[^\]]\]\s+(?:\*{1,2}\s*)?)Phase\s+(v\d+\.\d+-\d{2}(?:\.\d+)?|\d+(?:\.\d+)?)\s*:/gi;
37853785
let m;
37863786
while ((m = phasePattern.exec(roadmapContent)) !== null) {
37873787
roadmapPhases.add(m[1]);
@@ -4031,7 +4031,7 @@ function cmdValidateHealth(cwd, options, raw) {
40314031
if (fs.existsSync(roadmapPath)) {
40324032
const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
40334033
const roadmapPhases = new Set();
4034-
const phasePattern = /(?:#{2,4}|[-*]\s+\[[^\]]\]\s+\*{1,2})\s*Phase\s+(v\d+\.\d+-\d{2}(?:\.\d+)?|\d+(?:\.\d+)?)\s*:/gi;
4034+
const phasePattern = /(?:#{2,4}\s*|[-*]\s+\[[^\]]\]\s+(?:\*{1,2}\s*)?)Phase\s+(v\d+\.\d+-\d{2}(?:\.\d+)?|\d+(?:\.\d+)?)\s*:/gi;
40354035
let m;
40364036
while ((m = phasePattern.exec(roadmapContent)) !== null) {
40374037
roadmapPhases.add(m[1]);
@@ -4087,7 +4087,11 @@ function cmdValidateHealth(cwd, options, raw) {
40874087
}
40884088
}
40894089

4090-
// Phases on disk but not in ROADMAP (skip archived phases — they are expected to be absent from ROADMAP)
4090+
// Phases on disk but not in ROADMAP (skip archived phases — they are expected to be absent from ROADMAP).
4091+
// Collapse into ONE warning: emitting one W007 per orphan flooded /nf:health with dozens of
4092+
// duplicates and pinned the report at DEGRADED (especially when the ROADMAP parser missed the
4093+
// checklist phase format and matched nothing — see the phasePattern fix).
4094+
const orphanPhases = [];
40914095
for (const p of diskPhases) {
40924096
if (archivedPhaseIds.has(p)) continue;
40934097
const normalized = normalizePhaseName(p);
@@ -4096,9 +4100,17 @@ function cmdValidateHealth(cwd, options, raw) {
40964100
? `${parseInt(dParts[0], 10)}.${dParts[1]}`
40974101
: String(parseInt(dParts[0], 10));
40984102
if (!roadmapPhases.has(p) && !roadmapPhases.has(normalized) && !roadmapPhases.has(unpadded)) {
4099-
addIssue('warning', 'W007', `Phase ${p} exists on disk but not in ROADMAP.md`, 'Add to roadmap or remove directory');
4103+
orphanPhases.push(p);
41004104
}
41014105
}
4106+
if (orphanPhases.length > 0) {
4107+
addIssue(
4108+
'warning',
4109+
'W007',
4110+
`${orphanPhases.length} phase(s) exist on disk but not in ROADMAP.md: ${orphanPhases.join(', ')}`,
4111+
'Add them to the roadmap, remove the directories, or run /nf:cleanup'
4112+
);
4113+
}
41024114
}
41034115

41044116
// ─── Check 9: Quorum failure patterns ─────────────────────────────────────────

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
"secrets:history": "bash scripts/secret-audit.sh",
113113
"test": "npm run test:ci && npm run test:tui && npm run test:formal",
114114
"test:changed": "node bin/test-changed.cjs",
115-
"test:ci": "node scripts/lint-isolation.js && node scripts/verify-hooks-sync.cjs && node --test hooks/nf-precompact.test.js hooks/nf-context-monitor.test.js hooks/nf-session-start.test.js bin/conformance-schema.test.cjs bin/resolve-cli.test.cjs bin/secrets.test.cjs bin/verify-quorum-health.test.cjs hooks/nf-stop.test.js hooks/config-loader.test.js core/bin/nf-tools.test.cjs hooks/nf-circuit-breaker.test.js hooks/nf-prompt.test.js bin/update-scoreboard.test.cjs hooks/nf-statusline.test.js bin/review-mcp-logs.test.cjs bin/migrate-to-slots.test.cjs bin/validate-traces.test.cjs bin/write-check-result.test.cjs bin/check-results-exit.test.cjs bin/check-trace-redaction.test.cjs bin/check-trace-schema-drift.test.cjs bin/nForma.test.cjs bin/set-secret.test.cjs bin/issue-classifier.test.cjs bin/generate-tla-cfg.test.cjs bin/ccr-secure-config.test.cjs bin/nf-quorum-slot-worker-improvements.test.cjs bin/quorum-improvements-signal.test.cjs bin/quorum-checkpoint.test.cjs bin/claude-md-references.test.cjs hooks/nf-spec-regen.test.js bin/propose-debug-invariants.test.cjs bin/aggregate-requirements.test.cjs bin/validate-requirements-haiku.test.cjs bin/call-quorum-slot-retry.test.cjs bin/provider-mapping.test.cjs bin/provider-concurrency.test.cjs bin/token-dashboard.test.cjs bin/execution-progress.test.cjs bin/memory-store.test.cjs hooks/nf-session-end.test.js bin/skill-extractor.test.cjs bin/learning-extractor.test.cjs bin/continuous-verify.test.cjs bin/context-retriever.test.cjs bin/context-stack.test.cjs hooks/nf-destructive-git-guard.test.js bin/worktree-merge.test.cjs bin/call-quorum-slot-latency.test.cjs bin/nforma-cli.test.cjs bin/solve-trend.test.cjs bin/dedup-changelog.test.cjs bin/oscillation-detector.test.cjs bin/gate-stability.test.cjs bin/predictive-power.test.cjs bin/convergence-report.test.cjs bin/escalation-classifier.test.cjs test/formal-scope-scan-semantic.test.cjs bin/repowise/escape-xml.test.cjs bin/repowise/pack-file.test.cjs bin/repowise/context-packer.test.cjs bin/repowise/hotspot.test.cjs bin/repowise/resolve-hotspot-risk.test.cjs bin/repowise/cochange.test.cjs bin/repowise/inject-cochange-debug.test.cjs bin/repowise/skeleton.test.cjs bin/repowise/budget-compressor.test.cjs test/providers-path-consolidation.test.cjs test/quorum-consensus-gate-cluster.test.cjs test/quorum-preflight-maintool-healthy.test.cjs test/resolve-providers-order.test.cjs bin/no-side-effects-on-require.test.cjs bin/alloy-exec.test.cjs test/install-mcp-nfbin.test.cjs bin/semaphore-concurrency.test.cjs bin/quorum-dispatch-argv.test.cjs bin/quorum-content-verdict-integrity.test.cjs bin/call-quorum-slot-cooldown-path.test.cjs hooks/nf-prompt-cache-budget.test.js bin/coderlm-adapter-filter.test.cjs bin/solve-commit-artifacts.test.cjs bin/cli-robustness.test.cjs bin/mcp-skill-embedded.test.cjs bin/skill-eval-args.test.cjs bin/observe-handler-upstream.test.cjs bin/skill-mcp-tool-names.test.cjs bin/skill-command-correctness.test.cjs bin/mcp-update-classify.test.cjs bin/formal-test-sync-safety.test.cjs bin/skill-papercut-sweep.test.cjs",
115+
"test:ci": "node scripts/lint-isolation.js && node scripts/verify-hooks-sync.cjs && node --test hooks/nf-precompact.test.js hooks/nf-context-monitor.test.js hooks/nf-session-start.test.js bin/conformance-schema.test.cjs bin/resolve-cli.test.cjs bin/secrets.test.cjs bin/verify-quorum-health.test.cjs hooks/nf-stop.test.js hooks/config-loader.test.js core/bin/nf-tools.test.cjs hooks/nf-circuit-breaker.test.js hooks/nf-prompt.test.js bin/update-scoreboard.test.cjs hooks/nf-statusline.test.js bin/review-mcp-logs.test.cjs bin/migrate-to-slots.test.cjs bin/validate-traces.test.cjs bin/write-check-result.test.cjs bin/check-results-exit.test.cjs bin/check-trace-redaction.test.cjs bin/check-trace-schema-drift.test.cjs bin/nForma.test.cjs bin/set-secret.test.cjs bin/issue-classifier.test.cjs bin/generate-tla-cfg.test.cjs bin/ccr-secure-config.test.cjs bin/nf-quorum-slot-worker-improvements.test.cjs bin/quorum-improvements-signal.test.cjs bin/quorum-checkpoint.test.cjs bin/claude-md-references.test.cjs hooks/nf-spec-regen.test.js bin/propose-debug-invariants.test.cjs bin/aggregate-requirements.test.cjs bin/validate-requirements-haiku.test.cjs bin/call-quorum-slot-retry.test.cjs bin/provider-mapping.test.cjs bin/provider-concurrency.test.cjs bin/token-dashboard.test.cjs bin/execution-progress.test.cjs bin/memory-store.test.cjs hooks/nf-session-end.test.js bin/skill-extractor.test.cjs bin/learning-extractor.test.cjs bin/continuous-verify.test.cjs bin/context-retriever.test.cjs bin/context-stack.test.cjs hooks/nf-destructive-git-guard.test.js bin/worktree-merge.test.cjs bin/call-quorum-slot-latency.test.cjs bin/nforma-cli.test.cjs bin/solve-trend.test.cjs bin/dedup-changelog.test.cjs bin/oscillation-detector.test.cjs bin/gate-stability.test.cjs bin/predictive-power.test.cjs bin/convergence-report.test.cjs bin/escalation-classifier.test.cjs test/formal-scope-scan-semantic.test.cjs bin/repowise/escape-xml.test.cjs bin/repowise/pack-file.test.cjs bin/repowise/context-packer.test.cjs bin/repowise/hotspot.test.cjs bin/repowise/resolve-hotspot-risk.test.cjs bin/repowise/cochange.test.cjs bin/repowise/inject-cochange-debug.test.cjs bin/repowise/skeleton.test.cjs bin/repowise/budget-compressor.test.cjs test/providers-path-consolidation.test.cjs test/quorum-consensus-gate-cluster.test.cjs test/quorum-preflight-maintool-healthy.test.cjs test/resolve-providers-order.test.cjs bin/no-side-effects-on-require.test.cjs bin/alloy-exec.test.cjs test/install-mcp-nfbin.test.cjs bin/semaphore-concurrency.test.cjs bin/quorum-dispatch-argv.test.cjs bin/quorum-content-verdict-integrity.test.cjs bin/call-quorum-slot-cooldown-path.test.cjs hooks/nf-prompt-cache-budget.test.js bin/coderlm-adapter-filter.test.cjs bin/solve-commit-artifacts.test.cjs bin/cli-robustness.test.cjs bin/mcp-skill-embedded.test.cjs bin/skill-eval-args.test.cjs bin/observe-handler-upstream.test.cjs bin/skill-mcp-tool-names.test.cjs bin/skill-command-correctness.test.cjs bin/mcp-update-classify.test.cjs bin/formal-test-sync-safety.test.cjs bin/skill-papercut-sweep.test.cjs bin/roadmap-health-parser.test.cjs",
116116
"test:tui": "NF_TEST_MODE=1 node scripts/run-tui-tests.cjs",
117117
"test:install": "node --test test/install-virgin.test.cjs",
118118
"test:formal": "node --test bin/run-tlc.test.cjs bin/run-alloy.test.cjs bin/export-prism-constants.test.cjs bin/generate-petri-net.test.cjs bin/run-breaker-tlc.test.cjs bin/run-oscillation-tlc.test.cjs bin/run-protocol-tlc.test.cjs bin/run-audit-alloy.test.cjs bin/run-transcript-alloy.test.cjs bin/run-installer-alloy.test.cjs bin/run-formal-verify.test.cjs bin/xstate-to-tla.test.cjs bin/run-account-manager-tlc.test.cjs bin/run-account-pool-alloy.test.cjs bin/run-oauth-rotation-prism.test.cjs bin/run-prism.test.cjs bin/check-spec-sync.test.cjs bin/sensitivity-sweep-feedback.test.cjs bin/roadmapper-formal-integration.test.cjs bin/test-formal-integration.test.cjs test/alloy-headless.test.cjs bin/adapters/ir.test.cjs bin/adapters/emitter-tla.test.cjs bin/adapters/detect.test.cjs bin/adapters/scaffold-config.test.cjs bin/adapters/xstate-v5.test.cjs bin/adapters/xstate-v4.test.cjs bin/adapters/jsm.test.cjs bin/adapters/robot.test.cjs bin/adapters/asl.test.cjs bin/adapters/stately.test.cjs bin/adapters/python-transitions.test.cjs bin/adapters/sismic.test.cjs bin/adapters/looplab-fsm.test.cjs bin/adapters/qmuntal-stateless.test.cjs bin/fsm-to-tla.test.cjs",

0 commit comments

Comments
 (0)