@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,234 @@
|
|
|
1
|
+
# v0.10 — Prompt Optimizer
|
|
2
|
+
|
|
3
|
+
**Status:** Draft
|
|
4
|
+
**Author:** Subrina
|
|
5
|
+
**Date:** 2026-02-22
|
|
6
|
+
**Base:** v0.9.2
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Abstract prompt optimization layer that sits between prompt assembly and agent execution. Reduces token usage while preserving semantic meaning. Supports built-in strategies (rule-based, LLM) and external/custom optimizers.
|
|
11
|
+
|
|
12
|
+
## Motivation
|
|
13
|
+
|
|
14
|
+
- Prompts assembled by `promptStage` contain verbose formatting, redundant context, and boilerplate that inflates token counts
|
|
15
|
+
- Coding agents (Claude, etc.) perform equally well with concise instructions
|
|
16
|
+
- No standardized hook point exists for prompt transformation before execution
|
|
17
|
+
- External teams may want to plug in specialized compressors (LLMLingua, custom APIs)
|
|
18
|
+
|
|
19
|
+
## Architecture
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
promptStage → optimizerStage (NEW) → executionStage
|
|
23
|
+
↓
|
|
24
|
+
IPromptOptimizer (interface)
|
|
25
|
+
├── NoopOptimizer (default, passthrough)
|
|
26
|
+
├── RuleBasedOptimizer (built-in)
|
|
27
|
+
│ ├── strip redundant whitespace/formatting
|
|
28
|
+
│ ├── deduplicate context vs constitution overlap
|
|
29
|
+
│ └── compact acceptance criteria
|
|
30
|
+
└── LlmOptimizer (built-in, optional)
|
|
31
|
+
└── uses fast-tier model to rewrite verbose prompts
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### File Structure
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
src/optimizer/
|
|
38
|
+
types.ts # IPromptOptimizer, PromptOptimizerInput, PromptOptimizerResult
|
|
39
|
+
index.ts # resolveOptimizer() factory
|
|
40
|
+
noop.optimizer.ts # NoopOptimizer (passthrough)
|
|
41
|
+
rule-based.optimizer.ts # RuleBasedOptimizer
|
|
42
|
+
llm.optimizer.ts # LlmOptimizer
|
|
43
|
+
loader.ts # Custom module loader
|
|
44
|
+
src/pipeline/stages/
|
|
45
|
+
optimizer.ts # optimizerStage
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Interface
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
export interface IPromptOptimizer {
|
|
52
|
+
/** Unique optimizer name */
|
|
53
|
+
name: string;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Optimize a prompt before it is sent to the coding agent.
|
|
57
|
+
*
|
|
58
|
+
* Implementations MUST preserve all technical requirements,
|
|
59
|
+
* acceptance criteria semantics, and code references.
|
|
60
|
+
*/
|
|
61
|
+
optimize(input: PromptOptimizerInput): Promise<PromptOptimizerResult>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface PromptOptimizerInput {
|
|
65
|
+
/** Assembled prompt from promptStage */
|
|
66
|
+
prompt: string;
|
|
67
|
+
/** Stories being executed (for context) */
|
|
68
|
+
stories: UserStory[];
|
|
69
|
+
/** Raw context markdown (pre-assembly, for dedup detection) */
|
|
70
|
+
contextMarkdown?: string;
|
|
71
|
+
/** Nax configuration */
|
|
72
|
+
config: NaxConfig;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface PromptOptimizerResult {
|
|
76
|
+
/** Optimized prompt */
|
|
77
|
+
prompt: string;
|
|
78
|
+
/** Estimated token count before optimization */
|
|
79
|
+
originalTokens: number;
|
|
80
|
+
/** Estimated token count after optimization */
|
|
81
|
+
optimizedTokens: number;
|
|
82
|
+
/** Savings percentage (0-1) */
|
|
83
|
+
savings: number;
|
|
84
|
+
/** List of applied optimization rules/passes */
|
|
85
|
+
appliedRules: string[];
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Built-in Optimizers
|
|
90
|
+
|
|
91
|
+
### NoopOptimizer
|
|
92
|
+
|
|
93
|
+
Passthrough — returns prompt unchanged with zero savings. Default when optimizer is disabled or strategy is unrecognized.
|
|
94
|
+
|
|
95
|
+
### RuleBasedOptimizer
|
|
96
|
+
|
|
97
|
+
Deterministic, zero-cost transformations:
|
|
98
|
+
|
|
99
|
+
| Rule | Description |
|
|
100
|
+
|:-----|:------------|
|
|
101
|
+
| `stripWhitespace` | Collapse multiple blank lines to single, trim trailing whitespace |
|
|
102
|
+
| `compactCriteria` | Convert verbose acceptance criteria to terse bullet format |
|
|
103
|
+
| `deduplicateContext` | Remove context sections that duplicate constitution content |
|
|
104
|
+
| `maxPromptTokens` | If prompt exceeds threshold, aggressively trim context (not story/AC) |
|
|
105
|
+
|
|
106
|
+
### LlmOptimizer
|
|
107
|
+
|
|
108
|
+
Uses a fast-tier model (e.g., haiku) to rewrite the prompt:
|
|
109
|
+
|
|
110
|
+
- Only triggers when prompt exceeds `minPromptTokens` threshold
|
|
111
|
+
- System prompt: "Rewrite this coding task prompt to be {targetReduction}% shorter. Preserve ALL technical requirements, acceptance criteria, file paths, and code references exactly. Remove only verbose prose, redundant explanations, and formatting fluff."
|
|
112
|
+
- Falls back to original prompt if LLM call fails
|
|
113
|
+
|
|
114
|
+
## Configuration
|
|
115
|
+
|
|
116
|
+
New `optimizer` section in `nax/config.json`:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"optimizer": {
|
|
121
|
+
"enabled": true,
|
|
122
|
+
"strategy": "rule-based",
|
|
123
|
+
"strategies": {
|
|
124
|
+
"rule-based": {
|
|
125
|
+
"stripWhitespace": true,
|
|
126
|
+
"compactCriteria": true,
|
|
127
|
+
"deduplicateContext": true,
|
|
128
|
+
"maxPromptTokens": 8000
|
|
129
|
+
},
|
|
130
|
+
"llm": {
|
|
131
|
+
"model": "fast",
|
|
132
|
+
"targetReduction": 0.4,
|
|
133
|
+
"minPromptTokens": 2000
|
|
134
|
+
},
|
|
135
|
+
"custom": {
|
|
136
|
+
"module": "./my-optimizer.js",
|
|
137
|
+
"options": {}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
All fields are optional. When `optimizer` is absent or `enabled: false`, the NoopOptimizer is used.
|
|
145
|
+
|
|
146
|
+
## Pipeline Integration
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// src/pipeline/stages/optimizer.ts
|
|
150
|
+
export const optimizerStage: PipelineStage = {
|
|
151
|
+
name: "optimizer",
|
|
152
|
+
enabled: (ctx) => ctx.config.optimizer?.enabled ?? false,
|
|
153
|
+
async execute(ctx: PipelineContext): Promise<StageResult> {
|
|
154
|
+
const optimizer = resolveOptimizer(ctx.config);
|
|
155
|
+
const result = await optimizer.optimize({
|
|
156
|
+
prompt: ctx.prompt!,
|
|
157
|
+
stories: ctx.stories,
|
|
158
|
+
contextMarkdown: ctx.contextMarkdown,
|
|
159
|
+
config: ctx.config,
|
|
160
|
+
});
|
|
161
|
+
ctx.prompt = result.prompt;
|
|
162
|
+
logger.info("optimizer", `${optimizer.name}: ${result.savings}% savings`, {
|
|
163
|
+
originalTokens: result.originalTokens,
|
|
164
|
+
optimizedTokens: result.optimizedTokens,
|
|
165
|
+
rules: result.appliedRules,
|
|
166
|
+
});
|
|
167
|
+
return { action: "continue" };
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Stage order: `routing → context → constitution → prompt → **optimizer** → execution → review → acceptance → completion`
|
|
173
|
+
|
|
174
|
+
## Custom/External Optimizer
|
|
175
|
+
|
|
176
|
+
Custom optimizers are loaded via the **plugin system** (see `v0.10-plugin-system.md`). A plugin providing an optimizer implements the `IPromptOptimizer` interface:
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
// nax/plugins/my-optimizer/index.js
|
|
180
|
+
module.exports = {
|
|
181
|
+
name: "my-custom-optimizer",
|
|
182
|
+
version: "1.0.0",
|
|
183
|
+
provides: ["optimizer"],
|
|
184
|
+
extensions: {
|
|
185
|
+
optimizer: {
|
|
186
|
+
name: "llmlingua",
|
|
187
|
+
async optimize(input) {
|
|
188
|
+
const optimized = await externalService.compress(input.prompt);
|
|
189
|
+
return {
|
|
190
|
+
prompt: optimized,
|
|
191
|
+
originalTokens: estimateTokens(input.prompt),
|
|
192
|
+
optimizedTokens: estimateTokens(optimized),
|
|
193
|
+
savings: calculateSavings(input.prompt, optimized),
|
|
194
|
+
appliedRules: ["external-compression"],
|
|
195
|
+
};
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Plugin optimizers override the built-in strategy when loaded. See plugin system spec for loading and conflict resolution.
|
|
203
|
+
|
|
204
|
+
## User Stories
|
|
205
|
+
|
|
206
|
+
| # | Title | Complexity | Est. LOC | Dependencies |
|
|
207
|
+
|:--|:------|:-----------|:---------|:-------------|
|
|
208
|
+
| US-001 | Define IPromptOptimizer interface, types, and NoopOptimizer | simple | 60 | — |
|
|
209
|
+
| US-002 | Implement RuleBasedOptimizer | medium | 150 | US-001 |
|
|
210
|
+
| US-003 | Implement LlmOptimizer with fast-tier rewrite | medium | 120 | US-001 |
|
|
211
|
+
| US-004 | Add optimizerStage to pipeline + config schema + resolveOptimizer factory | medium | 100 | US-001 |
|
|
212
|
+
| US-005 | Custom module loader for external optimizers | simple | 60 | US-001, US-004 |
|
|
213
|
+
|
|
214
|
+
## Token Estimation
|
|
215
|
+
|
|
216
|
+
Use a simple heuristic for token counting (no external tokenizer dependency):
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
/** ~4 chars per token for English text (rough estimate) */
|
|
220
|
+
export function estimateTokens(text: string): number {
|
|
221
|
+
return Math.ceil(text.length / 4);
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
This is sufficient for savings calculation. Exact counts are not required.
|
|
226
|
+
|
|
227
|
+
## Design Decisions
|
|
228
|
+
|
|
229
|
+
1. **NoopOptimizer as default** — zero breaking changes, fully opt-in
|
|
230
|
+
2. **Strategy pattern** — `resolveOptimizer()` factory selects implementation based on config
|
|
231
|
+
3. **Composable (future)** — interface supports chaining (rule-based → LLM) in a future version
|
|
232
|
+
4. **Metrics in result** — always report token savings for cost tracking and logging
|
|
233
|
+
5. **Fail-safe** — all optimizers fall back to original prompt on error
|
|
234
|
+
6. **No external dependencies** — rule-based and LLM optimizers use only existing nax infrastructure
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# ngent v0.3 Specification
|
|
2
|
+
**Date:** 2026-02-17
|
|
3
|
+
**Status:** Draft
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
v0.3 adds LLM-enhanced analysis and a constitution system inspired by Relentless. The goal: replace keyword-based routing with codebase-aware intelligence, and give ngent a governance framework that agents reference during execution.
|
|
8
|
+
|
|
9
|
+
## Feature 1: LLM-Enhanced Analyze
|
|
10
|
+
|
|
11
|
+
### Problem
|
|
12
|
+
`ngent analyze` currently uses keyword matching to classify stories. "Add caching" looks simple by keywords, but if the codebase has no cache infrastructure, it's actually complex. Only an LLM reading the code can catch that.
|
|
13
|
+
|
|
14
|
+
### Solution
|
|
15
|
+
During `ngent analyze`, make one cheap LLM call (haiku) that reads the codebase structure + story descriptions and returns structured routing decisions.
|
|
16
|
+
|
|
17
|
+
### Flow
|
|
18
|
+
```
|
|
19
|
+
ngent analyze
|
|
20
|
+
1. Parse tasks.md → extract stories (existing)
|
|
21
|
+
2. Scan codebase → generate summary (NEW)
|
|
22
|
+
- file tree (src/ only, max depth 3)
|
|
23
|
+
- package.json dependencies
|
|
24
|
+
- existing test patterns
|
|
25
|
+
3. LLM call → classify all stories in one shot (NEW)
|
|
26
|
+
Input: codebase summary + all stories
|
|
27
|
+
Output: JSON array with per-story:
|
|
28
|
+
- complexity: simple/medium/complex/expert
|
|
29
|
+
- relevantFiles: string[] (files the story will likely touch)
|
|
30
|
+
- reasoning: string (why this classification)
|
|
31
|
+
- estimatedLOC: number
|
|
32
|
+
- risks: string[] (potential issues)
|
|
33
|
+
4. Merge LLM output into prd.json (existing routing fields)
|
|
34
|
+
5. Fall back to keyword matching if LLM call fails (graceful degradation)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Classification Prompt (single call)
|
|
38
|
+
```
|
|
39
|
+
You are a code complexity classifier. Given a codebase summary and user stories,
|
|
40
|
+
classify each story's implementation complexity.
|
|
41
|
+
|
|
42
|
+
CODEBASE:
|
|
43
|
+
{fileTree}
|
|
44
|
+
{dependencies}
|
|
45
|
+
{existingPatterns}
|
|
46
|
+
|
|
47
|
+
STORIES:
|
|
48
|
+
{storiesJson}
|
|
49
|
+
|
|
50
|
+
For each story, respond with JSON:
|
|
51
|
+
[{
|
|
52
|
+
"storyId": "US-001",
|
|
53
|
+
"complexity": "simple|medium|complex|expert",
|
|
54
|
+
"relevantFiles": ["src/path/to/file.ts"],
|
|
55
|
+
"reasoning": "Why this complexity level",
|
|
56
|
+
"estimatedLOC": 50,
|
|
57
|
+
"risks": ["No existing cache layer"]
|
|
58
|
+
}]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Config
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"analyze": {
|
|
65
|
+
"llmEnhanced": true,
|
|
66
|
+
"classifierModel": "fast",
|
|
67
|
+
"fallbackToKeywords": true,
|
|
68
|
+
"maxCodebaseSummaryTokens": 5000
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Cost
|
|
74
|
+
~$0.01-0.02 per analyze run (one haiku call). Pays for itself by preventing one misrouted story.
|
|
75
|
+
|
|
76
|
+
### Acceptance Criteria
|
|
77
|
+
- [ ] Codebase scanner generates file tree + dependency summary
|
|
78
|
+
- [ ] Single LLM call classifies all stories with structured JSON output
|
|
79
|
+
- [ ] relevantFiles populated in prd.json for context builder to use
|
|
80
|
+
- [ ] Falls back to keyword matching on LLM failure (timeout, parse error)
|
|
81
|
+
- [ ] Config option to disable LLM-enhanced analysis
|
|
82
|
+
- [ ] Works with existing tasks.md format (no changes required)
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Feature 2: Constitution System
|
|
87
|
+
|
|
88
|
+
### Problem
|
|
89
|
+
ngent agents execute stories with a generic prompt. There's no project-specific governance — coding standards, architectural rules, testing requirements. Relentless solves this with a versioned constitution that agents reference.
|
|
90
|
+
|
|
91
|
+
### Solution
|
|
92
|
+
Add a `constitution.md` file to the ngent project directory that gets injected into every agent session prompt.
|
|
93
|
+
|
|
94
|
+
### Structure
|
|
95
|
+
```
|
|
96
|
+
project/
|
|
97
|
+
ngent/
|
|
98
|
+
config.json
|
|
99
|
+
constitution.md ← NEW
|
|
100
|
+
tasks.md
|
|
101
|
+
prd.json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Constitution Format
|
|
105
|
+
```markdown
|
|
106
|
+
# Project Constitution
|
|
107
|
+
|
|
108
|
+
## Coding Standards
|
|
109
|
+
- Use Bun-native APIs, not Node.js
|
|
110
|
+
- Functional style for pure logic
|
|
111
|
+
- Max 400 lines per file
|
|
112
|
+
|
|
113
|
+
## Testing Requirements
|
|
114
|
+
- All new code must have tests
|
|
115
|
+
- Use bun:test (describe/test/expect)
|
|
116
|
+
- Target 80%+ coverage
|
|
117
|
+
|
|
118
|
+
## Architecture Rules
|
|
119
|
+
- Each module: types.ts, implementation, index.ts barrel
|
|
120
|
+
- No circular dependencies
|
|
121
|
+
- Immutable data patterns
|
|
122
|
+
|
|
123
|
+
## Forbidden Patterns
|
|
124
|
+
- No `any` type
|
|
125
|
+
- No console.log in production code
|
|
126
|
+
- No hardcoded secrets
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### How It Works
|
|
130
|
+
1. `ngent init` creates a starter `constitution.md` (template with common rules)
|
|
131
|
+
2. Human customizes it for their project
|
|
132
|
+
3. During `ngent run`, constitution is injected into every agent prompt:
|
|
133
|
+
```
|
|
134
|
+
CONSTITUTION (follow these rules strictly):
|
|
135
|
+
{constitutionContent}
|
|
136
|
+
|
|
137
|
+
STORY:
|
|
138
|
+
{storyPrompt}
|
|
139
|
+
```
|
|
140
|
+
4. Constitution content counts against context token budget (priority 95 — highest after story itself)
|
|
141
|
+
5. Large constitutions get truncated with warning
|
|
142
|
+
|
|
143
|
+
### Config
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"constitution": {
|
|
147
|
+
"enabled": true,
|
|
148
|
+
"path": "constitution.md",
|
|
149
|
+
"maxTokens": 2000
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Acceptance Criteria
|
|
155
|
+
- [ ] `ngent init` generates starter constitution.md
|
|
156
|
+
- [ ] Constitution loaded and injected into all agent prompts
|
|
157
|
+
- [ ] Counts against context token budget (priority 95)
|
|
158
|
+
- [ ] Warning if constitution exceeds maxTokens
|
|
159
|
+
- [ ] Config option to disable
|
|
160
|
+
- [ ] Works with both single-session and TDD modes
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Feature 3: Simplified Review Phase
|
|
165
|
+
|
|
166
|
+
### Problem
|
|
167
|
+
Stories are marked complete after tests pass. No automated quality gate for lint, typecheck, or code quality issues that tests don't catch.
|
|
168
|
+
|
|
169
|
+
### Solution
|
|
170
|
+
After each story's implementation, run a quick verification phase before marking it as passed.
|
|
171
|
+
|
|
172
|
+
### Flow
|
|
173
|
+
```
|
|
174
|
+
Story implementation complete (tests pass)
|
|
175
|
+
→ Review phase:
|
|
176
|
+
1. bun run typecheck (if tsconfig exists)
|
|
177
|
+
2. bun run lint (if lint script exists)
|
|
178
|
+
3. bun test (final verification)
|
|
179
|
+
→ All pass → mark story as passed
|
|
180
|
+
→ Any fail → mark story as failed (with review failure reason)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Config
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"review": {
|
|
187
|
+
"enabled": true,
|
|
188
|
+
"checks": ["typecheck", "lint", "test"],
|
|
189
|
+
"commands": {
|
|
190
|
+
"typecheck": "bun run typecheck",
|
|
191
|
+
"lint": "bun run lint",
|
|
192
|
+
"test": "bun test"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Acceptance Criteria
|
|
199
|
+
- [ ] Review phase runs after each story implementation
|
|
200
|
+
- [ ] Configurable checks (typecheck, lint, test)
|
|
201
|
+
- [ ] Custom commands per check
|
|
202
|
+
- [ ] Failure in review marks story as failed with reason
|
|
203
|
+
- [ ] Can be disabled via config
|
|
204
|
+
- [ ] Review results logged in progress.txt
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Feature 4: SpecKit-Inspired Workflow Commands (Optional)
|
|
209
|
+
|
|
210
|
+
Inspired by Relentless's command chain: specify → plan → tasks → analyze → implement.
|
|
211
|
+
|
|
212
|
+
### New Commands
|
|
213
|
+
```bash
|
|
214
|
+
ngent specify "Add URL shortener with analytics"
|
|
215
|
+
→ Generates spec.md from natural language (sonnet call)
|
|
216
|
+
|
|
217
|
+
ngent plan
|
|
218
|
+
→ LLM-enhanced analyze (Feature 1 above)
|
|
219
|
+
→ Auto-populates relevantFiles, complexity, risks
|
|
220
|
+
|
|
221
|
+
ngent run
|
|
222
|
+
→ Execute with constitution (Feature 2) + review (Feature 3)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
`ngent specify` is the DECOMPOSE stage discussed earlier — optional, human can still write tasks.md manually.
|
|
226
|
+
|
|
227
|
+
### Acceptance Criteria
|
|
228
|
+
- [ ] `ngent specify` generates structured spec.md from description
|
|
229
|
+
- [ ] `ngent plan` is alias for LLM-enhanced analyze
|
|
230
|
+
- [ ] Both commands optional — existing tasks.md workflow still works
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Priority Order
|
|
235
|
+
|
|
236
|
+
| # | Feature | Effort | Impact |
|
|
237
|
+
|:---|:---|:---|:---|
|
|
238
|
+
| 1 | LLM-Enhanced Analyze | M | High — fixes routing accuracy |
|
|
239
|
+
| 2 | Constitution System | S-M | High — governs all agent behavior |
|
|
240
|
+
| 3 | Review Phase | S | Medium — quality gate |
|
|
241
|
+
| 4 | SpecKit Commands | M | Low — convenience, not essential |
|
|
242
|
+
|
|
243
|
+
## Estimated Total
|
|
244
|
+
~600-800 LOC. Features 1-3 are the core of v0.3. Feature 4 is nice-to-have.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# ngent v0.4 Specification
|
|
2
|
+
**Date:** 2026-02-17
|
|
3
|
+
**Status:** Draft
|
|
4
|
+
|
|
5
|
+
## Feature: Acceptance Validation & Self-Correcting Loop
|
|
6
|
+
|
|
7
|
+
### Problem
|
|
8
|
+
ngent verifies stories individually (tests pass?) but never validates the feature as a whole against the human's acceptance criteria. Stories can all pass but the feature can still mismatch what was specified.
|
|
9
|
+
|
|
10
|
+
### Solution
|
|
11
|
+
Two-phase acceptance validation:
|
|
12
|
+
|
|
13
|
+
1. **At analyze time:** Generate acceptance tests from spec.md ACs
|
|
14
|
+
2. **After all stories complete:** Run acceptance tests as final gate
|
|
15
|
+
3. **On failure:** Auto-generate fix stories targeting only the gaps, retry (max 2 loops)
|
|
16
|
+
|
|
17
|
+
### Flow
|
|
18
|
+
```
|
|
19
|
+
ngent analyze
|
|
20
|
+
→ Decompose spec → stories (existing)
|
|
21
|
+
→ NEW: Generate acceptance tests from spec.md ACs
|
|
22
|
+
→ Write to ngent/features/<name>/acceptance.test.ts
|
|
23
|
+
|
|
24
|
+
ngent run
|
|
25
|
+
→ Execute all stories (existing pipeline)
|
|
26
|
+
→ All stories pass
|
|
27
|
+
→ NEW: Acceptance stage — run acceptance.test.ts
|
|
28
|
+
→ All pass → ✅ Feature complete
|
|
29
|
+
→ Some fail →
|
|
30
|
+
Map failed ACs → relevant stories
|
|
31
|
+
Create fix stories (US-FIX-001, etc.)
|
|
32
|
+
Run fix stories only
|
|
33
|
+
Re-run acceptance tests
|
|
34
|
+
Pass? → ✅ Done
|
|
35
|
+
Fail again? → Loop (max 2 retries)
|
|
36
|
+
Still failing? → ⏸ Pause, ask human
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Acceptance Test Generation
|
|
40
|
+
|
|
41
|
+
During `ngent analyze`, after decomposing stories, make one additional LLM call:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Input: spec.md acceptance criteria + codebase context + story list
|
|
45
|
+
Output: acceptance.test.ts with one test per AC
|
|
46
|
+
|
|
47
|
+
Example:
|
|
48
|
+
AC-2: "set(key, value, ttl) expires after ttl milliseconds"
|
|
49
|
+
→
|
|
50
|
+
test("AC-2: TTL expiry", async () => {
|
|
51
|
+
const store = new KVStore();
|
|
52
|
+
store.set("key", "value", 50);
|
|
53
|
+
await Bun.sleep(60);
|
|
54
|
+
expect(store.get("key")).toBeUndefined();
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Rules for acceptance tests:**
|
|
59
|
+
- Test observable behavior only (not implementation details)
|
|
60
|
+
- Each AC maps to exactly one test
|
|
61
|
+
- Tests are independent (no shared state)
|
|
62
|
+
- Tests must be runnable without mocking (integration-level)
|
|
63
|
+
|
|
64
|
+
### Fix Story Generation
|
|
65
|
+
|
|
66
|
+
When acceptance tests fail:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
interface FixStory {
|
|
70
|
+
id: string; // "US-FIX-001"
|
|
71
|
+
title: string; // "Fix: AC-2 TTL expiry timing"
|
|
72
|
+
failedAC: string; // "AC-2"
|
|
73
|
+
testOutput: string; // actual vs expected from test failure
|
|
74
|
+
relatedStories: string[]; // ["US-002"] — original stories that built this
|
|
75
|
+
description: string; // LLM-generated fix description
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The fix story prompt includes:
|
|
80
|
+
- The failed acceptance test output
|
|
81
|
+
- The relevant source code (from relatedStories)
|
|
82
|
+
- The original AC text
|
|
83
|
+
- Instruction: "Fix the code to make this acceptance test pass"
|
|
84
|
+
|
|
85
|
+
### Pipeline Integration
|
|
86
|
+
|
|
87
|
+
New pipeline stage: `acceptanceStage` — runs after `completionStage` when all stories are done.
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
const defaultPipeline: PipelineStage[] = [
|
|
91
|
+
queueCheckStage,
|
|
92
|
+
routingStage,
|
|
93
|
+
constitutionStage,
|
|
94
|
+
contextStage,
|
|
95
|
+
promptStage,
|
|
96
|
+
executionStage,
|
|
97
|
+
verifyStage,
|
|
98
|
+
reviewStage,
|
|
99
|
+
completionStage,
|
|
100
|
+
acceptanceStage, // NEW — runs only when all stories complete
|
|
101
|
+
];
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Config
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"acceptance": {
|
|
108
|
+
"enabled": true,
|
|
109
|
+
"maxRetries": 2,
|
|
110
|
+
"generateTests": true,
|
|
111
|
+
"testPath": "acceptance.test.ts"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Human Override
|
|
117
|
+
```bash
|
|
118
|
+
ngent accept --override AC-2 "intentional: using lazy expiry instead of exact timing"
|
|
119
|
+
```
|
|
120
|
+
Marks an AC as accepted despite test failure. Stored in prd.json:
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"acceptanceOverrides": {
|
|
124
|
+
"AC-2": "intentional: using lazy expiry instead of exact timing"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Acceptance Criteria for This Feature
|
|
130
|
+
- [ ] Acceptance tests generated from spec.md ACs during analyze
|
|
131
|
+
- [ ] Tests run after all stories complete
|
|
132
|
+
- [ ] Failed ACs mapped to relevant stories
|
|
133
|
+
- [ ] Fix stories auto-generated and executed
|
|
134
|
+
- [ ] Max 2 retry loops before pausing for human
|
|
135
|
+
- [ ] `ngent accept --override` skips specific ACs
|
|
136
|
+
- [ ] Works with existing pipeline (new stage, not inline)
|
|
137
|
+
- [ ] Config to disable acceptance validation
|
|
138
|
+
|
|
139
|
+
### Estimated Effort
|
|
140
|
+
~400-600 LOC. Medium complexity — mostly LLM prompt engineering for test generation and fix story creation.
|