@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,589 @@
|
|
|
1
|
+
# Deep Code Review: ngent v0.3.0
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-02-17
|
|
4
|
+
**Reviewer:** Subrina (AI)
|
|
5
|
+
**Version:** 0.3.0-dev
|
|
6
|
+
**Files:** 65 TypeScript files (src: ~7,172 LOC, test: ~7,757 LOC)
|
|
7
|
+
**Baseline:** 342 tests passing, 881 assertions, TypeScript strict mode
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Overall Grade: A- (88/100)
|
|
12
|
+
|
|
13
|
+
The v0.3 pipeline refactor represents a significant architectural improvement, successfully decomposing the monolithic runner into composable stages while maintaining backward compatibility. The new constitution, analyze, and review modules are well-designed with strong type safety and comprehensive test coverage. However, several medium-priority issues around JSDoc coverage, error handling consistency, and incomplete verify stage logic prevent this from achieving an A grade.
|
|
14
|
+
|
|
15
|
+
**Key Strengths:**
|
|
16
|
+
- Clean pipeline architecture with proper separation of concerns
|
|
17
|
+
- Excellent test coverage for new modules (constitution: 100%, review: 100%, pipeline: 90%+)
|
|
18
|
+
- Strong type safety with discriminated unions for pipeline results
|
|
19
|
+
- Proper integration between new and existing systems
|
|
20
|
+
|
|
21
|
+
**Areas for Improvement:**
|
|
22
|
+
- Incomplete verify stage (placeholder with TODO)
|
|
23
|
+
- JSDoc coverage gaps in pipeline stages (~40%)
|
|
24
|
+
- Inconsistent error handling patterns between stages
|
|
25
|
+
- Missing integration tests for full pipeline execution with all stages
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Findings
|
|
30
|
+
|
|
31
|
+
### 🔴 CRITICAL
|
|
32
|
+
|
|
33
|
+
None. The codebase is production-ready from a security and reliability standpoint.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
### 🟡 HIGH
|
|
38
|
+
|
|
39
|
+
#### BUG-7: Verify Stage is a No-Op Placeholder
|
|
40
|
+
**Severity:** HIGH | **Category:** Bug
|
|
41
|
+
**File:** `src/pipeline/stages/verify.ts:18-25`
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
export const verifyStage: PipelineStage = {
|
|
45
|
+
name: "verify",
|
|
46
|
+
enabled: () => true,
|
|
47
|
+
async execute(_ctx: PipelineContext): Promise<StageResult> {
|
|
48
|
+
// TODO: Add verification logic here
|
|
49
|
+
// - Run tests
|
|
50
|
+
// - Check build
|
|
51
|
+
// - Validate output
|
|
52
|
+
return { action: "continue" };
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Risk:** The verify stage is currently a no-op that always passes. This means agent output is never validated before being marked as passed. Stories could be marked complete even if tests fail or builds break.
|
|
58
|
+
|
|
59
|
+
**Fix:** Implement verification logic:
|
|
60
|
+
1. Run `bun test` in the workdir
|
|
61
|
+
2. Check exit code
|
|
62
|
+
3. Return `{ action: "fail", reason: "Tests failed" }` if exit code !== 0
|
|
63
|
+
4. Consider adding build verification for TypeScript projects
|
|
64
|
+
|
|
65
|
+
**Priority:** P0 — This is a critical gap in the execution pipeline.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
#### ENH-6: Pipeline Stages Have Inconsistent Error Handling
|
|
70
|
+
**Severity:** HIGH | **Category:** Enhancement
|
|
71
|
+
**File:** Multiple pipeline stages
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// Constitution stage: returns continue even if loading fails silently
|
|
75
|
+
if (result) {
|
|
76
|
+
ctx.constitution = result.content;
|
|
77
|
+
// ...logs...
|
|
78
|
+
}
|
|
79
|
+
// No else — just continues without constitution
|
|
80
|
+
|
|
81
|
+
// Execution stage: returns fail with clear reason
|
|
82
|
+
if (!ctx.prompt) {
|
|
83
|
+
return { action: "fail", reason: "Prompt not built (prompt stage skipped?)" };
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Risk:** Inconsistent error handling makes it hard to debug pipeline failures. Some stages silently continue on errors, others fail explicitly. This can lead to confusing behavior where a story fails for unclear reasons.
|
|
88
|
+
|
|
89
|
+
**Fix:** Establish consistent patterns:
|
|
90
|
+
1. **Soft failures** (constitution missing, context empty) → continue with warning log
|
|
91
|
+
2. **Hard failures** (no agent, invalid config) → return `{ action: "fail", reason: "..." }`
|
|
92
|
+
3. Document these patterns in a `PIPELINE.md` guide
|
|
93
|
+
|
|
94
|
+
**Priority:** P1 — Affects debugging experience and maintainability.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### 🟡 MEDIUM
|
|
99
|
+
|
|
100
|
+
#### ENH-7: Missing JSDoc on Pipeline Stages (~40% coverage)
|
|
101
|
+
**Severity:** MEDIUM | **Category:** Enhancement
|
|
102
|
+
**File:** `src/pipeline/stages/*.ts`
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// ✗ No JSDoc
|
|
106
|
+
export const queueCheckStage: PipelineStage = {
|
|
107
|
+
name: "queue-check",
|
|
108
|
+
enabled: () => true,
|
|
109
|
+
async execute(ctx: PipelineContext): Promise<StageResult> {
|
|
110
|
+
// ...
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// ✓ Should have JSDoc
|
|
115
|
+
/**
|
|
116
|
+
* Queue Check Stage
|
|
117
|
+
*
|
|
118
|
+
* Checks for queue commands (PAUSE/ABORT/SKIP) before executing a story.
|
|
119
|
+
* Processes commands atomically and updates PRD accordingly.
|
|
120
|
+
*
|
|
121
|
+
* @returns
|
|
122
|
+
* - `continue`: No queue commands, proceed
|
|
123
|
+
* - `pause`: PAUSE/ABORT command found, stop execution
|
|
124
|
+
* - `skip`: SKIP command removed all stories from batch
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* // User writes: echo "PAUSE" > .queue.txt
|
|
129
|
+
* const result = await queueCheckStage.execute(ctx);
|
|
130
|
+
* // result: { action: "pause", reason: "User requested pause via .queue.txt" }
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Impact:** New contributors need to read implementation code to understand stage behavior. Missing examples make it hard to understand stage interactions.
|
|
136
|
+
|
|
137
|
+
**Fix:** Add JSDoc to all 9 pipeline stages with:
|
|
138
|
+
- Brief description (1-2 sentences)
|
|
139
|
+
- Return value documentation (all possible actions)
|
|
140
|
+
- Example showing stage behavior in context
|
|
141
|
+
|
|
142
|
+
**Priority:** P2 — Documentation gap, but code is readable.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
#### TYPE-3: Constitution Stage Uses Loose Type Conversion
|
|
147
|
+
**Severity:** MEDIUM | **Category:** Type Safety
|
|
148
|
+
**File:** `src/pipeline/stages/prompt.ts:22-30`
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
// Convert constitution string to ConstitutionResult if present
|
|
152
|
+
const constitution: ConstitutionResult | undefined = ctx.constitution
|
|
153
|
+
? {
|
|
154
|
+
content: ctx.constitution,
|
|
155
|
+
tokens: Math.ceil(ctx.constitution.length / 4), // ⚠️ Duplicates estimation logic
|
|
156
|
+
originalTokens: Math.ceil(ctx.constitution.length / 4),
|
|
157
|
+
truncated: false,
|
|
158
|
+
}
|
|
159
|
+
: undefined;
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Risk:**
|
|
163
|
+
1. Duplicates token estimation logic (should use `estimateTokens()` from constitution module)
|
|
164
|
+
2. Uses 1 token ≈ 4 chars, but constitution loader uses 1 token ≈ 3 chars (inconsistent)
|
|
165
|
+
3. If context stores `ConstitutionResult` instead of `string`, this conversion is unnecessary
|
|
166
|
+
|
|
167
|
+
**Fix:**
|
|
168
|
+
1. Store `ConstitutionResult | undefined` in `PipelineContext.constitution` instead of `string | undefined`
|
|
169
|
+
2. Update constitution stage to assign the full result object
|
|
170
|
+
3. Remove conversion logic from prompt stage
|
|
171
|
+
|
|
172
|
+
**Priority:** P2 — Type inconsistency, but functionally correct.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
#### BUG-8: Pipeline Runner Doesn't Preserve Context Mutations Across Stages
|
|
177
|
+
**Severity:** MEDIUM | **Category:** Bug
|
|
178
|
+
**File:** `src/pipeline/runner.ts:48-127`
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
export async function runPipeline(
|
|
182
|
+
stages: PipelineStage[],
|
|
183
|
+
context: PipelineContext,
|
|
184
|
+
): Promise<PipelineRunResult> {
|
|
185
|
+
for (const stage of stages) {
|
|
186
|
+
// ...
|
|
187
|
+
result = await stage.execute(context); // ⚠️ Stages mutate context in-place
|
|
188
|
+
}
|
|
189
|
+
// ...
|
|
190
|
+
return {
|
|
191
|
+
success: true,
|
|
192
|
+
finalAction: "complete",
|
|
193
|
+
context, // ⚠️ Returns mutated context, but contract is unclear
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Risk:** Stages mutate the context object in-place. The function signature doesn't make it clear whether the input `context` is mutated or a new context is returned. This could cause subtle bugs if callers expect immutability.
|
|
199
|
+
|
|
200
|
+
**Fix:**
|
|
201
|
+
1. Document mutation contract in JSDoc: "Stages mutate the context in-place. The returned context is the same object, mutated."
|
|
202
|
+
2. Consider cloning context before pipeline execution for safer API (if mutation is unintended)
|
|
203
|
+
3. Add integration test verifying context mutations are preserved
|
|
204
|
+
|
|
205
|
+
**Priority:** P2 — Potential footgun, but current usage is correct.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
#### PERF-4: Prompt Stage Recreates ConstitutionResult on Every Execution
|
|
210
|
+
**Severity:** MEDIUM | **Category:** Performance
|
|
211
|
+
**File:** `src/pipeline/stages/prompt.ts:22-30`
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
async execute(ctx: PipelineContext): Promise<StageResult> {
|
|
215
|
+
// ⚠️ Re-creates ConstitutionResult every time even though content is static
|
|
216
|
+
const constitution: ConstitutionResult | undefined = ctx.constitution
|
|
217
|
+
? {
|
|
218
|
+
content: ctx.constitution,
|
|
219
|
+
tokens: Math.ceil(ctx.constitution.length / 4),
|
|
220
|
+
originalTokens: Math.ceil(ctx.constitution.length / 4),
|
|
221
|
+
truncated: false,
|
|
222
|
+
}
|
|
223
|
+
: undefined;
|
|
224
|
+
// ...
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Impact:** Constitution is loaded once per feature, but prompt stage recreates the result object on every story. For a 100-story feature, this wastes allocation cycles.
|
|
229
|
+
|
|
230
|
+
**Fix:** Store `ConstitutionResult` in context (see TYPE-3) so prompt stage can use it directly without reconstruction.
|
|
231
|
+
|
|
232
|
+
**Priority:** P3 — Micro-optimization, but aligns with TYPE-3 fix.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
#### ENH-8: No Integration Test for Full Pipeline with All Stages
|
|
237
|
+
**Severity:** MEDIUM | **Category:** Enhancement
|
|
238
|
+
**File:** `test/pipeline.test.ts`
|
|
239
|
+
|
|
240
|
+
**Current coverage:**
|
|
241
|
+
- ✓ Pipeline runner logic (continue/skip/fail/escalate/pause)
|
|
242
|
+
- ✓ Individual stage unit tests (constitution, review)
|
|
243
|
+
- ✗ Full pipeline execution with all 9 stages
|
|
244
|
+
|
|
245
|
+
**Missing:** An integration test that:
|
|
246
|
+
1. Sets up a real workdir with package.json, src/, test/
|
|
247
|
+
2. Runs `runPipeline(defaultPipeline, realContext)`
|
|
248
|
+
3. Verifies all stages execute in order
|
|
249
|
+
4. Checks context accumulation (constitution → context → prompt → agentResult → reviewResult)
|
|
250
|
+
|
|
251
|
+
**Fix:** Add `test/pipeline-integration.test.ts`:
|
|
252
|
+
```typescript
|
|
253
|
+
test("full pipeline execution with all stages", async () => {
|
|
254
|
+
const ctx = createRealTestContext(); // Real files, not mocks
|
|
255
|
+
const result = await runPipeline(defaultPipeline, ctx);
|
|
256
|
+
|
|
257
|
+
expect(result.success).toBe(true);
|
|
258
|
+
expect(result.context.constitution).toBeDefined();
|
|
259
|
+
expect(result.context.prompt).toBeDefined();
|
|
260
|
+
expect(result.context.agentResult).toBeDefined();
|
|
261
|
+
// etc.
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Priority:** P2 — Increases confidence in pipeline integration.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
#### STYLE-4: Magic Number for Constitution Token Estimation Inconsistency
|
|
270
|
+
**Severity:** MEDIUM | **Category:** Style
|
|
271
|
+
**File:** `src/pipeline/stages/prompt.ts:26` vs `src/constitution/loader.ts:21`
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
// constitution/loader.ts
|
|
275
|
+
export function estimateTokens(text: string): number {
|
|
276
|
+
return Math.ceil(text.length / 3); // 1 token ≈ 3 chars
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// pipeline/stages/prompt.ts
|
|
280
|
+
tokens: Math.ceil(ctx.constitution.length / 4), // ⚠️ 1 token ≈ 4 chars
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Risk:** Inconsistent token estimation can lead to underestimation in prompt stage, potentially hitting model context limits unexpectedly.
|
|
284
|
+
|
|
285
|
+
**Fix:** Always use `estimateTokens()` from constitution module. Extract as named constant if different heuristic is intentional:
|
|
286
|
+
```typescript
|
|
287
|
+
const CONSERVATIVE_TOKEN_ESTIMATE = 4; // chars per token (more conservative than 3)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Priority:** P2 — Consistency issue with functional impact.
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
### 🟢 LOW
|
|
295
|
+
|
|
296
|
+
#### ENH-9: Plan Command Doesn't Validate Spec Template Output
|
|
297
|
+
**Severity:** LOW | **Category:** Enhancement
|
|
298
|
+
**File:** `src/cli/plan.ts:50-132`
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
// In interactive mode, assume agent wrote the spec
|
|
302
|
+
if (interactive) {
|
|
303
|
+
if (result.specContent) {
|
|
304
|
+
await Bun.write(outputPath, result.specContent);
|
|
305
|
+
} else {
|
|
306
|
+
// If agent wrote directly, verify it exists
|
|
307
|
+
if (!existsSync(outputPath)) { // ⚠️ No format validation
|
|
308
|
+
throw new Error(`Interactive planning completed but spec not found at ${outputPath}`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**Impact:** Plan mode checks if spec file exists but doesn't validate it follows the template format. Agent could write invalid markdown or skip required sections (Problem, Requirements, Acceptance Criteria).
|
|
315
|
+
|
|
316
|
+
**Fix:** Add optional spec validation:
|
|
317
|
+
1. Parse output markdown
|
|
318
|
+
2. Check for required sections: `# Feature:`, `## Problem`, `## Requirements`, `## Acceptance Criteria`
|
|
319
|
+
3. Warn if sections are missing (don't fail, since agent may use different structure)
|
|
320
|
+
|
|
321
|
+
**Priority:** P3 — Nice-to-have validation, but agent output is typically well-structured.
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
#### STYLE-5: Analyze Classifier Uses `any` for LLM Response Parsing
|
|
326
|
+
**Severity:** LOW | **Category:** Type Safety
|
|
327
|
+
**File:** `src/analyze/classifier.ts:105-127`
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
// Extract text from response
|
|
331
|
+
const textContent = response.content.find((c: any) => c.type === "text"); // ⚠️ any
|
|
332
|
+
if (!textContent || textContent.type !== "text") {
|
|
333
|
+
throw new Error("No text response from LLM");
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Map to StoryClassification[]
|
|
337
|
+
const classifications: StoryClassification[] = parsed.map((item: any) => ({ // ⚠️ any
|
|
338
|
+
storyId: item.storyId,
|
|
339
|
+
complexity: validateComplexity(item.complexity),
|
|
340
|
+
// ...
|
|
341
|
+
}));
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Risk:** Using `any` bypasses type checking. If Anthropic SDK changes response structure, this code could fail at runtime without TypeScript catching it.
|
|
345
|
+
|
|
346
|
+
**Fix:** Define proper types:
|
|
347
|
+
```typescript
|
|
348
|
+
interface AnthropicTextContent {
|
|
349
|
+
type: "text";
|
|
350
|
+
text: string;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
interface LLMClassificationItem {
|
|
354
|
+
storyId: string;
|
|
355
|
+
complexity: string;
|
|
356
|
+
relevantFiles: unknown;
|
|
357
|
+
reasoning: unknown;
|
|
358
|
+
estimatedLOC: unknown;
|
|
359
|
+
risks: unknown;
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Priority:** P3 — Low risk since Anthropic SDK is stable, but better type safety is always preferred.
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
#### ENH-10: Pipeline Doesn't Log Which Stages Were Skipped
|
|
368
|
+
**Severity:** LOW | **Category:** Enhancement
|
|
369
|
+
**File:** `src/pipeline/runner.ts:52-56`
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
for (const stage of stages) {
|
|
373
|
+
// Skip disabled stages
|
|
374
|
+
if (!stage.enabled(context)) {
|
|
375
|
+
continue; // ⚠️ Silent skip — user doesn't know why stage didn't run
|
|
376
|
+
}
|
|
377
|
+
// ...
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
**Impact:** If a stage is disabled (e.g., `reviewStage` when `config.review.enabled = false`), the pipeline silently skips it. Users may be confused why review didn't run.
|
|
382
|
+
|
|
383
|
+
**Fix:** Add debug logging for skipped stages:
|
|
384
|
+
```typescript
|
|
385
|
+
if (!stage.enabled(context)) {
|
|
386
|
+
console.log(chalk.dim(` → Stage "${stage.name}" skipped (disabled)`));
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
**Priority:** P3 — Improves observability but not critical.
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
#### STYLE-6: Queue Check Stage Mutates Context Stories Array
|
|
396
|
+
**Severity:** LOW | **Category:** Style
|
|
397
|
+
**File:** `src/pipeline/stages/queue-check.ts:68`
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
// Remove from batch
|
|
401
|
+
ctx.stories = ctx.stories.filter((s) => s.id !== cmd.storyId); // ⚠️ Mutation
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**Risk:** Mutating `ctx.stories` directly could cause confusion if other code expects the original batch to remain unchanged.
|
|
405
|
+
|
|
406
|
+
**Fix:** Follow immutability principles:
|
|
407
|
+
```typescript
|
|
408
|
+
// Create new array instead of mutating
|
|
409
|
+
ctx.stories = ctx.stories.filter((s) => s.id !== cmd.storyId);
|
|
410
|
+
// ✓ Already immutable (filter returns new array), but could be clearer:
|
|
411
|
+
const updatedStories = ctx.stories.filter((s) => s.id !== cmd.storyId);
|
|
412
|
+
ctx.stories = updatedStories;
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**Note:** Current code is actually fine (filter returns new array), but the assignment pattern could be clearer.
|
|
416
|
+
|
|
417
|
+
**Priority:** P4 — Code works correctly, just a style preference.
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
#### ENH-11: No Dry-Run Support for Review Stage
|
|
422
|
+
**Severity:** LOW | **Category:** Enhancement
|
|
423
|
+
**File:** `src/pipeline/stages/review.ts:16-29`
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
async execute(ctx: PipelineContext): Promise<StageResult> {
|
|
427
|
+
console.log(chalk.cyan("\n → Running review phase..."));
|
|
428
|
+
|
|
429
|
+
const reviewResult = await runReview(ctx.config.review, ctx.workdir); // ⚠️ Always runs, even in dry-run mode
|
|
430
|
+
// ...
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
**Impact:** In dry-run mode, review stage still executes `bun test`, `bun run typecheck`, etc. This makes dry runs slow and may fail on incomplete code.
|
|
435
|
+
|
|
436
|
+
**Fix:** Check for dry-run flag in context:
|
|
437
|
+
```typescript
|
|
438
|
+
if (ctx.config.execution.dryRun) {
|
|
439
|
+
console.log(chalk.yellow(" [DRY RUN] Would run review phase"));
|
|
440
|
+
return { action: "continue" };
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
**Note:** PipelineContext doesn't currently have a `dryRun` flag. This would need to be added.
|
|
445
|
+
|
|
446
|
+
**Priority:** P4 — Minor UX improvement for dry runs.
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
#### TYPE-4: Routing Stage Console Logs Duplicate Logic
|
|
451
|
+
**Severity:** LOW | **Category:** Style
|
|
452
|
+
**File:** `src/pipeline/stages/routing.ts:32-45`
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
const isBatch = ctx.stories.length > 1;
|
|
456
|
+
|
|
457
|
+
if (isBatch) {
|
|
458
|
+
console.log(
|
|
459
|
+
chalk.dim(
|
|
460
|
+
` Complexity: ${routing.complexity} | Model: ${routing.modelTier} | TDD: ${routing.testStrategy}`,
|
|
461
|
+
),
|
|
462
|
+
);
|
|
463
|
+
} else {
|
|
464
|
+
console.log(
|
|
465
|
+
chalk.dim(
|
|
466
|
+
` Complexity: ${routing.complexity} | Model: ${routing.modelTier} | TDD: ${routing.testStrategy}`,
|
|
467
|
+
),
|
|
468
|
+
);
|
|
469
|
+
console.log(chalk.dim(` Routing: ${routing.reasoning}`));
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Issue:** Both branches log identical strings. Could be simplified:
|
|
474
|
+
```typescript
|
|
475
|
+
console.log(
|
|
476
|
+
chalk.dim(
|
|
477
|
+
` Complexity: ${routing.complexity} | Model: ${routing.modelTier} | TDD: ${routing.testStrategy}`,
|
|
478
|
+
),
|
|
479
|
+
);
|
|
480
|
+
if (!isBatch) {
|
|
481
|
+
console.log(chalk.dim(` Routing: ${routing.reasoning}`));
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
**Priority:** P4 — Code clarity, no functional impact.
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## Priority Fix Order
|
|
490
|
+
|
|
491
|
+
| Priority | ID | Effort | Description |
|
|
492
|
+
|:---|:---|:---|:---|
|
|
493
|
+
| **P0** | BUG-7 | M | Implement verify stage logic (run tests, check build) |
|
|
494
|
+
| **P1** | ENH-6 | L | Document and standardize error handling patterns across pipeline stages |
|
|
495
|
+
| **P1** | ENH-7 | M | Add JSDoc to all 9 pipeline stages with examples |
|
|
496
|
+
| **P2** | TYPE-3 | S | Store ConstitutionResult in context, remove prompt stage conversion |
|
|
497
|
+
| **P2** | BUG-8 | S | Document context mutation contract in runPipeline JSDoc |
|
|
498
|
+
| **P2** | ENH-8 | M | Add full pipeline integration test with all stages |
|
|
499
|
+
| **P2** | STYLE-4 | S | Fix token estimation inconsistency (use estimateTokens() everywhere) |
|
|
500
|
+
| **P3** | ENH-9 | M | Add optional spec validation to plan command |
|
|
501
|
+
| **P3** | STYLE-5 | S | Replace `any` with proper types in analyze classifier |
|
|
502
|
+
| **P3** | ENH-10 | S | Log skipped stages for observability |
|
|
503
|
+
| **P4** | STYLE-6 | — | (No action needed — code is correct) |
|
|
504
|
+
| **P4** | ENH-11 | S | Add dry-run support to review stage |
|
|
505
|
+
| **P4** | TYPE-4 | S | Simplify routing stage logging |
|
|
506
|
+
|
|
507
|
+
**Effort:** S = Small (<1hr), M = Medium (1-4hrs), L = Large (>4hrs)
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
## Dimension Scores
|
|
512
|
+
|
|
513
|
+
### Security: 20/20 ✓
|
|
514
|
+
- ✓ No hardcoded secrets or credentials
|
|
515
|
+
- ✓ Input validation on all boundaries (queue commands, spec parsing)
|
|
516
|
+
- ✓ Command injection prevention in review runner (using spawn with args array)
|
|
517
|
+
- ✓ Path traversal protection via config path-security module
|
|
518
|
+
- ✓ No eval or dynamic code execution
|
|
519
|
+
- ✓ Hook security validation from v0.2 still in place
|
|
520
|
+
|
|
521
|
+
**Notes:** Pipeline stages properly delegate to existing security-vetted modules (hooks, agents, prd). No new security concerns introduced.
|
|
522
|
+
|
|
523
|
+
### Reliability: 17/20
|
|
524
|
+
- ✓ Comprehensive error handling in pipeline runner (try/catch, stage failures)
|
|
525
|
+
- ✓ Proper resource cleanup (no leaked streams, timers, or file handles)
|
|
526
|
+
- ✓ Atomic queue file handling from v0.2 maintained
|
|
527
|
+
- ✗ **BUG-7:** Verify stage is a no-op (doesn't actually verify anything)
|
|
528
|
+
- ✗ **ENH-6:** Inconsistent error handling patterns across stages
|
|
529
|
+
- ⚠️ **BUG-8:** Context mutation contract unclear
|
|
530
|
+
|
|
531
|
+
**Deductions:** -3 for verify stage gap, -0.5 for inconsistent error patterns, -0.5 for mutation documentation gap.
|
|
532
|
+
|
|
533
|
+
### API Design: 18/20
|
|
534
|
+
- ✓ Clean pipeline abstraction with composable stages
|
|
535
|
+
- ✓ Well-defined stage interface (PipelineStage with enabled/execute)
|
|
536
|
+
- ✓ Discriminated union for StageResult (exhaustiveness checking)
|
|
537
|
+
- ✓ Consistent naming conventions (queueCheckStage, routingStage, etc.)
|
|
538
|
+
- ✓ Good separation of concerns (each stage has single responsibility)
|
|
539
|
+
- ✗ **TYPE-3:** Constitution type inconsistency (string vs ConstitutionResult)
|
|
540
|
+
- ✗ **ENH-7:** Missing JSDoc on 60% of pipeline stages
|
|
541
|
+
|
|
542
|
+
**Deductions:** -1 for type inconsistency, -1 for documentation gaps.
|
|
543
|
+
|
|
544
|
+
### Code Quality: 16/20
|
|
545
|
+
- ✓ Excellent test coverage (constitution: 100%, review: 100%, pipeline: 90%+)
|
|
546
|
+
- ✓ No dead code or commented-out blocks
|
|
547
|
+
- ✓ Files are appropriately sized (<400 lines for all pipeline stages)
|
|
548
|
+
- ✓ Consistent code style (Biome formatting)
|
|
549
|
+
- ✗ **STYLE-4:** Magic number inconsistency (token estimation)
|
|
550
|
+
- ✗ **STYLE-5:** Use of `any` in classifier LLM response parsing
|
|
551
|
+
- ✗ **TYPE-4:** Duplicate logging logic in routing stage
|
|
552
|
+
- ✗ **ENH-8:** Missing integration test for full pipeline
|
|
553
|
+
|
|
554
|
+
**Deductions:** -2 for missing integration test, -1 for any usage, -1 for magic number inconsistency.
|
|
555
|
+
|
|
556
|
+
### Best Practices: 17/20
|
|
557
|
+
- ✓ Follows established v0.2 patterns (hooks, routing, PRD management)
|
|
558
|
+
- ✓ Proper use of TypeScript features (discriminated unions, exhaustiveness checks)
|
|
559
|
+
- ✓ Clear module boundaries with barrel exports
|
|
560
|
+
- ✓ Good abstraction (pipeline runner is framework-agnostic)
|
|
561
|
+
- ✗ **ENH-6:** Inconsistent error handling (some stages silent fail, others don't)
|
|
562
|
+
- ✗ **ENH-10:** No observability for skipped stages
|
|
563
|
+
- ✗ **BUG-8:** Mutation contract unclear
|
|
564
|
+
|
|
565
|
+
**Deductions:** -2 for inconsistent patterns, -1 for observability gap.
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
## Summary
|
|
570
|
+
|
|
571
|
+
The v0.3 pipeline refactor is a **strong architectural improvement** that successfully decomposes the monolithic runner into composable, testable stages. The new modules (constitution, analyze, review) are well-designed with excellent test coverage and proper integration.
|
|
572
|
+
|
|
573
|
+
**Critical gap:** The verify stage is currently a placeholder (BUG-7). This must be implemented before v0.3 ships, as it's a core part of the quality gate.
|
|
574
|
+
|
|
575
|
+
**Recommended path forward:**
|
|
576
|
+
1. **Immediate (P0):** Implement verify stage with test execution
|
|
577
|
+
2. **Before v0.3 release (P1):** Add pipeline stage JSDoc and standardize error handling
|
|
578
|
+
3. **Post-v0.3 (P2-P4):** Address type inconsistencies, add integration tests, improve observability
|
|
579
|
+
|
|
580
|
+
**Grade justification:**
|
|
581
|
+
- Security: Excellent (20/20)
|
|
582
|
+
- Reliability: Very good, one critical gap (17/20)
|
|
583
|
+
- API Design: Very good, minor documentation gap (18/20)
|
|
584
|
+
- Code Quality: Good, missing integration tests (16/20)
|
|
585
|
+
- Best Practices: Good, inconsistent patterns (17/20)
|
|
586
|
+
|
|
587
|
+
**Total: 88/100 (A-)**
|
|
588
|
+
|
|
589
|
+
With BUG-7 fixed and ENH-6/ENH-7 addressed, this would easily achieve an **A (90+)**.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# v0.4 Implementation Plan: Acceptance Validation
|
|
2
|
+
**Date:** 2026-02-17
|
|
3
|
+
**Branch:** master
|
|
4
|
+
|
|
5
|
+
## Complexity Assessment
|
|
6
|
+
- **Files touched:** 8+ (new module + pipeline stage + analyze integration + config + CLI + tests)
|
|
7
|
+
- **LOC:** ~400-600 new
|
|
8
|
+
- **Architectural impact:** New pipeline stage, new analyze output, new retry loop in runner
|
|
9
|
+
- **Test strategy:** test-after (internal modules, not public API)
|
|
10
|
+
|
|
11
|
+
## Phase 1: Acceptance test generator
|
|
12
|
+
### 1a: Acceptance module
|
|
13
|
+
**File:** `src/acceptance/generator.ts` (NEW)
|
|
14
|
+
- Parse spec.md acceptance criteria (extract AC-N lines)
|
|
15
|
+
- Build LLM prompt: ACs + codebase context → test file
|
|
16
|
+
- Parse LLM response → write `acceptance.test.ts`
|
|
17
|
+
- Fallback: generate skeleton tests with TODO if LLM fails
|
|
18
|
+
|
|
19
|
+
### 1b: Integration with analyze
|
|
20
|
+
**File:** `src/cli/analyze.ts`
|
|
21
|
+
- After decompose, call acceptance test generator
|
|
22
|
+
- Write tests to `ngent/features/<name>/acceptance.test.ts`
|
|
23
|
+
- Config check: `acceptance.generateTests`
|
|
24
|
+
|
|
25
|
+
### 1c: Config schema update
|
|
26
|
+
**File:** `src/config/schema.ts`
|
|
27
|
+
- Add `acceptance` config block: `enabled`, `maxRetries`, `generateTests`, `testPath`
|
|
28
|
+
|
|
29
|
+
### Tests
|
|
30
|
+
- AC parser extracts criteria from spec markdown
|
|
31
|
+
- Generator produces valid test structure
|
|
32
|
+
- Config validation
|
|
33
|
+
|
|
34
|
+
**Commit:** `feat(acceptance): generate acceptance tests from spec ACs`
|
|
35
|
+
|
|
36
|
+
## Phase 2: Acceptance pipeline stage
|
|
37
|
+
### 2a: Acceptance stage
|
|
38
|
+
**File:** `src/pipeline/stages/acceptance.ts` (NEW)
|
|
39
|
+
- Only runs when all stories are complete (check prd status)
|
|
40
|
+
- Spawns `bun test acceptance.test.ts` in workdir
|
|
41
|
+
- Parses test output: which ACs passed/failed
|
|
42
|
+
- Returns `continue` if all pass, `fail` with details if any fail
|
|
43
|
+
|
|
44
|
+
### 2b: Register in default pipeline
|
|
45
|
+
**File:** `src/pipeline/stages/index.ts`
|
|
46
|
+
- Add `acceptanceStage` after `completionStage`
|
|
47
|
+
|
|
48
|
+
### Tests
|
|
49
|
+
- Stage skips when stories still pending
|
|
50
|
+
- Stage runs and parses test results
|
|
51
|
+
- Pass/fail detection
|
|
52
|
+
|
|
53
|
+
**Commit:** `feat(acceptance): add acceptance validation pipeline stage`
|
|
54
|
+
|
|
55
|
+
## Phase 3: Self-correcting fix loop
|
|
56
|
+
### 3a: Fix story generator
|
|
57
|
+
**File:** `src/acceptance/fix-generator.ts` (NEW)
|
|
58
|
+
- Input: failed ACs + test output + related stories + source code
|
|
59
|
+
- LLM call: generate fix story descriptions
|
|
60
|
+
- Output: FixStory objects with id, title, relatedStories, description
|
|
61
|
+
|
|
62
|
+
### 3b: Fix loop in runner
|
|
63
|
+
**File:** `src/execution/runner.ts`
|
|
64
|
+
- After acceptance stage fails: generate fix stories, append to prd
|
|
65
|
+
- Re-run pipeline for fix stories only
|
|
66
|
+
- Re-run acceptance tests
|
|
67
|
+
- Max `config.acceptance.maxRetries` loops
|
|
68
|
+
- If still failing: pause and report to human
|
|
69
|
+
|
|
70
|
+
### 3c: Accept override command
|
|
71
|
+
**File:** `src/cli/accept.ts` (NEW)
|
|
72
|
+
- `ngent accept --override AC-2 "reason"`
|
|
73
|
+
- Stores in prd.json `acceptanceOverrides`
|
|
74
|
+
- Acceptance stage skips overridden ACs
|
|
75
|
+
|
|
76
|
+
### Tests
|
|
77
|
+
- Fix story generation from failed ACs
|
|
78
|
+
- Retry loop respects maxRetries
|
|
79
|
+
- Override skips specified ACs
|
|
80
|
+
- Full integration: fail → fix → pass
|
|
81
|
+
|
|
82
|
+
**Commit:** `feat(acceptance): add self-correcting fix loop with human override`
|
|
83
|
+
|
|
84
|
+
## Test Strategy
|
|
85
|
+
- Mode: test-after
|
|
86
|
+
- Run `bun test && bun run typecheck` after each phase
|