@nathapp/nax 0.18.1
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/.gitlab-ci.yml +96 -0
- package/BRIEF.md +140 -0
- package/CHANGELOG.md +60 -0
- package/CLAUDE.md +159 -0
- package/README.md +373 -0
- package/US-007-IMPLEMENTATION.md +139 -0
- package/bin/nax.ts +930 -0
- package/biome.json +14 -0
- package/bun.lock +168 -0
- package/bunfig.toml +11 -0
- package/docs/20260216-fix-plan-context-review.md +56 -0
- package/docs/20260216-relentless-vs-ngent-comparison.md +208 -0
- package/docs/20260216-v02-plan.md +136 -0
- package/docs/20260216-v02-review.md +685 -0
- package/docs/20260217-dogfood-findings.md +56 -0
- package/docs/20260217-p2-plus-plan.md +117 -0
- package/docs/20260217-partial-fixes-plan.md +62 -0
- package/docs/20260217-plan-analyze-spec.md +117 -0
- package/docs/20260217-post-impl-review.md +1137 -0
- package/docs/20260217-quick-wins-plan.md +66 -0
- package/docs/20260217-split-runner-plan.md +75 -0
- package/docs/20260217-v03-impl-plan.md +80 -0
- package/docs/20260217-v03-post-impl-review.md +589 -0
- package/docs/20260217-v04-impl-plan.md +86 -0
- package/docs/20260217-v05-post-impl-review.md +850 -0
- package/docs/20260217-v06-post-impl-review.md +817 -0
- package/docs/20260218-adr003-port-plan.md +151 -0
- package/docs/20260218-review-adr003-verification.md +175 -0
- package/docs/20260219-fix-plan-bug16-19.md +79 -0
- package/docs/20260219-fix-plan-bug20-22.md +114 -0
- package/docs/20260219-plan-llm-routing.md +116 -0
- package/docs/20260219-review-bug20-22-fixes.md +135 -0
- package/docs/20260219-routing-baseline-keyword.md +63 -0
- package/docs/20260220-plan-structured-logging-p1.md +80 -0
- package/docs/20260220-plan-structured-logging-p2.md +37 -0
- package/docs/20260220-review-llm-routing.md +180 -0
- package/docs/20260220-review-post-fix-llm-routing.md +70 -0
- package/docs/20260221-fix-plan-relevantfiles-split.md +101 -0
- package/docs/20260221-fix-plan-routing-mode.md +125 -0
- package/docs/20260221-review-v0.9-implementation.md +379 -0
- package/docs/20260222-fix-plan-v091-routing-isolation.md +197 -0
- package/docs/20260223-fix-plan-prompt-audit.md +62 -0
- package/docs/20260224-nax-roadmap-phases.md +189 -0
- package/docs/20260225-phase2-llm-service-layer.md +401 -0
- package/docs/20260225-review-v0.10.1.md +187 -0
- package/docs/20260303-v010-implementation-plan.md +165 -0
- package/docs/CLAUDE.md.bak +191 -0
- package/docs/ROADMAP.md +165 -0
- package/docs/SPEC-rectification.md +0 -0
- package/docs/SPEC.md +324 -0
- package/docs/US-001-plugin-loading-verification.md +152 -0
- package/docs/architecture-analysis.md +1076 -0
- package/docs/bugs/BUG-21-escalation-null-attempts.md +48 -0
- package/docs/bugs-from-dogfood-run-c.md +243 -0
- package/docs/code-review-20260228.md +612 -0
- package/docs/code-review-v0.15.0.md +629 -0
- package/docs/hook-lifecycle-test-plan.md +149 -0
- package/docs/releases/v0.11.0-and-earlier.md +20 -0
- package/docs/releases/v0.12.0.md +15 -0
- package/docs/releases/v0.13.0.md +14 -0
- package/docs/releases/v0.14.0.md +20 -0
- package/docs/releases/v0.14.1.md +36 -0
- package/docs/releases/v0.14.2.md +51 -0
- package/docs/releases/v0.14.3.md +174 -0
- package/docs/releases/v0.14.4.md +94 -0
- package/docs/releases/v0.15.0.md +502 -0
- package/docs/releases/v0.15.1.md +170 -0
- package/docs/releases/v0.15.3.md +193 -0
- package/docs/specs/status-file-v0.10.1.md +812 -0
- package/docs/v0.10-global-config.md +206 -0
- package/docs/v0.10-plugin-system.md +415 -0
- package/docs/v0.10-prompt-optimizer.md +234 -0
- package/docs/v0.3-spec.md +244 -0
- package/docs/v0.4-spec.md +140 -0
- package/docs/v0.5-spec.md +237 -0
- package/docs/v0.6-spec.md +371 -0
- package/docs/v0.7-spec.md +177 -0
- package/docs/v0.8-llm-routing.md +206 -0
- package/docs/v0.8-structured-logging.md +132 -0
- package/docs/v0.9.3-prompt-audit.md +112 -0
- package/examples/plugins/console-reporter/index.test.ts +207 -0
- package/examples/plugins/console-reporter/index.ts +110 -0
- package/nax/config.json +147 -0
- package/nax/features/bugfix-v0171/prd.json +52 -0
- package/nax/features/config-management/prd.json +108 -0
- package/nax/features/config-management/progress.txt +5 -0
- package/nax/features/diagnose/acceptance.test.ts +412 -0
- package/nax/features/diagnose/prd.json +41 -0
- package/nax/features/orchestration-fixes/prd.json +89 -0
- package/nax/features/orchestration-fixes/progress.txt +1 -0
- package/nax/features/plugin-integration/US-007-VERIFICATION.md +259 -0
- package/nax/features/plugin-integration/prd.json +208 -0
- package/nax/features/plugin-integration/progress.txt +5 -0
- package/nax/features/precheck/prd.json +205 -0
- package/nax/features/precheck/progress.txt +15 -0
- package/nax/features/structured-logging/prd.json +199 -0
- package/nax/features/unlock/prd.json +36 -0
- package/package.json +47 -0
- package/src/acceptance/fix-generator.ts +348 -0
- package/src/acceptance/generator.ts +282 -0
- package/src/acceptance/index.ts +30 -0
- package/src/acceptance/types.ts +79 -0
- package/src/agents/claude-decompose.ts +169 -0
- package/src/agents/claude-plan.ts +139 -0
- package/src/agents/claude.ts +324 -0
- package/src/agents/cost.ts +268 -0
- package/src/agents/index.ts +13 -0
- package/src/agents/registry.ts +48 -0
- package/src/agents/types-extended.ts +133 -0
- package/src/agents/types.ts +113 -0
- package/src/agents/validation.ts +69 -0
- package/src/analyze/classifier.ts +305 -0
- package/src/analyze/index.ts +16 -0
- package/src/analyze/scanner.ts +175 -0
- package/src/analyze/types.ts +51 -0
- package/src/cli/accept.ts +108 -0
- package/src/cli/analyze-parser.ts +284 -0
- package/src/cli/analyze.ts +207 -0
- package/src/cli/config.ts +561 -0
- package/src/cli/constitution.ts +109 -0
- package/src/cli/diagnose-analysis.ts +159 -0
- package/src/cli/diagnose-formatter.ts +87 -0
- package/src/cli/diagnose.ts +203 -0
- package/src/cli/generate.ts +127 -0
- package/src/cli/index.ts +37 -0
- package/src/cli/init.ts +188 -0
- package/src/cli/interact.ts +295 -0
- package/src/cli/plan.ts +198 -0
- package/src/cli/plugins.ts +111 -0
- package/src/cli/prompts.ts +295 -0
- package/src/cli/runs.ts +174 -0
- package/src/cli/status-cost.ts +151 -0
- package/src/cli/status-features.ts +338 -0
- package/src/cli/status.ts +13 -0
- package/src/commands/common.ts +171 -0
- package/src/commands/diagnose.ts +17 -0
- package/src/commands/index.ts +8 -0
- package/src/commands/logs.ts +384 -0
- package/src/commands/precheck.ts +86 -0
- package/src/commands/unlock.ts +96 -0
- package/src/config/defaults.ts +160 -0
- package/src/config/index.ts +22 -0
- package/src/config/loader.ts +121 -0
- package/src/config/merger.ts +147 -0
- package/src/config/path-security.ts +121 -0
- package/src/config/paths.ts +27 -0
- package/src/config/schema.ts +56 -0
- package/src/config/schemas.ts +286 -0
- package/src/config/types.ts +423 -0
- package/src/config/validate.ts +103 -0
- package/src/constitution/generator.ts +191 -0
- package/src/constitution/generators/aider.ts +41 -0
- package/src/constitution/generators/claude.ts +35 -0
- package/src/constitution/generators/cursor.ts +36 -0
- package/src/constitution/generators/opencode.ts +38 -0
- package/src/constitution/generators/types.ts +33 -0
- package/src/constitution/generators/windsurf.ts +36 -0
- package/src/constitution/index.ts +10 -0
- package/src/constitution/loader.ts +133 -0
- package/src/constitution/types.ts +31 -0
- package/src/context/auto-detect.ts +227 -0
- package/src/context/builder.ts +246 -0
- package/src/context/elements.ts +83 -0
- package/src/context/formatter.ts +107 -0
- package/src/context/generator.ts +129 -0
- package/src/context/generators/aider.ts +34 -0
- package/src/context/generators/claude.ts +28 -0
- package/src/context/generators/cursor.ts +28 -0
- package/src/context/generators/opencode.ts +30 -0
- package/src/context/generators/windsurf.ts +28 -0
- package/src/context/greenfield.ts +114 -0
- package/src/context/index.ts +33 -0
- package/src/context/injector.ts +279 -0
- package/src/context/test-scanner.ts +370 -0
- package/src/context/types.ts +98 -0
- package/src/errors.ts +67 -0
- package/src/execution/batching.ts +157 -0
- package/src/execution/crash-recovery.ts +373 -0
- package/src/execution/escalation/escalation.ts +44 -0
- package/src/execution/escalation/index.ts +13 -0
- package/src/execution/escalation/tier-escalation.ts +295 -0
- package/src/execution/escalation/tier-outcome.ts +158 -0
- package/src/execution/helpers.ts +38 -0
- package/src/execution/index.ts +45 -0
- package/src/execution/lifecycle/acceptance-loop.ts +272 -0
- package/src/execution/lifecycle/headless-formatter.ts +85 -0
- package/src/execution/lifecycle/index.ts +12 -0
- package/src/execution/lifecycle/parallel-lifecycle.ts +101 -0
- package/src/execution/lifecycle/precheck-runner.ts +140 -0
- package/src/execution/lifecycle/run-cleanup.ts +81 -0
- package/src/execution/lifecycle/run-completion.ts +129 -0
- package/src/execution/lifecycle/run-initialization.ts +141 -0
- package/src/execution/lifecycle/run-lifecycle.ts +312 -0
- package/src/execution/lifecycle/run-setup.ts +204 -0
- package/src/execution/lifecycle/story-hooks.ts +38 -0
- package/src/execution/lifecycle/story-size-prompts.ts +123 -0
- package/src/execution/lock.ts +115 -0
- package/src/execution/parallel-executor.ts +216 -0
- package/src/execution/parallel.ts +400 -0
- package/src/execution/pid-registry.ts +280 -0
- package/src/execution/pipeline-result-handler.ts +388 -0
- package/src/execution/post-verify-rectification.ts +188 -0
- package/src/execution/post-verify.ts +274 -0
- package/src/execution/progress.ts +25 -0
- package/src/execution/prompts.ts +127 -0
- package/src/execution/queue-handler.ts +109 -0
- package/src/execution/rectification.ts +13 -0
- package/src/execution/runner.ts +377 -0
- package/src/execution/sequential-executor.ts +388 -0
- package/src/execution/status-file.ts +264 -0
- package/src/execution/status-writer.ts +139 -0
- package/src/execution/story-context.ts +229 -0
- package/src/execution/test-output-parser.ts +14 -0
- package/src/execution/verification.ts +72 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/runner.ts +286 -0
- package/src/hooks/types.ts +67 -0
- package/src/interaction/chain.ts +154 -0
- package/src/interaction/index.ts +60 -0
- package/src/interaction/init.ts +83 -0
- package/src/interaction/plugins/auto.ts +217 -0
- package/src/interaction/plugins/cli.ts +300 -0
- package/src/interaction/plugins/telegram.ts +384 -0
- package/src/interaction/plugins/webhook.ts +258 -0
- package/src/interaction/state.ts +171 -0
- package/src/interaction/triggers.ts +229 -0
- package/src/interaction/types.ts +163 -0
- package/src/logger/formatters.ts +84 -0
- package/src/logger/index.ts +16 -0
- package/src/logger/logger.ts +298 -0
- package/src/logger/types.ts +48 -0
- package/src/logging/formatter.ts +355 -0
- package/src/logging/index.ts +22 -0
- package/src/logging/types.ts +93 -0
- package/src/metrics/aggregator.ts +190 -0
- package/src/metrics/index.ts +14 -0
- package/src/metrics/tracker.ts +200 -0
- package/src/metrics/types.ts +109 -0
- package/src/optimizer/index.ts +62 -0
- package/src/optimizer/noop.optimizer.ts +24 -0
- package/src/optimizer/rule-based.optimizer.ts +248 -0
- package/src/optimizer/types.ts +53 -0
- package/src/pipeline/events.ts +130 -0
- package/src/pipeline/index.ts +19 -0
- package/src/pipeline/runner.ts +161 -0
- package/src/pipeline/stages/acceptance.ts +197 -0
- package/src/pipeline/stages/completion.ts +99 -0
- package/src/pipeline/stages/constitution.ts +63 -0
- package/src/pipeline/stages/context.ts +117 -0
- package/src/pipeline/stages/execution.ts +194 -0
- package/src/pipeline/stages/index.ts +62 -0
- package/src/pipeline/stages/optimizer.ts +74 -0
- package/src/pipeline/stages/prompt.ts +57 -0
- package/src/pipeline/stages/queue-check.ts +103 -0
- package/src/pipeline/stages/review.ts +181 -0
- package/src/pipeline/stages/routing.ts +81 -0
- package/src/pipeline/stages/verify.ts +100 -0
- package/src/pipeline/types.ts +167 -0
- package/src/plugins/index.ts +31 -0
- package/src/plugins/loader.ts +287 -0
- package/src/plugins/registry.ts +168 -0
- package/src/plugins/types.ts +327 -0
- package/src/plugins/validator.ts +352 -0
- package/src/prd/index.ts +172 -0
- package/src/prd/types.ts +202 -0
- package/src/precheck/checks-blockers.ts +391 -0
- package/src/precheck/checks-warnings.ts +142 -0
- package/src/precheck/checks.ts +30 -0
- package/src/precheck/index.ts +247 -0
- package/src/precheck/story-size-gate.ts +144 -0
- package/src/precheck/types.ts +31 -0
- package/src/queue/index.ts +2 -0
- package/src/queue/manager.ts +254 -0
- package/src/queue/types.ts +54 -0
- package/src/review/index.ts +8 -0
- package/src/review/runner.ts +172 -0
- package/src/review/types.ts +66 -0
- package/src/routing/builder.ts +81 -0
- package/src/routing/chain.ts +74 -0
- package/src/routing/index.ts +16 -0
- package/src/routing/loader.ts +58 -0
- package/src/routing/router.ts +303 -0
- package/src/routing/strategies/adaptive.ts +215 -0
- package/src/routing/strategies/index.ts +8 -0
- package/src/routing/strategies/keyword.ts +163 -0
- package/src/routing/strategies/llm-prompts.ts +209 -0
- package/src/routing/strategies/llm.ts +235 -0
- package/src/routing/strategies/manual.ts +50 -0
- package/src/routing/strategy.ts +99 -0
- package/src/tdd/cleanup.ts +111 -0
- package/src/tdd/index.ts +23 -0
- package/src/tdd/isolation.ts +123 -0
- package/src/tdd/orchestrator.ts +383 -0
- package/src/tdd/prompts.ts +270 -0
- package/src/tdd/rectification-gate.ts +183 -0
- package/src/tdd/session-runner.ts +179 -0
- package/src/tdd/types.ts +81 -0
- package/src/tdd/verdict.ts +271 -0
- package/src/tui/App.tsx +265 -0
- package/src/tui/components/AgentPanel.tsx +75 -0
- package/src/tui/components/CostOverlay.tsx +118 -0
- package/src/tui/components/HelpOverlay.tsx +107 -0
- package/src/tui/components/StatusBar.tsx +63 -0
- package/src/tui/components/StoriesPanel.tsx +177 -0
- package/src/tui/hooks/useKeyboard.ts +142 -0
- package/src/tui/hooks/useLayout.ts +137 -0
- package/src/tui/hooks/usePipelineEvents.ts +183 -0
- package/src/tui/hooks/usePty.ts +194 -0
- package/src/tui/index.tsx +38 -0
- package/src/tui/types.ts +76 -0
- package/src/utils/git.ts +83 -0
- package/src/utils/queue-writer.ts +54 -0
- package/src/verification/executor.ts +235 -0
- package/src/verification/gate.ts +207 -0
- package/src/verification/index.ts +12 -0
- package/src/verification/parser.ts +230 -0
- package/src/verification/rectification.ts +108 -0
- package/src/verification/types.ts +113 -0
- package/src/worktree/dispatcher.ts +65 -0
- package/src/worktree/index.ts +2 -0
- package/src/worktree/manager.ts +187 -0
- package/src/worktree/merge.ts +301 -0
- package/src/worktree/types.ts +4 -0
- package/test/TEST_COVERAGE_US001.md +217 -0
- package/test/TEST_COVERAGE_US003.md +84 -0
- package/test/TEST_COVERAGE_US005.md +86 -0
- package/test/US-002-orchestrator.test.ts +246 -0
- package/test/acceptance/cm-003-default-view.test.ts +194 -0
- package/test/execution/pid-registry.test.ts +240 -0
- package/test/execution/post-verify.test.ts +224 -0
- package/test/helpers/timeout.ts +42 -0
- package/test/integration/US-002-TEST-SUMMARY.md +107 -0
- package/test/integration/US-003-TEST-SUMMARY.md +149 -0
- package/test/integration/US-004-TEST-SUMMARY.md +106 -0
- package/test/integration/US-005-TEST-SUMMARY.md +138 -0
- package/test/integration/US-007-TEST-SUMMARY.md +100 -0
- package/test/integration/agent-validation.test.ts +439 -0
- package/test/integration/analyze-integration.test.ts +261 -0
- package/test/integration/analyze-scanner.test.ts +131 -0
- package/test/integration/cli-config-default-edge-cases.test.ts +222 -0
- package/test/integration/cli-config-default-view.test.ts +229 -0
- package/test/integration/cli-config-diff.test.ts +460 -0
- package/test/integration/cli-config.test.ts +736 -0
- package/test/integration/cli-diagnose.test.ts +592 -0
- package/test/integration/cli-logs.test.ts +314 -0
- package/test/integration/cli-plugins.test.ts +678 -0
- package/test/integration/cli-precheck.test.ts +371 -0
- package/test/integration/cli-run-headless.test.ts +173 -0
- package/test/integration/cli.test.ts +75 -0
- package/test/integration/config/merger.test.ts +465 -0
- package/test/integration/config/paths.test.ts +51 -0
- package/test/integration/config-loader.test.ts +265 -0
- package/test/integration/config.test.ts +444 -0
- package/test/integration/context-integration.test.ts +702 -0
- package/test/integration/context-provider-injection.test.ts +506 -0
- package/test/integration/context-verification-integration.test.ts +295 -0
- package/test/integration/e2e.test.ts +896 -0
- package/test/integration/execution.test.ts +625 -0
- package/test/integration/helpers.test.ts +295 -0
- package/test/integration/hooks.test.ts +361 -0
- package/test/integration/interaction-chain-pipeline.test.ts +464 -0
- package/test/integration/isolation.test.ts +143 -0
- package/test/integration/logger.test.ts +461 -0
- package/test/integration/parallel.test.ts +250 -0
- package/test/integration/path-security.test.ts +173 -0
- package/test/integration/pipeline-acceptance.test.ts +302 -0
- package/test/integration/pipeline-events.test.ts +475 -0
- package/test/integration/pipeline.test.ts +658 -0
- package/test/integration/plan.test.ts +157 -0
- package/test/integration/plugin-routing.test.ts +921 -0
- package/test/integration/plugins/config-integration.test.ts +172 -0
- package/test/integration/plugins/config-resolution.test.ts +522 -0
- package/test/integration/plugins/loader.test.ts +641 -0
- package/test/integration/plugins/registry.test.ts +746 -0
- package/test/integration/plugins/validator.test.ts +563 -0
- package/test/integration/prd-pause.test.ts +205 -0
- package/test/integration/prd-resolvers.test.ts +185 -0
- package/test/integration/precheck-integration.test.ts +468 -0
- package/test/integration/precheck.test.ts +805 -0
- package/test/integration/progress.test.ts +34 -0
- package/test/integration/rectification-flow.test.ts +512 -0
- package/test/integration/reporter-lifecycle.test.ts +860 -0
- package/test/integration/review-config-commands.test.ts +319 -0
- package/test/integration/review-config-schema.test.ts +116 -0
- package/test/integration/review-plugin-integration.test.ts +722 -0
- package/test/integration/review.test.ts +149 -0
- package/test/integration/routing-stage-bug-021.test.ts +274 -0
- package/test/integration/routing-stage-greenfield.test.ts +286 -0
- package/test/integration/runner-config-plugins.test.ts +461 -0
- package/test/integration/runner-fixes.test.ts +399 -0
- package/test/integration/runner-plugin-integration.test.ts +543 -0
- package/test/integration/runner.test.ts +1679 -0
- package/test/integration/s5-greenfield-fallback.test.ts +297 -0
- package/test/integration/status-file-integration.test.ts +325 -0
- package/test/integration/status-file.test.ts +379 -0
- package/test/integration/status-writer.test.ts +345 -0
- package/test/integration/story-id-in-events.test.ts +273 -0
- package/test/integration/tdd-cleanup.test.ts +246 -0
- package/test/integration/tdd-orchestrator.test.ts +1762 -0
- package/test/integration/test-scanner.test.ts +403 -0
- package/test/integration/verification-asset-check.test.ts +142 -0
- package/test/integration/verify-stage.test.ts +275 -0
- package/test/integration/worktree/manager.test.ts +218 -0
- package/test/integration/worktree/merge.test.ts +341 -0
- package/test/manual/logging-formatter-demo.ts +158 -0
- package/test/ui/tui-agent-panel.test.tsx +99 -0
- package/test/ui/tui-controls.test.ts +334 -0
- package/test/ui/tui-cost-and-pty.test.ts +189 -0
- package/test/ui/tui-layout.test.ts +378 -0
- package/test/ui/tui-pty-integration.test.tsx +159 -0
- package/test/ui/tui-stories.test.ts +332 -0
- package/test/unit/acceptance.test.ts +186 -0
- package/test/unit/agent-stderr-capture.test.ts +146 -0
- package/test/unit/analyze-classifier.test.ts +215 -0
- package/test/unit/analyze.test.ts +224 -0
- package/test/unit/auto-detect.test.ts +249 -0
- package/test/unit/cli-status.test.ts +417 -0
- package/test/unit/commands/common.test.ts +320 -0
- package/test/unit/commands/logs.test.ts +416 -0
- package/test/unit/commands/unlock.test.ts +319 -0
- package/test/unit/constitution-generators.test.ts +160 -0
- package/test/unit/constitution.test.ts +209 -0
- package/test/unit/context.test.ts +1722 -0
- package/test/unit/cost.test.ts +231 -0
- package/test/unit/crash-recovery.test.ts +308 -0
- package/test/unit/escalation.test.ts +126 -0
- package/test/unit/execution-logging-stderr.test.ts +156 -0
- package/test/unit/execution-stage.test.ts +122 -0
- package/test/unit/fix-generator.test.ts +275 -0
- package/test/unit/formatters.test.ts +469 -0
- package/test/unit/greenfield.test.ts +179 -0
- package/test/unit/helpers.test.ts +317 -0
- package/test/unit/interaction/human-review-trigger.test.ts +164 -0
- package/test/unit/interaction-network-failures.test.ts +389 -0
- package/test/unit/interaction-plugins.test.ts +164 -0
- package/test/unit/isolation.test.ts +134 -0
- package/test/unit/logging/formatter.test.ts +455 -0
- package/test/unit/merge.test.ts +268 -0
- package/test/unit/metrics.test.ts +276 -0
- package/test/unit/optimizer/noop.optimizer.test.ts +125 -0
- package/test/unit/optimizer/rule-based.optimizer.test.ts +358 -0
- package/test/unit/prd-auto-default.test.ts +290 -0
- package/test/unit/prd-failure-category.test.ts +176 -0
- package/test/unit/prd-get-next-story.test.ts +186 -0
- package/test/unit/precheck-checks.test.ts +840 -0
- package/test/unit/precheck-story-size-gate.test.ts +287 -0
- package/test/unit/precheck-types.test.ts +142 -0
- package/test/unit/prompts.test.ts +475 -0
- package/test/unit/queue.test.ts +237 -0
- package/test/unit/rectification.test.ts +284 -0
- package/test/unit/registry.test.ts +287 -0
- package/test/unit/routing.test.ts +937 -0
- package/test/unit/run-lifecycle.test.ts +140 -0
- package/test/unit/storyid-events.test.ts +224 -0
- package/test/unit/tdd-verdict.test.ts +492 -0
- package/test/unit/test-output-parser.test.ts +377 -0
- package/test/unit/verdict.test.ts +324 -0
- package/test/unit/worktree-manager.test.ts +158 -0
- package/tsconfig.json +27 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Acceptance Test: nax diagnose CLI
|
|
3
|
+
*
|
|
4
|
+
* Validates that the nax diagnose command meets all acceptance criteria.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, test, expect, beforeEach, afterEach } from "bun:test";
|
|
8
|
+
import { existsSync, mkdirSync, rmSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { diagnoseCommand } from "../../../src/cli/diagnose";
|
|
12
|
+
import type { PRD } from "../../../src/prd";
|
|
13
|
+
import { savePRD } from "../../../src/prd";
|
|
14
|
+
import type { NaxStatusFile } from "../../../src/execution/status-file";
|
|
15
|
+
|
|
16
|
+
// Test fixture directory
|
|
17
|
+
let testDir: string;
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
// Create unique test directory
|
|
21
|
+
testDir = join(tmpdir(), `nax-diagnose-acceptance-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
22
|
+
mkdirSync(testDir, { recursive: true });
|
|
23
|
+
mkdirSync(join(testDir, "nax", "features"), { recursive: true });
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
afterEach(() => {
|
|
27
|
+
// Clean up test directory
|
|
28
|
+
if (existsSync(testDir)) {
|
|
29
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Create a minimal PRD fixture
|
|
35
|
+
*/
|
|
36
|
+
function createPRD(feature: string, stories: Array<Partial<PRD["userStories"][0]>>): PRD {
|
|
37
|
+
return {
|
|
38
|
+
project: "test-project",
|
|
39
|
+
feature,
|
|
40
|
+
branchName: "feature/test",
|
|
41
|
+
createdAt: "2026-01-01T00:00:00Z",
|
|
42
|
+
updatedAt: "2026-01-01T00:00:00Z",
|
|
43
|
+
userStories: stories.map((s, i) => ({
|
|
44
|
+
id: s.id ?? `US-${String(i + 1).padStart(3, "0")}`,
|
|
45
|
+
title: s.title ?? "Test Story",
|
|
46
|
+
description: s.description ?? "Test description",
|
|
47
|
+
acceptanceCriteria: s.acceptanceCriteria ?? [],
|
|
48
|
+
tags: s.tags ?? [],
|
|
49
|
+
dependencies: s.dependencies ?? [],
|
|
50
|
+
status: s.status ?? "pending",
|
|
51
|
+
passes: s.passes ?? false,
|
|
52
|
+
escalations: s.escalations ?? [],
|
|
53
|
+
attempts: s.attempts ?? 0,
|
|
54
|
+
priorErrors: s.priorErrors ?? [],
|
|
55
|
+
...s,
|
|
56
|
+
})),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Create a status.json fixture
|
|
62
|
+
*/
|
|
63
|
+
async function createStatusFile(
|
|
64
|
+
dir: string,
|
|
65
|
+
feature: string,
|
|
66
|
+
overrides: Partial<NaxStatusFile> = {},
|
|
67
|
+
): Promise<void> {
|
|
68
|
+
const status: NaxStatusFile = {
|
|
69
|
+
version: 1,
|
|
70
|
+
run: {
|
|
71
|
+
id: "run-001",
|
|
72
|
+
feature,
|
|
73
|
+
startedAt: "2026-01-01T10:00:00Z",
|
|
74
|
+
status: "running",
|
|
75
|
+
dryRun: false,
|
|
76
|
+
pid: process.pid,
|
|
77
|
+
...overrides.run,
|
|
78
|
+
},
|
|
79
|
+
progress: {
|
|
80
|
+
total: 3,
|
|
81
|
+
passed: 1,
|
|
82
|
+
failed: 1,
|
|
83
|
+
paused: 0,
|
|
84
|
+
blocked: 0,
|
|
85
|
+
pending: 1,
|
|
86
|
+
...overrides.progress,
|
|
87
|
+
},
|
|
88
|
+
cost: {
|
|
89
|
+
spent: 0.05,
|
|
90
|
+
limit: null,
|
|
91
|
+
...overrides.cost,
|
|
92
|
+
},
|
|
93
|
+
current: null,
|
|
94
|
+
iterations: 1,
|
|
95
|
+
updatedAt: "2026-01-01T10:30:00Z",
|
|
96
|
+
durationMs: 1800000,
|
|
97
|
+
...overrides,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
await Bun.write(join(dir, ".nax-status.json"), JSON.stringify(status, null, 2));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Create a lock file fixture
|
|
105
|
+
*/
|
|
106
|
+
async function createLockFile(dir: string, pid: number): Promise<void> {
|
|
107
|
+
await Bun.write(
|
|
108
|
+
join(dir, "nax.lock"),
|
|
109
|
+
JSON.stringify({
|
|
110
|
+
pid,
|
|
111
|
+
timestamp: Date.now(),
|
|
112
|
+
}),
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// AC1: Basic diagnosis with all 5 sections
|
|
118
|
+
// ============================================================================
|
|
119
|
+
|
|
120
|
+
describe("AC1: nax diagnose reads last run and prints all 5 sections", () => {
|
|
121
|
+
test("prints Run Summary, Story Breakdown, Failure Analysis, Lock Check, Recommendations", async () => {
|
|
122
|
+
const feature = "test-feature";
|
|
123
|
+
const featureDir = join(testDir, "nax", "features", feature);
|
|
124
|
+
mkdirSync(featureDir, { recursive: true });
|
|
125
|
+
|
|
126
|
+
const prd = createPRD(feature, [
|
|
127
|
+
{ id: "US-001", title: "Passed Story", status: "passed", passes: true, attempts: 1 },
|
|
128
|
+
{
|
|
129
|
+
id: "US-002",
|
|
130
|
+
title: "Failed Story",
|
|
131
|
+
status: "failed",
|
|
132
|
+
passes: false,
|
|
133
|
+
attempts: 3,
|
|
134
|
+
priorErrors: ["tests-failing", "tests-failing"],
|
|
135
|
+
},
|
|
136
|
+
{ id: "US-003", title: "Pending Story", status: "pending", passes: false, attempts: 0 },
|
|
137
|
+
]);
|
|
138
|
+
|
|
139
|
+
await savePRD(prd, join(featureDir, "prd.json"));
|
|
140
|
+
await createStatusFile(testDir, feature);
|
|
141
|
+
|
|
142
|
+
let output = "";
|
|
143
|
+
const originalLog = console.log;
|
|
144
|
+
console.log = (...args: unknown[]) => {
|
|
145
|
+
output += args.join(" ") + "\n";
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
await diagnoseCommand({ feature, workdir: testDir, verbose: true });
|
|
150
|
+
|
|
151
|
+
// Verify all sections present
|
|
152
|
+
expect(output).toContain("Diagnosis Report");
|
|
153
|
+
expect(output).toContain("Run Summary");
|
|
154
|
+
expect(output).toContain("Story Breakdown");
|
|
155
|
+
expect(output).toContain("Failure Analysis");
|
|
156
|
+
expect(output).toContain("Lock Check");
|
|
157
|
+
expect(output).toContain("Recommendations");
|
|
158
|
+
|
|
159
|
+
// Verify counts
|
|
160
|
+
expect(output).toContain("Passed: 1");
|
|
161
|
+
expect(output).toContain("Failed: 1");
|
|
162
|
+
expect(output).toContain("Pending: 1");
|
|
163
|
+
} finally {
|
|
164
|
+
console.log = originalLog;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// ============================================================================
|
|
170
|
+
// AC2: Pattern classification for failed stories
|
|
171
|
+
// ============================================================================
|
|
172
|
+
|
|
173
|
+
describe("AC2: Each failed story shows pattern classification", () => {
|
|
174
|
+
test("classifies all failure patterns correctly", async () => {
|
|
175
|
+
const feature = "patterns-feature";
|
|
176
|
+
const featureDir = join(testDir, "nax", "features", feature);
|
|
177
|
+
mkdirSync(featureDir, { recursive: true });
|
|
178
|
+
|
|
179
|
+
const prd = createPRD(feature, [
|
|
180
|
+
{
|
|
181
|
+
id: "US-001",
|
|
182
|
+
title: "Greenfield Story",
|
|
183
|
+
status: "failed",
|
|
184
|
+
failureCategory: "greenfield-no-tests",
|
|
185
|
+
attempts: 1,
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: "US-002",
|
|
189
|
+
title: "Test Mismatch",
|
|
190
|
+
status: "failed",
|
|
191
|
+
priorErrors: ["tests-failing", "tests-failing"],
|
|
192
|
+
attempts: 2,
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
id: "US-003",
|
|
196
|
+
title: "Isolation Violation",
|
|
197
|
+
status: "failed",
|
|
198
|
+
failureCategory: "isolation-violation",
|
|
199
|
+
attempts: 1,
|
|
200
|
+
},
|
|
201
|
+
]);
|
|
202
|
+
|
|
203
|
+
await savePRD(prd, join(featureDir, "prd.json"));
|
|
204
|
+
|
|
205
|
+
let output = "";
|
|
206
|
+
const originalLog = console.log;
|
|
207
|
+
console.log = (...args: unknown[]) => {
|
|
208
|
+
output += args.join(" ") + "\n";
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
try {
|
|
212
|
+
await diagnoseCommand({ feature, workdir: testDir });
|
|
213
|
+
|
|
214
|
+
expect(output).toContain("GREENFIELD_TDD");
|
|
215
|
+
expect(output).toContain("TEST_MISMATCH");
|
|
216
|
+
expect(output).toContain("ISOLATION_VIOLATION");
|
|
217
|
+
} finally {
|
|
218
|
+
console.log = originalLog;
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// ============================================================================
|
|
224
|
+
// AC3: Stale lock detection
|
|
225
|
+
// ============================================================================
|
|
226
|
+
|
|
227
|
+
describe("AC3: Stale nax.lock detection", () => {
|
|
228
|
+
test("detects stale lock and shows fix command", async () => {
|
|
229
|
+
const feature = "locked-feature";
|
|
230
|
+
const featureDir = join(testDir, "nax", "features", feature);
|
|
231
|
+
mkdirSync(featureDir, { recursive: true });
|
|
232
|
+
|
|
233
|
+
const prd = createPRD(feature, [{ id: "US-001", title: "Test Story", status: "pending" }]);
|
|
234
|
+
await savePRD(prd, join(featureDir, "prd.json"));
|
|
235
|
+
await createLockFile(testDir, 999999); // Dead PID
|
|
236
|
+
|
|
237
|
+
let output = "";
|
|
238
|
+
const originalLog = console.log;
|
|
239
|
+
console.log = (...args: unknown[]) => {
|
|
240
|
+
output += args.join(" ") + "\n";
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
await diagnoseCommand({ feature, workdir: testDir });
|
|
245
|
+
|
|
246
|
+
expect(output).toContain("Stale lock detected");
|
|
247
|
+
expect(output).toContain("rm nax.lock");
|
|
248
|
+
} finally {
|
|
249
|
+
console.log = originalLog;
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// ============================================================================
|
|
255
|
+
// AC4: JSON output mode
|
|
256
|
+
// ============================================================================
|
|
257
|
+
|
|
258
|
+
describe("AC4: --json flag outputs machine-readable JSON", () => {
|
|
259
|
+
test("outputs valid JSON with all report fields", async () => {
|
|
260
|
+
const feature = "json-feature";
|
|
261
|
+
const featureDir = join(testDir, "nax", "features", feature);
|
|
262
|
+
mkdirSync(featureDir, { recursive: true });
|
|
263
|
+
|
|
264
|
+
const prd = createPRD(feature, [
|
|
265
|
+
{ id: "US-001", title: "Passed Story", status: "passed", passes: true },
|
|
266
|
+
{ id: "US-002", title: "Failed Story", status: "failed", attempts: 2 },
|
|
267
|
+
]);
|
|
268
|
+
|
|
269
|
+
await savePRD(prd, join(featureDir, "prd.json"));
|
|
270
|
+
|
|
271
|
+
let output = "";
|
|
272
|
+
const originalLog = console.log;
|
|
273
|
+
console.log = (...args: unknown[]) => {
|
|
274
|
+
output += args.join(" ") + "\n";
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
try {
|
|
278
|
+
await diagnoseCommand({ feature, workdir: testDir, json: true });
|
|
279
|
+
|
|
280
|
+
const report = JSON.parse(output);
|
|
281
|
+
|
|
282
|
+
expect(report).toHaveProperty("runSummary");
|
|
283
|
+
expect(report).toHaveProperty("storyBreakdown");
|
|
284
|
+
expect(report).toHaveProperty("failureAnalysis");
|
|
285
|
+
expect(report).toHaveProperty("lockCheck");
|
|
286
|
+
expect(report).toHaveProperty("recommendations");
|
|
287
|
+
expect(report).toHaveProperty("dataSources");
|
|
288
|
+
|
|
289
|
+
expect(report.runSummary.storiesPassed).toBe(1);
|
|
290
|
+
expect(report.runSummary.storiesFailed).toBe(1);
|
|
291
|
+
} finally {
|
|
292
|
+
console.log = originalLog;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// ============================================================================
|
|
298
|
+
// AC5: Graceful degradation when events.jsonl missing
|
|
299
|
+
// ============================================================================
|
|
300
|
+
|
|
301
|
+
describe("AC5: Works gracefully when events.jsonl missing", () => {
|
|
302
|
+
test("uses PRD + git log only and prints note", async () => {
|
|
303
|
+
const feature = "no-events-feature";
|
|
304
|
+
const featureDir = join(testDir, "nax", "features", feature);
|
|
305
|
+
mkdirSync(featureDir, { recursive: true });
|
|
306
|
+
|
|
307
|
+
const prd = createPRD(feature, [{ id: "US-001", title: "Test Story", status: "passed", passes: true }]);
|
|
308
|
+
await savePRD(prd, join(featureDir, "prd.json"));
|
|
309
|
+
|
|
310
|
+
let output = "";
|
|
311
|
+
const originalLog = console.log;
|
|
312
|
+
console.log = (...args: unknown[]) => {
|
|
313
|
+
output += args.join(" ") + "\n";
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
try {
|
|
317
|
+
await diagnoseCommand({ feature, workdir: testDir });
|
|
318
|
+
|
|
319
|
+
expect(output).toContain("Diagnosis Report");
|
|
320
|
+
expect(output).toContain("events.jsonl not found");
|
|
321
|
+
} finally {
|
|
322
|
+
console.log = originalLog;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
// ============================================================================
|
|
328
|
+
// AC6: -f and -d flags for targeting
|
|
329
|
+
// ============================================================================
|
|
330
|
+
|
|
331
|
+
describe("AC6: -f <feature> and -d <workdir> flags work", () => {
|
|
332
|
+
test("diagnoses specific feature with -f flag", async () => {
|
|
333
|
+
const feature = "specific-feature";
|
|
334
|
+
const featureDir = join(testDir, "nax", "features", feature);
|
|
335
|
+
mkdirSync(featureDir, { recursive: true });
|
|
336
|
+
|
|
337
|
+
const prd = createPRD(feature, [{ id: "US-001", title: "Specific Story", status: "passed", passes: true }]);
|
|
338
|
+
await savePRD(prd, join(featureDir, "prd.json"));
|
|
339
|
+
|
|
340
|
+
let output = "";
|
|
341
|
+
const originalLog = console.log;
|
|
342
|
+
console.log = (...args: unknown[]) => {
|
|
343
|
+
output += args.join(" ") + "\n";
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
try {
|
|
347
|
+
await diagnoseCommand({ feature, workdir: testDir, verbose: true });
|
|
348
|
+
|
|
349
|
+
expect(output).toContain(feature);
|
|
350
|
+
expect(output).toContain("Specific Story");
|
|
351
|
+
} finally {
|
|
352
|
+
console.log = originalLog;
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
// ============================================================================
|
|
358
|
+
// AC7: AUTO_RECOVERED shown as INFO not ERROR
|
|
359
|
+
// ============================================================================
|
|
360
|
+
|
|
361
|
+
describe("AC7: AUTO_RECOVERED stories shown as INFO", () => {
|
|
362
|
+
test("displays AUTO_RECOVERED with INFO level, not ERROR", async () => {
|
|
363
|
+
const feature = "recovered-feature";
|
|
364
|
+
const featureDir = join(testDir, "nax", "features", feature);
|
|
365
|
+
mkdirSync(featureDir, { recursive: true });
|
|
366
|
+
|
|
367
|
+
const prd = createPRD(feature, [
|
|
368
|
+
{
|
|
369
|
+
id: "US-001",
|
|
370
|
+
title: "Recovered Story",
|
|
371
|
+
status: "passed",
|
|
372
|
+
passes: true,
|
|
373
|
+
priorErrors: ["greenfield-no-tests"],
|
|
374
|
+
attempts: 2,
|
|
375
|
+
},
|
|
376
|
+
]);
|
|
377
|
+
|
|
378
|
+
await savePRD(prd, join(featureDir, "prd.json"));
|
|
379
|
+
|
|
380
|
+
let output = "";
|
|
381
|
+
const originalLog = console.log;
|
|
382
|
+
console.log = (...args: unknown[]) => {
|
|
383
|
+
output += args.join(" ") + "\n";
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
try {
|
|
387
|
+
await diagnoseCommand({ feature, workdir: testDir });
|
|
388
|
+
|
|
389
|
+
expect(output).toContain("INFO");
|
|
390
|
+
expect(output).toContain("AUTO_RECOVERED");
|
|
391
|
+
expect(output).not.toContain("ERROR US-001");
|
|
392
|
+
} finally {
|
|
393
|
+
console.log = originalLog;
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
// ============================================================================
|
|
399
|
+
// AC8: TypeScript compiles cleanly
|
|
400
|
+
// ============================================================================
|
|
401
|
+
|
|
402
|
+
describe("AC8: TypeScript compiles cleanly", () => {
|
|
403
|
+
test("bun x tsc --noEmit passes", async () => {
|
|
404
|
+
const result = Bun.spawnSync(["bun", "x", "tsc", "--noEmit"], {
|
|
405
|
+
cwd: join(__dirname, "../../.."),
|
|
406
|
+
stdout: "pipe",
|
|
407
|
+
stderr: "pipe",
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
expect(result.exitCode).toBe(0);
|
|
411
|
+
}, 60000);
|
|
412
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"project": "nax",
|
|
3
|
+
"feature": "diagnose",
|
|
4
|
+
"branchName": "feat/v0.14.1-diagnose-cli",
|
|
5
|
+
"createdAt": "2026-02-28T12:00:00Z",
|
|
6
|
+
"userStories": [
|
|
7
|
+
{
|
|
8
|
+
"id": "US-001",
|
|
9
|
+
"title": "nax diagnose CLI \u2014 pure pattern-matching diagnosis",
|
|
10
|
+
"description": "Implement the `nax diagnose` command that reads existing run artifacts (events.jsonl from ~/.nax/events/<project>/, status.json from <workdir>/.nax-status.json, PRD from nax/features/<feature>/prd.json, nax.lock from <workdir>/nax.lock, git log) and produces a structured human-readable diagnosis report. No LLM calls. No agent. Purely deterministic pattern matching.\n\nCOMMAND SIGNATURE:\n nax diagnose [-f <feature>] [-d <workdir>] [--json] [--verbose]\n\nOUTPUT SECTIONS:\n1. Run Summary \u2014 feature, last run time, status (complete/stalled/failed), stories passed/failed/pending, cost, commits produced\n2. Story Breakdown \u2014 per-story: status, attempts, tier, strategy, pattern detected\n3. Failure Analysis \u2014 for each failed story: pattern name, symptom description, fix suggestion\n4. Lock Check \u2014 is nax.lock present? Is PID alive (process.kill(pid, 0))? Show fix command if stale.\n5. Recommendations \u2014 ordered list of next actions\n\nFAILURE PATTERNS TO DETECT (match in order):\n- GREENFIELD_TDD: failureCategory === greenfield-no-tests in priorErrors or events\n- TEST_MISMATCH: 2+ consecutive tests-failing escalation events for same story\n- ENVIRONMENTAL: precheck-failed event OR blocker in status.json\n- RATE_LIMITED: rateLimited: true in agent session failure events\n- ISOLATION_VIOLATION: failureCategory === isolation-violation\n- MAX_TIERS_EXHAUSTED: story has priorErrors for all configured tiers AND status is failed/paused\n- SESSION_CRASH: session-failure category + no commits for that story in git log\n- STALLED: isStalled flag in status.json OR all pending stories blocked by dependencies\n- LOCK_STALE: nax.lock present + PID not alive\n- AUTO_RECOVERED: story had greenfield-no-tests but status is passed (S5 worked)\n- UNKNOWN: no pattern matched\n\nGRACEFUL DEGRADATION: If events.jsonl is missing, fall back to PRD priorErrors + git log only. Never crash \u2014 always produce partial output with a note about missing data.\n\nFILES TO CREATE:\n- src/cli/diagnose.ts \u2014 main implementation (read artifacts, pattern match, format output)\n- src/commands/diagnose.ts \u2014 thin commander wrapper registering the command\n- Register in bin/nax.ts \u2014 add diagnose command import\n- test/integration/cli-diagnose.test.ts \u2014 integration tests covering all ACs",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
"AC1: `nax diagnose` reads the last run for the current directory feature and prints human-readable output with all 5 sections (Run Summary, Story Breakdown, Failure Analysis, Lock Check, Recommendations)",
|
|
13
|
+
"AC2: Each failed story shows a pattern classification from the known patterns list, or UNKNOWN if no match",
|
|
14
|
+
"AC3: Stale nax.lock (lock present + PID dead) is detected and a fix command shown: rm nax.lock",
|
|
15
|
+
"AC4: `--json` flag outputs machine-readable JSON containing the same data as human output",
|
|
16
|
+
"AC5: Works gracefully when events.jsonl is missing \u2014 uses PRD + git log only, prints a note about missing events",
|
|
17
|
+
"AC6: `-f <feature>` targets a specific feature; `-d <workdir>` sets working directory",
|
|
18
|
+
"AC7: AUTO_RECOVERED stories (S5 switched strategy, story passed) are shown as INFO not ERROR",
|
|
19
|
+
"AC8: TypeScript compiles cleanly (bun x tsc --noEmit)"
|
|
20
|
+
],
|
|
21
|
+
"dependencies": [],
|
|
22
|
+
"tags": [
|
|
23
|
+
"cli",
|
|
24
|
+
"medium"
|
|
25
|
+
],
|
|
26
|
+
"status": "passed",
|
|
27
|
+
"passes": true,
|
|
28
|
+
"attempts": 1,
|
|
29
|
+
"escalations": [],
|
|
30
|
+
"priorErrors": [
|
|
31
|
+
"Manual accept: verified 8/8 AC tests pass on VPS. Mac01 Bun env issue with git detection in temp dirs during verification."
|
|
32
|
+
],
|
|
33
|
+
"storyPoints": 1
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"analyzeConfig": {
|
|
37
|
+
"maxStories": 5,
|
|
38
|
+
"granularity": "medium"
|
|
39
|
+
},
|
|
40
|
+
"updatedAt": "2026-02-28T06:18:08Z"
|
|
41
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"project": "nax",
|
|
3
|
+
"branchName": "feat/v0.18.0-orchestration-fixes",
|
|
4
|
+
"feature": "orchestration-fixes",
|
|
5
|
+
"userStories": [
|
|
6
|
+
{
|
|
7
|
+
"id": "BUG-021",
|
|
8
|
+
"title": "Fix misleading Task classified log",
|
|
9
|
+
"description": "The 'Task classified' log in routing.ts currently logs the raw LLM output even after config/cache overrides are applied. This makes it look like overrides are ignored when they aren't.\n\nFix: Ensure the log reflects the final routing state (ctx.routing) after all overrides and greenfield detection are finished.\n\nAcceptance criteria:\n1. Log shows final testStrategy/complexity/modelTier after all overrides\n2. Existing tests pass",
|
|
10
|
+
"complexity": "simple",
|
|
11
|
+
"status": "passed",
|
|
12
|
+
"attempts": 0,
|
|
13
|
+
"priorErrors": [
|
|
14
|
+
"Attempt 1 failed with model tier: fast"
|
|
15
|
+
],
|
|
16
|
+
"escalations": [],
|
|
17
|
+
"dependencies": [],
|
|
18
|
+
"tags": [],
|
|
19
|
+
"acceptanceCriteria": [],
|
|
20
|
+
"storyPoints": 1,
|
|
21
|
+
"routing": {
|
|
22
|
+
"complexity": "simple",
|
|
23
|
+
"modelTier": "balanced",
|
|
24
|
+
"testStrategy": "three-session-tdd-lite",
|
|
25
|
+
"reasoning": "three-session-tdd-lite: strategy:lite"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "BUG-022",
|
|
30
|
+
"title": "Fix story interleaving in getNextStory()",
|
|
31
|
+
"description": "When a story fails and escalates, getNextStory() currently round-robins to the next pending story. This wastes iterations by jumping between unrelated tasks.\n\nFix: Update getNextStory() in src/execution/sequential-executor.ts to prioritize retrying the current story until max attempts are reached before moving to the next story.\n\nAcceptance criteria:\n1. If current story is failed but has attempts remaining, it is picked again for retry\n2. Run order: S1-I1 -> S1-I2 (retry) -> S2-I1 (if S1 complete/failed out)\n3. Unit test for getNextStory() behavior",
|
|
32
|
+
"complexity": "simple",
|
|
33
|
+
"status": "passed",
|
|
34
|
+
"attempts": 0,
|
|
35
|
+
"priorErrors": [
|
|
36
|
+
"Attempt 1 failed with model tier: fast"
|
|
37
|
+
],
|
|
38
|
+
"escalations": [],
|
|
39
|
+
"dependencies": [],
|
|
40
|
+
"tags": [],
|
|
41
|
+
"acceptanceCriteria": [],
|
|
42
|
+
"storyPoints": 1,
|
|
43
|
+
"routing": {
|
|
44
|
+
"complexity": "simple",
|
|
45
|
+
"modelTier": "balanced",
|
|
46
|
+
"testStrategy": "three-session-tdd-lite",
|
|
47
|
+
"reasoning": "three-session-tdd-lite: strategy:lite"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "BUG-023",
|
|
52
|
+
"title": "Log exitCode/stderr on agent failure",
|
|
53
|
+
"description": "Agent session failures currently log 'rateLimited' but hide the actual exit code and stderr. This makes diagnosing silent failures (like 401, 500, or process crashes) difficult.\n\nFix: Audit src/agents/adapters/claude.ts and src/pipeline/stages/execution.ts. Ensure the 'Agent session failed' event includes exitCode and the tail of stderr in its data payload.\n\nAcceptance criteria:\n1. agent.complete event includes exitCode and stderr tail on failure\n2. Logs are machine-readable and don't break JSONL format",
|
|
54
|
+
"complexity": "simple",
|
|
55
|
+
"status": "passed",
|
|
56
|
+
"attempts": 0,
|
|
57
|
+
"priorErrors": [],
|
|
58
|
+
"escalations": [],
|
|
59
|
+
"dependencies": [],
|
|
60
|
+
"tags": [],
|
|
61
|
+
"acceptanceCriteria": [],
|
|
62
|
+
"storyPoints": 1
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "BUG-025",
|
|
66
|
+
"title": "Integrate Interaction Chain into Runner Loop",
|
|
67
|
+
"description": "The Interaction system is initialized but never called from the core orchestrator. This is a major integration task.\n\nFix:\n1. Add 'human-review' to TriggerName in src/interaction/types.ts and metadata in TRIGGER_METADATA\n2. Pass interactionChain from runner.ts -> executeSequential -> Pipeline\n3. Inject 'interaction' into PipelineContext\n4. Call executeTrigger('human-review', ...) when a story reaches max retries or a critical failure occurs\n5. Verify other triggers (security-review, story-ambiguity) are called at relevant pipeline stages\n\nAcceptance criteria:\n1. interactionChain is accessible in PipelineContext\n2. Story reaching max retries triggers a 'human-review' interaction request\n3. Test with CLI interaction plugin (non-headless)",
|
|
68
|
+
"complexity": "medium",
|
|
69
|
+
"status": "failed",
|
|
70
|
+
"attempts": 1,
|
|
71
|
+
"priorErrors": [
|
|
72
|
+
"Attempt 1 failed with model tier: balanced"
|
|
73
|
+
],
|
|
74
|
+
"escalations": [],
|
|
75
|
+
"dependencies": [],
|
|
76
|
+
"tags": [],
|
|
77
|
+
"acceptanceCriteria": [],
|
|
78
|
+
"storyPoints": 1,
|
|
79
|
+
"routing": {
|
|
80
|
+
"complexity": "complex",
|
|
81
|
+
"modelTier": "powerful",
|
|
82
|
+
"testStrategy": "three-session-tdd-lite",
|
|
83
|
+
"reasoning": "three-session-tdd-lite: security-critical, strategy:lite"
|
|
84
|
+
},
|
|
85
|
+
"failureCategory": "session-failure"
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
"updatedAt": "2026-03-02T16:29:51.415Z"
|
|
89
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[2026-03-02T16:29:51.415Z] BUG-025 — FAILED — Integrate Interaction Chain into Runner Loop — Execution failed
|