@nforma.ai/nforma 0.2.1 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/agents/{qgsd-codebase-mapper.md → nf-codebase-mapper.md} +1 -1
- package/agents/{qgsd-debugger.md → nf-debugger.md} +3 -3
- package/agents/{qgsd-executor.md → nf-executor.md} +14 -14
- package/agents/{qgsd-integration-checker.md → nf-integration-checker.md} +1 -1
- package/agents/{qgsd-phase-researcher.md → nf-phase-researcher.md} +6 -6
- package/agents/{qgsd-plan-checker.md → nf-plan-checker.md} +9 -9
- package/agents/{qgsd-planner.md → nf-planner.md} +9 -9
- package/agents/{qgsd-project-researcher.md → nf-project-researcher.md} +2 -2
- package/agents/{qgsd-quorum-orchestrator.md → nf-quorum-orchestrator.md} +33 -33
- package/agents/{qgsd-quorum-slot-worker.md → nf-quorum-slot-worker.md} +3 -3
- package/agents/{qgsd-quorum-synthesizer.md → nf-quorum-synthesizer.md} +3 -3
- package/agents/{qgsd-quorum-test-worker.md → nf-quorum-test-worker.md} +1 -1
- package/agents/{qgsd-quorum-worker.md → nf-quorum-worker.md} +6 -6
- package/agents/{qgsd-research-synthesizer.md → nf-research-synthesizer.md} +5 -5
- package/agents/{qgsd-roadmapper.md → nf-roadmapper.md} +3 -3
- package/agents/{qgsd-verifier.md → nf-verifier.md} +8 -8
- package/bin/accept-debug-invariant.cjs +2 -2
- package/bin/account-manager.cjs +10 -10
- package/bin/aggregate-requirements.cjs +1 -1
- package/bin/analyze-assumptions.cjs +3 -3
- package/bin/analyze-state-space.cjs +14 -14
- package/bin/assumption-register.cjs +146 -0
- package/bin/attribute-trace-divergence.cjs +1 -1
- package/bin/auth-drivers/gh-cli.cjs +1 -1
- package/bin/auth-drivers/pool.cjs +1 -1
- package/bin/autoClosePtoF.cjs +3 -3
- package/bin/budget-tracker.cjs +77 -0
- package/bin/build-layer-manifest.cjs +153 -0
- package/bin/call-quorum-slot.cjs +3 -3
- package/bin/ccr-secure-config.cjs +5 -5
- package/bin/check-bundled-sdks.cjs +1 -1
- package/bin/check-mcp-health.cjs +1 -1
- package/bin/check-provider-health.cjs +6 -6
- package/bin/check-spec-sync.cjs +26 -26
- package/bin/check-trace-schema-drift.cjs +5 -5
- package/bin/conformance-schema.cjs +2 -2
- package/bin/cross-layer-dashboard.cjs +297 -0
- package/bin/design-impact.cjs +377 -0
- package/bin/detect-coverage-gaps.cjs +7 -7
- package/bin/failure-mode-catalog.cjs +227 -0
- package/bin/failure-taxonomy.cjs +177 -0
- package/bin/formal-scope-scan.cjs +179 -0
- package/bin/gate-a-grounding.cjs +334 -0
- package/bin/gate-b-abstraction.cjs +243 -0
- package/bin/gate-c-validation.cjs +166 -0
- package/bin/generate-formal-specs.cjs +17 -17
- package/bin/generate-petri-net.cjs +3 -3
- package/bin/generate-tla-cfg.cjs +5 -5
- package/bin/git-heatmap.cjs +571 -0
- package/bin/harness-diagnostic.cjs +326 -0
- package/bin/hazard-model.cjs +261 -0
- package/bin/install-formal-tools.cjs +1 -1
- package/bin/install.js +184 -139
- package/bin/instrumentation-map.cjs +178 -0
- package/bin/invariant-catalog.cjs +437 -0
- package/bin/issue-classifier.cjs +2 -2
- package/bin/load-baseline-requirements.cjs +4 -4
- package/bin/manage-agents-core.cjs +32 -32
- package/bin/migrate-to-slots.cjs +39 -39
- package/bin/mismatch-register.cjs +217 -0
- package/bin/nForma.cjs +176 -81
- package/bin/{qgsd-solve.cjs → nf-solve.cjs} +327 -14
- package/bin/observe-config.cjs +8 -0
- package/bin/observe-debt-writer.cjs +1 -1
- package/bin/observe-handler-deps.cjs +356 -0
- package/bin/observe-handler-grafana.cjs +2 -17
- package/bin/observe-handler-internal.cjs +5 -5
- package/bin/observe-handler-logstash.cjs +2 -17
- package/bin/observe-handler-prometheus.cjs +2 -17
- package/bin/observe-handler-upstream.cjs +251 -0
- package/bin/observe-handlers.cjs +12 -33
- package/bin/observe-render.cjs +68 -22
- package/bin/observe-utils.cjs +37 -0
- package/bin/observed-fsm.cjs +324 -0
- package/bin/planning-paths.cjs +6 -0
- package/bin/polyrepo.cjs +1 -1
- package/bin/probe-quorum-slots.cjs +1 -1
- package/bin/promote-gate-maturity.cjs +274 -0
- package/bin/promote-model.cjs +1 -1
- package/bin/propose-debug-invariants.cjs +1 -1
- package/bin/quorum-cache.cjs +144 -0
- package/bin/quorum-consensus-gate.cjs +1 -1
- package/bin/quorum-slot-dispatch.cjs +6 -6
- package/bin/requirements-core.cjs +1 -1
- package/bin/review-mcp-logs.cjs +1 -1
- package/bin/risk-heatmap.cjs +151 -0
- package/bin/run-account-manager-tlc.cjs +4 -4
- package/bin/run-account-pool-alloy.cjs +2 -2
- package/bin/run-alloy.cjs +2 -2
- package/bin/run-audit-alloy.cjs +2 -2
- package/bin/run-breaker-tlc.cjs +3 -3
- package/bin/run-formal-check.cjs +9 -9
- package/bin/run-formal-verify.cjs +30 -9
- package/bin/run-installer-alloy.cjs +2 -2
- package/bin/run-oscillation-tlc.cjs +4 -4
- package/bin/run-phase-tlc.cjs +1 -1
- package/bin/run-protocol-tlc.cjs +4 -4
- package/bin/run-quorum-composition-alloy.cjs +2 -2
- package/bin/run-sensitivity-sweep.cjs +2 -2
- package/bin/run-stop-hook-tlc.cjs +3 -3
- package/bin/run-tlc.cjs +21 -21
- package/bin/run-transcript-alloy.cjs +2 -2
- package/bin/secrets.cjs +5 -5
- package/bin/security-sweep.cjs +238 -0
- package/bin/sensitivity-report.cjs +3 -3
- package/bin/set-secret.cjs +5 -5
- package/bin/setup-telemetry-cron.sh +3 -3
- package/bin/stall-detector.cjs +126 -0
- package/bin/state-candidates.cjs +206 -0
- package/bin/sync-baseline-requirements.cjs +1 -1
- package/bin/telemetry-collector.cjs +1 -1
- package/bin/test-changed.cjs +111 -0
- package/bin/test-recipe-gen.cjs +250 -0
- package/bin/trace-corpus-stats.cjs +211 -0
- package/bin/unified-mcp-server.mjs +3 -3
- package/bin/update-scoreboard.cjs +1 -1
- package/bin/validate-memory.cjs +2 -2
- package/bin/validate-traces.cjs +10 -10
- package/bin/verify-quorum-health.cjs +66 -5
- package/bin/xstate-to-tla.cjs +4 -4
- package/bin/xstate-trace-walker.cjs +3 -3
- package/commands/{qgsd → nf}/add-phase.md +3 -3
- package/commands/{qgsd → nf}/add-requirement.md +3 -3
- package/commands/{qgsd → nf}/add-todo.md +3 -3
- package/commands/{qgsd → nf}/audit-milestone.md +4 -4
- package/commands/{qgsd → nf}/check-todos.md +3 -3
- package/commands/{qgsd → nf}/cleanup.md +3 -3
- package/commands/{qgsd → nf}/close-formal-gaps.md +2 -2
- package/commands/{qgsd → nf}/complete-milestone.md +9 -9
- package/commands/{qgsd → nf}/debug.md +9 -9
- package/commands/{qgsd → nf}/discuss-phase.md +3 -3
- package/commands/{qgsd → nf}/execute-phase.md +15 -15
- package/commands/{qgsd → nf}/fix-tests.md +3 -3
- package/commands/{qgsd → nf}/formal-test-sync.md +1 -1
- package/commands/{qgsd → nf}/health.md +3 -3
- package/commands/{qgsd → nf}/help.md +3 -3
- package/commands/{qgsd → nf}/insert-phase.md +3 -3
- package/commands/nf/join-discord.md +18 -0
- package/commands/{qgsd → nf}/list-phase-assumptions.md +2 -2
- package/commands/{qgsd → nf}/map-codebase.md +7 -7
- package/commands/{qgsd → nf}/map-requirements.md +3 -3
- package/commands/{qgsd → nf}/mcp-restart.md +3 -3
- package/commands/{qgsd → nf}/mcp-set-model.md +8 -8
- package/commands/{qgsd → nf}/mcp-setup.md +63 -63
- package/commands/{qgsd → nf}/mcp-status.md +3 -3
- package/commands/{qgsd → nf}/mcp-update.md +7 -7
- package/commands/{qgsd → nf}/new-milestone.md +8 -8
- package/commands/{qgsd → nf}/new-project.md +8 -8
- package/commands/{qgsd → nf}/observe.md +49 -16
- package/commands/{qgsd → nf}/pause-work.md +3 -3
- package/commands/{qgsd → nf}/plan-milestone-gaps.md +5 -5
- package/commands/{qgsd → nf}/plan-phase.md +6 -6
- package/commands/{qgsd → nf}/polyrepo.md +2 -2
- package/commands/{qgsd → nf}/progress.md +3 -3
- package/commands/{qgsd → nf}/queue.md +2 -2
- package/commands/{qgsd → nf}/quick.md +8 -8
- package/commands/{qgsd → nf}/quorum-test.md +10 -10
- package/commands/{qgsd → nf}/quorum.md +40 -40
- package/commands/{qgsd → nf}/reapply-patches.md +2 -2
- package/commands/{qgsd → nf}/remove-phase.md +3 -3
- package/commands/{qgsd → nf}/research-phase.md +12 -12
- package/commands/{qgsd → nf}/resume-work.md +3 -3
- package/commands/nf/review-requirements.md +31 -0
- package/commands/{qgsd → nf}/set-profile.md +3 -3
- package/commands/{qgsd → nf}/settings.md +6 -6
- package/commands/{qgsd → nf}/solve.md +35 -35
- package/commands/{qgsd → nf}/sync-baselines.md +4 -4
- package/commands/{qgsd → nf}/triage.md +10 -10
- package/commands/{qgsd → nf}/update.md +3 -3
- package/commands/{qgsd → nf}/verify-work.md +5 -5
- package/hooks/dist/config-loader.js +188 -32
- package/hooks/dist/conformance-schema.cjs +2 -2
- package/hooks/dist/gsd-context-monitor.js +118 -13
- package/hooks/dist/{qgsd-check-update.js → nf-check-update.js} +5 -5
- package/hooks/dist/{qgsd-circuit-breaker.js → nf-circuit-breaker.js} +35 -24
- package/hooks/dist/nf-circuit-breaker.test.js +1002 -0
- package/hooks/dist/{qgsd-precompact.js → nf-precompact.js} +13 -13
- package/hooks/dist/nf-precompact.test.js +227 -0
- package/hooks/dist/{qgsd-prompt.js → nf-prompt.js} +110 -33
- package/hooks/dist/nf-prompt.test.js +698 -0
- package/hooks/dist/nf-session-start.js +185 -0
- package/hooks/dist/nf-session-start.test.js +354 -0
- package/hooks/dist/{qgsd-slot-correlator.js → nf-slot-correlator.js} +13 -5
- package/hooks/dist/nf-slot-correlator.test.js +85 -0
- package/hooks/dist/{qgsd-spec-regen.js → nf-spec-regen.js} +17 -8
- package/hooks/dist/nf-spec-regen.test.js +73 -0
- package/hooks/dist/{qgsd-statusline.js → nf-statusline.js} +12 -3
- package/hooks/dist/nf-statusline.test.js +157 -0
- package/hooks/dist/{qgsd-stop.js → nf-stop.js} +152 -18
- package/hooks/dist/nf-stop.test.js +1388 -0
- package/hooks/dist/{qgsd-token-collector.js → nf-token-collector.js} +12 -4
- package/hooks/dist/nf-token-collector.test.js +262 -0
- package/hooks/dist/unified-mcp-server.mjs +2 -2
- package/package.json +4 -4
- package/scripts/build-hooks.js +13 -6
- package/scripts/secret-audit.sh +1 -1
- package/scripts/verify-hooks-sync.cjs +90 -0
- package/templates/{qgsd.json → nf.json} +4 -4
- package/commands/qgsd/join-discord.md +0 -18
- package/hooks/dist/qgsd-session-start.js +0 -122
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// hooks/
|
|
2
|
+
// hooks/nf-circuit-breaker.js
|
|
3
3
|
// PreToolUse hook — oscillation detection, state persistence, and notification for circuit breaker.
|
|
4
4
|
//
|
|
5
5
|
// Reads JSON from stdin (Claude Code PreToolUse event payload), checks for oscillation
|
|
@@ -94,30 +94,38 @@ function getCommitDiff(gitRoot, olderHash, newerHash, files) {
|
|
|
94
94
|
|
|
95
95
|
// Second-pass reversion check: given the hashes (newest-first) belonging to
|
|
96
96
|
// run-groups for an oscillating file set key, and the files in that set,
|
|
97
|
-
// determines whether the pattern is true oscillation or TDD progression.
|
|
97
|
+
// determines whether the pattern is true oscillation or TDD/workflow progression.
|
|
98
|
+
//
|
|
99
|
+
// Algorithm: sum net change (additions - deletions) across all consecutive pairs,
|
|
100
|
+
// AND track whether at least one pair has negative net change (content removal).
|
|
98
101
|
//
|
|
99
|
-
// Algorithm: sum net change (additions - deletions) across all consecutive pairs.
|
|
100
102
|
// - Positive total net change → file grew overall → TDD progression (not oscillation).
|
|
101
|
-
// - Zero or negative total net change
|
|
103
|
+
// - Zero or negative total net change WITH at least one pair showing net deletions
|
|
104
|
+
// → true oscillation (content was added then removed).
|
|
105
|
+
// - Zero or negative total net change with NO pair showing net deletions
|
|
106
|
+
// (all pairs are zero-net substitutions) → NOT oscillation. This is monotonic
|
|
107
|
+
// workflow progression (e.g., template → linter substitution → population).
|
|
102
108
|
//
|
|
103
109
|
// This correctly handles TDD patterns where a line like `module.exports` is modified
|
|
104
110
|
// (1 deletion, 1 addition per commit) alongside net-new lines — the net change remains
|
|
105
111
|
// positive because new functions are added each time.
|
|
106
112
|
//
|
|
107
|
-
// For true oscillation (same content toggled back and forth),
|
|
108
|
-
//
|
|
113
|
+
// For true oscillation (same content toggled back and forth), at least one pair
|
|
114
|
+
// will show a net-negative change (lines removed that were added in a prior pair).
|
|
109
115
|
//
|
|
110
116
|
// hashes: all commit hashes (newest-first) in the oscillating run-groups
|
|
111
117
|
// files: file paths in the oscillating set
|
|
112
118
|
// gitRoot: git repository root
|
|
113
119
|
//
|
|
114
|
-
// Returns true if real oscillation (net change <= 0
|
|
120
|
+
// Returns true if real oscillation (net change <= 0 AND at least one negative pair).
|
|
121
|
+
// Returns false if all pairs are zero-net substitutions (monotonic workflow progression).
|
|
115
122
|
// Returns true also if ALL pairs errored out (git unavailable → fall back to original behavior).
|
|
116
123
|
function hasReversionInHashes(gitRoot, hashes, files) {
|
|
117
124
|
// hashes are newest-first; consecutive pairs: (hashes[i], hashes[i-1]) where
|
|
118
125
|
// hashes[i] is older (higher index = earlier in time), hashes[i-1] is newer.
|
|
119
126
|
// We diff older → newer: git diff <hashes[i]> <hashes[i-1]>
|
|
120
127
|
let totalNetChange = 0;
|
|
128
|
+
let hasNegativePair = false;
|
|
121
129
|
let errorsOnly = true;
|
|
122
130
|
|
|
123
131
|
for (let i = hashes.length - 1; i >= 1; i--) {
|
|
@@ -142,15 +150,18 @@ function hasReversionInHashes(gitRoot, hashes, files) {
|
|
|
142
150
|
else if (line.startsWith('-')) deletions++;
|
|
143
151
|
}
|
|
144
152
|
|
|
145
|
-
|
|
153
|
+
const pairNet = additions - deletions;
|
|
154
|
+
totalNetChange += pairNet;
|
|
155
|
+
if (pairNet < 0) hasNegativePair = true;
|
|
146
156
|
}
|
|
147
157
|
|
|
148
158
|
// If all pairs errored out → fall back to original behavior (treat as oscillation)
|
|
149
159
|
if (errorsOnly) return true;
|
|
150
160
|
|
|
151
161
|
// Positive net change → file grew overall → TDD progression, not oscillation
|
|
152
|
-
// Zero or negative net change
|
|
153
|
-
|
|
162
|
+
// Zero or negative net change WITH at least one negative pair → real oscillation
|
|
163
|
+
// Zero or negative net change with NO negative pair → monotonic substitution workflow, not oscillation
|
|
164
|
+
return totalNetChange <= 0 && hasNegativePair;
|
|
154
165
|
}
|
|
155
166
|
|
|
156
167
|
// Detects true oscillation: returns { detected: bool, fileSet: string[] }
|
|
@@ -301,7 +312,7 @@ function writeState(statePath, fileSet, snapshot) {
|
|
|
301
312
|
};
|
|
302
313
|
fs.writeFileSync(statePath, JSON.stringify(state, null, 2), 'utf8');
|
|
303
314
|
} catch (e) {
|
|
304
|
-
process.stderr.write(`[
|
|
315
|
+
process.stderr.write(`[nf] WARNING: Could not write circuit breaker state: ${e.message}\n`);
|
|
305
316
|
// Fail-open: do not block execution
|
|
306
317
|
}
|
|
307
318
|
}
|
|
@@ -329,7 +340,7 @@ function appendFalseNegative(statePath, fileSet) {
|
|
|
329
340
|
});
|
|
330
341
|
fs.writeFileSync(fnLogPath, JSON.stringify(existing, null, 2), 'utf8');
|
|
331
342
|
} catch (e) {
|
|
332
|
-
process.stderr.write(`[
|
|
343
|
+
process.stderr.write(`[nf] WARNING: Could not write false-negative log: ${e.message}\n`);
|
|
333
344
|
// Fail-open: do not block execution
|
|
334
345
|
}
|
|
335
346
|
}
|
|
@@ -352,7 +363,7 @@ function writeOscillationLog(logPath, log) {
|
|
|
352
363
|
fs.mkdirSync(path.dirname(logPath), { recursive: true });
|
|
353
364
|
fs.writeFileSync(logPath, JSON.stringify(log, null, 2), 'utf8');
|
|
354
365
|
} catch (e) {
|
|
355
|
-
process.stderr.write(`[
|
|
366
|
+
process.stderr.write(`[nf] WARNING: Could not write oscillation log: ${e.message}\n`);
|
|
356
367
|
}
|
|
357
368
|
}
|
|
358
369
|
|
|
@@ -387,7 +398,7 @@ function appendConformanceEvent(event) {
|
|
|
387
398
|
const logPath = pp.resolve(process.cwd(), 'conformance-events');
|
|
388
399
|
fs.appendFileSync(logPath, JSON.stringify(event) + '\n', 'utf8');
|
|
389
400
|
} catch (err) {
|
|
390
|
-
process.stderr.write('[
|
|
401
|
+
process.stderr.write('[nf] conformance log write failed: ' + err.message + '\n');
|
|
391
402
|
}
|
|
392
403
|
}
|
|
393
404
|
|
|
@@ -416,12 +427,12 @@ function buildBlockReason(state) {
|
|
|
416
427
|
lines.push('');
|
|
417
428
|
}
|
|
418
429
|
lines.push(
|
|
419
|
-
'Invoke Oscillation Resolution Mode per R5 in CLAUDE.md — see
|
|
430
|
+
'Invoke Oscillation Resolution Mode per R5 in CLAUDE.md — see core/workflows/oscillation-resolution-mode.md for the full procedure.',
|
|
420
431
|
'',
|
|
421
432
|
'Read-only operations are still allowed (e.g. git log --oneline to review the commit history).',
|
|
422
433
|
'You must manually commit a root-cause fix before write operations are unblocked.',
|
|
423
434
|
'',
|
|
424
|
-
"After committing the fix, run 'npx
|
|
435
|
+
"After committing the fix, run 'npx nforma --reset-breaker' to clear the circuit breaker state.",
|
|
425
436
|
);
|
|
426
437
|
return lines.join('\n');
|
|
427
438
|
}
|
|
@@ -453,11 +464,11 @@ function buildWarningNotice(state) {
|
|
|
453
464
|
}
|
|
454
465
|
|
|
455
466
|
lines.push(
|
|
456
|
-
'Invoke Oscillation Resolution Mode per R5 in CLAUDE.md — see
|
|
467
|
+
'Invoke Oscillation Resolution Mode per R5 in CLAUDE.md — see core/workflows/oscillation-resolution-mode.md for the full procedure.',
|
|
457
468
|
'',
|
|
458
|
-
'After committing the fix, run \'npx
|
|
459
|
-
'To temporarily disable the circuit breaker for deliberate iterative work, run \'npx
|
|
460
|
-
'Re-enable with \'npx
|
|
469
|
+
'After committing the fix, run \'npx nforma --reset-breaker\' to clear the circuit breaker state.',
|
|
470
|
+
'To temporarily disable the circuit breaker for deliberate iterative work, run \'npx nforma --disable-breaker\'.',
|
|
471
|
+
'Re-enable with \'npx nforma --enable-breaker\' when done.'
|
|
461
472
|
);
|
|
462
473
|
|
|
463
474
|
return lines.join('\n');
|
|
@@ -568,10 +579,10 @@ req.end();
|
|
|
568
579
|
// Clear state file so PreToolUse stops warning
|
|
569
580
|
const statePath = path.join(gitRoot, '.claude', 'circuit-breaker-state.json');
|
|
570
581
|
try { if (fs.existsSync(statePath)) fs.rmSync(statePath); } catch {}
|
|
571
|
-
process.stderr.write(`[
|
|
582
|
+
process.stderr.write(`[nf] INFO: Oscillation resolved by Haiku — circuit breaker cleared.\n`);
|
|
572
583
|
}
|
|
573
584
|
} catch (e) {
|
|
574
|
-
process.stderr.write(`[
|
|
585
|
+
process.stderr.write(`[nf] WARNING: PostToolUse Haiku check failed: ${e.message}\n`);
|
|
575
586
|
}
|
|
576
587
|
process.exit(0);
|
|
577
588
|
}
|
|
@@ -627,7 +638,7 @@ req.end();
|
|
|
627
638
|
if (verdict === 'REFINEMENT') {
|
|
628
639
|
// Haiku confirmed this is iterative refinement, not a bug loop — do not notify.
|
|
629
640
|
// Log false-negative for auditability (stderr + persistent file).
|
|
630
|
-
process.stderr.write(`[
|
|
641
|
+
process.stderr.write(`[nf] INFO: circuit breaker false-negative — Haiku classified oscillation as REFINEMENT (files: ${result.fileSet.join(', ')}). Allowing tool call to proceed.\n`);
|
|
631
642
|
appendFalseNegative(statePath, result.fileSet);
|
|
632
643
|
process.exit(0);
|
|
633
644
|
}
|
|
@@ -656,7 +667,7 @@ req.end();
|
|
|
656
667
|
};
|
|
657
668
|
writeOscillationLog(logPath, oscLog);
|
|
658
669
|
|
|
659
|
-
// Write state so
|
|
670
|
+
// Write state so nf-prompt.js picks it up on next user message
|
|
660
671
|
writeState(statePath, result.fileSet, fileSets);
|
|
661
672
|
|
|
662
673
|
appendConformanceEvent({
|