@nathapp/nax 0.28.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -2
- package/bin/nax.ts +2 -3
- package/dist/nax.js +72753 -0
- package/package.json +11 -3
- package/src/cli/analyze.ts +2 -7
- package/src/cli/config.ts +3 -1
- package/src/config/defaults.ts +1 -0
- package/src/config/schemas.ts +1 -0
- package/src/config/types.ts +1 -0
- package/src/context/builder.ts +10 -1
- package/src/execution/lifecycle/headless-formatter.ts +2 -4
- package/src/prompts/builder.ts +12 -69
- package/src/prompts/sections/isolation.ts +38 -8
- package/src/prompts/sections/role-task.ts +79 -17
- package/src/review/runner.ts +6 -1
- package/src/version.ts +2 -1
- package/.claude/rules/01-project-conventions.md +0 -34
- package/.claude/rules/02-test-architecture.md +0 -39
- package/.claude/rules/03-test-writing.md +0 -58
- package/.claude/rules/04-forbidden-patterns.md +0 -29
- package/.claude/settings.json +0 -15
- package/.githooks/pre-commit +0 -16
- package/.gitlab-ci.yml +0 -103
- package/.mcp.json +0 -8
- package/BRIEF.md +0 -140
- package/CLAUDE.md +0 -143
- package/US-007-IMPLEMENTATION.md +0 -139
- package/biome.json +0 -14
- package/bun.lock +0 -163
- package/bunfig.toml +0 -12
- package/docker-compose.test.yml +0 -15
- package/docs/20260216-fix-plan-context-review.md +0 -56
- package/docs/20260216-relentless-vs-ngent-comparison.md +0 -208
- package/docs/20260216-v02-plan.md +0 -136
- package/docs/20260216-v02-review.md +0 -685
- package/docs/20260217-dogfood-findings.md +0 -56
- package/docs/20260217-p2-plus-plan.md +0 -117
- package/docs/20260217-partial-fixes-plan.md +0 -62
- package/docs/20260217-plan-analyze-spec.md +0 -117
- package/docs/20260217-post-impl-review.md +0 -1137
- package/docs/20260217-quick-wins-plan.md +0 -66
- package/docs/20260217-split-runner-plan.md +0 -75
- package/docs/20260217-v03-impl-plan.md +0 -80
- package/docs/20260217-v03-post-impl-review.md +0 -589
- package/docs/20260217-v04-impl-plan.md +0 -86
- package/docs/20260217-v05-post-impl-review.md +0 -850
- package/docs/20260217-v06-post-impl-review.md +0 -817
- package/docs/20260218-adr003-port-plan.md +0 -151
- package/docs/20260218-review-adr003-verification.md +0 -175
- package/docs/20260219-fix-plan-bug16-19.md +0 -79
- package/docs/20260219-fix-plan-bug20-22.md +0 -114
- package/docs/20260219-plan-llm-routing.md +0 -116
- package/docs/20260219-review-bug20-22-fixes.md +0 -135
- package/docs/20260219-routing-baseline-keyword.md +0 -63
- package/docs/20260220-plan-structured-logging-p1.md +0 -80
- package/docs/20260220-plan-structured-logging-p2.md +0 -37
- package/docs/20260220-review-llm-routing.md +0 -180
- package/docs/20260220-review-post-fix-llm-routing.md +0 -70
- package/docs/20260221-fix-plan-relevantfiles-split.md +0 -101
- package/docs/20260221-fix-plan-routing-mode.md +0 -125
- package/docs/20260221-review-v0.9-implementation.md +0 -379
- package/docs/20260222-fix-plan-v091-routing-isolation.md +0 -197
- package/docs/20260223-fix-plan-prompt-audit.md +0 -62
- package/docs/20260224-nax-roadmap-phases.md +0 -189
- package/docs/20260225-phase2-llm-service-layer.md +0 -401
- package/docs/20260225-review-v0.10.1.md +0 -187
- package/docs/20260303-v010-implementation-plan.md +0 -165
- package/docs/20260304-review-nax.md +0 -492
- package/docs/CLAUDE.md.bak +0 -191
- package/docs/ROADMAP.md +0 -390
- package/docs/SPEC-rectification.md +0 -0
- package/docs/SPEC.md +0 -324
- package/docs/US-001-plugin-loading-verification.md +0 -152
- package/docs/adr/ADR-005-implementation-plan.md +0 -655
- package/docs/adr/ADR-005-pipeline-re-architecture.md +0 -464
- package/docs/architecture-analysis.md +0 -1076
- package/docs/bugs/BUG-21-escalation-null-attempts.md +0 -48
- package/docs/bugs-from-dogfood-run-c.md +0 -243
- package/docs/code-review-20260228.md +0 -612
- package/docs/code-review-v0.15.0.md +0 -629
- package/docs/hook-lifecycle-test-plan.md +0 -149
- package/docs/releases/v0.11.0-and-earlier.md +0 -20
- package/docs/releases/v0.12.0.md +0 -15
- package/docs/releases/v0.13.0.md +0 -14
- package/docs/releases/v0.14.0.md +0 -20
- package/docs/releases/v0.14.1.md +0 -36
- package/docs/releases/v0.14.2.md +0 -51
- package/docs/releases/v0.14.3.md +0 -174
- package/docs/releases/v0.14.4.md +0 -94
- package/docs/releases/v0.15.0.md +0 -502
- package/docs/releases/v0.15.1.md +0 -170
- package/docs/releases/v0.15.3.md +0 -193
- package/docs/specs/bug-039-orphan-processes.md +0 -131
- package/docs/specs/bug-040-review-rectification.md +0 -82
- package/docs/specs/bug-041-cross-story-test-isolation.md +0 -88
- package/docs/specs/bug-042-verifier-failure-capture.md +0 -117
- package/docs/specs/bun-pty-migration.md +0 -171
- package/docs/specs/central-run-registry.md +0 -116
- package/docs/specs/feat-010-smart-runner-git-history.md +0 -96
- package/docs/specs/feat-011-file-context-strategy.md +0 -73
- package/docs/specs/feat-012-tdd-writer-tier.md +0 -79
- package/docs/specs/feat-013-test-after-review.md +0 -89
- package/docs/specs/feat-014-heartbeat-observability.md +0 -127
- package/docs/specs/status-file-consolidation.md +0 -93
- package/docs/specs/status-file-v0.10.1.md +0 -812
- package/docs/specs/trigger-completion.md +0 -145
- package/docs/specs/verification-architecture-v2.md +0 -343
- package/docs/tdd/strategies.md +0 -97
- package/docs/v0.10-global-config.md +0 -206
- package/docs/v0.10-plugin-system.md +0 -415
- package/docs/v0.10-prompt-optimizer.md +0 -234
- package/docs/v0.3-spec.md +0 -244
- package/docs/v0.4-spec.md +0 -140
- package/docs/v0.5-spec.md +0 -237
- package/docs/v0.6-spec.md +0 -371
- package/docs/v0.7-spec.md +0 -177
- package/docs/v0.8-llm-routing.md +0 -206
- package/docs/v0.8-structured-logging.md +0 -132
- package/docs/v0.9.3-prompt-audit.md +0 -112
- package/examples/plugins/console-reporter/index.test.ts +0 -207
- package/examples/plugins/console-reporter/index.ts +0 -110
- package/memory/topic/feat-010-baseref.md +0 -28
- package/memory/topic/feat-013-test-after-deprecation.md +0 -22
- package/nax/config.json +0 -154
- package/nax/features/bug-039-medium/prd.json +0 -45
- package/nax/features/bugfix-v0171/prd.json +0 -52
- package/nax/features/central-run-registry/prd.json +0 -105
- package/nax/features/config-management/prd.json +0 -108
- package/nax/features/config-management/progress.txt +0 -5
- package/nax/features/diagnose/acceptance.test.ts +0 -414
- package/nax/features/diagnose/prd.json +0 -41
- package/nax/features/nax-compliance/prd.json +0 -52
- package/nax/features/nax-compliance/progress.txt +0 -1
- package/nax/features/orchestration-fixes/prd.json +0 -89
- package/nax/features/orchestration-fixes/progress.txt +0 -1
- package/nax/features/plugin-integration/US-007-VERIFICATION.md +0 -259
- package/nax/features/plugin-integration/prd.json +0 -208
- package/nax/features/plugin-integration/progress.txt +0 -5
- package/nax/features/post-rearch-bugfix/prd.json +0 -137
- package/nax/features/precheck/prd.json +0 -205
- package/nax/features/precheck/progress.txt +0 -15
- package/nax/features/prompt-builder/prd.json +0 -152
- package/nax/features/prompt-builder/progress.txt +0 -3
- package/nax/features/review-quality/prd.json +0 -55
- package/nax/features/routing-persistence/prd.json +0 -104
- package/nax/features/routing-persistence/progress.txt +0 -1
- package/nax/features/smart-test-runner/plan.md +0 -7
- package/nax/features/smart-test-runner/prd.json +0 -203
- package/nax/features/smart-test-runner/progress.txt +0 -13
- package/nax/features/smart-test-runner/spec.md +0 -7
- package/nax/features/smart-test-runner/tasks.md +0 -8
- package/nax/features/status-file-consolidation/prd.json +0 -106
- package/nax/features/structured-logging/prd.json +0 -199
- package/nax/features/trigger-completion/prd.json +0 -150
- package/nax/features/trigger-completion/progress.txt +0 -7
- package/nax/features/unlock/prd.json +0 -36
- package/nax/features/v0.18.3-execution-reliability/prd.json +0 -80
- package/nax/features/v0.18.3-execution-reliability/progress.txt +0 -3
- package/nax/features/v0.19.0-hardening/plan.md +0 -7
- package/nax/features/v0.19.0-hardening/prd.json +0 -84
- package/nax/features/v0.19.0-hardening/progress.txt +0 -7
- package/nax/features/v0.19.0-hardening/spec.md +0 -18
- package/nax/features/v0.19.0-hardening/tasks.md +0 -8
- package/nax/features/verify-v2/prd.json +0 -79
- package/nax/features/verify-v2/progress.txt +0 -3
- package/nax/status.json +0 -36
- package/src/prompts/templates/implementer.ts +0 -6
- package/src/prompts/templates/single-session.ts +0 -6
- package/src/prompts/templates/test-writer.ts +0 -6
- package/src/prompts/templates/verifier.ts +0 -6
- package/test/COVERAGE-GAPS.md +0 -333
- package/test/e2e/cm-003-default-view.test.ts +0 -195
- package/test/e2e/plan-analyze-run.test.ts +0 -902
- package/test/helpers/helpers.test.ts +0 -295
- package/test/helpers/timeout.ts +0 -42
- package/test/integration/US-002-TEST-SUMMARY.md +0 -107
- package/test/integration/US-003-TEST-SUMMARY.md +0 -149
- package/test/integration/US-004-TEST-SUMMARY.md +0 -106
- package/test/integration/US-005-TEST-SUMMARY.md +0 -138
- package/test/integration/US-007-TEST-SUMMARY.md +0 -100
- package/test/integration/cli/agent-validation.test.ts +0 -439
- package/test/integration/cli/cli-config-default-edge-cases.test.ts +0 -223
- package/test/integration/cli/cli-config-default-view.test.ts +0 -230
- package/test/integration/cli/cli-config-diff.test.ts +0 -461
- package/test/integration/cli/cli-config-prompts-explain.test.ts +0 -74
- package/test/integration/cli/cli-config.test.ts +0 -737
- package/test/integration/cli/cli-diagnose.test.ts +0 -595
- package/test/integration/cli/cli-logs.test.ts +0 -346
- package/test/integration/cli/cli-plugins.test.ts +0 -679
- package/test/integration/cli/cli-precheck.test.ts +0 -372
- package/test/integration/cli/cli-run-headless.test.ts +0 -174
- package/test/integration/cli/cli.test.ts +0 -76
- package/test/integration/cli/precheck-integration.test.ts +0 -476
- package/test/integration/cli/precheck-orchestrator.test.ts +0 -247
- package/test/integration/cli/precheck.test.ts +0 -806
- package/test/integration/config/config-loader.test.ts +0 -266
- package/test/integration/config/config.test.ts +0 -444
- package/test/integration/config/merger.test.ts +0 -466
- package/test/integration/config/paths.test.ts +0 -52
- package/test/integration/config/security-loader.test.ts +0 -83
- package/test/integration/context/context-integration.test.ts +0 -703
- package/test/integration/context/context-path-security.test.ts +0 -173
- package/test/integration/context/context-provider-injection.test.ts +0 -507
- package/test/integration/context/context-verification-integration.test.ts +0 -296
- package/test/integration/context/s5-greenfield-fallback.test.ts +0 -298
- package/test/integration/execution/execution-isolation.test.ts +0 -143
- package/test/integration/execution/execution.test.ts +0 -634
- package/test/integration/execution/feature-status-write.test.ts +0 -302
- package/test/integration/execution/parallel.test.ts +0 -251
- package/test/integration/execution/prd-pause.test.ts +0 -205
- package/test/integration/execution/prd-resolvers.test.ts +0 -186
- package/test/integration/execution/progress.test.ts +0 -34
- package/test/integration/execution/runner-batching.test.ts +0 -682
- package/test/integration/execution/runner-config-plugins.test.ts +0 -462
- package/test/integration/execution/runner-escalation.test.ts +0 -561
- package/test/integration/execution/runner-fixes.test.ts +0 -400
- package/test/integration/execution/runner-plugin-integration.test.ts +0 -544
- package/test/integration/execution/runner-queue-and-attempts.test.ts +0 -476
- package/test/integration/execution/status-file-integration.test.ts +0 -289
- package/test/integration/execution/status-file.test.ts +0 -380
- package/test/integration/execution/status-writer.test.ts +0 -447
- package/test/integration/execution/story-id-in-events.test.ts +0 -274
- package/test/integration/interaction/interaction-chain-pipeline.test.ts +0 -476
- package/test/integration/pipeline/hooks.test.ts +0 -363
- package/test/integration/pipeline/pipeline-acceptance.test.ts +0 -303
- package/test/integration/pipeline/pipeline-events.test.ts +0 -476
- package/test/integration/pipeline/pipeline.test.ts +0 -660
- package/test/integration/pipeline/reporter-lifecycle.test.ts +0 -862
- package/test/integration/pipeline/verify-stage.test.ts +0 -286
- package/test/integration/plan/analyze-integration.test.ts +0 -262
- package/test/integration/plan/analyze-scanner.test.ts +0 -132
- package/test/integration/plan/logger.test.ts +0 -461
- package/test/integration/plan/plan.test.ts +0 -157
- package/test/integration/plugins/config-integration.test.ts +0 -173
- package/test/integration/plugins/config-resolution.test.ts +0 -523
- package/test/integration/plugins/loader.test.ts +0 -644
- package/test/integration/plugins/plugins-registry.test.ts +0 -747
- package/test/integration/plugins/validator.test.ts +0 -564
- package/test/integration/prompts/pb-004-migration.test.ts +0 -523
- package/test/integration/review/review-config-commands.test.ts +0 -320
- package/test/integration/review/review-config-schema.test.ts +0 -117
- package/test/integration/review/review-plugin-integration.test.ts +0 -729
- package/test/integration/review/review.test.ts +0 -150
- package/test/integration/routing/plugin-routing-advanced.test.ts +0 -461
- package/test/integration/routing/plugin-routing-core.test.ts +0 -527
- package/test/integration/routing/routing-stage-bug-021.test.ts +0 -275
- package/test/integration/routing/routing-stage-greenfield.test.ts +0 -287
- package/test/integration/tdd/tdd-cleanup.test.ts +0 -246
- package/test/integration/tdd/tdd-orchestrator-core.test.ts +0 -565
- package/test/integration/tdd/tdd-orchestrator-failureCategory.test.ts +0 -355
- package/test/integration/tdd/tdd-orchestrator-fallback.test.ts +0 -311
- package/test/integration/tdd/tdd-orchestrator-lite.test.ts +0 -289
- package/test/integration/tdd/tdd-orchestrator-prompts.test.ts +0 -260
- package/test/integration/tdd/tdd-orchestrator-verdict.test.ts +0 -536
- package/test/integration/tmp/headless-test/test.jsonl +0 -30
- package/test/integration/verification/test-scanner.test.ts +0 -403
- package/test/integration/verification/verification-asset-check.test.ts +0 -143
- package/test/integration/worktree/manager.test.ts +0 -218
- package/test/integration/worktree/worktree-merge.test.ts +0 -341
- package/test/manual/logging-formatter-demo.ts +0 -158
- package/test/ui/tui-agent-panel.test.tsx +0 -99
- package/test/ui/tui-pty-integration.test.tsx +0 -146
- package/test/unit/acceptance.test.ts +0 -187
- package/test/unit/agent-stderr-capture.test.ts +0 -147
- package/test/unit/agents/claude.test.ts +0 -107
- package/test/unit/analyze-classifier.test.ts +0 -216
- package/test/unit/analyze.test.ts +0 -224
- package/test/unit/auto-detect.test.ts +0 -250
- package/test/unit/cli-status-project-level.test.ts +0 -283
- package/test/unit/cli-status.test.ts +0 -418
- package/test/unit/commands/common.test.ts +0 -321
- package/test/unit/commands/logs.test.ts +0 -458
- package/test/unit/commands/runs.test.ts +0 -303
- package/test/unit/commands/unlock.test.ts +0 -320
- package/test/unit/config/defaults.test.ts +0 -70
- package/test/unit/config/quality-commands-schema.test.ts +0 -72
- package/test/unit/config/regression-gate-schema.test.ts +0 -160
- package/test/unit/config/smart-runner-flag.test.ts +0 -250
- package/test/unit/constitution-generators.test.ts +0 -161
- package/test/unit/constitution.test.ts +0 -210
- package/test/unit/context/context-autodetect.test.ts +0 -297
- package/test/unit/context/context-build.test.ts +0 -575
- package/test/unit/context/context-coverage.test.ts +0 -236
- package/test/unit/context/context-error.test.ts +0 -93
- package/test/unit/context/context-estimate-tokens.test.ts +0 -201
- package/test/unit/context/context-format.test.ts +0 -302
- package/test/unit/context/context-isolation.test.ts +0 -267
- package/test/unit/context/context-sort.test.ts +0 -93
- package/test/unit/context/context-story.test.ts +0 -108
- package/test/unit/context/prior-failures.test.ts +0 -463
- package/test/unit/context.test.ts +0 -1726
- package/test/unit/cost.test.ts +0 -231
- package/test/unit/crash-recovery.test.ts +0 -309
- package/test/unit/escalation.test.ts +0 -127
- package/test/unit/execution/lifecycle/run-completion.test.ts +0 -240
- package/test/unit/execution/lifecycle/run-regression.test.ts +0 -420
- package/test/unit/execution/pid-registry.test.ts +0 -241
- package/test/unit/execution/sequential-executor.test.ts +0 -235
- package/test/unit/execution/sfc-004-dead-code-cleanup.test.ts +0 -89
- package/test/unit/execution/structured-failure.test.ts +0 -415
- package/test/unit/execution-logging-stderr.test.ts +0 -157
- package/test/unit/execution-stage.test.ts +0 -123
- package/test/unit/fix-generator.test.ts +0 -276
- package/test/unit/formatters.test.ts +0 -468
- package/test/unit/greenfield.test.ts +0 -180
- package/test/unit/hooks/shell-security.test.ts +0 -40
- package/test/unit/interaction/auto-plugin.test.ts +0 -162
- package/test/unit/interaction/human-review-trigger.test.ts +0 -165
- package/test/unit/interaction-network-failures.test.ts +0 -390
- package/test/unit/interaction-plugins.test.ts +0 -472
- package/test/unit/logging/formatter.test.ts +0 -456
- package/test/unit/merge.test.ts +0 -269
- package/test/unit/metrics/aggregator.test.ts +0 -164
- package/test/unit/metrics/tracker.test.ts +0 -186
- package/test/unit/metrics.test.ts +0 -276
- package/test/unit/optimizer/noop.optimizer.test.ts +0 -125
- package/test/unit/optimizer/rule-based.optimizer.test.ts +0 -358
- package/test/unit/pipeline/event-bus.test.ts +0 -105
- package/test/unit/pipeline/routing-partial-override.test.ts +0 -121
- package/test/unit/pipeline/runner-retry.test.ts +0 -89
- package/test/unit/pipeline/stages/autofix.test.ts +0 -97
- package/test/unit/pipeline/stages/completion-review-gate.test.ts +0 -218
- package/test/unit/pipeline/stages/execution-ambiguity.test.ts +0 -311
- package/test/unit/pipeline/stages/execution-merge-conflict.test.ts +0 -218
- package/test/unit/pipeline/stages/rectify.test.ts +0 -101
- package/test/unit/pipeline/stages/regression-stage.test.ts +0 -69
- package/test/unit/pipeline/stages/review.test.ts +0 -201
- package/test/unit/pipeline/stages/routing-idempotence.test.ts +0 -139
- package/test/unit/pipeline/stages/routing-initial-complexity.test.ts +0 -321
- package/test/unit/pipeline/stages/routing-persistence.test.ts +0 -380
- package/test/unit/pipeline/stages/verify.test.ts +0 -267
- package/test/unit/pipeline/subscribers/events-writer.test.ts +0 -227
- package/test/unit/pipeline/subscribers/hooks.test.ts +0 -84
- package/test/unit/pipeline/subscribers/interaction.test.ts +0 -313
- package/test/unit/pipeline/subscribers/registry.test.ts +0 -149
- package/test/unit/pipeline/subscribers/reporters.test.ts +0 -90
- package/test/unit/pipeline/verify-smart-runner.test.ts +0 -345
- package/test/unit/prd-auto-default.test.ts +0 -291
- package/test/unit/prd-failure-category.test.ts +0 -177
- package/test/unit/prd-get-next-story.test.ts +0 -215
- package/test/unit/precheck/checks-warnings.test.ts +0 -114
- package/test/unit/precheck-checks.test.ts +0 -841
- package/test/unit/precheck-story-size-gate.test.ts +0 -288
- package/test/unit/precheck-types.test.ts +0 -143
- package/test/unit/prompts/builder.test.ts +0 -258
- package/test/unit/prompts/loader.test.ts +0 -355
- package/test/unit/prompts/sections/conventions.test.ts +0 -30
- package/test/unit/prompts/sections/isolation.test.ts +0 -35
- package/test/unit/prompts/sections/role-task.test.ts +0 -40
- package/test/unit/prompts/sections/sections.test.ts +0 -238
- package/test/unit/prompts/sections/story.test.ts +0 -45
- package/test/unit/prompts/sections/verdict.test.ts +0 -58
- package/test/unit/prompts.test.ts +0 -476
- package/test/unit/queue.test.ts +0 -237
- package/test/unit/rectification.test.ts +0 -285
- package/test/unit/registry.test.ts +0 -288
- package/test/unit/review/runner.test.ts +0 -117
- package/test/unit/routing/content-hash.test.ts +0 -99
- package/test/unit/routing/routing-stability.test.ts +0 -208
- package/test/unit/routing/strategies/llm.test.ts +0 -306
- package/test/unit/routing-advanced.test.ts +0 -313
- package/test/unit/routing-core.test.ts +0 -341
- package/test/unit/routing-strategies.test.ts +0 -440
- package/test/unit/storyid-events.test.ts +0 -213
- package/test/unit/tdd-verdict.test.ts +0 -492
- package/test/unit/test-output-parser.test.ts +0 -377
- package/test/unit/ui/tui-controls.test.ts +0 -335
- package/test/unit/ui/tui-cost-and-pty.test.ts +0 -190
- package/test/unit/ui/tui-layout.test.ts +0 -379
- package/test/unit/ui/tui-stories.test.ts +0 -333
- package/test/unit/unit-isolation.test.ts +0 -135
- package/test/unit/utils/git.test.ts +0 -50
- package/test/unit/utils/path-security.test.ts +0 -47
- package/test/unit/utils-helpers.test.ts +0 -318
- package/test/unit/verdict.test.ts +0 -325
- package/test/unit/verification/orchestrator-types.test.ts +0 -54
- package/test/unit/verification/orchestrator.test.ts +0 -66
- package/test/unit/verification/smart-runner-config.test.ts +0 -163
- package/test/unit/verification/smart-runner-discovery.test.ts +0 -354
- package/test/unit/verification/smart-runner.test.ts +0 -262
- package/test/unit/verification/strategies/acceptance.test.ts +0 -33
- package/test/unit/verification/strategies/regression.test.ts +0 -87
- package/test/unit/verification/strategies/scoped.test.ts +0 -100
- package/test/unit/worktree-manager.test.ts +0 -159
- package/tsconfig.json +0 -27
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
/**
|
|
3
|
-
* Integration tests for contextFiles/expectedFiles split
|
|
4
|
-
* Verifies that context builder and verification use the correct resolvers
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, expect, test } from "bun:test";
|
|
8
|
-
import fs from "node:fs/promises";
|
|
9
|
-
import os from "node:os";
|
|
10
|
-
import path from "node:path";
|
|
11
|
-
import { buildContext } from "../../../src/context/builder";
|
|
12
|
-
import type { ContextBudget, StoryContext } from "../../../src/context/types";
|
|
13
|
-
import { getContextFiles, getExpectedFiles } from "../../../src/prd";
|
|
14
|
-
import type { PRD, UserStory } from "../../../src/prd";
|
|
15
|
-
|
|
16
|
-
const createTestPRD = (stories: Partial<UserStory>[]): PRD => ({
|
|
17
|
-
project: "test-project",
|
|
18
|
-
feature: "test-feature",
|
|
19
|
-
branchName: "test-branch",
|
|
20
|
-
createdAt: new Date().toISOString(),
|
|
21
|
-
updatedAt: new Date().toISOString(),
|
|
22
|
-
userStories: stories.map((s, i) => ({
|
|
23
|
-
id: s.id || `US-${String(i + 1).padStart(3, "0")}`,
|
|
24
|
-
title: s.title || "Test Story",
|
|
25
|
-
description: s.description || "Test description",
|
|
26
|
-
acceptanceCriteria: s.acceptanceCriteria || ["AC1"],
|
|
27
|
-
dependencies: s.dependencies || [],
|
|
28
|
-
tags: s.tags || [],
|
|
29
|
-
status: s.status || "pending",
|
|
30
|
-
passes: s.passes ?? false,
|
|
31
|
-
escalations: s.escalations || [],
|
|
32
|
-
attempts: s.attempts || 0,
|
|
33
|
-
contextFiles: s.contextFiles,
|
|
34
|
-
expectedFiles: s.expectedFiles,
|
|
35
|
-
relevantFiles: s.relevantFiles,
|
|
36
|
-
})),
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe("Context and Verification Integration", () => {
|
|
40
|
-
test("story with contextFiles uses them for context injection", async () => {
|
|
41
|
-
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "nax-test-"));
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
// Create test files
|
|
45
|
-
await fs.writeFile(path.join(tempDir, "src-file.ts"), 'export const src = "source";');
|
|
46
|
-
await fs.writeFile(path.join(tempDir, "dist-file.js"), 'const dist = "output";');
|
|
47
|
-
|
|
48
|
-
const prd = createTestPRD([
|
|
49
|
-
{
|
|
50
|
-
id: "US-001",
|
|
51
|
-
title: "Story with contextFiles",
|
|
52
|
-
description: "Test",
|
|
53
|
-
acceptanceCriteria: ["AC1"],
|
|
54
|
-
contextFiles: ["src-file.ts"], // Only for context
|
|
55
|
-
expectedFiles: ["dist-file.js"], // Only for verification
|
|
56
|
-
},
|
|
57
|
-
]);
|
|
58
|
-
|
|
59
|
-
const storyContext: StoryContext = {
|
|
60
|
-
prd,
|
|
61
|
-
currentStoryId: "US-001",
|
|
62
|
-
workdir: tempDir,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const budget: ContextBudget = {
|
|
66
|
-
maxTokens: 10000,
|
|
67
|
-
reservedForInstructions: 1000,
|
|
68
|
-
availableForContext: 9000,
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const built = await buildContext(storyContext, budget);
|
|
72
|
-
|
|
73
|
-
// Context should include src-file.ts (from contextFiles)
|
|
74
|
-
const fileElements = built.elements.filter((e) => e.type === "file");
|
|
75
|
-
expect(fileElements.length).toBe(1);
|
|
76
|
-
expect(fileElements[0].filePath).toBe("src-file.ts");
|
|
77
|
-
expect(fileElements[0].content).toContain("source");
|
|
78
|
-
|
|
79
|
-
// Context should NOT include dist-file.js (only in expectedFiles)
|
|
80
|
-
expect(fileElements.some((e) => e.filePath === "dist-file.js")).toBe(false);
|
|
81
|
-
|
|
82
|
-
// Verification should use expectedFiles
|
|
83
|
-
const story = prd.userStories[0];
|
|
84
|
-
const filesToVerify = getExpectedFiles(story);
|
|
85
|
-
expect(filesToVerify).toEqual(["dist-file.js"]);
|
|
86
|
-
} finally {
|
|
87
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test("story with relevantFiles uses them for context, not verification", async () => {
|
|
92
|
-
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "nax-test-"));
|
|
93
|
-
|
|
94
|
-
try {
|
|
95
|
-
await fs.writeFile(path.join(tempDir, "legacy.ts"), 'export const legacy = "old";');
|
|
96
|
-
|
|
97
|
-
const prd = createTestPRD([
|
|
98
|
-
{
|
|
99
|
-
id: "US-001",
|
|
100
|
-
title: "Legacy story",
|
|
101
|
-
description: "Test",
|
|
102
|
-
acceptanceCriteria: ["AC1"],
|
|
103
|
-
relevantFiles: ["legacy.ts"], // Backward compat
|
|
104
|
-
},
|
|
105
|
-
]);
|
|
106
|
-
|
|
107
|
-
const storyContext: StoryContext = {
|
|
108
|
-
prd,
|
|
109
|
-
currentStoryId: "US-001",
|
|
110
|
-
workdir: tempDir,
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const budget: ContextBudget = {
|
|
114
|
-
maxTokens: 10000,
|
|
115
|
-
reservedForInstructions: 1000,
|
|
116
|
-
availableForContext: 9000,
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const built = await buildContext(storyContext, budget);
|
|
120
|
-
|
|
121
|
-
// Context should use relevantFiles as fallback
|
|
122
|
-
const contextFiles = getContextFiles(prd.userStories[0]);
|
|
123
|
-
expect(contextFiles).toEqual(["legacy.ts"]);
|
|
124
|
-
|
|
125
|
-
const fileElements = built.elements.filter((e) => e.type === "file");
|
|
126
|
-
expect(fileElements.length).toBe(1);
|
|
127
|
-
expect(fileElements[0].filePath).toBe("legacy.ts");
|
|
128
|
-
|
|
129
|
-
// Verification should NOT use relevantFiles (opt-in only)
|
|
130
|
-
const filesToVerify = getExpectedFiles(prd.userStories[0]);
|
|
131
|
-
expect(filesToVerify).toEqual([]);
|
|
132
|
-
} finally {
|
|
133
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
test("story with no files specified should have empty context and verification", () => {
|
|
138
|
-
const prd = createTestPRD([
|
|
139
|
-
{
|
|
140
|
-
id: "US-001",
|
|
141
|
-
title: "Minimal story",
|
|
142
|
-
description: "Test",
|
|
143
|
-
acceptanceCriteria: ["AC1"],
|
|
144
|
-
},
|
|
145
|
-
]);
|
|
146
|
-
|
|
147
|
-
const story = prd.userStories[0];
|
|
148
|
-
|
|
149
|
-
// Context should be empty
|
|
150
|
-
const contextFiles = getContextFiles(story);
|
|
151
|
-
expect(contextFiles).toEqual([]);
|
|
152
|
-
|
|
153
|
-
// Verification should be empty
|
|
154
|
-
const expectedFiles = getExpectedFiles(story);
|
|
155
|
-
expect(expectedFiles).toEqual([]);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
test("story with contextFiles but no expectedFiles should skip verification", async () => {
|
|
159
|
-
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "nax-test-"));
|
|
160
|
-
|
|
161
|
-
try {
|
|
162
|
-
await fs.writeFile(path.join(tempDir, "helper.ts"), 'export const helper = "util";');
|
|
163
|
-
|
|
164
|
-
const prd = createTestPRD([
|
|
165
|
-
{
|
|
166
|
-
id: "US-001",
|
|
167
|
-
title: "Refactor story",
|
|
168
|
-
description: "Test",
|
|
169
|
-
acceptanceCriteria: ["AC1"],
|
|
170
|
-
contextFiles: ["helper.ts"], // For context only
|
|
171
|
-
// No expectedFiles - just modifying existing code
|
|
172
|
-
},
|
|
173
|
-
]);
|
|
174
|
-
|
|
175
|
-
const storyContext: StoryContext = {
|
|
176
|
-
prd,
|
|
177
|
-
currentStoryId: "US-001",
|
|
178
|
-
workdir: tempDir,
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
const budget: ContextBudget = {
|
|
182
|
-
maxTokens: 10000,
|
|
183
|
-
reservedForInstructions: 1000,
|
|
184
|
-
availableForContext: 9000,
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
const built = await buildContext(storyContext, budget);
|
|
188
|
-
|
|
189
|
-
// Context should include helper.ts
|
|
190
|
-
const fileElements = built.elements.filter((e) => e.type === "file");
|
|
191
|
-
expect(fileElements.length).toBe(1);
|
|
192
|
-
expect(fileElements[0].filePath).toBe("helper.ts");
|
|
193
|
-
|
|
194
|
-
// Verification should be skipped (empty array)
|
|
195
|
-
const filesToVerify = getExpectedFiles(prd.userStories[0]);
|
|
196
|
-
expect(filesToVerify).toEqual([]);
|
|
197
|
-
} finally {
|
|
198
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
test("story with both contextFiles and expectedFiles should use each correctly", async () => {
|
|
203
|
-
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "nax-test-"));
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
await fs.writeFile(path.join(tempDir, "input.ts"), 'export const input = "in";');
|
|
207
|
-
await fs.writeFile(path.join(tempDir, "config.json"), '{"key": "value"}');
|
|
208
|
-
await fs.writeFile(path.join(tempDir, "output.js"), 'const output = "out";');
|
|
209
|
-
|
|
210
|
-
const prd = createTestPRD([
|
|
211
|
-
{
|
|
212
|
-
id: "US-001",
|
|
213
|
-
title: "Build story",
|
|
214
|
-
description: "Test",
|
|
215
|
-
acceptanceCriteria: ["AC1"],
|
|
216
|
-
contextFiles: ["input.ts", "config.json"], // For context
|
|
217
|
-
expectedFiles: ["output.js"], // For verification
|
|
218
|
-
},
|
|
219
|
-
]);
|
|
220
|
-
|
|
221
|
-
const storyContext: StoryContext = {
|
|
222
|
-
prd,
|
|
223
|
-
currentStoryId: "US-001",
|
|
224
|
-
workdir: tempDir,
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
const budget: ContextBudget = {
|
|
228
|
-
maxTokens: 10000,
|
|
229
|
-
reservedForInstructions: 1000,
|
|
230
|
-
availableForContext: 9000,
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
const built = await buildContext(storyContext, budget);
|
|
234
|
-
|
|
235
|
-
// Context should include input.ts and config.json
|
|
236
|
-
const fileElements = built.elements.filter((e) => e.type === "file");
|
|
237
|
-
expect(fileElements.length).toBe(2);
|
|
238
|
-
expect(fileElements.some((e) => e.filePath === "input.ts")).toBe(true);
|
|
239
|
-
expect(fileElements.some((e) => e.filePath === "config.json")).toBe(true);
|
|
240
|
-
|
|
241
|
-
// Context should NOT include output.js (only in expectedFiles)
|
|
242
|
-
expect(fileElements.some((e) => e.filePath === "output.js")).toBe(false);
|
|
243
|
-
|
|
244
|
-
// Verification should only check output.js
|
|
245
|
-
const filesToVerify = getExpectedFiles(prd.userStories[0]);
|
|
246
|
-
expect(filesToVerify).toEqual(["output.js"]);
|
|
247
|
-
} finally {
|
|
248
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
test("migration path: story with relevantFiles + new contextFiles should prefer contextFiles", async () => {
|
|
253
|
-
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "nax-test-"));
|
|
254
|
-
|
|
255
|
-
try {
|
|
256
|
-
await fs.writeFile(path.join(tempDir, "new.ts"), 'export const newFile = "new";');
|
|
257
|
-
await fs.writeFile(path.join(tempDir, "old.ts"), 'export const oldFile = "old";');
|
|
258
|
-
|
|
259
|
-
const prd = createTestPRD([
|
|
260
|
-
{
|
|
261
|
-
id: "US-001",
|
|
262
|
-
title: "Migrated story",
|
|
263
|
-
description: "Test",
|
|
264
|
-
acceptanceCriteria: ["AC1"],
|
|
265
|
-
contextFiles: ["new.ts"], // New field
|
|
266
|
-
relevantFiles: ["old.ts"], // Deprecated field (kept for backward compat)
|
|
267
|
-
},
|
|
268
|
-
]);
|
|
269
|
-
|
|
270
|
-
const storyContext: StoryContext = {
|
|
271
|
-
prd,
|
|
272
|
-
currentStoryId: "US-001",
|
|
273
|
-
workdir: tempDir,
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
const budget: ContextBudget = {
|
|
277
|
-
maxTokens: 10000,
|
|
278
|
-
reservedForInstructions: 1000,
|
|
279
|
-
availableForContext: 9000,
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
const built = await buildContext(storyContext, budget);
|
|
283
|
-
|
|
284
|
-
// Context should prefer contextFiles over relevantFiles
|
|
285
|
-
const fileElements = built.elements.filter((e) => e.type === "file");
|
|
286
|
-
expect(fileElements.length).toBe(1);
|
|
287
|
-
expect(fileElements[0].filePath).toBe("new.ts");
|
|
288
|
-
expect(fileElements[0].content).toContain("newFile");
|
|
289
|
-
|
|
290
|
-
// Old file should not be loaded
|
|
291
|
-
expect(fileElements.some((e) => e.filePath === "old.ts")).toBe(false);
|
|
292
|
-
} finally {
|
|
293
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
});
|
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
/**
|
|
3
|
-
* S5: Strategy Fallback Tests
|
|
4
|
-
*
|
|
5
|
-
* Tests for greenfield-no-tests → test-after strategy switch.
|
|
6
|
-
*
|
|
7
|
-
* When a story fails with greenfield-no-tests failure category,
|
|
8
|
-
* it should switch to test-after strategy (once) instead of escalating tier.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { describe, expect, test } from "bun:test";
|
|
12
|
-
import { resolveMaxAttemptsOutcome } from "../../../src/execution/runner";
|
|
13
|
-
import type { UserStory } from "../../../src/prd";
|
|
14
|
-
import type { FailureCategory } from "../../../src/tdd/types";
|
|
15
|
-
|
|
16
|
-
describe("S5: greenfield-no-tests fallback", () => {
|
|
17
|
-
/**
|
|
18
|
-
* Simulates the escalation routing logic from runner.ts for test-after switch.
|
|
19
|
-
* This mirrors the exact transform applied when greenfield-no-tests fires.
|
|
20
|
-
*/
|
|
21
|
-
function applyGreenfieldFallbackRouting(
|
|
22
|
-
story: UserStory,
|
|
23
|
-
escalateFailureCategory: FailureCategory | undefined,
|
|
24
|
-
nextTier: "fast" | "balanced" | "powerful",
|
|
25
|
-
): { routing: UserStory["routing"]; attempts: number } {
|
|
26
|
-
const escalateRetryAsTestAfter = escalateFailureCategory === "greenfield-no-tests";
|
|
27
|
-
const currentTestStrategy = story.routing?.testStrategy ?? "test-after";
|
|
28
|
-
const shouldSwitchToTestAfter = escalateRetryAsTestAfter && currentTestStrategy !== "test-after";
|
|
29
|
-
|
|
30
|
-
const updatedRouting = story.routing
|
|
31
|
-
? {
|
|
32
|
-
...story.routing,
|
|
33
|
-
modelTier: shouldSwitchToTestAfter ? story.routing.modelTier : nextTier,
|
|
34
|
-
...(shouldSwitchToTestAfter ? { testStrategy: "test-after" as const } : {}),
|
|
35
|
-
}
|
|
36
|
-
: undefined;
|
|
37
|
-
|
|
38
|
-
const shouldResetAttempts = shouldSwitchToTestAfter || story.routing?.modelTier !== nextTier;
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
routing: updatedRouting,
|
|
42
|
-
attempts: shouldResetAttempts ? 0 : (story.attempts ?? 0) + 1,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
describe("AC1: greenfield-no-tests switches to test-after on first occurrence", () => {
|
|
47
|
-
test("story on three-session-tdd switches to test-after and resets attempts", () => {
|
|
48
|
-
const story: UserStory = {
|
|
49
|
-
id: "US-001",
|
|
50
|
-
title: "Greenfield Story",
|
|
51
|
-
description: "Story with no existing tests",
|
|
52
|
-
acceptanceCriteria: ["AC1"],
|
|
53
|
-
tags: [],
|
|
54
|
-
dependencies: [],
|
|
55
|
-
status: "pending",
|
|
56
|
-
passes: false,
|
|
57
|
-
escalations: [],
|
|
58
|
-
attempts: 2,
|
|
59
|
-
routing: {
|
|
60
|
-
complexity: "complex",
|
|
61
|
-
modelTier: "fast",
|
|
62
|
-
testStrategy: "three-session-tdd",
|
|
63
|
-
reasoning: "complex",
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const { routing, attempts } = applyGreenfieldFallbackRouting(story, "greenfield-no-tests", "balanced");
|
|
68
|
-
|
|
69
|
-
// Should switch to test-after WITHOUT escalating tier
|
|
70
|
-
expect(routing?.testStrategy).toBe("test-after");
|
|
71
|
-
expect(routing?.modelTier).toBe("fast"); // Tier stays the same
|
|
72
|
-
expect(attempts).toBe(0); // Attempts reset on strategy switch
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test("story on three-session-tdd-lite switches to test-after", () => {
|
|
76
|
-
const story: UserStory = {
|
|
77
|
-
id: "US-002",
|
|
78
|
-
title: "Lite TDD Story",
|
|
79
|
-
description: "Story using lite mode",
|
|
80
|
-
acceptanceCriteria: ["AC1"],
|
|
81
|
-
tags: [],
|
|
82
|
-
dependencies: [],
|
|
83
|
-
status: "pending",
|
|
84
|
-
passes: false,
|
|
85
|
-
escalations: [],
|
|
86
|
-
attempts: 3,
|
|
87
|
-
routing: {
|
|
88
|
-
complexity: "complex",
|
|
89
|
-
modelTier: "balanced",
|
|
90
|
-
testStrategy: "three-session-tdd-lite",
|
|
91
|
-
reasoning: "complex",
|
|
92
|
-
},
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const { routing, attempts } = applyGreenfieldFallbackRouting(story, "greenfield-no-tests", "powerful");
|
|
96
|
-
|
|
97
|
-
expect(routing?.testStrategy).toBe("test-after");
|
|
98
|
-
expect(routing?.modelTier).toBe("balanced"); // Tier stays the same
|
|
99
|
-
expect(attempts).toBe(0); // Attempts reset
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
describe("AC2: greenfield-no-tests on test-after proceeds with normal escalation", () => {
|
|
104
|
-
test("story already on test-after escalates tier normally", () => {
|
|
105
|
-
const story: UserStory = {
|
|
106
|
-
id: "US-003",
|
|
107
|
-
title: "Test-after Story",
|
|
108
|
-
description: "Story already using test-after",
|
|
109
|
-
acceptanceCriteria: ["AC1"],
|
|
110
|
-
tags: [],
|
|
111
|
-
dependencies: [],
|
|
112
|
-
status: "pending",
|
|
113
|
-
passes: false,
|
|
114
|
-
escalations: [],
|
|
115
|
-
attempts: 4,
|
|
116
|
-
routing: {
|
|
117
|
-
complexity: "simple",
|
|
118
|
-
modelTier: "fast",
|
|
119
|
-
testStrategy: "test-after",
|
|
120
|
-
reasoning: "simple",
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const { routing, attempts } = applyGreenfieldFallbackRouting(story, "greenfield-no-tests", "balanced");
|
|
125
|
-
|
|
126
|
-
// Should NOT switch strategy (already test-after)
|
|
127
|
-
expect(routing?.testStrategy).toBe("test-after");
|
|
128
|
-
// Should escalate tier normally
|
|
129
|
-
expect(routing?.modelTier).toBe("balanced");
|
|
130
|
-
// Attempts reset on tier escalation
|
|
131
|
-
expect(attempts).toBe(0);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
test("greenfield-no-tests fires twice on same story (second time escalates)", () => {
|
|
135
|
-
// First occurrence: three-session-tdd → test-after
|
|
136
|
-
let story: UserStory = {
|
|
137
|
-
id: "US-004",
|
|
138
|
-
title: "Double Greenfield",
|
|
139
|
-
description: "Story that triggers greenfield twice",
|
|
140
|
-
acceptanceCriteria: ["AC1"],
|
|
141
|
-
tags: [],
|
|
142
|
-
dependencies: [],
|
|
143
|
-
status: "pending",
|
|
144
|
-
passes: false,
|
|
145
|
-
escalations: [],
|
|
146
|
-
attempts: 2,
|
|
147
|
-
routing: {
|
|
148
|
-
complexity: "complex",
|
|
149
|
-
modelTier: "fast",
|
|
150
|
-
testStrategy: "three-session-tdd",
|
|
151
|
-
reasoning: "complex",
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// First greenfield-no-tests: switch to test-after
|
|
156
|
-
let result = applyGreenfieldFallbackRouting(story, "greenfield-no-tests", "balanced");
|
|
157
|
-
story = {
|
|
158
|
-
...story,
|
|
159
|
-
attempts: result.attempts,
|
|
160
|
-
routing: result.routing,
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
expect(story.routing?.testStrategy).toBe("test-after");
|
|
164
|
-
expect(story.routing?.modelTier).toBe("fast");
|
|
165
|
-
expect(story.attempts).toBe(0);
|
|
166
|
-
|
|
167
|
-
// Second greenfield-no-tests: already on test-after, escalate tier
|
|
168
|
-
result = applyGreenfieldFallbackRouting(story, "greenfield-no-tests", "balanced");
|
|
169
|
-
story = {
|
|
170
|
-
...story,
|
|
171
|
-
attempts: result.attempts,
|
|
172
|
-
routing: result.routing,
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
expect(story.routing?.testStrategy).toBe("test-after"); // Stays test-after
|
|
176
|
-
expect(story.routing?.modelTier).toBe("balanced"); // Tier escalates
|
|
177
|
-
expect(story.attempts).toBe(0); // Attempts reset on tier change
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
describe("resolveMaxAttemptsOutcome for greenfield-no-tests", () => {
|
|
182
|
-
test("greenfield-no-tests returns pause (requires human review)", () => {
|
|
183
|
-
const result = resolveMaxAttemptsOutcome("greenfield-no-tests");
|
|
184
|
-
expect(result).toBe("pause");
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
test("greenfield-no-tests pauses only when max attempts exhausted", () => {
|
|
188
|
-
// This test documents that pause only happens AFTER the one-time switch
|
|
189
|
-
// When canEscalate=false (max attempts reached), resolveMaxAttemptsOutcome fires
|
|
190
|
-
const result = resolveMaxAttemptsOutcome("greenfield-no-tests");
|
|
191
|
-
expect(result).toBe("pause");
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
describe("non-greenfield-no-tests categories behave normally", () => {
|
|
196
|
-
test("isolation-violation does NOT trigger test-after switch", () => {
|
|
197
|
-
const story: UserStory = {
|
|
198
|
-
id: "US-005",
|
|
199
|
-
title: "Isolation Violation",
|
|
200
|
-
description: "Story with isolation issue",
|
|
201
|
-
acceptanceCriteria: ["AC1"],
|
|
202
|
-
tags: [],
|
|
203
|
-
dependencies: [],
|
|
204
|
-
status: "pending",
|
|
205
|
-
passes: false,
|
|
206
|
-
escalations: [],
|
|
207
|
-
attempts: 2,
|
|
208
|
-
routing: {
|
|
209
|
-
complexity: "complex",
|
|
210
|
-
modelTier: "fast",
|
|
211
|
-
testStrategy: "three-session-tdd",
|
|
212
|
-
reasoning: "complex",
|
|
213
|
-
},
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
const { routing, attempts } = applyGreenfieldFallbackRouting(story, "isolation-violation", "balanced");
|
|
217
|
-
|
|
218
|
-
// Should NOT switch to test-after (different failure category)
|
|
219
|
-
expect(routing?.testStrategy).toBe("three-session-tdd");
|
|
220
|
-
// Should escalate tier normally
|
|
221
|
-
expect(routing?.modelTier).toBe("balanced");
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
test("tests-failing does NOT trigger test-after switch", () => {
|
|
225
|
-
const story: UserStory = {
|
|
226
|
-
id: "US-006",
|
|
227
|
-
title: "Tests Failing",
|
|
228
|
-
description: "Story with failing tests",
|
|
229
|
-
acceptanceCriteria: ["AC1"],
|
|
230
|
-
tags: [],
|
|
231
|
-
dependencies: [],
|
|
232
|
-
status: "pending",
|
|
233
|
-
passes: false,
|
|
234
|
-
escalations: [],
|
|
235
|
-
attempts: 3,
|
|
236
|
-
routing: {
|
|
237
|
-
complexity: "complex",
|
|
238
|
-
modelTier: "fast",
|
|
239
|
-
testStrategy: "three-session-tdd",
|
|
240
|
-
reasoning: "complex",
|
|
241
|
-
},
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
const { routing, attempts } = applyGreenfieldFallbackRouting(story, "tests-failing", "balanced");
|
|
245
|
-
|
|
246
|
-
expect(routing?.testStrategy).toBe("three-session-tdd");
|
|
247
|
-
expect(routing?.modelTier).toBe("balanced");
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
describe("edge cases", () => {
|
|
252
|
-
test("story without routing field handles switch gracefully", () => {
|
|
253
|
-
const story: UserStory = {
|
|
254
|
-
id: "US-007",
|
|
255
|
-
title: "No Routing",
|
|
256
|
-
description: "Story without routing",
|
|
257
|
-
acceptanceCriteria: ["AC1"],
|
|
258
|
-
tags: [],
|
|
259
|
-
dependencies: [],
|
|
260
|
-
status: "pending",
|
|
261
|
-
passes: false,
|
|
262
|
-
escalations: [],
|
|
263
|
-
attempts: 1,
|
|
264
|
-
routing: undefined,
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
const { routing, attempts } = applyGreenfieldFallbackRouting(story, "greenfield-no-tests", "balanced");
|
|
268
|
-
|
|
269
|
-
expect(routing).toBeUndefined();
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
test("undefined failure category does NOT trigger test-after switch", () => {
|
|
273
|
-
const story: UserStory = {
|
|
274
|
-
id: "US-008",
|
|
275
|
-
title: "No Category",
|
|
276
|
-
description: "Story with no failure category",
|
|
277
|
-
acceptanceCriteria: ["AC1"],
|
|
278
|
-
tags: [],
|
|
279
|
-
dependencies: [],
|
|
280
|
-
status: "pending",
|
|
281
|
-
passes: false,
|
|
282
|
-
escalations: [],
|
|
283
|
-
attempts: 2,
|
|
284
|
-
routing: {
|
|
285
|
-
complexity: "complex",
|
|
286
|
-
modelTier: "fast",
|
|
287
|
-
testStrategy: "three-session-tdd",
|
|
288
|
-
reasoning: "complex",
|
|
289
|
-
},
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
const { routing, attempts } = applyGreenfieldFallbackRouting(story, undefined, "balanced");
|
|
293
|
-
|
|
294
|
-
expect(routing?.testStrategy).toBe("three-session-tdd");
|
|
295
|
-
expect(routing?.modelTier).toBe("balanced");
|
|
296
|
-
});
|
|
297
|
-
});
|
|
298
|
-
});
|