pan-wizard 3.36.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.
Files changed (314) hide show
  1. package/CHANGELOG.md +3645 -0
  2. package/README.md +36 -48
  3. package/agents/pan-conductor.md +2 -3
  4. package/agents/pan-counterfactual.md +1 -2
  5. package/agents/pan-debugger.md +14 -3
  6. package/agents/pan-design-checker.md +1 -2
  7. package/agents/pan-designer.md +1 -2
  8. package/agents/pan-document_code.md +1 -2
  9. package/agents/pan-hardener.md +2 -3
  10. package/agents/pan-integration-checker.md +1 -2
  11. package/agents/pan-knowledge.md +1 -2
  12. package/agents/pan-meta-reviewer.md +3 -3
  13. package/agents/pan-optimizer.md +4 -4
  14. package/agents/pan-phase-researcher.md +79 -488
  15. package/agents/pan-plan-checker.md +12 -2
  16. package/agents/pan-planner.md +10 -6
  17. package/agents/pan-previewer.md +1 -2
  18. package/agents/pan-project-researcher.md +70 -499
  19. package/agents/pan-release.md +1 -1
  20. package/agents/pan-reviewer.md +9 -3
  21. package/agents/pan-roadmapper.md +12 -7
  22. package/agents/pan-verifier.md +7 -2
  23. package/bin/install-lib.cjs +134 -14
  24. package/bin/install.js +59 -12
  25. package/commands/pan/army.md +1 -1
  26. package/commands/pan/autodev.md +76 -0
  27. package/commands/pan/exec-phase.md +3 -4
  28. package/commands/pan/focus-auto.md +14 -7
  29. package/commands/pan/focus-design.md +4 -5
  30. package/commands/pan/focus-docs.md +24 -0
  31. package/commands/pan/learn.md +13 -6
  32. package/commands/pan/milestone-audit.md +8 -1
  33. package/commands/pan/milestone-done.md +10 -5
  34. package/commands/pan/milestone-new.md +2 -2
  35. package/commands/pan/new-project.md +15 -12
  36. package/commands/pan/plan-phase.md +15 -9
  37. package/commands/pan/quick.md +1 -1
  38. package/commands/pan/review-deep.md +11 -5
  39. package/commands/pan/settings.md +6 -0
  40. package/commands/pan/verify-phase.md +6 -2
  41. package/docs/AGENTS.md +917 -0
  42. package/docs/ARCHITECTURE.md +1054 -0
  43. package/docs/CLI-REFERENCE.md +4582 -0
  44. package/docs/COMPARISON.md +116 -0
  45. package/docs/DEVELOPMENT.md +490 -0
  46. package/docs/ECOSYSTEM-REVIEW-2026-06.md +107 -0
  47. package/docs/ECOSYSTEM-REVIEW-2026-08.md +349 -0
  48. package/docs/EXAMPLES.md +584 -0
  49. package/docs/FAQ.md +254 -0
  50. package/docs/FIELD-HARVEST-2026-07.md +88 -0
  51. package/docs/FIELD-REPORT-army-2026-06.md +121 -0
  52. package/docs/HOOKS.md +638 -0
  53. package/docs/IMPROVEMENT-TODO.md +246 -0
  54. package/docs/INTERNALS.md +485 -0
  55. package/docs/MIGRATION-v2-to-v3.md +258 -0
  56. package/docs/SECURITY-HARDENING.md +230 -0
  57. package/docs/SKILLS-ENHANCEMENT-PLAN-V2.md +122 -0
  58. package/docs/SKILLS-FULL-TEXT.md +9685 -0
  59. package/docs/SKILLS-REFERENCE.md +1037 -0
  60. package/docs/TROUBLESHOOTING.md +1084 -0
  61. package/docs/USER-GUIDE.md +1437 -0
  62. package/docs/archive/SKILLS-ENHANCEMENT-PLAN.md +230 -0
  63. package/docs/audits/AUDIT-2026-08-e2e-ROADMAP.md +117 -0
  64. package/docs/audits/AUDIT-2026-08-e2e-VERIFICATION.md +693 -0
  65. package/docs/audits/AUDIT-2026-08-e2e.md +1546 -0
  66. package/docs/audits/OUTSTANDING-2026-08.md +275 -0
  67. package/docs/audits/STABILITY-TEST-2026-08.md +640 -0
  68. package/docs/branding/README-brand-draft.md +119 -0
  69. package/docs/branding/handoff/IMPLEMENTATION.md +205 -0
  70. package/docs/branding/handoff/README-brand-draft.md +119 -0
  71. package/docs/branding/handoff/image-prompts.md +46 -0
  72. package/docs/branding/image-prompts.md +46 -0
  73. package/docs/branding/nano-banana-prompts.txt +60 -0
  74. package/docs/context-monitor.md +13 -0
  75. package/docs/decisions/ADR-0001-strategic-feature-prioritization.md +83 -0
  76. package/docs/decisions/ADR-0002-copilot-cli-runtime.md +71 -0
  77. package/docs/decisions/ADR-0003-smart-execution.md +84 -0
  78. package/docs/decisions/ADR-0004-copilot-cli-interaction.md +89 -0
  79. package/docs/decisions/ADR-0005-command-naming.md +80 -0
  80. package/docs/decisions/ADR-0006-focus-commands.md +101 -0
  81. package/docs/decisions/ADR-0007-ship-v1.md +73 -0
  82. package/docs/decisions/ADR-0008-map-codebase-mermaid-togaf.md +80 -0
  83. package/docs/decisions/ADR-0009-production-deployment-checklist.md +68 -0
  84. package/docs/decisions/ADR-0010-standards-integration.md +79 -0
  85. package/docs/decisions/ADR-0011-help-commands-rewrite.md +64 -0
  86. package/docs/decisions/ADR-0012-contributors-attribution-index.md +42 -0
  87. package/docs/decisions/ADR-0013-strategic-feature-additions.md +53 -0
  88. package/docs/decisions/ADR-0014-internal-cleanup-code-quality.md +53 -0
  89. package/docs/decisions/ADR-0015-focus-auto-runner.md +296 -0
  90. package/docs/decisions/ADR-0016-enhanced-doc-sync.md +54 -0
  91. package/docs/decisions/ADR-0017-enhanced-focus-design.md +69 -0
  92. package/docs/decisions/ADR-0018-user-reality-testing.md +84 -0
  93. package/docs/decisions/ADR-0019-end-to-end-user-acceptance-testing.md +113 -0
  94. package/docs/decisions/ADR-0020-ai-drift-prevention.md +55 -0
  95. package/docs/decisions/ADR-0021-codebase-mapper-v2.md +76 -0
  96. package/docs/decisions/ADR-0022-lifecycle-completeness.md +63 -0
  97. package/docs/decisions/ADR-0023-opus-4-7-adoption.md +89 -0
  98. package/docs/decisions/ADR-0024-spec-b-v2-completion.md +137 -0
  99. package/docs/decisions/ADR-0025-behavioral-guardrails-layer.md +129 -0
  100. package/docs/decisions/ADR-0026-self-improvement-loop.md +171 -0
  101. package/docs/decisions/ADR-0027-doc-code-link-graph.md +164 -0
  102. package/docs/decisions/ADR-0028-unified-agents-skills-target.md +46 -0
  103. package/docs/decisions/ADR-0029-experiment-evaluator.md +76 -0
  104. package/docs/decisions/ADR-0030-planning-concurrency.md +37 -0
  105. package/docs/decisions/ADR-0031-focus-auto-backlog-source.md +47 -0
  106. package/docs/decisions/ADR-0032-squad-model.md +64 -0
  107. package/docs/decisions/ADR-0033-army-campaign.md +40 -0
  108. package/docs/decisions/ADR-0034-scheduled-campaigns.md +57 -0
  109. package/docs/decisions/ADR-0035-army-hud-dashboard.md +40 -0
  110. package/docs/decisions/ADR-0036-agentic-memory-architecture.md +106 -0
  111. package/docs/decisions/ADR-0037-pin-security-agents-to-opus.md +51 -0
  112. package/docs/decisions/ADR-0038-skill-aligned-decomposition.md +41 -0
  113. package/docs/decisions/ADR-0039-worktree-as-project-variant.md +37 -0
  114. package/docs/decisions/ADR-0040-memory-injection-defense.md +55 -0
  115. package/docs/decisions/ADR-0041-mcp-dual-era-bridge.md +47 -0
  116. package/docs/decisions/ADR-0042-design-parity-both-flows.md +45 -0
  117. package/docs/decisions/ADR-0043-addressable-planning-roots.md +56 -0
  118. package/docs/decisions/ADR-0044-bound-the-cached-context.md +104 -0
  119. package/docs/decisions/ADR-0045-agent-plugins-bundle.md +76 -0
  120. package/docs/decisions/ADR-0046-subagent-frontmatter-decisions.md +39 -0
  121. package/docs/decisions/ADR-0047-pan-harness.md +76 -0
  122. package/docs/decisions/ADR-0048-one-core-per-project.md +43 -0
  123. package/docs/decisions/ADR-0049-machine-verdicts-and-findings-ledger.md +116 -0
  124. package/docs/specs/ai_drift_prevention_featureai.md +286 -0
  125. package/docs/specs/codebase_mapper_v2_featureai.md +930 -0
  126. package/docs/specs/command_naming_optimization_featureai.md +930 -0
  127. package/docs/specs/comp_analysis_markdown_v1.md +149 -0
  128. package/docs/specs/continuous_autonomous_execution_featureai.md +304 -0
  129. package/docs/specs/contributors_attribution_index_featureai.md +476 -0
  130. package/docs/specs/copilot_cli_interaction_featureai.md +868 -0
  131. package/docs/specs/copilot_cli_runtime_featureai.md +647 -0
  132. package/docs/specs/custom-skills-assessment.md +461 -0
  133. package/docs/specs/deployment_audit_findings_featureai.md +243 -0
  134. package/docs/specs/doc_code_link_graph_featureai.md +253 -0
  135. package/docs/specs/documentation_alignment_cleanup_featureai.md +69 -0
  136. package/docs/specs/e2e_visual_testing_featureai.md +615 -0
  137. package/docs/specs/end_to_end_user_acceptance_testing_featureai.md +810 -0
  138. package/docs/specs/evidence-loop-plan.md +76 -0
  139. package/docs/specs/evidence_loop_featureai.md +497 -0
  140. package/docs/specs/focus-auto-optimize-category.md +449 -0
  141. package/docs/specs/focus-auto-optimize-superplan.md +188 -0
  142. package/docs/specs/focus_auto_runner_featureai.md +1102 -0
  143. package/docs/specs/focus_design_v2_featureai.md +197 -0
  144. package/docs/specs/focus_sync_v2_featureai.md +202 -0
  145. package/docs/specs/git_integration_overhaul_featureai.md +326 -0
  146. package/docs/specs/glm_zai_provider_featureai.md +200 -0
  147. package/docs/specs/googlecli_adoption_featureai.md +661 -0
  148. package/docs/specs/help_commands_rewrite_featureai.md +860 -0
  149. package/docs/specs/industry_analysis_strategic_additions_featureai.md +231 -0
  150. package/docs/specs/industry_comparison_and_feature_gaps_featureai.md +674 -0
  151. package/docs/specs/internal_cleanup_code_quality_featureai.md +486 -0
  152. package/docs/specs/investigations/README.md +31 -0
  153. package/docs/specs/investigations/digests/2026-09-28.md +47 -0
  154. package/docs/specs/investigations/digests/2026-10-08.md +62 -0
  155. package/docs/specs/investigations/digests/2026-10-10.md +61 -0
  156. package/docs/specs/investigations/features/debugger-red-loop-first.md +55 -0
  157. package/docs/specs/investigations/features/harness-cross-host-behaviour.md +93 -0
  158. package/docs/specs/investigations/features/optimize-apply-regression-gate.md +66 -0
  159. package/docs/specs/investigations/features/reviewer-smell-baseline.md +57 -0
  160. package/docs/specs/investigations/features/trace-failure-capture.md +69 -0
  161. package/docs/specs/lifecycle_completeness_featureai.md +754 -0
  162. package/docs/specs/local-first-ci.md +42 -0
  163. package/docs/specs/map_codebase_mermaid_togaf_featureai.md +805 -0
  164. package/docs/specs/market-delta-2026-09-superplan.md +310 -0
  165. package/docs/specs/market-ideas-2026-09.md +131 -0
  166. package/docs/specs/market-ideas-2026-10.md +428 -0
  167. package/docs/specs/market-ideas-ledger.md +177 -0
  168. package/docs/specs/memory-optimization-2026-10.md +285 -0
  169. package/docs/specs/multi-track-planning-roots.md +143 -0
  170. package/docs/specs/multi_model_routing_featureai.md +687 -0
  171. package/docs/specs/multi_model_routing_superplan.md +197 -0
  172. package/docs/specs/opus_47_existing_enhancements_featureai.md +247 -0
  173. package/docs/specs/opus_47_extended_features_featureai.md +363 -0
  174. package/docs/specs/opus_47_extended_features_v2_featureai.md +397 -0
  175. package/docs/specs/pan_focus_commands_featureai.md +2336 -0
  176. package/docs/specs/pan_zcode_mcp_bridge_featureai.md +120 -0
  177. package/docs/specs/product-excellence-superplan.md +315 -0
  178. package/docs/specs/product_excellence_program_2026_q4_featureai.md +365 -0
  179. package/docs/specs/production_deployment_readiness_featureai.md +433 -0
  180. package/docs/specs/production_readiness_ship_v1_featureai.md +698 -0
  181. package/docs/specs/real_test_enforcement_featureai.md +213 -0
  182. package/docs/specs/reality-check-2026-09-superplan.md +362 -0
  183. package/docs/specs/right-sized-ceremony.md +74 -0
  184. package/docs/specs/roadmap_and_competition_2026_q4_featureai.md +390 -0
  185. package/docs/specs/self_improvement_loop_featureai.md +875 -0
  186. package/docs/specs/skill-aligned-decomposition.md +155 -0
  187. package/docs/specs/standards_integration_featureai.md +833 -0
  188. package/docs/specs/testing-system-redesign-2026-09.md +267 -0
  189. package/docs/specs/user_reality_testing_system_featureai.md +788 -0
  190. package/docs/specs/watch-triggers.json +22 -0
  191. package/docs/specs/workflow-integration-redesign.md +742 -0
  192. package/docs/specs/workflow_state_consistency_featureai.md +183 -0
  193. package/hooks/dist/pan-context-monitor.js +9 -2
  194. package/hooks/dist/pan-cost-logger.js +5 -0
  195. package/hooks/dist/pan-guard.js +28 -5
  196. package/hooks/dist/pan-stop-guard.js +9 -9
  197. package/hooks/dist/pan-trace-logger.js +5 -0
  198. package/package.json +10 -2
  199. package/pan-wizard-core/bin/lib/agents-md.cjs +57 -8
  200. package/pan-wizard-core/bin/lib/autodev-report.cjs +180 -0
  201. package/pan-wizard-core/bin/lib/autodev.cjs +642 -0
  202. package/pan-wizard-core/bin/lib/ci.cjs +143 -0
  203. package/pan-wizard-core/bin/lib/commands.cjs +1 -1
  204. package/pan-wizard-core/bin/lib/config.cjs +31 -2
  205. package/pan-wizard-core/bin/lib/constants.cjs +27 -1
  206. package/pan-wizard-core/bin/lib/core.cjs +22 -10
  207. package/pan-wizard-core/bin/lib/cost.cjs +14 -4
  208. package/pan-wizard-core/bin/lib/cross-family.cjs +164 -0
  209. package/pan-wizard-core/bin/lib/debug-cases.cjs +104 -0
  210. package/pan-wizard-core/bin/lib/failure-class.cjs +81 -0
  211. package/pan-wizard-core/bin/lib/findings.cjs +34 -4
  212. package/pan-wizard-core/bin/lib/focus.cjs +1 -1
  213. package/pan-wizard-core/bin/lib/hosts.cjs +88 -0
  214. package/pan-wizard-core/bin/lib/init.cjs +7 -2
  215. package/pan-wizard-core/bin/lib/knowledge.cjs +2 -0
  216. package/pan-wizard-core/bin/lib/merge.cjs +50 -0
  217. package/pan-wizard-core/bin/lib/mutate.cjs +16 -5
  218. package/pan-wizard-core/bin/lib/next-action.cjs +112 -0
  219. package/pan-wizard-core/bin/lib/optimize.cjs +2 -2
  220. package/pan-wizard-core/bin/lib/phase.cjs +48 -4
  221. package/pan-wizard-core/bin/lib/plan-lint.cjs +150 -1
  222. package/pan-wizard-core/bin/lib/preview.cjs +23 -4
  223. package/pan-wizard-core/bin/lib/requirements-lint.cjs +130 -0
  224. package/pan-wizard-core/bin/lib/research-lint.cjs +150 -3
  225. package/pan-wizard-core/bin/lib/review-deep.cjs +14 -22
  226. package/pan-wizard-core/bin/lib/review-vote.cjs +105 -0
  227. package/pan-wizard-core/bin/lib/runner.cjs +2 -16
  228. package/pan-wizard-core/bin/lib/sizing.cjs +356 -0
  229. package/pan-wizard-core/bin/lib/squads.cjs +1 -1
  230. package/pan-wizard-core/bin/lib/state-write.cjs +247 -0
  231. package/pan-wizard-core/bin/lib/uat.cjs +149 -0
  232. package/pan-wizard-core/bin/lib/verdict.cjs +26 -3
  233. package/pan-wizard-core/bin/lib/verify-plan-set.cjs +30 -1
  234. package/pan-wizard-core/bin/lib/verify-preflight.cjs +2 -2
  235. package/pan-wizard-core/bin/lib/verify-red.cjs +37 -1
  236. package/pan-wizard-core/bin/lib/verify-retro.cjs +3 -2
  237. package/pan-wizard-core/bin/lib/verify.cjs +59 -4
  238. package/pan-wizard-core/bin/lib/worktree.cjs +70 -0
  239. package/pan-wizard-core/bin/pan-tools.cjs +168 -27
  240. package/pan-wizard-core/learnings/universal/autonomous-loop.md +2 -2
  241. package/pan-wizard-core/references/continuation-format.md +3 -3
  242. package/pan-wizard-core/references/guardrails.md +1 -1
  243. package/pan-wizard-core/references/model-profiles.md +2 -3
  244. package/pan-wizard-core/references/questioning.md +24 -0
  245. package/pan-wizard-core/references/ui-brand.md +4 -6
  246. package/pan-wizard-core/references/verdict-contract.md +2 -1
  247. package/pan-wizard-core/templates/config.json +5 -1
  248. package/pan-wizard-core/templates/debug.md +1 -0
  249. package/pan-wizard-core/templates/discovery.md +2 -2
  250. package/pan-wizard-core/templates/requirements.md +9 -0
  251. package/pan-wizard-core/workflows/add-phase.md +4 -6
  252. package/pan-wizard-core/workflows/assumptions.md +19 -1
  253. package/pan-wizard-core/workflows/diagnose-issues.md +2 -0
  254. package/pan-wizard-core/workflows/discuss-phase.md +4 -2
  255. package/pan-wizard-core/workflows/exec-lean.md +69 -0
  256. package/pan-wizard-core/workflows/exec-phase.md +36 -8
  257. package/{commands/pan → pan-wizard-core/workflows}/focus-doc-audit.md +13 -29
  258. package/{commands/pan → pan-wizard-core/workflows}/focus-drift-walking.md +3 -18
  259. package/{commands/pan → pan-wizard-core/workflows}/focus-exec.md +8 -23
  260. package/{commands/pan → pan-wizard-core/workflows}/focus-plan.md +6 -20
  261. package/{commands/pan → pan-wizard-core/workflows}/focus-scan.md +3 -16
  262. package/{commands/pan → pan-wizard-core/workflows}/focus-sync.md +7 -21
  263. package/pan-wizard-core/workflows/health.md +6 -0
  264. package/pan-wizard-core/workflows/help.md +31 -53
  265. package/pan-wizard-core/workflows/insert-phase.md +4 -6
  266. package/pan-wizard-core/workflows/learn.md +3 -3
  267. package/pan-wizard-core/workflows/milestone-audit.md +2 -2
  268. package/pan-wizard-core/workflows/milestone-new.md +38 -95
  269. package/pan-wizard-core/workflows/new-project.md +96 -258
  270. package/pan-wizard-core/workflows/optimize.md +107 -5
  271. package/pan-wizard-core/workflows/phase-tests.md +10 -0
  272. package/pan-wizard-core/workflows/plan-phase.md +86 -43
  273. package/pan-wizard-core/workflows/profile.md +50 -0
  274. package/pan-wizard-core/workflows/progress.md +10 -0
  275. package/pan-wizard-core/workflows/quick.md +34 -43
  276. package/pan-wizard-core/workflows/research-phase.md +118 -40
  277. package/pan-wizard-core/workflows/resume-project.md +18 -2
  278. package/pan-wizard-core/workflows/settings.md +21 -24
  279. package/pan-wizard-core/workflows/todo-check.md +6 -2
  280. package/pan-wizard-core/workflows/transition.md +22 -4
  281. package/pan-wizard-core/workflows/uat-walkthrough.md +90 -0
  282. package/pan-wizard-core/workflows/update.md +1 -1
  283. package/pan-wizard-core/workflows/verify-phase.md +2 -2
  284. package/scripts/build-agent-plugin.js +35 -15
  285. package/scripts/build-plugin.js +10 -1
  286. package/scripts/deprecate-old-versions.js +70 -3
  287. package/scripts/generate-skills-docs.py +1 -1
  288. package/scripts/git-hooks/pre-push +27 -0
  289. package/scripts/install-git-hooks.js +7 -5
  290. package/scripts/install-pre-push.cjs +38 -0
  291. package/scripts/land.cjs +151 -0
  292. package/scripts/local-ci.cjs +501 -0
  293. package/scripts/local-schedule.cjs +277 -0
  294. package/scripts/prompt-lint.cjs +32 -0
  295. package/scripts/prompt-rules.cjs +156 -0
  296. package/scripts/run-tests.cjs +7 -1
  297. package/scripts/test-quality-lint.cjs +3 -3
  298. package/scripts/test-surface.cjs +9 -2
  299. package/agents/pan-research-synthesizer.md +0 -246
  300. package/commands/pan/audit-deployment.md +0 -386
  301. package/commands/pan/dashboard.md +0 -22
  302. package/commands/pan/discord.md +0 -19
  303. package/commands/pan/mcp-bridge.md +0 -143
  304. package/commands/pan/milestone-cleanup.md +0 -19
  305. package/commands/pan/milestone-gaps.md +0 -35
  306. package/commands/pan/optimize.md +0 -115
  307. package/commands/pan/profile.md +0 -76
  308. package/commands/pan/research-phase.md +0 -189
  309. package/pan-wizard-core/bin/lib/bridge.cjs +0 -269
  310. package/pan-wizard-core/templates/research-project/architecture.md +0 -210
  311. package/pan-wizard-core/templates/research-project/features.md +0 -153
  312. package/pan-wizard-core/templates/research-project/pitfalls.md +0 -206
  313. package/pan-wizard-core/templates/research-project/stack.md +0 -126
  314. package/pan-wizard-core/templates/research-project/summary.md +0 -170
@@ -0,0 +1,640 @@
1
+ # Stability Test — Deployed Install, 2026-08
2
+
3
+ **Point-in-time document.** Everything below describes source `D:\PanWizard` on branch
4
+ `fix/e2e-audit-highs-2026-08` at commit `2be1000` (`package.json` version 3.23.0), tested against
5
+ real installs under `d:\pantesting\stab-*` on Windows 11 / Node 24. The repo moves; a finding
6
+ marked open here may already be closed. Re-verify before quoting this document as current.
7
+
8
+ A concurrent session committed to the source repo during the test window (HEAD advanced
9
+ `05e8f5b` → `2be1000`, plus untracked `docs/specs/panloop-self-optimization.md` and `tools/`).
10
+ Every code-level finding below was re-read against `2be1000` after the fact, including by the
11
+ author of this document, so the results are not stale relative to that move.
12
+
13
+ ---
14
+
15
+ ## 0. Resolution (2026-08-06, after this report)
16
+
17
+ **Every Critical and High in this report is fixed and re-verified in a deployed install.** The
18
+ verdict in §1 below is preserved as written — it was correct at the time and the reasoning is worth
19
+ keeping — but it is no longer the current state.
20
+
21
+ Fixed, each with a regression test that fails against the pre-fix code (`ee2338b`, `caf3c91`,
22
+ `cfe9735`, `3a63163`):
23
+
24
+ | Was | Now |
25
+ |---|---|
26
+ | Installer destroyed an unparseable `settings.json` | `readSettings` distinguishes "absent" from "unusable"; the file survives byte-identical, warned, install continues |
27
+ | `verify reconcile` was a dead gate — the parser demanded 4-space indent, every shipped surface emits 2 | Parser derives indent from the document; a rubber-stamped pass over a stub exits 1, an honest pass exits 0 |
28
+ | `phase remove 0` corrupted the roadmap; a large negative hung for hours | Both rejected in ~200ms before anything is touched; the renumber loop also has its own floor |
29
+ | `pan-tools commit` staged a sensitive file then blocked, leaving the secret in the index and wedging all later commits | PAN's own additions are unstaged on refusal; the user's pre-staged files are left alone |
30
+
31
+ Re-verified against a fresh 5-runtime install (`d:\pantesting\reverify`): install exits 0 with no
32
+ errors and no `learnings/internal` leak; all five runtimes carry their full command surface in their
33
+ native layout; a `//`-commented `settings.json` survives an upgrade with a warning; the reconcile
34
+ gate refuses a stub and passes an honest artifact; all four Codex hooks exit 0 in a `"type":
35
+ "module"` project with the `commonjs` marker present; `bus drain --mode consume --limit 2` leaves the
36
+ unread remainder intact; `phase remove 0` and `-1234567890` both exit 1 promptly with the roadmap
37
+ untouched; a blocked commit leaves the secret out of the index while preserving what the user had
38
+ staged; all five Claude hooks exit 0; and the real home is untouched.
39
+
40
+ **Still open: the Medium and Low tail in §3** — the OpenCode global permission glob (the second item
41
+ §1 called release-blocking, a permanent-residue defect), `focus scan` finding no work items on PAN's
42
+ own roadmap template, the `learn` commands resolving their store from cwd, cost understating by
43
+ roughly a third, and `preview`/`phase add` dropping checklist-format phases. None of these destroys
44
+ data or silently disarms a gate, which is what separated the blockers from the rest.
45
+
46
+ **One finding here is worth carrying forward as a method, not just a fix.** The reconcile gate had
47
+ been verified as working by five rounds of adversarial audit — against fixtures the auditors wrote
48
+ by hand at 4-space indent. It had never once been run against a plan in the format PAN itself
49
+ emits. Its regression test now parses the shipped template file rather than a literal, so the
50
+ emitted format and the parser cannot drift apart again without failing. Prefer a test that reads
51
+ PAN's own output over one that restates what you believe the format to be.
52
+
53
+ ---
54
+
55
+ ## 1. Verdict (as written on 2026-08-06, before the fixes above)
56
+
57
+ **No — do not publish this as-is. Yes — publish after two fixes, both small and both localized.**
58
+
59
+ One defect is release-blocking: **the installer silently destroys a `settings.json` it cannot
60
+ parse as strict JSON** — no warning, no backup, exit 0, success ticks printed the whole way. A
61
+ second is a permanent-residue defect: **the global OpenCode permission grant points at a directory
62
+ that does not exist, and the uninstaller can never remove it** — this machine is already carrying
63
+ that residue from an earlier cycle.
64
+
65
+ Everything else found in the deployed test is Medium or below, and — this is the part that should
66
+ matter to a maintainer who has been reading audit reports for weeks — **nothing in the core
67
+ lifecycle broke.** Install, verify, upgrade, self-repair, uninstall, and user-config preservation
68
+ all held up under deliberate abuse. The command layer took hundreds of hostile invocations without
69
+ a single stack trace.
70
+
71
+ **What would change the verdict to "publish":**
72
+
73
+ 1. `readSettings()` stops swallowing parse errors and stops returning `{}` for a file that exists
74
+ (fix at `bin/install.js:257`, with a plain-object type guard). The correct pattern already lives
75
+ in the same file for `opencode.json` — copy it upward.
76
+ 2. The OpenCode permission path stops disagreeing with itself (`bin/install.js:1538-1540`), gets
77
+ `--config-dir` threaded in, and the uninstall key filter (`bin/install.js:1397`) widens so
78
+ machines already carrying `pan-wizard/*` get cleaned on the next uninstall.
79
+ 3. A regression test that a `settings.json` containing a `//` comment survives an install
80
+ byte-identical. Without a test this class comes back — see §5.
81
+
82
+ **What would change the verdict to "don't publish, keep digging":** findings from the three test
83
+ areas whose reports did not reach this document (see the coverage caveat immediately below). If
84
+ hooks, hostile-input, or regression testing surfaced anything of Critical or High severity, this
85
+ verdict is void and must be rewritten.
86
+
87
+ ### Coverage caveat — read this before trusting the verdict
88
+
89
+ Six test areas ran. **Three area reports reached this document in full or in part; three did not.**
90
+
91
+ | Area | Sandbox | Report received | Verdict as reported |
92
+ |---|---|---|---|
93
+ | 1 — Install / upgrade / uninstall, 5 runtimes, local + global | `stab-install` | Full | FAIL |
94
+ | 2 — Global install + scope detection | `stab-global` | Full | FAIL |
95
+ | 3 — CLI functional sweep against a deployed install | `stab-cli` | **Evidence only; failure list truncated** | FAIL |
96
+ | 4 — Hooks | `stab-hooks` | **Not received** | unknown |
97
+ | 5 — Hostile input | `stab-hostile` | **Not received** | unknown |
98
+ | 6 — Regression | `stab-regress` | **Not received** | unknown |
99
+
100
+ The three sandboxes exist on disk, so those areas did run. Their findings are simply not in front
101
+ of me, and I will not invent them. **Area 3 is the sharper gap:** its verdict is FAIL, but the
102
+ portion of its report I received contains no failures — only its evidence, which is uniformly
103
+ strong. Its FAIL therefore rests entirely on findings I cannot see. Fold those four reports in
104
+ before treating §1 as final.
105
+
106
+ ### Where a reported verdict looks unsupported by its own evidence
107
+
108
+ - **Area 2 (`FAIL`) is overstated.** Its highest-severity finding is Medium. Its evidence shows the
109
+ primary paths passing: global install across all five runtimes clean, scope detection correct on
110
+ the canonical path in every runtime × mode combination tested, the capability-warning matrix
111
+ correct in every case including the future-model cases that must *not* warn, and a global
112
+ uninstall that left one residual file. Every failure it reports lives on the `--config-dir` side
113
+ road or in the OpenCode permission glob. On a consistent severity ladder that is
114
+ `PASS_WITH_NOTES`, not `FAIL`. Read as FAIL it inflates the apparent instability of the release.
115
+ - **Area 2 and Area 1 double-count one defect.** The OpenCode `pan-wizard/*` glob is a single bug;
116
+ Area 1 rated it High (it also caught the un-removable-residue half), Area 2 rated it Medium.
117
+ It is counted once below, as High.
118
+ - **Area 3's `FAIL` cannot be evaluated** for the reason given above. Its evidence, as received,
119
+ reports zero stack traces across every fault class it tried.
120
+ - **Area 1's `FAIL` is supported** — an independently reproduced silent-data-loss defect justifies
121
+ it without argument.
122
+
123
+ ---
124
+
125
+ ## 2. What was actually exercised
126
+
127
+ Concrete, so you can judge the coverage rather than take a number on faith.
128
+
129
+ **Isolation.** Every install ran with `HOME` and `USERPROFILE` redirected into a sandbox fake home,
130
+ verified *before* the first global run via `node -e "require('os').homedir()"`. `D:\PanWizard` was
131
+ never the installer's cwd and was only ever read. Final real-home audit after all runs:
132
+ `~/.claude/settings.json` md5 unchanged from baseline, `~/.agents/skills` still empty, `~/.codex`
133
+ still absent, no `pan-*` anywhere under `~/.copilot`, `~/.gemini`, or `~/.config/opencode`. The
134
+ only real-home deltas were Claude Code's own session churn. The earlier home-pollution incident
135
+ (a full skills tree written into the real home) did not recur.
136
+
137
+ **Installs.** Fresh install of all five runtimes locally; the same command re-run over itself
138
+ (upgrade path); all five globally; `--all --local`; `--config-dir` with absolute, `./`-prefixed,
139
+ and bare-relative values; uninstall per-runtime and all-at-once; uninstall with the manifest
140
+ deliberately deleted; uninstall of an already-clean runtime. Host projects included a CJS repo, an
141
+ ESM repo (`"type": "module"`), a path containing spaces, a repo with a pre-existing `AGENTS.md` +
142
+ `CLAUDE.md` + a user's own statusline, a non-PAN repo, and an empty directory.
143
+
144
+ **Integrity, both directions.** Every entry in every runtime manifest re-hashed with SHA-256:
145
+ zero missing, zero mismatches, on the fresh install, after upgrade, and from the spaces path.
146
+ Reverse sweep — every file on disk reconciled against the manifest — accounted for all untracked
147
+ files as merge/config files the installer intentionally leaves user-editable. Deleting a core
148
+ module and a command file, then reinstalling, restored both (self-repair works). Planted legacy
149
+ artifacts in the pre-rename locations were swept.
150
+
151
+ **Content and path rewriting.** For each runtime: its command surface, agent surface, skill surface,
152
+ and the shared core (workflows, templates, references) present; every skill carries frontmatter with
153
+ `name` and `description`. Every embedded `pan-tools.cjs` reference extracted per runtime and checked
154
+ to point only at that runtime's own directory — zero `~/.claude` leaks into non-Claude runtimes. Two
155
+ genuine rewrite misses were found this way and are listed below. (Counts of commands/agents/modules
156
+ are deliberately absent from this document; enumerate with `ls commands/pan/*.md`, `ls agents/*.md`,
157
+ `ls pan-wizard-core/bin/lib/*.cjs`.)
158
+
159
+ **Hooks, actually fired.** Every registered hook command across all six hook config files was
160
+ executed exactly as registered, with realistic stdin payloads (`SessionStart`, `PostToolUse` with
161
+ tool name/input/response, `SubagentStop` with usage + agent type + a real two-line
162
+ `transcript.jsonl`). All exited 0. Side effects verified, not assumed: a v3 token record landed in
163
+ `.planning/metrics/tokens.jsonl` with `token_source: "transcript"`, and a trace session directory
164
+ was created. Re-run under an ESM host — still 0, because each runtime dir ships its own
165
+ `package.json` CommonJS shield. Global hooks (absolute quoted paths) run from a non-PAN repo exited
166
+ 0 and correctly created no `.planning/`.
167
+
168
+ **Upgrade safety.** File list before and after a re-install: identical. Hook arrays not duplicated.
169
+ Local modifications planted across all runtimes were detected, reported, and backed up to
170
+ `pan-local-patches/` with correct `backup-meta.json`, originals restored pristine — with one
171
+ exception, listed below.
172
+
173
+ **Uninstall safety.** User keys planted in four config files and three user-owned files before
174
+ uninstalling: all survived. Claude kept `permissions.allow`/`deny`, `env`, `model`, and the user's
175
+ own `PreToolUse` hook while PAN's own entries and statusline were removed. Gemini kept theme and a
176
+ custom key; Copilot kept its user pref; OpenCode kept theme and model. The host project's own files
177
+ were md5-identical to their pre-install baselines, and its git history was intact. In the project
178
+ with a pre-existing `AGENTS.md` and `CLAUDE.md`, both files came back **byte-identical** to
179
+ pre-install after the full cycle. Ref-counting held: uninstalling one runtime of several left the
180
+ shared sections in place; uninstalling the last one removed them.
181
+
182
+ **Hostile probing of the CLI.** Against a deployed `--claude --local` install in a brownfield JS
183
+ repo with git history, driven through the *installed* dispatcher (never the source copy): 184
184
+ distinct command surfaces across roughly 430 invocations in six fault classes — happy path, missing
185
+ required arguments, nonexistent phase/id, malformed `config.json`, malformed JSONL/JSON state, and
186
+ corrupted `state.md`/`roadmap.md`/plan frontmatter including raw NUL bytes. **Zero stack traces.**
187
+ `validate health` correctly surfaced the broken config as a structured error; `hud`, `report index`,
188
+ `dashboard`, `preflight`, `retro`, and `context-budget` all still produced output on a corrupted
189
+ project. Two previously-fixed data-loss defects were re-confirmed fixed under adversarial input:
190
+ `bus drain --mode consume` removes exactly the messages it returned and preserves a malformed line
191
+ verbatim; the cost ledger prices genuine pre-fix rows lacking `event_sig` alongside current rows,
192
+ quarantines implausible values, and skips a torn half-written row without failing the report.
193
+
194
+ **Independent re-verification for this document.** The blocking defect was reproduced first-hand in
195
+ a fresh sandbox (`d:\pantesting\stab-verdict`), and the four cited root causes were read directly
196
+ out of `bin/install.js`, `pan-wizard-core/learnings/index.json`, `commands/pan/audit-deployment.md`,
197
+ and `pan-wizard-core/workflows/update.md` at `2be1000`.
198
+
199
+ ---
200
+
201
+ ## 3. Findings, ranked and separated by class
202
+
203
+ ### (a) Code defects — wrong behavior, wrong results, or data loss
204
+
205
+ **A1 — BLOCKING · Critical · The installer destroys a `settings.json` it cannot parse as strict
206
+ JSON: no warning, no backup, exit 0.**
207
+
208
+ Reproduced independently for this document:
209
+
210
+ ```bash
211
+ mkdir -p /d/pantesting/stab-verdict/host/.claude
212
+ printf '{\n // my model choice\n "model": "opus",\n "permissions": { "allow": ["Bash(ls)"] },\n "env": { "ACME_TOKEN_PATH": "/secrets/tok" }\n}\n' \
213
+ > /d/pantesting/stab-verdict/host/.claude/settings.json
214
+ cd /d/pantesting/stab-verdict/host && node /d/PanWizard/bin/install.js --claude --local
215
+ ```
216
+
217
+ Observed: `EXIT=0`. Warning/`⚠`/"could not parse" lines in the whole install log: **0**. Output
218
+ ends with `✓ Configured statusline` and `Done!`. Afterwards `.claude/settings.json` contains only
219
+ `hooks` and `statusLine` — `model`, `permissions`, and `env` are gone, and `find` for `*.bak` or
220
+ `settings.json.*` returns nothing. Area 1 reproduced the same outcome across four malformed
221
+ variants (JSONC comment, trailing comma, truncated, binary) and for the other two settings-based
222
+ runtimes, destroying Gemini's `selectedAuthType` and Copilot's `trustedFolders`.
223
+
224
+ Root cause, `bin/install.js:257`:
225
+
226
+ ```js
227
+ function readSettings(settingsPath) {
228
+ try {
229
+ return JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
230
+ } catch {
231
+ return {};
232
+ }
233
+ }
234
+ ```
235
+
236
+ Ten call sites treat that `{}` as "the user has no settings" and write a fresh object back. The
237
+ *correct* pattern already exists in the same file, at `configureOpencodePermissions()`
238
+ (`bin/install.js:~1520`): `parseJsonc` + `⚠ Could not parse opencode.json - skipping permission
239
+ config … Your config was NOT modified` + early return. Verified working — a malformed
240
+ `opencode.json` was left byte-identical in the same test run.
241
+
242
+ **User impact.** A user whose `settings.json` contains a `//` comment — a thing people write
243
+ constantly — permanently loses it on install *or upgrade*. Lost content includes Claude Code
244
+ permission allow/deny lists, env vars, and custom hooks; Gemini auth type (forces re-auth); Copilot
245
+ `trustedFolders` (a security setting). Unrecoverable if the file was not in git. The trigger is
246
+ conditional — the file has to be non-strict JSON, which is a minority of users, and runtimes
247
+ themselves write strict JSON — but the consequence is total, silent, and printed as success. That
248
+ combination is what makes it blocking rather than merely serious. Note the same hole sits on the
249
+ **uninstall** path at `bin/install.js:1258`.
250
+
251
+ ---
252
+
253
+ **A2 — BLOCKING · High · The global OpenCode permission grant points at a directory that does not
254
+ exist, and the uninstaller can never remove it. This machine already carries the residue.**
255
+
256
+ ```bash
257
+ cd <sandbox>/proj && HOME=<fakehome> node /d/PanWizard/bin/install.js --opencode --global
258
+ # prints: ✓ Configured read permission for PAN docs
259
+ cat <fakehome>/.config/opencode/opencode.json
260
+ # {"permission":{"read":{"~/.config/opencode/pan-wizard/*":"allow"},
261
+ # "external_directory":{"~/.config/opencode/pan-wizard/*":"allow"}}}
262
+ ls -d <fakehome>/.config/opencode/pan-wizard # No such file or directory
263
+ ls -d <fakehome>/.config/opencode/pan-wizard-core # exists — this is what was installed
264
+ ```
265
+
266
+ Root cause, `bin/install.js:1538-1540` — the two branches disagree, and only the default-global one
267
+ is wrong:
268
+
269
+ ```js
270
+ const panPath = opencodeConfigDir === defaultConfigDir
271
+ ? '~/.config/opencode/pan-wizard/*' // missing "-core"
272
+ : `${opencodeConfigDir.replace(/\\/g, '/')}/pan-wizard-core/*`; // correct everywhere else
273
+ ```
274
+
275
+ The uninstaller at `bin/install.js:1397` only prunes keys where `key.includes('pan-wizard-core')`,
276
+ so the broken spelling can never match and survives every uninstall.
277
+
278
+ **Confirmed on the developer's real machine, read-only, not created by this test run** (the test's
279
+ global installs went to a fake home):
280
+
281
+ ```bash
282
+ cat C:/Users/ocker/.config/opencode/opencode.json
283
+ # still contains both ~/.config/opencode/pan-wizard/* entries
284
+ ls -d C:/Users/ocker/.config/opencode/pan-wizard-core # No such file or directory
285
+ ls -d C:/Users/ocker/.config/opencode/pan-wizard # No such file or directory
286
+ ```
287
+
288
+ A previous global install/uninstall cycle left dangling PAN permission grants behind permanently.
289
+
290
+ **User impact.** Two failures. (1) Every default-location global OpenCode install gets a permission
291
+ rule that cannot match, so PAN's own core docs — the workflows, references, and templates that
292
+ `external_directory` guards — are never allow-listed, which is precisely what the grant was written
293
+ to prevent, while the installer prints `✓ Configured read permission for PAN docs`. (2) Uninstall
294
+ reports success and "Your other files and settings have been preserved" while leaving PAN-authored
295
+ keys in the user's global config forever. Whether OpenCode then blocks, prompts, or ignores the
296
+ missing grant needs a live OpenCode runtime — the severity here rests on the confirmed mismatch and
297
+ the confirmed permanent residue, not on an observed block.
298
+
299
+ ---
300
+
301
+ **A3 — High (cluster) · `--config-dir` is advertised but not threaded through the post-install
302
+ paths, so a `--config-dir` install can never update itself.**
303
+
304
+ Three distinct defects, one theme. `--config-dir` is documented in `--help`.
305
+
306
+ - `configureOpencodePermissions(isGlobal = true)` (`bin/install.js:1504`, called at `:2608` as
307
+ `configureOpencodePermissions(isGlobal)`) takes no explicit dir and resolves via
308
+ `getOpencodeGlobalDir()`. With `--opencode --global --config-dir <dir>`, `<dir>` gets **no**
309
+ `opencode.json` and the default `~/.config/opencode/opencode.json` is created instead — a file in
310
+ the location the user deliberately avoided, carrying the broken glob from A2.
311
+ - `pan-wizard-core/workflows/update.md` never mentions `--config-dir` (`grep -c config-dir` → 0 at
312
+ `2be1000`). Step 1 correctly detects the custom-dir install and reads its version, then
313
+ `run_update` runs bare `npx -y pan-wizard@latest --global`. Observed: the custom dir stayed at the
314
+ stale version while a full second install appeared in the home dir. The user sees
315
+ "PAN Updated: 3.22.0 → 3.23.0" while the install their runtime actually loads is still 3.22.0,
316
+ and every subsequent update repeats it.
317
+ - A relative `--config-dir` breaks scope detection in both directions, because the installed
318
+ detection block infers scope from the *shape* of the templated prefix
319
+ (`case "$VERSION_FILE" in ./*) LOCAL ;; *) GLOBAL ;; esac`, `workflows/update.md:23-26`).
320
+ `--global --config-dir './relcfg'` templates `./relcfg/...` and reports **LOCAL** — the same
321
+ user-visible failure as the N2 regression this design was introduced to fix.
322
+ `--config-dir 'barecfg'` reports GLOBAL but is cwd-relative, so detection returns UNKNOWN from
323
+ any other directory. Fix is one line at the templating site: `path.resolve` the value.
324
+
325
+ ---
326
+
327
+ **A4 — Medium · `UNKNOWN` scope is routed to `--global`, so a local-only user running `/pan:update`
328
+ from a subdirectory gets an unrequested global install in their real home.**
329
+
330
+ Detection templates a cwd-relative `./.claude/pan-wizard-core/VERSION` for local installs. Run the
331
+ installed detection block verbatim from `<project>/src/deep` and it prints `UNKNOWN`; from the
332
+ project root it prints `3.23.0 LOCAL`. `workflows/update.md:152-163` then says:
333
+ **"If GLOBAL install (or unknown):** `npx -y pan-wizard@latest --global`". Blast radius is the real
334
+ home — `~/.claude`, `~/.gemini`, `~/.codex`, plus the shared skills tree, which is the same
335
+ directory as the earlier home-pollution incident — while the local install the user meant to update
336
+ stays stale. The precondition is real rather than theoretical: Codex and Copilot resolve skills from
337
+ the repo root and can legitimately be invoked from a subdirectory. Caveat: the routing step is prose
338
+ an LLM executes. The `UNKNOWN` output was confirmed deterministically and the instruction text was
339
+ read; an LLM was not observed acting on it. Either walk up to the project root, or make `UNKNOWN`
340
+ stop and ask.
341
+
342
+ ---
343
+
344
+ **A5 — Medium · The installer prints `✓ Configured … hook` four times and `✓ Configured statusline`
345
+ while registering nothing, when `settings.json` holds a JSON array.**
346
+
347
+ `printf '["not","an","object"]' > .claude/settings.json`, then install: exit 0, five success ticks,
348
+ `grep -c pan-check-update .claude/settings.json` → 0, and the file on disk is the same array
349
+ re-serialized (so it *was* written). `readSettings` returns the array; callers assign
350
+ `settings.hooks = …` as a named property on an Array; `JSON.stringify` drops it. Cost logging,
351
+ context monitoring, update check, and the statusline are all silently inert while the install
352
+ reports complete. **Same root cause as A1** — no type validation around `readSettings`. Fix A1 with
353
+ a plain-object guard and this closes with it.
354
+
355
+ ---
356
+
357
+ **A6 — Medium · Codex skill edits are silently overwritten with no backup, while the docs promise a
358
+ backup.**
359
+
360
+ `saveLocalPatches()` skips any manifest key containing `..` (`bin/install.js:1770`), and Codex's
361
+ entire skill surface is tracked as `../.agents/skills/…`. Observed: six in-tree edits across the
362
+ other runtimes were reported and backed up correctly; the `.agents/skills/pan-help/SKILL.md` edit
363
+ was not mentioned in the output, not backed up, and gone from disk after reinstall.
364
+ `docs/USER-GUIDE.md:1089` and `docs/AGENTS.md:910` both promise the backup unqualified. The code
365
+ comment acknowledges the exception; the user-facing docs do not. Codex has no other command surface,
366
+ so this is the whole customization story for that runtime. Cheapest fix is the doc line; the better
367
+ fix is a sibling patches directory.
368
+
369
+ ---
370
+
371
+ **A7 — Medium · Internal learnings are stripped from disk but `learnings/index.json` still lists
372
+ them.**
373
+
374
+ Verified at source: `index.json` carries 4 topics with `scope: "internal"` whose files
375
+ (`learnings/internal/{experiment-runner,external-research,loop-design,pan-dev-bugs}.md`) exist only
376
+ upstream and are correctly removed from every installed copy by the strip at `bin/install.js:639`
377
+ and `:2074`. The strip does not rewrite the index. Two effects: internal topic names and pattern IDs
378
+ ship to every public install, defeating the strip's purpose for metadata; and the index's own totals
379
+ overstate what is installed, so anything sizing or budgeting against it is wrong. Degrades silently
380
+ rather than crashing.
381
+
382
+ ---
383
+
384
+ **A8 — Low · A corrupt `pan-file-manifest.json` silently disables local-patch backup.**
385
+ `saveLocalPatches()` does `try { … } catch { return [] }`, so an unreadable manifest is
386
+ indistinguishable from "no local modifications". Observed: install exits 0, prints
387
+ `✓ Wrote file manifest` and `✓ Verified …`, and never mentions that it could not read the old
388
+ manifest. A truncated manifest — interrupted install, bad merge — means the next upgrade overwrites
389
+ every locally modified PAN file with no backup and no notice. Third symptom of the same
390
+ catch-and-continue pattern as A1 and A5. One warning line makes it recoverable.
391
+
392
+ **A9 — Low · `pan-tools` has two incompatible error contracts, and one `learn` dispatch is broken.**
393
+ `context-budget --raw` prints a plain-text error to **stdout** and exits **0** (so a caller that
394
+ `JSON.parse`s it gets a string); `knowledge playbook` returns a JSON envelope with a raw ENOENT and
395
+ a Windows path, exit 0; `roadmap get-phase` with no argument writes to stderr and exits **1**. Any
396
+ wrapper gating on exit status treats a missing `.planning/` as success. Separately,
397
+ `learn index|list|topics|"search plan"` all return the identical "No trace session active" error —
398
+ the subcommand is ignored; only `learn promote` dispatches.
399
+
400
+ **A10 — Low · A local install writes an absolute machine path into a project file.**
401
+ `.opencode/opencode.json` gets
402
+ `{"permission":{"read":{"D:/…/host/.opencode/pan-wizard-core/*":"allow"}}}`. If that file is
403
+ committed — and PAN creates it inside the project — every teammate and CI runner inherits a grant
404
+ pointing at the original author's absolute path, silently doing nothing for them.
405
+
406
+ **A11 — Low · Uninstall orphans.** After a full local uninstall, `pan-local-patches/` trees survive
407
+ containing PAN source files, and the uninstall summary never names them (the manifest that described
408
+ them is deleted, so nothing points the user at them). After a full global uninstall,
409
+ `.claude/cache/pan-update-check.json` survives. Empty runtime directories survive local uninstall.
410
+ Retaining the patches is correct — doing it silently, under a banner reading "Your other files and
411
+ settings have been preserved", is not.
412
+
413
+ ### (b) Documentation and prose that does not match the code
414
+
415
+ The first of these is prose that *behaves* like code, and it is the most consequential item in this
416
+ class by a wide margin.
417
+
418
+ **B1 — The shipped `/pan:audit-deployment` command specifies wrong paths for OpenCode and Codex, so
419
+ the audit it drives reports false failures on a healthy install.**
420
+ `commands/pan/audit-deployment.md:81-82` says OpenCode commands live at `CONFIG_DIR/command/`
421
+ (singular) and Codex skills at `CONFIG_DIR/skills/pan-*/SKILL.md`. Verified against the installer:
422
+ `bin/install.js:1661` writes `commands/` (plural) and `:1475` treats `command/` as the *legacy*
423
+ directory to sweep; Codex's skills go to `./.agents/skills/` and `.codex/skills` does not exist.
424
+ The wrong text ships in every installed copy and both skill trees. Section 1.4 is marked CRITICAL,
425
+ so an LLM following this checklist on a correct OpenCode or Codex install will find nothing where
426
+ it was told to look and report the command surface as missing. `README.md:143` and
427
+ `docs/USER-GUIDE.md:1200` already state the correct locations, so the shipped command contradicts
428
+ the shipped docs. Users chasing a fabricated CRITICAL on a healthy install is the exact opposite of
429
+ what a deployment audit is for.
430
+
431
+ **B2 — `mcp-bridge` points non-Claude runtimes at `.claude/settings.json`.**
432
+ `commands/pan/mcp-bridge.md:101` tells the user to check "the host runtime's MCP config —
433
+ `.claude/settings.json` for Claude Code, or the runtime's equivalent", and that line ships unchanged
434
+ into the OpenCode, Codex, and Copilot copies. Those runtimes use `.opencode/opencode.json`,
435
+ Codex config, and `.github/mcp.json`. The per-runtime rewrite substitutes command names and
436
+ `pan-tools` paths in this same file but leaves this path alone — the one genuine rewrite miss in
437
+ otherwise-correct templating. Effect: a user whose MCP tools do not appear is sent to inspect a file
438
+ their runtime does not read, and the troubleshooting path dead-ends.
439
+
440
+ **B3 — The installer tells Copilot users to run a command form Copilot does not have.** After
441
+ backing up local modifications it prints "Run `/pan:patches`", but `reportLocalPatches()` only
442
+ special-cases OpenCode (`/pan-patches`) and Codex (`$pan-patches`); Copilot falls through to the
443
+ Claude/Gemini form. The installer's own closing line correctly says `/pan-new-project` for Copilot.
444
+ A Copilot user follows the instruction, the command does not exist, and their backed-up
445
+ modifications are never merged.
446
+
447
+ **B4 — The installer prints paths that do not exist for global and `--config-dir` installs.**
448
+ `--copilot --global` prints `✓ Configured hooks (.github/hooks/pan.json: …)` while the file is at
449
+ `~/.copilot/hooks/pan.json` and no `.github` exists in the home dir. `--codex --global --config-dir
450
+ <dir>` prints `✓ Configured hooks (.codex/hooks.json: …)` while the file is at `<dir>/hooks.json`.
451
+ Users troubleshooting hooks go looking in a directory that is not there.
452
+
453
+ **B5 — `docs/USER-GUIDE.md:1089` and `docs/AGENTS.md:910` promise local-patch backup without
454
+ qualification** — see A6. Whichever way A6 is resolved, one of these two lines has to change.
455
+
456
+ ### (c) Cosmetic
457
+
458
+ **C1 — `workflows/update.md`'s cache-clear step offers two branches that are byte-identical in
459
+ every install.** Both the LOCAL and GLOBAL branches read the same templated path, because there is
460
+ one install location per install and the path is templated at install time — the file even says so.
461
+ Harmless, but it invites a reader (or an LLM) to choose between options that cannot differ, in the
462
+ one workflow whose scope handling has already regressed twice.
463
+
464
+ **C2 — Per-runtime `Done!` blocks print out of order** relative to the `Installing for …` headers
465
+ during a multi-runtime global install (OpenCode's `Done!` appears under Copilot's install).
466
+
467
+ **C3 — `context-budget`'s error text has no trailing newline**, so it runs into the next shell
468
+ prompt.
469
+
470
+ ---
471
+
472
+ ## 4. What could not be tested headless
473
+
474
+ PAN's orchestration layer is prompts — commands, agents, workflows, and templates that an LLM
475
+ executes inside a host runtime. Nothing in a headless harness can exercise that. What this test
476
+ verified is that the files are present at the documented paths, structurally valid, correctly
477
+ path-rewritten per runtime, and that every executable the prompts invoke (`pan-tools`, the hooks)
478
+ runs and produces the right side effects. What remains unverified:
479
+
480
+ - **Whether each runtime actually loads what PAN registers.** Claude Code discovering the flat
481
+ `.claude/skills/pan-*.md` shims (real Claude Code skills are `<dir>/SKILL.md`, and PAN writes
482
+ single `.md` files here while writing proper skill directories for the shared and Copilot trees —
483
+ this is the single most likely place for a silent no-op); Codex resolving `$pan-*` from
484
+ `.agents/skills`; Gemini's `experimental.enableAgents`; the `.github/hooks/pan.json` `version: 1`
485
+ schema and its camelCase event names; Copilot's documented cross-read of `.claude/settings.json`.
486
+ Files written and valid — hosts honoring them, unverified.
487
+ - **Codex's project-trust gate.** `.codex/` config only loads once the project is trusted. The
488
+ installer prints the reminder; the behavior needs a live Codex CLI.
489
+ - **Every LLM-executed instruction.** Structure, frontmatter, and embedded tool paths were checked
490
+ for the whole command/agent/workflow/template surface. That an agent following those instructions
491
+ produces a correct plan, execution, or verification was not tested and cannot be.
492
+ - **The `run_update` routing decision** (A4, A3) — the detection bash is deterministic and was run
493
+ verbatim from the installed files; the LOCAL/GLOBAL/UNKNOWN → flag mapping is prose.
494
+ - **Statusline rendering inside each runtime.** The hook exits 0 and emits plausible ANSI text; each
495
+ host's statusline contract is unverified, and the installer itself flags Copilot's as experimental.
496
+ - **A real cross-version npm upgrade.** Only the same-version installer could be re-run, with stale
497
+ artifacts simulated by hand. Genuine migration paths — renamed commands, schema bumps from an
498
+ older published version — are untested.
499
+ - **The network half of the update workflow** — `npm view`, the changelog fetch, real
500
+ `npx -y pan-wizard@latest` resolution.
501
+ - **OpenCode's enforcement of the malformed grant** (A2) — the mismatch is proven; the consequence
502
+ is inferred.
503
+ - **Interactive install prompts.** Every run was flag-driven.
504
+
505
+ **How to smoke-test the unverifiable layer yourself, in one session.** In a scratch directory,
506
+ install one runtime locally, then run a single full lifecycle in that runtime:
507
+ `/pan:new-project` → `/pan:plan-phase 1` → `/pan:execute-phase 1` → `/pan:verify-phase 1` →
508
+ `/pan:cost report`. Watch four things: the commands are *discoverable* (they autocomplete), the
509
+ statusline appears, `.planning/` fills with real artifacts rather than templates,
510
+ and `.planning/metrics/tokens.jsonl` grows — that last one proves the `SubagentStop` hook is being
511
+ called by the host, which is the discovery question the harness cannot answer. Repeat for a second
512
+ runtime, ideally Codex, since its skill surface has the most unverified assumptions. Thirty minutes
513
+ covers what weeks of headless testing structurally cannot.
514
+
515
+ ---
516
+
517
+ ## 5. What the audit chain's finding count actually means
518
+
519
+ The chain that preceded this test produced a large number of findings, and the count is the reason
520
+ this release feels unstable. It is worth being precise about what the count is made of, because this
521
+ deployed test is the cleanest available read on that question — it tested the *shipped artifact*,
522
+ not the source.
523
+
524
+ **The overwhelming majority of what turns up is claims that do not match the code, not code that
525
+ does not work.** That pattern repeats here. Of everything reported in this test, exactly two items
526
+ are release-blocking, and both are single-expression defects in one function each. Below that line
527
+ sit a cluster of `--config-dir` gaps on a side road, three symptoms of one shared discipline
528
+ problem, and a set of prose-versus-code mismatches. The prose items are real and worth fixing — B1
529
+ in particular, because it is prose an LLM executes, which is a category this project generates a lot
530
+ of and should treat as code. But a doc line that names the wrong directory is not evidence of an
531
+ unstable product. It is evidence of documentation drifting faster than it was maintained, which is
532
+ exactly what a long audit chain is supposed to find and precisely why the count is large.
533
+
534
+ **Does the code layer look solid? Yes — with one named exception.** The things that would indicate
535
+ an unstable product were all specifically attacked, and all held:
536
+
537
+ - Manifest integrity verified in both directions, on fresh install, after upgrade, and from a path
538
+ containing spaces: zero missing files, zero hash mismatches.
539
+ - Upgrade is idempotent — the file list before and after a re-install is identical, hook arrays are
540
+ not duplicated, and no shadow command surfaces appear.
541
+ - Self-repair works: deleted core files come back on reinstall.
542
+ - Uninstall preserved **every** planted user key across four config files and three user-owned
543
+ files, and returned a pre-existing `AGENTS.md` and `CLAUDE.md` byte-identical to their pre-install
544
+ state. Host project files and git history untouched throughout.
545
+ - Ref-counting across five runtimes behaves correctly in both directions.
546
+ - 184 command surfaces × roughly 430 invocations × six fault classes, including malformed JSON,
547
+ malformed JSONL, corrupted frontmatter, and raw NUL bytes: **zero stack traces**, structured
548
+ errors throughout.
549
+ - Two historical data-loss defects were re-attacked adversarially and are genuinely fixed
550
+ (`bus drain` consume semantics; cost-ledger old-schema compatibility with a torn row present).
551
+ - Two historical regressions did not reproduce: the scope-detection misfire on the canonical path
552
+ (correct in every runtime × mode tested) and the capability-warning crash (the whole matrix
553
+ correct, including future model IDs that must *not* warn).
554
+ - The real home was verifiably untouched across dozens of install and uninstall cycles, including
555
+ every global one.
556
+
557
+ **The one named exception is a discipline problem, not an architecture problem, and it is the reason
558
+ for the blocking verdict.** A1, A5, and A8 are the same mistake three times:
559
+ `catch { return empty }`, followed by code that treats "empty" as "user has nothing", followed by a
560
+ success message. The project already knows the right pattern — `configureOpencodePermissions()`
561
+ implements it correctly, in the same file, refusing to touch a config it cannot parse and saying so.
562
+ Promote that pattern to every config reader, add the type guard, and cover it with a test, and this
563
+ class is closed rather than merely patched. That is a contained, high-confidence fix — which is why
564
+ the recommendation below is "fix and publish", not "hold and keep auditing".
565
+
566
+ One process note worth acting on: `grep -rn "pan-wizard/\*"` across tests, core, docs, and README
567
+ returns nothing. The A2 string is asserted nowhere, which is why green tests did not catch a typo
568
+ that has been shipping and leaving residue on real machines. Every fix below should land with an
569
+ assertion on the literal string it fixes.
570
+
571
+ ---
572
+
573
+ ## 6. Release recommendation
574
+
575
+ **Hold the publish. Fix two things, verify Areas 3-6, then publish.** Do not restart the audit
576
+ chain — the evidence does not support that, and another round will produce another pile of prose
577
+ findings while these two defects keep shipping.
578
+
579
+ **Preconditions (blocking):**
580
+
581
+ 1. **A1 + A5** — `readSettings()` must distinguish "file absent" from "file present but
582
+ unparseable", must refuse to write when it cannot parse, must warn when it refuses, and must
583
+ reject non-plain-object contents. Port the `parseJsonc` + warn + early-return pattern from
584
+ `configureOpencodePermissions()`. Apply to all ten call sites, including the uninstall path at
585
+ `bin/install.js:1258`. **Ship with a test** asserting a `settings.json` containing a `//` comment
586
+ is byte-identical after an install, and one asserting an array-valued `settings.json` produces a
587
+ warning rather than five success ticks.
588
+ 2. **A2 + A3a** — fix the default-global `panPath` to `pan-wizard-core/*`; give
589
+ `configureOpencodePermissions` an `explicitDir` parameter and pass it from the call site at
590
+ `bin/install.js:2608`; widen the uninstall key filter at `bin/install.js:1397` to prune both
591
+ spellings so machines already carrying the residue (including this one) get cleaned on the next
592
+ uninstall. Assert the literal grant string in a test.
593
+ 3. **Fold in the four missing area reports** — Area 3's failure list plus hooks, hostile-input, and
594
+ regression. If any is Critical or High, this section is void.
595
+
596
+ **Strongly recommended before publish (cheap, user-visible):**
597
+
598
+ 4. **A3b + A3c** — `path.resolve` the `--config-dir` value before templating, and thread
599
+ `--config-dir` into `workflows/update.md`'s `run_update` command. Without these a `--config-dir`
600
+ user can never update and is never told why.
601
+ 5. **A4** — change the `UNKNOWN` branch from "treat as global" to "stop and ask". A one-line prose
602
+ change that removes the only path in this report that writes into a user's real home unasked.
603
+ 6. **B1** — one-line path correction in `commands/pan/audit-deployment.md`. It is the checklist that
604
+ generates fabricated CRITICALs on healthy installs, which actively feeds the impression this
605
+ document exists to correct.
606
+
607
+ **Fine to defer to a follow-up:** A6-A11, B2-B5, C1-C3. None of them break a working install.
608
+
609
+ ### One-command smoke test after publishing
610
+
611
+ Run this from Git Bash immediately after the release lands. It checks the blocking defect against
612
+ the *published* package and confirms the deployed CLI is alive:
613
+
614
+ ```bash
615
+ D=$(mktemp -d) && cd "$D" && git init -q && mkdir -p .claude && \
616
+ printf '{\n // keep my model\n "model": "opus",\n "permissions": {"allow":["Bash(ls)"]}\n}\n' > .claude/settings.json && \
617
+ npx -y pan-wizard@latest --claude --local && \
618
+ { grep -q '"model"' .claude/settings.json && echo "PASS: settings.json preserved" || echo "FAIL: settings.json DESTROYED"; } && \
619
+ node ./.claude/pan-wizard-core/bin/pan-tools.cjs validate health; echo "exit=$?"; echo "sandbox: $D"
620
+ ```
621
+
622
+ Expect `PASS: settings.json preserved` and a structured `validate health` result. `FAIL` means A1
623
+ shipped — unpublish or patch immediately, because that path silently eats user config on every
624
+ install *and* upgrade.
625
+
626
+ For the OpenCode half, in a throwaway `HOME`:
627
+
628
+ ```bash
629
+ npx -y pan-wizard@latest --opencode --global && \
630
+ grep -o 'pan-wizard[a-z-]*' "$HOME/.config/opencode/opencode.json" | sort -u
631
+ ```
632
+
633
+ Expect `pan-wizard-core` only. Bare `pan-wizard` means A2 shipped.
634
+
635
+ ---
636
+
637
+ *Sandboxes retained for re-verification: `d:\pantesting\stab-install`, `stab-global`, `stab-cli`,
638
+ `stab-hooks`, `stab-hostile`, `stab-regress`, and `stab-verdict` (this document's independent A1
639
+ repro). Nothing under `D:\PanWizard` was modified to produce this report except the creation of this
640
+ file.*