pan-wizard 3.35.0 → 3.37.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 +3645 -0
- package/README.md +46 -52
- package/agents/pan-conductor.md +2 -3
- package/agents/pan-counterfactual.md +1 -2
- package/agents/pan-debugger.md +14 -3
- package/agents/pan-design-checker.md +1 -2
- package/agents/pan-designer.md +2 -3
- package/agents/pan-document_code.md +1 -2
- package/agents/pan-executor.md +25 -0
- package/agents/pan-hardener.md +4 -3
- package/agents/pan-integration-checker.md +1 -2
- package/agents/pan-knowledge.md +1 -2
- package/agents/pan-meta-reviewer.md +3 -3
- package/agents/pan-optimizer.md +4 -4
- package/agents/pan-phase-researcher.md +80 -475
- package/agents/pan-plan-checker.md +40 -3
- package/agents/pan-planner.md +21 -7
- package/agents/pan-previewer.md +3 -2
- package/agents/pan-project-researcher.md +72 -493
- package/agents/pan-release.md +1 -1
- package/agents/pan-reviewer.md +14 -3
- package/agents/pan-roadmapper.md +12 -7
- package/agents/pan-verifier.md +9 -4
- package/bin/install-lib.cjs +134 -14
- package/bin/install.js +59 -12
- package/commands/pan/army.md +1 -1
- package/commands/pan/autodev.md +76 -0
- package/commands/pan/cost.md +21 -1
- package/commands/pan/exec-phase.md +3 -4
- package/commands/pan/focus-auto.md +14 -7
- package/commands/pan/focus-design.md +4 -5
- package/commands/pan/focus-docs.md +24 -0
- package/commands/pan/learn.md +13 -6
- package/commands/pan/milestone-audit.md +8 -1
- package/commands/pan/milestone-done.md +10 -5
- package/commands/pan/milestone-new.md +2 -2
- package/commands/pan/new-project.md +15 -12
- package/commands/pan/plan-phase.md +15 -9
- package/commands/pan/preview.md +1 -1
- package/commands/pan/quick.md +1 -1
- package/commands/pan/review-deep.md +11 -5
- package/commands/pan/settings.md +6 -0
- package/commands/pan/verify-phase.md +6 -2
- package/docs/AGENTS.md +917 -0
- package/docs/ARCHITECTURE.md +1054 -0
- package/docs/CLI-REFERENCE.md +4582 -0
- package/docs/COMPARISON.md +116 -0
- package/docs/DEVELOPMENT.md +490 -0
- package/docs/ECOSYSTEM-REVIEW-2026-06.md +107 -0
- package/docs/ECOSYSTEM-REVIEW-2026-08.md +349 -0
- package/docs/EXAMPLES.md +584 -0
- package/docs/FAQ.md +254 -0
- package/docs/FIELD-HARVEST-2026-07.md +88 -0
- package/docs/FIELD-REPORT-army-2026-06.md +121 -0
- package/docs/HOOKS.md +638 -0
- package/docs/IMPROVEMENT-TODO.md +246 -0
- package/docs/INTERNALS.md +485 -0
- package/docs/MIGRATION-v2-to-v3.md +258 -0
- package/docs/SECURITY-HARDENING.md +230 -0
- package/docs/SKILLS-ENHANCEMENT-PLAN-V2.md +122 -0
- package/docs/SKILLS-FULL-TEXT.md +9685 -0
- package/docs/SKILLS-REFERENCE.md +1037 -0
- package/docs/TROUBLESHOOTING.md +1084 -0
- package/docs/USER-GUIDE.md +1437 -0
- package/docs/archive/SKILLS-ENHANCEMENT-PLAN.md +230 -0
- package/docs/audits/AUDIT-2026-08-e2e-ROADMAP.md +117 -0
- package/docs/audits/AUDIT-2026-08-e2e-VERIFICATION.md +693 -0
- package/docs/audits/AUDIT-2026-08-e2e.md +1546 -0
- package/docs/audits/OUTSTANDING-2026-08.md +275 -0
- package/docs/audits/STABILITY-TEST-2026-08.md +640 -0
- package/docs/branding/README-brand-draft.md +119 -0
- package/docs/branding/handoff/IMPLEMENTATION.md +205 -0
- package/docs/branding/handoff/README-brand-draft.md +119 -0
- package/docs/branding/handoff/image-prompts.md +46 -0
- package/docs/branding/image-prompts.md +46 -0
- package/docs/branding/nano-banana-prompts.txt +60 -0
- package/docs/context-monitor.md +13 -0
- package/docs/decisions/ADR-0001-strategic-feature-prioritization.md +83 -0
- package/docs/decisions/ADR-0002-copilot-cli-runtime.md +71 -0
- package/docs/decisions/ADR-0003-smart-execution.md +84 -0
- package/docs/decisions/ADR-0004-copilot-cli-interaction.md +89 -0
- package/docs/decisions/ADR-0005-command-naming.md +80 -0
- package/docs/decisions/ADR-0006-focus-commands.md +101 -0
- package/docs/decisions/ADR-0007-ship-v1.md +73 -0
- package/docs/decisions/ADR-0008-map-codebase-mermaid-togaf.md +80 -0
- package/docs/decisions/ADR-0009-production-deployment-checklist.md +68 -0
- package/docs/decisions/ADR-0010-standards-integration.md +79 -0
- package/docs/decisions/ADR-0011-help-commands-rewrite.md +64 -0
- package/docs/decisions/ADR-0012-contributors-attribution-index.md +42 -0
- package/docs/decisions/ADR-0013-strategic-feature-additions.md +53 -0
- package/docs/decisions/ADR-0014-internal-cleanup-code-quality.md +53 -0
- package/docs/decisions/ADR-0015-focus-auto-runner.md +296 -0
- package/docs/decisions/ADR-0016-enhanced-doc-sync.md +54 -0
- package/docs/decisions/ADR-0017-enhanced-focus-design.md +69 -0
- package/docs/decisions/ADR-0018-user-reality-testing.md +84 -0
- package/docs/decisions/ADR-0019-end-to-end-user-acceptance-testing.md +113 -0
- package/docs/decisions/ADR-0020-ai-drift-prevention.md +55 -0
- package/docs/decisions/ADR-0021-codebase-mapper-v2.md +76 -0
- package/docs/decisions/ADR-0022-lifecycle-completeness.md +63 -0
- package/docs/decisions/ADR-0023-opus-4-7-adoption.md +89 -0
- package/docs/decisions/ADR-0024-spec-b-v2-completion.md +137 -0
- package/docs/decisions/ADR-0025-behavioral-guardrails-layer.md +129 -0
- package/docs/decisions/ADR-0026-self-improvement-loop.md +171 -0
- package/docs/decisions/ADR-0027-doc-code-link-graph.md +164 -0
- package/docs/decisions/ADR-0028-unified-agents-skills-target.md +46 -0
- package/docs/decisions/ADR-0029-experiment-evaluator.md +76 -0
- package/docs/decisions/ADR-0030-planning-concurrency.md +37 -0
- package/docs/decisions/ADR-0031-focus-auto-backlog-source.md +47 -0
- package/docs/decisions/ADR-0032-squad-model.md +64 -0
- package/docs/decisions/ADR-0033-army-campaign.md +40 -0
- package/docs/decisions/ADR-0034-scheduled-campaigns.md +57 -0
- package/docs/decisions/ADR-0035-army-hud-dashboard.md +40 -0
- package/docs/decisions/ADR-0036-agentic-memory-architecture.md +106 -0
- package/docs/decisions/ADR-0037-pin-security-agents-to-opus.md +51 -0
- package/docs/decisions/ADR-0038-skill-aligned-decomposition.md +41 -0
- package/docs/decisions/ADR-0039-worktree-as-project-variant.md +37 -0
- package/docs/decisions/ADR-0040-memory-injection-defense.md +55 -0
- package/docs/decisions/ADR-0041-mcp-dual-era-bridge.md +47 -0
- package/docs/decisions/ADR-0042-design-parity-both-flows.md +45 -0
- package/docs/decisions/ADR-0043-addressable-planning-roots.md +56 -0
- package/docs/decisions/ADR-0044-bound-the-cached-context.md +104 -0
- package/docs/decisions/ADR-0045-agent-plugins-bundle.md +76 -0
- package/docs/decisions/ADR-0046-subagent-frontmatter-decisions.md +39 -0
- package/docs/decisions/ADR-0047-pan-harness.md +76 -0
- package/docs/decisions/ADR-0048-one-core-per-project.md +43 -0
- package/docs/decisions/ADR-0049-machine-verdicts-and-findings-ledger.md +116 -0
- package/docs/specs/ai_drift_prevention_featureai.md +286 -0
- package/docs/specs/codebase_mapper_v2_featureai.md +930 -0
- package/docs/specs/command_naming_optimization_featureai.md +930 -0
- package/docs/specs/comp_analysis_markdown_v1.md +149 -0
- package/docs/specs/continuous_autonomous_execution_featureai.md +304 -0
- package/docs/specs/contributors_attribution_index_featureai.md +476 -0
- package/docs/specs/copilot_cli_interaction_featureai.md +868 -0
- package/docs/specs/copilot_cli_runtime_featureai.md +647 -0
- package/docs/specs/custom-skills-assessment.md +461 -0
- package/docs/specs/deployment_audit_findings_featureai.md +243 -0
- package/docs/specs/doc_code_link_graph_featureai.md +253 -0
- package/docs/specs/documentation_alignment_cleanup_featureai.md +69 -0
- package/docs/specs/e2e_visual_testing_featureai.md +615 -0
- package/docs/specs/end_to_end_user_acceptance_testing_featureai.md +810 -0
- package/docs/specs/evidence-loop-plan.md +76 -0
- package/docs/specs/evidence_loop_featureai.md +497 -0
- package/docs/specs/focus-auto-optimize-category.md +449 -0
- package/docs/specs/focus-auto-optimize-superplan.md +188 -0
- package/docs/specs/focus_auto_runner_featureai.md +1102 -0
- package/docs/specs/focus_design_v2_featureai.md +197 -0
- package/docs/specs/focus_sync_v2_featureai.md +202 -0
- package/docs/specs/git_integration_overhaul_featureai.md +326 -0
- package/docs/specs/glm_zai_provider_featureai.md +200 -0
- package/docs/specs/googlecli_adoption_featureai.md +661 -0
- package/docs/specs/help_commands_rewrite_featureai.md +860 -0
- package/docs/specs/industry_analysis_strategic_additions_featureai.md +231 -0
- package/docs/specs/industry_comparison_and_feature_gaps_featureai.md +674 -0
- package/docs/specs/internal_cleanup_code_quality_featureai.md +486 -0
- package/docs/specs/investigations/README.md +31 -0
- package/docs/specs/investigations/digests/2026-09-28.md +47 -0
- package/docs/specs/investigations/digests/2026-10-08.md +62 -0
- package/docs/specs/investigations/digests/2026-10-10.md +61 -0
- package/docs/specs/investigations/features/debugger-red-loop-first.md +55 -0
- package/docs/specs/investigations/features/harness-cross-host-behaviour.md +93 -0
- package/docs/specs/investigations/features/optimize-apply-regression-gate.md +66 -0
- package/docs/specs/investigations/features/reviewer-smell-baseline.md +57 -0
- package/docs/specs/investigations/features/trace-failure-capture.md +69 -0
- package/docs/specs/lifecycle_completeness_featureai.md +754 -0
- package/docs/specs/local-first-ci.md +42 -0
- package/docs/specs/map_codebase_mermaid_togaf_featureai.md +805 -0
- package/docs/specs/market-delta-2026-09-superplan.md +310 -0
- package/docs/specs/market-ideas-2026-09.md +131 -0
- package/docs/specs/market-ideas-2026-10.md +428 -0
- package/docs/specs/market-ideas-ledger.md +177 -0
- package/docs/specs/memory-optimization-2026-10.md +285 -0
- package/docs/specs/multi-track-planning-roots.md +143 -0
- package/docs/specs/multi_model_routing_featureai.md +687 -0
- package/docs/specs/multi_model_routing_superplan.md +197 -0
- package/docs/specs/opus_47_existing_enhancements_featureai.md +247 -0
- package/docs/specs/opus_47_extended_features_featureai.md +363 -0
- package/docs/specs/opus_47_extended_features_v2_featureai.md +397 -0
- package/docs/specs/pan_focus_commands_featureai.md +2336 -0
- package/docs/specs/pan_zcode_mcp_bridge_featureai.md +120 -0
- package/docs/specs/product-excellence-superplan.md +315 -0
- package/docs/specs/product_excellence_program_2026_q4_featureai.md +365 -0
- package/docs/specs/production_deployment_readiness_featureai.md +433 -0
- package/docs/specs/production_readiness_ship_v1_featureai.md +698 -0
- package/docs/specs/real_test_enforcement_featureai.md +213 -0
- package/docs/specs/reality-check-2026-09-superplan.md +362 -0
- package/docs/specs/right-sized-ceremony.md +74 -0
- package/docs/specs/roadmap_and_competition_2026_q4_featureai.md +390 -0
- package/docs/specs/self_improvement_loop_featureai.md +875 -0
- package/docs/specs/skill-aligned-decomposition.md +155 -0
- package/docs/specs/standards_integration_featureai.md +833 -0
- package/docs/specs/testing-system-redesign-2026-09.md +267 -0
- package/docs/specs/user_reality_testing_system_featureai.md +788 -0
- package/docs/specs/watch-triggers.json +22 -0
- package/docs/specs/workflow-integration-redesign.md +742 -0
- package/docs/specs/workflow_state_consistency_featureai.md +183 -0
- package/hooks/dist/pan-context-monitor.js +9 -2
- package/hooks/dist/pan-cost-logger.js +5 -0
- package/hooks/dist/pan-guard.js +28 -5
- package/hooks/dist/pan-stop-guard.js +9 -9
- package/hooks/dist/pan-trace-logger.js +5 -0
- package/package.json +10 -2
- package/pan-wizard-core/bin/lib/agents-md.cjs +57 -8
- package/pan-wizard-core/bin/lib/autodev-report.cjs +180 -0
- package/pan-wizard-core/bin/lib/autodev.cjs +642 -0
- package/pan-wizard-core/bin/lib/ci.cjs +143 -0
- package/pan-wizard-core/bin/lib/commands.cjs +1 -1
- package/pan-wizard-core/bin/lib/config.cjs +41 -5
- package/pan-wizard-core/bin/lib/constants.cjs +27 -1
- package/pan-wizard-core/bin/lib/core.cjs +31 -14
- package/pan-wizard-core/bin/lib/cost.cjs +160 -4
- package/pan-wizard-core/bin/lib/cross-family.cjs +164 -0
- package/pan-wizard-core/bin/lib/debug-cases.cjs +104 -0
- package/pan-wizard-core/bin/lib/doc-lint.cjs +5 -3
- package/pan-wizard-core/bin/lib/failure-class.cjs +81 -0
- package/pan-wizard-core/bin/lib/findings.cjs +148 -9
- package/pan-wizard-core/bin/lib/focus.cjs +1 -1
- package/pan-wizard-core/bin/lib/git.cjs +1 -1
- package/pan-wizard-core/bin/lib/hosts.cjs +88 -0
- package/pan-wizard-core/bin/lib/init.cjs +7 -2
- package/pan-wizard-core/bin/lib/knowledge.cjs +2 -0
- package/pan-wizard-core/bin/lib/merge.cjs +50 -0
- package/pan-wizard-core/bin/lib/mutate.cjs +268 -0
- package/pan-wizard-core/bin/lib/next-action.cjs +112 -0
- package/pan-wizard-core/bin/lib/optimize.cjs +2 -2
- package/pan-wizard-core/bin/lib/phase-gate.cjs +15 -9
- package/pan-wizard-core/bin/lib/phase-remove.cjs +91 -11
- package/pan-wizard-core/bin/lib/phase.cjs +85 -13
- package/pan-wizard-core/bin/lib/plan-lint.cjs +310 -0
- package/pan-wizard-core/bin/lib/preview.cjs +26 -4
- package/pan-wizard-core/bin/lib/requirements-lint.cjs +130 -0
- package/pan-wizard-core/bin/lib/research-lint.cjs +268 -0
- package/pan-wizard-core/bin/lib/review-deep.cjs +14 -22
- package/pan-wizard-core/bin/lib/review-vote.cjs +105 -0
- package/pan-wizard-core/bin/lib/roadmap.cjs +1 -0
- package/pan-wizard-core/bin/lib/runner.cjs +2 -16
- package/pan-wizard-core/bin/lib/sizing.cjs +356 -0
- package/pan-wizard-core/bin/lib/squads.cjs +1 -1
- package/pan-wizard-core/bin/lib/state-write.cjs +247 -0
- package/pan-wizard-core/bin/lib/test-gate.cjs +433 -0
- package/pan-wizard-core/bin/lib/uat.cjs +149 -0
- package/pan-wizard-core/bin/lib/usage.cjs +104 -0
- package/pan-wizard-core/bin/lib/verdict.cjs +26 -3
- package/pan-wizard-core/bin/lib/verify-plan-set.cjs +30 -1
- package/pan-wizard-core/bin/lib/verify-preflight.cjs +2 -2
- package/pan-wizard-core/bin/lib/verify-red.cjs +174 -0
- package/pan-wizard-core/bin/lib/verify-retro.cjs +3 -2
- package/pan-wizard-core/bin/lib/verify-scope.cjs +143 -2
- package/pan-wizard-core/bin/lib/verify.cjs +86 -31
- package/pan-wizard-core/bin/lib/worktree.cjs +70 -0
- package/pan-wizard-core/bin/pan-tools.cjs +257 -28
- package/pan-wizard-core/learnings/universal/autonomous-loop.md +2 -2
- package/pan-wizard-core/mcp/orchestrator.cjs +4 -1
- package/pan-wizard-core/references/continuation-format.md +3 -3
- package/pan-wizard-core/references/design-methodology.md +1 -1
- package/pan-wizard-core/references/guardrails.md +1 -1
- package/pan-wizard-core/references/handoff-decisions.md +1 -1
- package/pan-wizard-core/references/model-profiles.md +2 -3
- package/pan-wizard-core/references/questioning.md +24 -0
- package/pan-wizard-core/references/ui-brand.md +4 -6
- package/pan-wizard-core/references/verdict-contract.md +2 -1
- package/pan-wizard-core/templates/config.json +10 -2
- package/pan-wizard-core/templates/debug.md +1 -0
- package/pan-wizard-core/templates/design.md +5 -4
- package/pan-wizard-core/templates/discovery.md +2 -2
- package/pan-wizard-core/templates/phase-prompt.md +7 -0
- package/pan-wizard-core/templates/requirements.md +9 -0
- package/pan-wizard-core/templates/research.md +10 -0
- package/pan-wizard-core/templates/summary-complex.md +5 -1
- package/pan-wizard-core/templates/summary-minimal.md +4 -0
- package/pan-wizard-core/templates/summary-standard.md +5 -1
- package/pan-wizard-core/templates/summary.md +8 -1
- package/pan-wizard-core/workflows/add-phase.md +4 -6
- package/pan-wizard-core/workflows/assumptions.md +19 -1
- package/pan-wizard-core/workflows/diagnose-issues.md +2 -0
- package/pan-wizard-core/workflows/discuss-phase.md +4 -2
- package/pan-wizard-core/workflows/exec-lean.md +69 -0
- package/pan-wizard-core/workflows/exec-phase.md +79 -15
- package/pan-wizard-core/workflows/execute-plan.md +3 -1
- package/{commands/pan → pan-wizard-core/workflows}/focus-doc-audit.md +13 -29
- package/{commands/pan → pan-wizard-core/workflows}/focus-drift-walking.md +3 -18
- package/{commands/pan → pan-wizard-core/workflows}/focus-exec.md +8 -23
- package/{commands/pan → pan-wizard-core/workflows}/focus-plan.md +6 -20
- package/{commands/pan → pan-wizard-core/workflows}/focus-scan.md +3 -16
- package/{commands/pan → pan-wizard-core/workflows}/focus-sync.md +7 -21
- package/pan-wizard-core/workflows/health.md +6 -0
- package/pan-wizard-core/workflows/help.md +114 -77
- package/pan-wizard-core/workflows/insert-phase.md +4 -6
- package/pan-wizard-core/workflows/learn.md +3 -3
- package/pan-wizard-core/workflows/milestone-audit.md +2 -2
- package/pan-wizard-core/workflows/milestone-new.md +38 -95
- package/pan-wizard-core/workflows/new-project.md +96 -258
- package/pan-wizard-core/workflows/optimize.md +107 -5
- package/pan-wizard-core/workflows/phase-tests.md +10 -0
- package/pan-wizard-core/workflows/plan-phase.md +106 -45
- package/pan-wizard-core/workflows/profile.md +50 -0
- package/pan-wizard-core/workflows/progress.md +10 -0
- package/pan-wizard-core/workflows/quick.md +34 -43
- package/pan-wizard-core/workflows/remove-phase.md +11 -1
- package/pan-wizard-core/workflows/research-phase.md +118 -40
- package/pan-wizard-core/workflows/resume-project.md +18 -2
- package/pan-wizard-core/workflows/settings.md +33 -19
- package/pan-wizard-core/workflows/todo-check.md +6 -2
- package/pan-wizard-core/workflows/transition.md +22 -4
- package/pan-wizard-core/workflows/uat-walkthrough.md +90 -0
- package/pan-wizard-core/workflows/update.md +1 -1
- package/pan-wizard-core/workflows/verify-phase.md +39 -46
- package/scripts/build-agent-plugin.js +35 -15
- package/scripts/build-help.cjs +106 -0
- package/scripts/build-plugin.js +10 -1
- package/scripts/deprecate-old-versions.js +70 -3
- package/scripts/generate-skills-docs.py +1 -1
- package/scripts/git-hooks/pre-push +27 -0
- package/scripts/install-git-hooks.js +7 -5
- package/scripts/install-pre-push.cjs +38 -0
- package/scripts/land.cjs +151 -0
- package/scripts/local-ci.cjs +501 -0
- package/scripts/local-schedule.cjs +277 -0
- package/scripts/mutation-probe.cjs +7 -80
- package/scripts/prompt-lint.cjs +32 -0
- package/scripts/prompt-rules.cjs +156 -0
- package/scripts/run-tests.cjs +7 -1
- package/scripts/test-quality-lint.cjs +3 -3
- package/scripts/test-surface.cjs +175 -6
- package/agents/pan-research-synthesizer.md +0 -246
- package/commands/pan/audit-deployment.md +0 -386
- package/commands/pan/dashboard.md +0 -22
- package/commands/pan/discord.md +0 -19
- package/commands/pan/mcp-bridge.md +0 -143
- package/commands/pan/milestone-cleanup.md +0 -19
- package/commands/pan/milestone-gaps.md +0 -35
- package/commands/pan/optimize.md +0 -115
- package/commands/pan/profile.md +0 -76
- package/commands/pan/research-phase.md +0 -189
- package/pan-wizard-core/bin/lib/bridge.cjs +0 -269
- package/pan-wizard-core/templates/research-project/architecture.md +0 -204
- package/pan-wizard-core/templates/research-project/features.md +0 -147
- package/pan-wizard-core/templates/research-project/pitfalls.md +0 -200
- package/pan-wizard-core/templates/research-project/stack.md +0 -120
- package/pan-wizard-core/templates/research-project/summary.md +0 -170
|
@@ -168,6 +168,36 @@ function checkCheckpointTask(type, attrs, body, errors, warnings) {
|
|
|
168
168
|
return { name: label, type, auto_select: autoMatch ? autoMatch[1] : null };
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
// The elements a plan nests. A file that ends with one of them still open was cut
|
|
172
|
+
// off: runtimes cap tool output, and a long plan has been truncated mid-tag while
|
|
173
|
+
// the write reported success (market-ideas M47; gsd-core v1.18.0).
|
|
174
|
+
const PLAN_TAGS = ['tasks', 'task', 'name', 'files', 'action', 'verify', 'done'];
|
|
175
|
+
const TRUNCATION_MARKER = /\[\s*\.{0,3}\s*(?:output\s+)?truncated\b|<!--\s*(?:continue|continued|truncated)\b|\(output truncated\)|\bcontinued in next (?:message|write)\b/i;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Signs that a plan file was cut off. Pure; tags inside fenced code blocks do not count.
|
|
179
|
+
* @param {string} content - plan file content
|
|
180
|
+
* @returns {string[]} one message per problem, empty when the file is whole
|
|
181
|
+
*/
|
|
182
|
+
function detectPlanTruncation(content) {
|
|
183
|
+
const text = String(content || '').replace(/\r\n/g, '\n').replace(/^(`{3,}|~{3,})[^\n]*\n[\s\S]*?^\1[ \t]*$/gm, '');
|
|
184
|
+
const out = [];
|
|
185
|
+
const open = [];
|
|
186
|
+
const tagRe = new RegExp(`<(/?)(${PLAN_TAGS.join('|')})\\b[^>]*?(/?)>`, 'g');
|
|
187
|
+
let m;
|
|
188
|
+
while ((m = tagRe.exec(text)) !== null) {
|
|
189
|
+
const [, closing, tag, selfClosing] = m;
|
|
190
|
+
if (selfClosing) continue;
|
|
191
|
+
if (!closing) { open.push(tag); continue; }
|
|
192
|
+
const at = open.lastIndexOf(tag);
|
|
193
|
+
if (at >= 0) open.splice(at);
|
|
194
|
+
}
|
|
195
|
+
if (open.length) out.push(`Plan looks truncated: the file ends with ${open.map((t) => `<${t}>`).join(' > ')} still open`);
|
|
196
|
+
const marker = text.match(TRUNCATION_MARKER);
|
|
197
|
+
if (marker) out.push(`Plan looks truncated: it contains a continuation marker ("${marker[0].trim()}")`);
|
|
198
|
+
return out;
|
|
199
|
+
}
|
|
200
|
+
|
|
171
201
|
/**
|
|
172
202
|
* Validate a plan.md structure: required frontmatter, task elements, and consistency.
|
|
173
203
|
* @param {string} cwd - Working directory path
|
|
@@ -180,11 +210,19 @@ function cmdVerifyPlanStructure(cwd, filePath, raw) {
|
|
|
180
210
|
const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);
|
|
181
211
|
const content = safeReadFile(fullPath);
|
|
182
212
|
if (!content) { output({ error: 'File not found', path: filePath }, raw); return; }
|
|
213
|
+
const r = planStructure(content);
|
|
214
|
+
output(r, raw, r.valid ? 'valid' : 'invalid');
|
|
215
|
+
}
|
|
183
216
|
|
|
217
|
+
/** A plan's structure check (cmdVerifyPlanStructure without the output). Pure. */
|
|
218
|
+
function planStructure(content) {
|
|
184
219
|
const fm = extractFrontmatter(content);
|
|
185
220
|
const errors = [];
|
|
186
221
|
const warnings = [];
|
|
187
222
|
|
|
223
|
+
// A cut-off plan first: its task count and fields would mislead (M47).
|
|
224
|
+
errors.push(...detectPlanTruncation(content));
|
|
225
|
+
|
|
188
226
|
// Check required frontmatter fields
|
|
189
227
|
const required = ['phase', 'plan', 'type', 'wave', 'depends_on', 'files_modified', 'autonomous', 'must_haves'];
|
|
190
228
|
for (const field of required) {
|
|
@@ -246,14 +284,14 @@ function cmdVerifyPlanStructure(cwd, filePath, raw) {
|
|
|
246
284
|
errors.push('Has checkpoint tasks but autonomous is not false');
|
|
247
285
|
}
|
|
248
286
|
|
|
249
|
-
|
|
287
|
+
return {
|
|
250
288
|
valid: errors.length === 0,
|
|
251
289
|
errors,
|
|
252
290
|
warnings,
|
|
253
291
|
task_count: tasks.length,
|
|
254
292
|
tasks,
|
|
255
293
|
frontmatter_fields: Object.keys(fm),
|
|
256
|
-
}
|
|
294
|
+
};
|
|
257
295
|
}
|
|
258
296
|
|
|
259
297
|
/**
|
|
@@ -572,8 +610,31 @@ function reconcilePhase(cwd, phaseNum) {
|
|
|
572
610
|
contradictions.push(`verification status "${status}" but ${keyLinks.total - keyLinks.verified}/${keyLinks.total} key-link(s) UNWIRED`);
|
|
573
611
|
}
|
|
574
612
|
}
|
|
613
|
+
// The engine's test run (V2) is the record the verifier copies its test gate from: a
|
|
614
|
+
// verification that says otherwise, or passes over a failed run, contradicts it.
|
|
615
|
+
const testRun = require('./test-gate.cjs').readTestRun(cwd, phaseNum);
|
|
616
|
+
const writtenGate = (verRaw.match(/^test_gate:\s*([A-Za-z_]+)/m) || [])[1] || null;
|
|
617
|
+
if (testRun && testRun.status) {
|
|
618
|
+
const why = testRun.reason ? ` (${testRun.reason})` : '';
|
|
619
|
+
if (writtenGate && writtenGate.toLowerCase() !== testRun.status) {
|
|
620
|
+
contradictions.push(`verification test_gate "${writtenGate}" but the engine's test run recorded "${testRun.status}"${why}`);
|
|
621
|
+
} else if (!writtenGate && claimsPass && testRun.status === 'failed') {
|
|
622
|
+
contradictions.push(`verification status "${status}" but the engine's test run failed${why}`);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
// V5G: in gate mode, a mutation score below the floor means the tests do not pin the
|
|
626
|
+
// code, so a passed verification is a contradiction until they do.
|
|
627
|
+
const mutFile = files.find((f) => /-mutation\.json$/.test(f));
|
|
628
|
+
if (claimsPass && mutFile) {
|
|
629
|
+
let mut = null;
|
|
630
|
+
try { mut = JSON.parse(safeReadFile(path.join(dir, mutFile)) || 'null'); } catch {}
|
|
631
|
+
if (mut && mut.mode === 'gate' && mut.gate && mut.gate.failed) {
|
|
632
|
+
contradictions.push(`verification status "${status}" but the mutation score ${mut.score} is below the floor ${mut.gate.floor} (workflow.mutation_gate: gate): ${mut.survived} of ${mut.sampled} mutants survived`);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
575
635
|
return {
|
|
576
636
|
phase: String(phaseNum), found: true, verification_status: status, claims_pass: claimsPass,
|
|
637
|
+
test_run: testRun ? { status: testRun.status, head: testRun.head || null, regressions: (testRun.regressions || []).length } : undefined,
|
|
577
638
|
mechanical_signals: signals, artifacts, key_links: keyLinks, contradictions,
|
|
578
639
|
reconciled: contradictions.length === 0,
|
|
579
640
|
note: signals === 0 ? 'no must_haves declared — mechanical reconciliation unavailable; verdict trusted' : undefined,
|
|
@@ -1460,9 +1521,13 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1460
1521
|
}
|
|
1461
1522
|
|
|
1462
1523
|
// Perform repairs if requested and there are repairable issues
|
|
1524
|
+
// L6a: health asks per repair class. Without --repair the result lists the classes;
|
|
1525
|
+
// --only limits a repair to the ones the user chose.
|
|
1526
|
+
const only = Array.isArray(options.only) && options.only.length ? new Set(options.only) : null;
|
|
1527
|
+
const chosen = only ? repairs.filter((r) => only.has(r)) : repairs;
|
|
1463
1528
|
let repairActions = [];
|
|
1464
|
-
if (options.repair &&
|
|
1465
|
-
repairActions = repairIssues(cwd,
|
|
1529
|
+
if (options.repair && chosen.length > 0) {
|
|
1530
|
+
repairActions = repairIssues(cwd, chosen);
|
|
1466
1531
|
}
|
|
1467
1532
|
|
|
1468
1533
|
// Check 10 (optional): full validation — run tests and build
|
|
@@ -1535,6 +1600,7 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1535
1600
|
warnings,
|
|
1536
1601
|
info,
|
|
1537
1602
|
repairable_count: repairableCount,
|
|
1603
|
+
repairs_available: repairs.length > 0 ? [...new Set(repairs)] : undefined,
|
|
1538
1604
|
repairs_performed: repairActions.length > 0 ? repairActions : undefined,
|
|
1539
1605
|
};
|
|
1540
1606
|
if (options.full) {
|
|
@@ -1557,35 +1623,22 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
1557
1623
|
}
|
|
1558
1624
|
|
|
1559
1625
|
/**
|
|
1560
|
-
* Run
|
|
1626
|
+
* Run the project's tests through the engine's test gate (V2): any language, the
|
|
1627
|
+
* project's own command, and a crash reads failed. `pass` is null when there was nothing
|
|
1628
|
+
* to run (no test command, or one that ran no tests).
|
|
1561
1629
|
*/
|
|
1562
1630
|
function runFullTestCheck(cwd) {
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
const passMatch = result.match(/[#ℹ]\s*pass\s+(\d+)/);
|
|
1575
|
-
return {
|
|
1576
|
-
pass: true,
|
|
1577
|
-
exitCode: 0,
|
|
1578
|
-
tests: testMatch ? parseInt(testMatch[1], 10) : null,
|
|
1579
|
-
passing: passMatch ? parseInt(passMatch[1], 10) : null,
|
|
1580
|
-
};
|
|
1581
|
-
} catch (err) {
|
|
1582
|
-
return {
|
|
1583
|
-
pass: false,
|
|
1584
|
-
exitCode: err.status || 1,
|
|
1585
|
-
tests: null,
|
|
1586
|
-
passing: null,
|
|
1587
|
-
};
|
|
1588
|
-
}
|
|
1631
|
+
const rec = require('./test-gate.cjs').runTests(cwd, { timeoutMs: 120000 });
|
|
1632
|
+
return {
|
|
1633
|
+
pass: rec.status === 'passed' ? true : (rec.status === 'failed' ? false : null),
|
|
1634
|
+
exitCode: rec.exit,
|
|
1635
|
+
tests: rec.total,
|
|
1636
|
+
passing: rec.passed,
|
|
1637
|
+
status: rec.status,
|
|
1638
|
+
command: rec.command,
|
|
1639
|
+
reason: rec.reason || undefined,
|
|
1640
|
+
failing: rec.failing && rec.failing.length ? rec.failing.slice(0, 20) : undefined,
|
|
1641
|
+
};
|
|
1589
1642
|
}
|
|
1590
1643
|
|
|
1591
1644
|
/**
|
|
@@ -1623,8 +1676,10 @@ function runFullBuildCheck(cwd) {
|
|
|
1623
1676
|
// ─── Deployment validation — extracted to verify-deploy.cjs (re-exported below)
|
|
1624
1677
|
|
|
1625
1678
|
module.exports = {
|
|
1679
|
+
planStructure,
|
|
1626
1680
|
cmdVerifySummary,
|
|
1627
1681
|
cmdVerifyPlanStructure,
|
|
1682
|
+
detectPlanTruncation,
|
|
1628
1683
|
cmdVerifyPhaseCompleteness,
|
|
1629
1684
|
cmdVerifyReferences,
|
|
1630
1685
|
cmdVerifyCommits,
|
|
@@ -208,7 +208,77 @@ function cmdWorktreeCleanup(cwd, raw, opts) {
|
|
|
208
208
|
output(r, raw, lines.length ? lines.join('\n') : 'nothing to clean');
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
// ─── Shadow-merge preflight (program A3) ────────────────────────────────────
|
|
212
|
+
// Branches that each pass the oracle can still break it together. Before merging a
|
|
213
|
+
// sub-wave back, merge every branch onto the base in a throwaway worktree, in order,
|
|
214
|
+
// and run the test command there. A conflict is named; a red result is bisected to
|
|
215
|
+
// "each passes alone" (break_together) or the branches that fail on their own.
|
|
216
|
+
|
|
217
|
+
const GIT_IDENTITY = ['-c', 'user.name=PAN preflight', '-c', 'user.email=preflight@pan.local', '-c', 'commit.gpgsign=false'];
|
|
218
|
+
|
|
219
|
+
function runOracle(dir, test) {
|
|
220
|
+
const { spawnSync } = require('child_process');
|
|
221
|
+
const r = spawnSync(test, { cwd: dir, shell: true, encoding: 'utf8', timeout: 20 * 60 * 1000 });
|
|
222
|
+
return r.status === 0;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @param {string} cwd
|
|
227
|
+
* @param {{base?: string, branches: string[], test?: string}} opts
|
|
228
|
+
* @returns {{ok: boolean, verdict: 'clean'|'conflict'|'break_together'|'branch_fails'|'base_failing'|'no_test', ...}}
|
|
229
|
+
*/
|
|
230
|
+
function shadowMergePreflight(cwd, opts = {}) {
|
|
231
|
+
if (!isGitRepo(cwd)) return { error: 'not_git', reason: 'the preflight needs a git repository' };
|
|
232
|
+
const base = opts.base || 'HEAD';
|
|
233
|
+
const branches = (opts.branches || []).filter(Boolean);
|
|
234
|
+
let test = opts.test;
|
|
235
|
+
if (!test) {
|
|
236
|
+
try { test = require('./test-gate.cjs').detectTestCommand(cwd).command; } catch { test = null; }
|
|
237
|
+
}
|
|
238
|
+
if (!test) return { ok: false, verdict: 'no_test', base, branches, reason: 'no test command: pass --test or set one for the project' };
|
|
239
|
+
const os = require('os');
|
|
240
|
+
const fsx = require('fs');
|
|
241
|
+
const dir = fsx.mkdtempSync(path.join(os.tmpdir(), 'pan-preflight-'));
|
|
242
|
+
fsx.rmSync(dir, { recursive: true, force: true });
|
|
243
|
+
const add = execGit(cwd, ['worktree', 'add', '--detach', dir, base]);
|
|
244
|
+
if (add.exitCode !== 0) return { error: 'worktree_failed', reason: add.stderr.trim() };
|
|
245
|
+
const g = (args) => execGit(dir, [...GIT_IDENTITY, ...args]);
|
|
246
|
+
const result = { base, branches, test, merged: [], alone: {} };
|
|
247
|
+
try {
|
|
248
|
+
if (!runOracle(dir, test)) return { ...result, ok: false, verdict: 'base_failing', reason: 'the oracle already fails on the base: a merge cannot be judged' };
|
|
249
|
+
for (const b of branches) {
|
|
250
|
+
const m = g(['merge', '--no-ff', '--no-edit', b]);
|
|
251
|
+
if (m.exitCode !== 0) {
|
|
252
|
+
const files = g(['diff', '--name-only', '--diff-filter=U']).stdout.split('\n').map((x) => x.trim()).filter(Boolean);
|
|
253
|
+
g(['merge', '--abort']);
|
|
254
|
+
return { ...result, ok: false, verdict: 'conflict', conflict: { branch: b, files, after: [...result.merged] } };
|
|
255
|
+
}
|
|
256
|
+
result.merged.push(b);
|
|
257
|
+
}
|
|
258
|
+
if (runOracle(dir, test)) return { ...result, ok: true, verdict: 'clean' };
|
|
259
|
+
for (const b of branches) {
|
|
260
|
+
g(['reset', '--hard', '-q', base]);
|
|
261
|
+
result.alone[b] = g(['merge', '--no-ff', '--no-edit', b]).exitCode === 0 && runOracle(dir, test);
|
|
262
|
+
}
|
|
263
|
+
const failing = branches.filter((b) => !result.alone[b]);
|
|
264
|
+
return failing.length
|
|
265
|
+
? { ...result, ok: false, verdict: 'branch_fails', failing }
|
|
266
|
+
: { ...result, ok: false, verdict: 'break_together', reason: 'each branch passes alone; merged together they fail' };
|
|
267
|
+
} finally {
|
|
268
|
+
execGit(cwd, ['worktree', 'remove', '--force', dir]);
|
|
269
|
+
try { fsx.rmSync(dir, { recursive: true, force: true }); } catch {}
|
|
270
|
+
execGit(cwd, ['worktree', 'prune']);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function cmdWorktreePreflight(cwd, opts, raw) {
|
|
275
|
+
const r = shadowMergePreflight(cwd, opts);
|
|
276
|
+
output(r, raw, r.verdict || r.error);
|
|
277
|
+
}
|
|
278
|
+
|
|
211
279
|
module.exports = {
|
|
280
|
+
shadowMergePreflight,
|
|
281
|
+
cmdWorktreePreflight,
|
|
212
282
|
ARMY_BRANCH_PREFIX,
|
|
213
283
|
createTaskWorktree,
|
|
214
284
|
removeTaskWorktree,
|