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.
- package/CHANGELOG.md +3645 -0
- package/README.md +36 -48
- 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 +1 -2
- package/agents/pan-document_code.md +1 -2
- package/agents/pan-hardener.md +2 -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 +79 -488
- package/agents/pan-plan-checker.md +12 -2
- package/agents/pan-planner.md +10 -6
- package/agents/pan-previewer.md +1 -2
- package/agents/pan-project-researcher.md +70 -499
- package/agents/pan-release.md +1 -1
- package/agents/pan-reviewer.md +9 -3
- package/agents/pan-roadmapper.md +12 -7
- package/agents/pan-verifier.md +7 -2
- 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/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/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 +31 -2
- package/pan-wizard-core/bin/lib/constants.cjs +27 -1
- package/pan-wizard-core/bin/lib/core.cjs +22 -10
- package/pan-wizard-core/bin/lib/cost.cjs +14 -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/failure-class.cjs +81 -0
- package/pan-wizard-core/bin/lib/findings.cjs +34 -4
- package/pan-wizard-core/bin/lib/focus.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 +16 -5
- 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.cjs +48 -4
- package/pan-wizard-core/bin/lib/plan-lint.cjs +150 -1
- package/pan-wizard-core/bin/lib/preview.cjs +23 -4
- package/pan-wizard-core/bin/lib/requirements-lint.cjs +130 -0
- package/pan-wizard-core/bin/lib/research-lint.cjs +150 -3
- 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/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/uat.cjs +149 -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 +37 -1
- package/pan-wizard-core/bin/lib/verify-retro.cjs +3 -2
- package/pan-wizard-core/bin/lib/verify.cjs +59 -4
- package/pan-wizard-core/bin/lib/worktree.cjs +70 -0
- package/pan-wizard-core/bin/pan-tools.cjs +168 -27
- package/pan-wizard-core/learnings/universal/autonomous-loop.md +2 -2
- package/pan-wizard-core/references/continuation-format.md +3 -3
- package/pan-wizard-core/references/guardrails.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 +5 -1
- package/pan-wizard-core/templates/debug.md +1 -0
- package/pan-wizard-core/templates/discovery.md +2 -2
- package/pan-wizard-core/templates/requirements.md +9 -0
- 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 +36 -8
- 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 +31 -53
- 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 +86 -43
- 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/research-phase.md +118 -40
- package/pan-wizard-core/workflows/resume-project.md +18 -2
- package/pan-wizard-core/workflows/settings.md +21 -24
- 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 +2 -2
- package/scripts/build-agent-plugin.js +35 -15
- 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/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 +9 -2
- 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 -210
- package/pan-wizard-core/templates/research-project/features.md +0 -153
- package/pan-wizard-core/templates/research-project/pitfalls.md +0 -206
- package/pan-wizard-core/templates/research-project/stack.md +0 -126
- 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.*
|