wicked-garden 12.32.2 → 12.34.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 (198) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.gitattributes +2 -0
  4. package/AGENTS.md +4 -0
  5. package/CHANGELOG.md +28 -16
  6. package/README.md +8 -0
  7. package/hooks/scripts/bootstrap.py +11 -0
  8. package/install.mjs +28 -2
  9. package/package.json +1 -1
  10. package/pyproject.toml +6 -1
  11. package/scripts/_python.sh +5 -1
  12. package/scripts/_run.py +4 -3
  13. package/scripts/crew/archetypes_v11.py +1 -2
  14. package/scripts/crew/stack_registry.py +1 -2
  15. package/scripts/domain/validate_domain_model.py +2 -1
  16. package/scripts/qe/lib/gate.mjs +1 -1
  17. package/scripts/resolve_path.py +2 -2
  18. package/scripts/wicked-garden +22 -0
  19. package/scripts/wicked-garden.cmd +4 -0
  20. package/scripts/wicked-garden.mjs +448 -0
  21. package/skills/agentic/SKILL.md +9 -4
  22. package/skills/agentic/refs/review.md +8 -8
  23. package/skills/agentic-architect/SKILL.md +11 -4
  24. package/skills/agentic-performance-analyst/SKILL.md +10 -3
  25. package/skills/agentic-safety-reviewer/SKILL.md +12 -5
  26. package/skills/archetype/SKILL.md +10 -3
  27. package/skills/archetype/refs/build.md +5 -5
  28. package/skills/archetype/refs/decide.md +2 -2
  29. package/skills/archetype/refs/incident.md +2 -2
  30. package/skills/archetype/refs/migrate.md +3 -3
  31. package/skills/archetype/refs/modernize.md +5 -5
  32. package/skills/archetype/refs/review.md +8 -5
  33. package/skills/archetype/refs/ship.md +2 -2
  34. package/skills/archetype/refs/specify.md +2 -2
  35. package/skills/archetype/refs/triage.md +1 -1
  36. package/skills/classify/SKILL.md +11 -4
  37. package/skills/core/SKILL.md +13 -8
  38. package/skills/core/refs/install.md +7 -5
  39. package/skills/core/refs/report-issue.md +4 -2
  40. package/skills/core/refs/reset.md +6 -6
  41. package/skills/core/refs/setup.md +21 -19
  42. package/skills/crew-implementer/SKILL.md +2 -0
  43. package/skills/crew-researcher/SKILL.md +2 -0
  44. package/skills/crew-reviewer/SKILL.md +9 -2
  45. package/skills/data/SKILL.md +12 -7
  46. package/skills/data/refs/data.md +2 -2
  47. package/skills/data-engineer/SKILL.md +9 -2
  48. package/skills/deliberate/SKILL.md +5 -0
  49. package/skills/deliberate/refs/run-workflow.md +7 -2
  50. package/skills/domain/SKILL.md +13 -13
  51. package/skills/domain/vendor/README.md +4 -2
  52. package/skills/domain/vendor/VERSION +1 -1
  53. package/skills/domain-coverage/SKILL.md +2 -0
  54. package/skills/domain-extractor/SKILL.md +11 -4
  55. package/skills/domain-modeler/SKILL.md +3 -1
  56. package/skills/engineering/SKILL.md +15 -11
  57. package/skills/engineering/debugging/SKILL.md +2 -0
  58. package/skills/engineering/patch/SKILL.md +14 -9
  59. package/skills/engineering/patch/refs/new-generator.md +5 -5
  60. package/skills/engineering/patch/refs/output-samples.md +1 -1
  61. package/skills/engineering/refs/review.md +1 -1
  62. package/skills/engineering-api-documentarian/SKILL.md +2 -0
  63. package/skills/engineering-conformance-reviewer/SKILL.md +2 -0
  64. package/skills/engineering-migration-engineer/SKILL.md +4 -2
  65. package/skills/engineering-solution-architect/SKILL.md +2 -0
  66. package/skills/ground/SKILL.md +4 -0
  67. package/skills/integration-discovery/SKILL.md +2 -0
  68. package/skills/integration-discovery/refs/cli-detection.md +2 -0
  69. package/skills/jam/SKILL.md +11 -4
  70. package/skills/jam/refs/revisit.md +2 -0
  71. package/skills/jam-brainstorm-facilitator/SKILL.md +18 -10
  72. package/skills/jam-council/SKILL.md +13 -5
  73. package/skills/mem/SKILL.md +8 -3
  74. package/skills/mem-capture/SKILL.md +11 -4
  75. package/skills/mem-ingest/SKILL.md +12 -5
  76. package/skills/persona/SKILL.md +5 -0
  77. package/skills/persona/refs/as.md +6 -4
  78. package/skills/persona/refs/define.md +4 -4
  79. package/skills/persona/refs/list.md +2 -2
  80. package/skills/persona-agent/SKILL.md +2 -0
  81. package/skills/platform/SKILL.md +5 -5
  82. package/skills/platform/audit/SKILL.md +8 -2
  83. package/skills/platform/audit/refs/audit.md +2 -2
  84. package/skills/platform/compliance/SKILL.md +8 -2
  85. package/skills/platform/compliance/refs/compliance.md +2 -2
  86. package/skills/platform/gh-cli/SKILL.md +14 -12
  87. package/skills/platform/gh-cli/refs/automation.md +3 -3
  88. package/skills/platform/gh-cli/refs/gh-ops.md +15 -15
  89. package/skills/platform/gh-cli/refs/operations.md +1 -1
  90. package/skills/platform/github-actions/SKILL.md +3 -1
  91. package/skills/platform/glab-cli/SKILL.md +11 -9
  92. package/skills/platform/glab-cli/refs/glab-ops.md +12 -12
  93. package/skills/platform/health/SKILL.md +1 -1
  94. package/skills/platform/observability/SKILL.md +16 -11
  95. package/skills/platform/observability/refs/plugin-health.md +2 -2
  96. package/skills/platform/peer-health/SKILL.md +7 -2
  97. package/skills/platform/prereq-doctor/SKILL.md +10 -4
  98. package/skills/platform/refs/security-scan.md +1 -1
  99. package/skills/platform-compliance-officer/SKILL.md +11 -4
  100. package/skills/platform-privacy-expert/SKILL.md +2 -0
  101. package/skills/platform-security-engineer/SKILL.md +8 -1
  102. package/skills/product/SKILL.md +28 -28
  103. package/skills/product/acceptance-criteria/SKILL.md +1 -1
  104. package/skills/product/analyze/SKILL.md +6 -1
  105. package/skills/product/imagery/SKILL.md +3 -1
  106. package/skills/product/imagery/alter/SKILL.md +8 -3
  107. package/skills/product/imagery/alter/refs/editing-reference.md +3 -3
  108. package/skills/product/imagery/create/SKILL.md +8 -3
  109. package/skills/product/imagery/scripts/edit.sh +6 -4
  110. package/skills/product/imagery/scripts/generate.sh +6 -4
  111. package/skills/product/listen/SKILL.md +7 -1
  112. package/skills/product/listen/refs/channels.md +4 -4
  113. package/skills/product/refs/analyze.md +1 -1
  114. package/skills/product/refs/listen.md +1 -1
  115. package/skills/product/refs/synthesize.md +1 -1
  116. package/skills/product/requirements-analysis/SKILL.md +2 -0
  117. package/skills/product/requirements-analysis/refs/requirements-example-export-integration.md +3 -0
  118. package/skills/product/requirements-navigate/SKILL.md +1 -1
  119. package/skills/product/strategy/SKILL.md +3 -2
  120. package/skills/product-a11y-expert/SKILL.md +3 -1
  121. package/skills/product-requirements-analyst/SKILL.md +11 -4
  122. package/skills/product-ui-reviewer/SKILL.md +3 -1
  123. package/skills/product-ux-designer/SKILL.md +2 -0
  124. package/skills/product-value-strategist/SKILL.md +5 -3
  125. package/skills/prove/SKILL.md +8 -3
  126. package/skills/qe/SKILL.md +58 -58
  127. package/skills/qe/refs/accept.md +5 -3
  128. package/skills/qe/refs/author.md +105 -12
  129. package/skills/qe/refs/campaign-ci.md +11 -11
  130. package/skills/qe/refs/campaign-degradation.md +3 -3
  131. package/skills/qe/refs/campaign-flake-policy.md +4 -4
  132. package/skills/qe/refs/campaign-grading.md +7 -7
  133. package/skills/qe/refs/campaign.md +20 -16
  134. package/skills/qe/refs/evidence.md +3 -3
  135. package/skills/qe/refs/execute.md +7 -5
  136. package/skills/qe/refs/insight.md +3 -1
  137. package/skills/qe/refs/intake.md +4 -4
  138. package/skills/qe/refs/integration.md +1 -1
  139. package/skills/qe/refs/plan.md +4 -2
  140. package/skills/qe/refs/review.md +108 -4
  141. package/skills/qe-a11y-test-engineer/SKILL.md +25 -2
  142. package/skills/qe-acceptance-test-executor/SKILL.md +4 -0
  143. package/skills/qe-acceptance-test-reviewer/SKILL.md +2 -0
  144. package/skills/qe-acceptance-test-writer/SKILL.md +4 -0
  145. package/skills/qe-ai-feature-test-engineer/SKILL.md +8 -1
  146. package/skills/qe-chaos-test-engineer/SKILL.md +8 -1
  147. package/skills/qe-code-analyzer/SKILL.md +2 -0
  148. package/skills/qe-compliance-test-engineer/SKILL.md +8 -1
  149. package/skills/qe-contract-testing-engineer/SKILL.md +18 -0
  150. package/skills/qe-coverage-archaeologist/SKILL.md +2 -0
  151. package/skills/qe-data-quality-tester/SKILL.md +18 -0
  152. package/skills/qe-e2e-orchestrator/SKILL.md +9 -1
  153. package/skills/qe-exploratory-tester/SKILL.md +2 -0
  154. package/skills/qe-flaky-test-hunter/SKILL.md +8 -1
  155. package/skills/qe-fuzz-property-engineer/SKILL.md +18 -0
  156. package/skills/qe-iac-test-engineer/SKILL.md +8 -1
  157. package/skills/qe-incident-to-scenario-synthesizer/SKILL.md +9 -2
  158. package/skills/qe-integration-test-engineer/SKILL.md +18 -0
  159. package/skills/qe-load-performance-engineer/SKILL.md +19 -1
  160. package/skills/qe-localization-test-engineer/SKILL.md +18 -0
  161. package/skills/qe-mutation-test-engineer/SKILL.md +8 -1
  162. package/skills/qe-observability-test-engineer/SKILL.md +18 -0
  163. package/skills/qe-production-quality-engineer/SKILL.md +2 -0
  164. package/skills/qe-release-readiness-engineer/SKILL.md +11 -4
  165. package/skills/qe-requirements-quality-analyst/SKILL.md +2 -0
  166. package/skills/qe-risk-assessor/SKILL.md +2 -0
  167. package/skills/qe-scenario-executor/SKILL.md +8 -1
  168. package/skills/qe-security-test-engineer/SKILL.md +8 -1
  169. package/skills/qe-semantic-reviewer/SKILL.md +2 -0
  170. package/skills/qe-snapshot-hygiene-auditor/SKILL.md +8 -1
  171. package/skills/qe-test-automation-engineer/SKILL.md +27 -1
  172. package/skills/qe-test-code-quality-auditor/SKILL.md +93 -5
  173. package/skills/qe-test-data-manager/SKILL.md +18 -0
  174. package/skills/qe-test-designer/SKILL.md +2 -0
  175. package/skills/qe-test-impact-analyzer/SKILL.md +12 -5
  176. package/skills/qe-test-oracle/SKILL.md +2 -0
  177. package/skills/qe-test-strategist/SKILL.md +2 -0
  178. package/skills/qe-testability-reviewer/SKILL.md +2 -0
  179. package/skills/qe-ui-component-test-engineer/SKILL.md +12 -1
  180. package/skills/qe-visual-regression-engineer/SKILL.md +24 -1
  181. package/skills/repo-learn/SKILL.md +1 -1
  182. package/skills/runtime-exec/SKILL.md +32 -18
  183. package/skills/search/SKILL.md +12 -11
  184. package/skills/search/codebase-narrator/SKILL.md +3 -3
  185. package/skills/search/refs/answer.md +2 -2
  186. package/skills/smaht/SKILL.md +10 -2
  187. package/skills/smaht/discovery/SKILL.md +3 -0
  188. package/skills/smaht/intent/SKILL.md +10 -5
  189. package/skills/smaht/propose-skills/SKILL.md +11 -6
  190. package/skills/smaht/refs/briefing.md +8 -6
  191. package/skills/smaht/refs/events-import.md +2 -2
  192. package/skills/smaht/refs/state.md +6 -6
  193. package/skills/swarm/SKILL.md +6 -4
  194. package/skills/wickedizer/SKILL.md +2 -0
  195. package/skills/workflow/SKILL.md +18 -13
  196. package/skills/workflow/refs/integration.md +2 -0
  197. package/skills/worktrees/SKILL.md +2 -0
  198. package/uv.lock +740 -0
@@ -1 +1 @@
1
- {"name": "wicked-garden", "owner": {"name": "Mike Parcewski"}, "plugins": [{"name": "wicked-garden", "source": "./", "description": "Your coding agent already plans and swarms \u2014 Wicked Garden is the curated toolkit for what it can't: proof-not-claims gates, code links grep can't see, deterministic refactor, cross-session memory, real multi-model second opinions. Don't fight the harness; fill its gaps. The gate needs wicked-vault (a self-contained infra peer, installed directly) and re-derives through garden's built-in engine; estate/bus are opt-in layers (wicked-testing and wicked-brain are retired \u2014 QE ships in-catalog as the qe domain, memory lives in wicked-estate).", "version": "12.32.2"}], "version": "12.32.2"}
1
+ {"name": "wicked-garden", "owner": {"name": "Mike Parcewski"}, "plugins": [{"name": "wicked-garden", "source": "./", "description": "Your coding agent already plans and swarms \u2014 Wicked Garden is the curated toolkit for what it can't: proof-not-claims gates, code links grep can't see, deterministic refactor, cross-session memory, real multi-model second opinions. Don't fight the harness; fill its gaps. The gate needs wicked-vault (a self-contained infra peer, installed directly) and re-derives through garden's built-in engine; estate/bus are opt-in layers (wicked-testing and wicked-brain are retired \u2014 QE ships in-catalog as the qe domain, memory lives in wicked-estate).", "version": "12.34.0"}], "version": "12.34.0"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wicked-garden",
3
- "version": "12.32.2",
3
+ "version": "12.34.0",
4
4
  "description": "Your coding agent's harness already plans and swarms; Wicked Garden is the curated toolkit for what it can't do alone. Proof, not claims \u2014 gates re-derive 'done' through the internal loom engine (fail-closed, independently attested via wicked-vault), so a self-asserted pass can't lie its way green. Relationships grep can't see \u2014 the wicked-estate code graph + injected bus/dispatch/capability/archetype edges power blast-radius & lineage. Plus deterministic multi-file refactor (wicked-patch), cross-session memory + knowledge (the mem domain over wicked-estate), real multi-model second opinions (jam:council), portable expertise as on-demand skill-refs, and evidence-gated testing (the in-catalog qe domain). It reads the shape of your work to apply the right rigor \u2014 steering, not a pipeline \u2014 then gets out of the way. The compiler stamps a self-contained evidence gate into any repo that runs with no wicked-garden installed. Don't fight the harness; fill its gaps. The evidence gate requires wicked-vault, a self-contained infra peer wicked-garden installs directly; wicked-bus is an opt-in layer \u2014 install what you'll use, the toolkit works without the rest.",
5
5
  "wicked_vault_version": "^0.5.0",
6
6
  "wicked_ledger_version": "^0.4.0",
package/.gitattributes ADDED
@@ -0,0 +1,2 @@
1
+ # Windows command twins must keep CRLF line endings; everything else stays LF.
2
+ *.cmd text eol=crlf
package/AGENTS.md CHANGED
@@ -11,3 +11,7 @@ memory, storage, and security.
11
11
  This file is intentionally a thin pointer so there is exactly one source of truth.
12
12
  Other AI coding tools (Codex, Cursor, Aider, OpenCode, Zed/ACP, …) that read `AGENTS.md`:
13
13
  follow the link above to `.claude/CLAUDE.md`.
14
+
15
+ ## Cross-CLI skills (portability rule) — mirrored from `.claude/CLAUDE.md`
16
+
17
+ A skill's text must work wherever it is installed — Claude Code (plugin), Codex, OpenCode, Pi and Antigravity (skills-only, flat by name) and wicked-crew's snapshot. Therefore, under `skills/`: (1) refer to your own files by a path relative to the skill's base directory (`refs/plan.md`), never `${CLAUDE_PLUGIN_ROOT}`, `${CLAUDE_SKILL_DIR}` or `../`; (2) refer to another skill by its **name** (`wicked-garden-qe`, "its `refs/review.md`"), never by a filesystem path — the installer lays skills out flat by name; every `wicked-garden-<x>` token must resolve to a declared skill, and an identifier that merely looks like one (an evaluator id, a sibling plugin) is marked right after the token: `` `wicked-garden-x` <!-- not-a-skill --> `` (token-scoped — a marker elsewhere on the line exempts nothing); (3) run shared runtime code only through the launcher: `wicked-garden run scripts/<path> [args]` (or `wicked-garden path <dir>`, `wicked-garden python -c …`), include the standard `## Runtime` block once (exact text in `tests/portability_rules.garden.json`; the shared rules crew also enforces are the vendored canonical `tests/portability_rules.json`), and give a manual alternative for hosts without it; (4) write harness features with a fallback: "invoke skill X (Skill tool) — otherwise open its SKILL.md and follow it inline", "ask the user (AskUserQuestion where available, else plain text and wait)"; (5) `context: fork` and `allowed-tools` are Claude Code loading hints, fine to keep — say in the body what to do when the harness cannot fork. Hooks (`hooks/`) are Claude-plugin mechanics and keep `${CLAUDE_PLUGIN_ROOT}`. `tests/test_skill_portability.py` fails the build on any violation; run `python3 scripts/wg/portability_codemod.py --dry-run` to see the fix. The launcher lives once in `scripts/wicked-garden.mjs` (twins `scripts/wicked-garden`, `scripts/wicked-garden.cmd`; npm bin `wicked-garden run|python|path|root|doctor`); root order `WICKED_GARDEN_ROOT` → `CLAUDE_PLUGIN_ROOT` → its own package; it never writes under the root.
package/CHANGELOG.md CHANGED
@@ -2,25 +2,19 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
- ### Added
6
- - **AW-25 golden path — the wiki pipeline's own evidence-gated proof (recon arch-R21).** The guardrails program now applies its own DoD to itself: a committed, re-runnable acceptance scenario proves seed doc → `wicked-core rules ingest`/`fanout` (isolated stores; enforcement over the crew API, never CLI against a daemon store) → `rules.recall` over the **installed** `wicked-estate-mcp` 0.15.1 returning the rule with its digest-bearing provenance citation → an ISOLATED crew daemon's governed run deterministically tripping the canary trigger (the token rides the run INTENT, so the gate's evaluated context matches with no reliance on the worker model) → the gate denial citing the rule id + wiki URI (`POL-2500`, `wiki://aw25-golden#POL-2500` — via policy criteria AND `conform:` obligations, two independent citation paths) → the ConformanceClaim visible in `GET /runs/:id/acceptance` (deny-dominates, `guardrailed: false`). Ships as `scenarios/qe/aw25-golden-path.md` (scenario-format v1.1, category cli, isolation exclusive), `evidence/aw25-golden/` (seed ruleset with doc↔gate id-twinned `POL-2500`, `run.sh` fail-loud chain script, `campaign-recon.aw25.json` — spec-2 schema-validated plan with a machinery-verified claim ceiling, and the recorded `chain/` evidence 00–07 from a real run), plus `tests/qe/test_aw25_golden_artifacts.py` pinning the artifacts (schema validity, id-twinning, the AC-critical citation assertions in run.sh) hermetically. Evaluator≠creator: the verdict of record is crew's acceptance read, captured verbatim. Findings recorded in the evidence README: the <200-char PHASE SUBSTANCE GATE rejects a too-terse canary BEFORE any claim is recorded (first trip hit exactly this), and the ACP carrier reports `enforcement: enforced` with an empty `armedUnits` list.
7
- - **Flaky-verdict policy at the campaign acceptance gate (TH-21, ADR 0006 — RECON-TEST-HARNESS test-R23).** One flaky scenario can no longer silently deny OR silently pass a nightly campaign, and exclusions always carry reasons. New written policy `skills/qe/refs/campaign-flake-policy.md` + pure policy engine `scripts/qe/lib/flake-policy.mjs`, applied by `campaign-scoreboard.mjs` on every assembly: (a) **bounded diagnostic re-runs with BOTH verdicts recorded** — a re-run lands as its own runs+verdicts rows under the same stable scenario id (TH-6's flake history, now consumed at the gate via `flake_policy.history`); mixed outcomes are a `flake_signal` blocker naming `wicked-garden-qe-flaky-test-hunter` (never best-of-N), >1+2 runs of one rung is a `rerun_bound_exceeded` violation, and a `--runs` selection showing PASS while omitting a same-window deny-graded sibling is a `pass_laundering_risk` violation; (b) **quarantine lane with owner+deadline via the hunter's taxonomy** — the gate consumes the hunter's ledger `tasks` row fail-closed (`quarantined: true` + scenario binding + taxonomy cause + owner + unexpired `quarantine_expires`; invalid/expired records are reported and NOT honored — the scenario keeps denying); (c) **quarantined scenarios are excluded-with-reason** — rows stay on the scoreboard, the exclusion (id/cause/owner/deadline/reason/observed grades) rides `certification.excluded` + `certification.gate_summary`, and `gate.mjs --exclusions-from <scoreboard.json>` appends the canonical clause to `verdict_summary` so it reaches crew's acceptance payload (the 8-field `wicked.qe.gate.*` wire contract untouched; exclusions missing id/reason/owner/deadline exit 3). A fully-quarantined campaign cannot certify; a quarantined PASS is excluded too; structural violations are never excused. Hunter's SKILL.md §5/§6 now pin the machine contract (body gains required `owner`). Tests: `tests/qe/test_campaign_flake_policy.py` (9 CLI cases, hermetic) + `scripts/qe/runner/test/th21-flake-policy.test.mjs` (14 unit cases).
8
- - **qe campaign grading through the accept trio (TH-10, ADR 0006).** New `skills/qe/refs/campaign-grading.md` playbook: campaign evidence bundles grade through the SAME role-isolated reviewer as `refs/accept.md` (evidence PATHS only; isolation hard-enforced on Claude Code via host-level `allowed-tools`, advisory on Gemini/Codex/Cursor/Kiro — the boundary is now written down in both refs), with validate-before-grading against wicked-ledger's evidence-manifest 2.1 contract (schema-fail = INCONCLUSIVE; validator unavailable = fail closed). New deterministic glue `scripts/qe/lib/campaign-scoreboard.mjs` assembles the campaign-proven verbatim scoreboard shape `{id, grade, executor_claim, evidence_ok}` and makes self-grading structurally impossible: verdict rows by executor identities (`qe-runner/executor-claim`, `*executor*`, the `test-designer` dev-loop) are refused as grade sources and reported as `self_grade_attempt` violations; `executor_claim` derives from manifest-2.1 `scenario_evidence.status` (the contract's "executor's claim, never the verdict of record" field). Encodes the scenario-defect vs product-finding fork (verdict-reason tag `[scenario-defect]` → bounded re-author/re-run fix lane; `[product-finding]` → GH issue + idempotent ledger `tasks` mirror via `--mirror-tasks`) so certification terminates: `certification.disposition` is always `certified` or `not-certified`, never pending. Reviewer skill gains the campaign-bundle duties (structural floor re-check, claim-vs-evidence posture, mandatory non-PASS classification). Tests: `tests/qe/test_campaign_scoreboard.py` (8 cases, hermetic via a `WICKED_LEDGER_PKG_DIR` stub).
9
- - **`qe campaign` recon+generation action (TH-7, ADR 0006).** New `campaign` action on the `wicked-garden-qe` router (`skills/qe/refs/campaign.md`): derives a capability inventory from three lenses — the estate code graph when the target repo is indexed, docs recall via `wicked-garden-mem`, and live probing (health endpoints, crew's committed `packages/crew/endpoint-manifest.json`, DOM landmarks) — and emits a dependency-ordered campaign plan CONFORMING to `schemas/campaign-recon.schema.json` v1 (never a parallel format), persisted as a ledger `strategies` row + scenario-format v1 files under `.wicked-qe/campaigns/<name>/`. Assembly/validation glue is `scripts/qe/campaign_plan.py` (stdlib-only, fail-closed): honest `sources.estate: "unindexed"` degradation is DERIVED (an unindexed plan claiming estate-sourced entries is rejected), doc-derived claims are forced `status: "proposed"` pending human review (the incident-to-scenario pending-review pattern), ladder order + rung↔capability binding are enforced beyond the JSON schema, and generated stubs fail until authored (never a silent PASS). Tests: `tests/qe/test_campaign_action.py` validates a generated three-lens plan against the schema itself.
10
- - **qe dispatch guard (TH-7, guard half of the retired agent-surface cleanup — arch-R25 ≡ test-R20).** `scripts/qe/campaign_dispatch.py`: every qe dispatch resolves its specialist through `resolve_specialist()`, which asserts the resolved worker is a shipped `wicked-garden-qe-*` skill and BLOCKS retired `wicked-testing-*` / `wicked-brain-*` names at dispatch with a clear error naming the garden replacement (exit 2 on the CLI; never a silent rewrite). Wired into `skills/qe/SKILL.md` (fork workers) and `skills/qe/refs/execute.md` (dispatch block).
5
+ ## [12.34.0] — 2026-09-11
6
+
7
+ ### Changed
8
+ - **qe `author` / `review`: run what you claim, cite what you cover, deliver through the run (wave 6 — R4-r2, F-7R2-015/016).** The wave-6 acceptance review of a governed "New test" run found the worker had shipped a Playwright suite it never executed (it failed on its first check when run independently — 0 of 12 assertions reached), sold 22 pre-existing tests as a "29-scenario suite" without a single `file:line`, described wait-gating it had not written, and opened the PR itself with `gh pr create` from its shell — while seven default-allow gates passed it. The `wicked-garden-qe` router's `author` and `review` actions now carry the contract that makes that impossible to do honestly. **author** (`skills/qe/refs/author.md` § Verified-test contract, copied into every code-producing dispatch's args — a fork worker sees only its args): detect the repo's harness first (`package.json` scripts, `vitest`/`jest`/`playwright` configs, `pyproject.toml` pytest, an existing `e2e/` rig) and name the exact command; write BEHAVIOUR tests (observable outcome, never a mock asserting on a mock; know the source change that would fail each test); RUN every produced file with the harness's real command before claiming it and record file · exact command · result in the PLAN's execution table — a test not executed is `unverified`, never `covered`, never "passes"; claim pre-existing coverage only with `path:line` and report new vs pre-existing counts separately; label fixture-bound e2e `needs-fixture` with how to start it and run it against that fixture (selectors/test ids/text verified against the source); carry `not covered` rows for every intent gap; and NEVER `git push` / `gh pr create` / `gh pr merge` — the run's deliver phase opens the PR (standalone, the human does). The PLAN's status vocabulary is closed: `covered` · `unverified` · `needs-fixture` · `failing` · `not covered`. **review** (`skills/qe/refs/review.md` § Reviewing produced tests, dispatched to `wicked-garden-qe-test-code-quality-auditor` §9, which grades in a dedicated produced-test mode where `PASS` is reachable — every claim verified at `path:line`, every produced test executed and green, no `unverified`; P1/P2-only → `CONDITIONAL`; any P0 → `FAIL` — with a guarded source-mutation restore that never `git checkout`s over the author's uncommitted edit): open every `covered` claim at its `file:line` and reclassify unsupported ones; require an execution record for every produced file and FAIL the plan (`[unexecuted-test]`) when one is missing or a `needs-fixture` e2e was never run against its fixture; mutate-or-reason about at least two tested behaviours (apply a source mutation, confirm the test fails, restore — or name the mutation and the catching assertion when the harness cannot run); flag implementation-shaped tests; check every e2e oracle against the source on the visited route; check scope honesty; and never open, edit, merge or push the PR — the verdict goes back to the run. The same rules land in the workers the dispatches reach: `wicked-garden-qe-test-automation-engineer` ("Run what you write"), `wicked-garden-qe-e2e-orchestrator` (fixture named + started, oracles checked against the source, wait for the state you assert), `wicked-garden-qe-ui-component-test-engineer`, and — as one shared run-before-claim / cite / never-ship block pointing at the contract by skill name — the ten code-producing Tier-2 specialists (`test-data-manager`, `contract-testing-engineer`, `integration-test-engineer`, `visual-regression-engineer`, `a11y-test-engineer`, `load-performance-engineer`, `fuzz-property-engineer`, `localization-test-engineer`, `observability-test-engineer`, `data-quality-tester`), so a direct invocation on the flat Codex/Pi/OpenCode layout is bound the same way as a router dispatch. Cross-CLI wording throughout (the 12.33 portability convention — no CLI-specific delivery mechanics; "the run's deliver phase opens the PR"); `tests/test_skill_portability.py` stays at 0 violations and the router stays at the 200-line cap.
11
9
 
12
10
  ### Fixed
13
- - **Re-landed TH-5's campaign-recon schema, clobbered by #1083's stale-base squash.** PR #1083 (TH-4) was squashed from a branch cut before #1082 merged, silently reverting `schemas/campaign-recon.schema.json`, `tests/qe/test_campaign_recon_schema.py`, and the `schemas/README.md` standalone-contract section. Restored byte-for-byte from the #1082 squash commit. (The same squash also reverted #1081's docs/peer-floor work — flagged to its owning lane, not restored here.)
11
+ - **Domain schema bundle re-vendored at `1.2.0`.** `skills/domain/vendor/VERSION` was still `1.1.0` while the live owner (wicked-core `crates/wicked-governance/schemas/`) had moved to `1.2.0` with the STEERING unification's optional fields on `conformance-rules.schema.json`, so `tests/domain/test_schema_vendor_pin.py::test_vendored_bundle_version_matches_owner_when_present` failed whenever a sibling `wicked-core` checkout was present (CI, with no sibling, skipped it). Re-vendored from wicked-core `main` @ `e421e87` per the vendor README's procedure: `domain-model.schema.json` is confirmed byte-identical to the owner copy (same git blob), only `VERSION` and the README's bundle-history prose moved; the document contract stays `domain-model@1.0.0`.
12
+ - **`pyproject.toml` `version` documented as not a release anchor.** It had sat at `1.33.0` since the plugin was 1.x; the release train (`release.yml` → `npm version` → `.github/scripts/sync-plugin-version.mjs`) bumps package.json + `.claude-plugin/{plugin,marketplace}.json` only, this Python project is never built or published, and nothing reads the field — so instead of inventing a fourth anchor it is pinned to the `0.0.0` placeholder with the convention written above it (mirrored in `uv.lock`).
14
13
 
15
- ### Changed
16
- - **`wicked_ledger_version` floor `^0.2.0` → `^0.4.0` (recon XC-4 — the wicked-ledger 2.1 floor-bump wave).** wicked-ledger 0.4.0 ships evidence-manifest **2.1.0** (optional `scenario_evidence` block + first-class `claim_level` enum, `validateManifest` reviewer entry point — TH-5) and new-feature API surface, so the npm minor moved and the old caret (`^0.2.0` excludes 0.3+) had to move with it. Store compat is unchanged in every direction a garden consumer touches: SQLite `schema_version` stays **3** (no new migrations since 0.1.0), and manifest 2.1 is a **minor** — 2.0.0 bundles still validate (covered by the ledger's backward-compat smoke test) and 2.x readers gate on the major. The pin is single-sourced in `plugin.json`; the six qe skill files (`skills/qe/SKILL.md`, `skills/qe/refs/{accept,insight,integration}.md`, `skills/qe-release-readiness-engineer/SKILL.md`, `skills/qe-test-impact-analyzer/SKILL.md`) reference it symbolically and needed no edits — this completes the ledger-pin half DT-13 deferred to XC-4.
17
- - **Peer-floor and manifest truth pass (recon DT-13).** One consistent vault-floor story: every doc restatement now says **≥ 0.5.0** — the floor `scripts/loom/manifest.py` (`version_pin="0.5"`) and `plugin.json` (`wicked_vault_version ^0.5.0`) have carried since 12.31.0 (checked by the peer registry's health probe: `loom doctor` reports a below-floor vault as `drift` and exits non-zero) — replacing the stale `≥ 0.4.0` (README, CONTRIBUTING, `skills/archetype/refs/{review,incident,migrate,modernize,specify}.md`) and `^0.3.0` (`docs/required-peers.md`) claims. manifest.py + plugin.json are declared the single source; restatements carry a greppable `<!-- vault-floor -->` marker, and `docs/required-peers.md` documents the bump procedure. `skills/core/refs/setup.md` now checks the probed vault version against the floor and tells a below-floor (e.g. 0.4.x) user to upgrade via `npm i -g wicked-vault@latest`.
18
- - **`docs/required-peers.md` rewritten to the shipped truth.** The vault install command is now the working `npm i -g wicked-vault` form (was `npx wicked-vault-install`, which E404s on a fresh machine — no npm package of that name exists; it's a bin of `wicked-vault`). The loom row no longer presents a required external peer pinned `^0.2.0`: the engine has been absorbed in-package (`scripts/loom/`, dispatched in-process by `scripts/_loom.py`) since 12.27.0. **Decision (recon OQ-4):** the standalone `wicked-loom` npm package (0.4.0, not deprecated) is not a sanctioned install path — the pin is deleted, not bumped; `WICKED_LOOM_BIN` stays a debugging escape hatch.
19
- - **`.claude-plugin/plugin.json`: deleted the retired `wicked_brain_version` pin** (`^0.18.0` — wicked-brain retired 2026-08, Phase 5-S7; nothing reads the key). The `wicked_ledger_version ^0.2.0` pin is deliberately untouched here — it moves with the coordinated wicked-ledger 2.1 floor-bump wave.
20
- - **`.claude-plugin/marketplace.json`: retired-layers copy fixed** — "testing/brain/bus are opt-in layers" → estate/bus are the opt-in layers; wicked-testing and wicked-brain are retired (QE ships in-catalog as the `qe` domain; memory lives in wicked-estate).
21
- - **`docs/brain-chunk-format.md`: retirement banner added** (recon DT-18) — the doc read as live instructions to write chunks into `~/.wicked-brain`, which is a frozen archive that must never be written; the format is preserved as historical reference for the chunks migrated into wicked-estate.
22
- - **Site: the wicked-interactive card tells the document-engine story** (recon DT-12) — wicked-interactive moved planes rather than retiring: it is the foundation's document engine (storage, version lineage, HTML/PDF/PPTX/video rendering) that wicked-crew spawns and proxies, not a standalone visual builder. Install command unchanged (two-step marketplace add + install).
23
- - **Backfilled the 12.30.0 and 12.31.0 changelog entries below** (recon DT-17) — the previous release entry was 12.29.1 while npm shipped 12.31.0; the vault-direct-peer entry that sat under [Unreleased] shipped in 12.31.0 and now lives there.
14
+ ## [12.33.0] — 2026-09-11
15
+
16
+ ### Added
17
+ - **Cross-CLI skill portability — one catalog that works wherever it is installed (F-079, #1120).** wicked-garden is installed directly into Claude Code, Codex, OpenCode, Pi and Antigravity by third parties (`npx wicked-installer` → a FLAT, skills-only copy laid out by skill NAME, with no `scripts/`, no venv and no plugin root) and snapshotted by wicked-crew for every seat; only Claude Code ever substituted `${CLAUDE_PLUGIN_ROOT}`, so 77 of the 142 skills crew publishes were `portable: false` and every non-Claude seat was denied them. The skill text itself is now cross-CLI — a convention, a launcher and a lint, all in this release. **Convention** (`.claude/CLAUDE.md`, "Cross-CLI skills"): a skill refers to its OWN files by a base-directory-relative path (`refs/plan.md` — every probed CLI announces or resolves the skill's base directory); to ANOTHER skill by **name** (`wicked-garden-qe` + its `refs/review.md`), never by a filesystem path (`../` and `${CLAUDE_PLUGIN_ROOT}/skills/…` both die in the flat layout); to the shared runtime only through the **launcher** — `wicked-garden run scripts/<x>.py [args]`, `wicked-garden path <dir>`, `wicked-garden python -c …` — with one standard `## Runtime` block per script-backed SKILL.md (exact text in `tests/portability_rules.json`) telling the model what to do when the launcher or Python is missing; harness mechanics carry an inline fallback (fork workers: "when your harness cannot fork, run it inline…"; `Skill(skill=…)` dispatch: "on any other harness open the named skill's SKILL.md and carry it out inline"; AskUserQuestion: plain-text-and-wait). **Launcher** — `scripts/wicked-garden.mjs` (node ≥ 20 — the package's `engines` floor — no deps; POSIX twin `scripts/wicked-garden` and Windows twin `scripts/wicked-garden.cmd` for crew's snapshot PATH; the npm bin `wicked-garden` delegates `run|python|path|root|doctor` to it): root order `WICKED_GARDEN_ROOT` (crew seats; REFUSED loudly when it is not a garden root — never falls back to a different garden) → `CLAUDE_PLUGIN_ROOT` → its own package dir; interpreter `.py` → `<root>/.venv` → `uv run --project <root> --frozen --no-dev` with `UV_PROJECT_ENVIRONMENT` under the user cache dir (never under the root; skipped without `uv.lock`, which the npm package now ships) → `python3` → `python` → `py -3`; `.mjs/.js/.cjs` → node, `.sh` → sh; the child keeps the caller's cwd and gets both root variables; every failure is one JSON line naming what was tried. **Lint** — `tests/test_skill_portability.py` fails CI on any `plugin-root` / `skill-dir-var` / `cwd-script` / `relative-link` / `cross-skill-path` / `unresolved-skill-name` / `missing-runtime-preamble` / `slash-form` / missing-fallback token over every text file under `skills/` (nested modules attributed to their own skill, exactly as crew's catalog does), with the rules as data: `tests/portability_rules.json` is wicked-crew's CANONICAL parity fixture vendored byte-for-byte (every regex, the fence walk, option skipping, bundle existence and `../` resolution come from it; its 86 `cases[]` are re-derived here, and `tests/test_portability_fixture_parity.py` pins the vendored bytes + re-computes its `sha256_of_rules`), `tests/portability_rules.garden.json` carries garden's additions (the exact `## Runtime` block, fallback sentences, name resolver, slash-form ban, bare `scripts/x.py <args>` spans), an EMPTY allowlist, and the non-vacuity guard INVERTED: 0 plugin-root refs (was 471 in 103 files), > 200 launcher calls (248 real call sites — the two template mentions inside each `## Runtime` block are not counted), 0 unresolved names. **Codemod** — `scripts/wg/portability_codemod.py --dry-run|--write` (dev tooling, not shipped) performed the rewrite mechanically (585 changes in 166 files, reproducible from `main`; ~20 sites by hand: inline-Python heredocs, the status-line snippet, the imagery shell wrappers, the legacy `crew:*` command table) and reports every rewrite and every unresolvable target. The four skill-local `scripts/` dirs (gh-cli, glab-cli, github-actions, imagery) are stdlib-only and are invoked base-dir-relatively (`python3 scripts/gh_ops.py …`); nested imagery modules reach the parent's `provider.py` through the launcher. `skills/qe/refs/campaign-ci.md` (a template for the TARGET repo's CI) pins `npx wicked-garden@12 run …`. `tests/test_launcher.py` covers root order, the loud refusal, venv preference, uv-outside-the-root (and never creating `<root>/.venv`), cwd, env handoff, twins + executable bit, `doctor`, Windows path building via the exported pure functions and the bin delegation; `tests/test_skill_dispatch_refs_resolve.py` now checks launcher targets exist. **Hooks**: `hooks/scripts/bootstrap.py` additionally exports `WICKED_GARDEN_ROOT` and prepends `<plugin root>/scripts` to the Bash tool's PATH via `CLAUDE_ENV_FILE`, so `wicked-garden run …` resolves to the plugin's own launcher on Claude Code with no npm install (hooks otherwise keep `${CLAUDE_PLUGIN_ROOT}` — they are Claude-plugin mechanics). **Migration for third parties / other CLIs:** on Codex, Pi, OpenCode and Antigravity the skills-only install has no `scripts/`, so `npm i -g wicked-garden` (or `npx wicked-garden`) is the runtime prerequisite for script-backed skills — the launcher resolves the runtime from its own package and reports what it found with `wicked-garden doctor`; prose-only skills need nothing. Under wicked-crew, `WICKED_GARDEN_ROOT=<snapshot>` + `<snapshot>/scripts` on the seat PATH (a wicked-core change in this wave) make the launcher use the snapshot and its synced `.venv`. Crew's publisher becomes a validator that reports per-reason portability (separate PR); after crew refreshes to this garden, all 142 skills are expected to publish `portable: true`.
24
18
 
25
19
  ## [12.32.2] — 2026-09-10
26
20
 
@@ -41,14 +35,32 @@
41
35
 
42
36
  ## [12.32.0] — 2026-08-30
43
37
 
38
+ _The detailed bullets below the three summary bullets were relocated here from `[Unreleased]` in the 12.33.0 cut: each landed before the `v12.32.0` tag and first shipped in it (`git tag --contains` on every landing commit), but the 12.32.0 cut summarised them and left the detail under `[Unreleased]`, where the 12.32.1/12.32.2 hotfix cuts deliberately left it._
39
+
44
40
  ### Added
45
41
  - **qe campaign suite complete**: recon+generation w/ dispatch guard, intake propose-as-gate, accept-trio grading, flaky-verdict quarantine, degradation scenarios, campaign rerun+diff, CI recipes (PR subset / governed nightly), vault-backed evidence integrity (content-addressed, redaction-first), AW-25 golden-path evidence chain, dogfood corpus wiring.
46
42
  - **Per-turn rules source**: stop.py names `rules.recall` as THE per-turn source; guard_pipeline consumes a graph-derived rules dir with content-hash provenance; `WG_OUTGOV` defaults to advisory `warn`.
47
43
  - **Architecture-wiki pointers** in the mem/search/conformance skills (`knowledge.recall {"scope_prefix":"wiki:"}` + estate `rules.recall`).
44
+ - **AW-25 golden path — the wiki pipeline's own evidence-gated proof (recon arch-R21).** The guardrails program now applies its own DoD to itself: a committed, re-runnable acceptance scenario proves seed doc → `wicked-core rules ingest`/`fanout` (isolated stores; enforcement over the crew API, never CLI against a daemon store) → `rules.recall` over the **installed** `wicked-estate-mcp` 0.15.1 returning the rule with its digest-bearing provenance citation → an ISOLATED crew daemon's governed run deterministically tripping the canary trigger (the token rides the run INTENT, so the gate's evaluated context matches with no reliance on the worker model) → the gate denial citing the rule id + wiki URI (`POL-2500`, `wiki://aw25-golden#POL-2500` — via policy criteria AND `conform:` obligations, two independent citation paths) → the ConformanceClaim visible in `GET /runs/:id/acceptance` (deny-dominates, `guardrailed: false`). Ships as `scenarios/qe/aw25-golden-path.md` (scenario-format v1.1, category cli, isolation exclusive), `evidence/aw25-golden/` (seed ruleset with doc↔gate id-twinned `POL-2500`, `run.sh` fail-loud chain script, `campaign-recon.aw25.json` — spec-2 schema-validated plan with a machinery-verified claim ceiling, and the recorded `chain/` evidence 00–07 from a real run), plus `tests/qe/test_aw25_golden_artifacts.py` pinning the artifacts (schema validity, id-twinning, the AC-critical citation assertions in run.sh) hermetically. Evaluator≠creator: the verdict of record is crew's acceptance read, captured verbatim. Findings recorded in the evidence README: the <200-char PHASE SUBSTANCE GATE rejects a too-terse canary BEFORE any claim is recorded (first trip hit exactly this), and the ACP carrier reports `enforcement: enforced` with an empty `armedUnits` list.
45
+ - **Flaky-verdict policy at the campaign acceptance gate (TH-21, ADR 0006 — RECON-TEST-HARNESS test-R23).** One flaky scenario can no longer silently deny OR silently pass a nightly campaign, and exclusions always carry reasons. New written policy `skills/qe/refs/campaign-flake-policy.md` + pure policy engine `scripts/qe/lib/flake-policy.mjs`, applied by `campaign-scoreboard.mjs` on every assembly: (a) **bounded diagnostic re-runs with BOTH verdicts recorded** — a re-run lands as its own runs+verdicts rows under the same stable scenario id (TH-6's flake history, now consumed at the gate via `flake_policy.history`); mixed outcomes are a `flake_signal` blocker naming `wicked-garden-qe-flaky-test-hunter` (never best-of-N), >1+2 runs of one rung is a `rerun_bound_exceeded` violation, and a `--runs` selection showing PASS while omitting a same-window deny-graded sibling is a `pass_laundering_risk` violation; (b) **quarantine lane with owner+deadline via the hunter's taxonomy** — the gate consumes the hunter's ledger `tasks` row fail-closed (`quarantined: true` + scenario binding + taxonomy cause + owner + unexpired `quarantine_expires`; invalid/expired records are reported and NOT honored — the scenario keeps denying); (c) **quarantined scenarios are excluded-with-reason** — rows stay on the scoreboard, the exclusion (id/cause/owner/deadline/reason/observed grades) rides `certification.excluded` + `certification.gate_summary`, and `gate.mjs --exclusions-from <scoreboard.json>` appends the canonical clause to `verdict_summary` so it reaches crew's acceptance payload (the 8-field `wicked.qe.gate.*` wire contract untouched; exclusions missing id/reason/owner/deadline exit 3). A fully-quarantined campaign cannot certify; a quarantined PASS is excluded too; structural violations are never excused. Hunter's SKILL.md §5/§6 now pin the machine contract (body gains required `owner`). Tests: `tests/qe/test_campaign_flake_policy.py` (9 CLI cases, hermetic) + `scripts/qe/runner/test/th21-flake-policy.test.mjs` (14 unit cases).
46
+ - **qe campaign grading through the accept trio (TH-10, ADR 0006).** New `skills/qe/refs/campaign-grading.md` playbook: campaign evidence bundles grade through the SAME role-isolated reviewer as `refs/accept.md` (evidence PATHS only; isolation hard-enforced on Claude Code via host-level `allowed-tools`, advisory on Gemini/Codex/Cursor/Kiro — the boundary is now written down in both refs), with validate-before-grading against wicked-ledger's evidence-manifest 2.1 contract (schema-fail = INCONCLUSIVE; validator unavailable = fail closed). New deterministic glue `scripts/qe/lib/campaign-scoreboard.mjs` assembles the campaign-proven verbatim scoreboard shape `{id, grade, executor_claim, evidence_ok}` and makes self-grading structurally impossible: verdict rows by executor identities (`qe-runner/executor-claim`, `*executor*`, the `test-designer` dev-loop) are refused as grade sources and reported as `self_grade_attempt` violations; `executor_claim` derives from manifest-2.1 `scenario_evidence.status` (the contract's "executor's claim, never the verdict of record" field). Encodes the scenario-defect vs product-finding fork (verdict-reason tag `[scenario-defect]` → bounded re-author/re-run fix lane; `[product-finding]` → GH issue + idempotent ledger `tasks` mirror via `--mirror-tasks`) so certification terminates: `certification.disposition` is always `certified` or `not-certified`, never pending. Reviewer skill gains the campaign-bundle duties (structural floor re-check, claim-vs-evidence posture, mandatory non-PASS classification). Tests: `tests/qe/test_campaign_scoreboard.py` (8 cases, hermetic via a `WICKED_LEDGER_PKG_DIR` stub).
47
+ - **`qe campaign` recon+generation action (TH-7, ADR 0006).** New `campaign` action on the `wicked-garden-qe` router (`skills/qe/refs/campaign.md`): derives a capability inventory from three lenses — the estate code graph when the target repo is indexed, docs recall via `wicked-garden-mem`, and live probing (health endpoints, crew's committed `packages/crew/endpoint-manifest.json`, DOM landmarks) — and emits a dependency-ordered campaign plan CONFORMING to `schemas/campaign-recon.schema.json` v1 (never a parallel format), persisted as a ledger `strategies` row + scenario-format v1 files under `.wicked-qe/campaigns/<name>/`. Assembly/validation glue is `scripts/qe/campaign_plan.py` (stdlib-only, fail-closed): honest `sources.estate: "unindexed"` degradation is DERIVED (an unindexed plan claiming estate-sourced entries is rejected), doc-derived claims are forced `status: "proposed"` pending human review (the incident-to-scenario pending-review pattern), ladder order + rung↔capability binding are enforced beyond the JSON schema, and generated stubs fail until authored (never a silent PASS). Tests: `tests/qe/test_campaign_action.py` validates a generated three-lens plan against the schema itself.
48
+ - **qe dispatch guard (TH-7, guard half of the retired agent-surface cleanup — arch-R25 ≡ test-R20).** `scripts/qe/campaign_dispatch.py`: every qe dispatch resolves its specialist through `resolve_specialist()`, which asserts the resolved worker is a shipped `wicked-garden-qe-*` skill and BLOCKS retired `wicked-testing-*` / `wicked-brain-*` names at dispatch with a clear error naming the garden replacement (exit 2 on the CLI; never a silent rewrite). Wired into `skills/qe/SKILL.md` (fork workers) and `skills/qe/refs/execute.md` (dispatch block).
49
+
50
+ ### Fixed
51
+ - **Re-landed TH-5's campaign-recon schema, clobbered by #1083's stale-base squash.** PR #1083 (TH-4) was squashed from a branch cut before #1082 merged, silently reverting `schemas/campaign-recon.schema.json`, `tests/qe/test_campaign_recon_schema.py`, and the `schemas/README.md` standalone-contract section. Restored byte-for-byte from the #1082 squash commit. (The same squash also reverted #1081's docs/peer-floor work — flagged to its owning lane, not restored here.)
48
52
 
49
53
  ### Changed
50
54
  - Site version stamp injected at build from the plugin manifest (DT-7 — can never re-stale).
51
55
  - campaign-recon schema v2: `desktop` category tiers + `isolation` annotation in one bump.
56
+ - **`wicked_ledger_version` floor `^0.2.0` → `^0.4.0` (recon XC-4 — the wicked-ledger 2.1 floor-bump wave).** wicked-ledger 0.4.0 ships evidence-manifest **2.1.0** (optional `scenario_evidence` block + first-class `claim_level` enum, `validateManifest` reviewer entry point — TH-5) and new-feature API surface, so the npm minor moved and the old caret (`^0.2.0` excludes 0.3+) had to move with it. Store compat is unchanged in every direction a garden consumer touches: SQLite `schema_version` stays **3** (no new migrations since 0.1.0), and manifest 2.1 is a **minor** — 2.0.0 bundles still validate (covered by the ledger's backward-compat smoke test) and 2.x readers gate on the major. The pin is single-sourced in `plugin.json`; the six qe skill files (`skills/qe/SKILL.md`, `skills/qe/refs/{accept,insight,integration}.md`, `skills/qe-release-readiness-engineer/SKILL.md`, `skills/qe-test-impact-analyzer/SKILL.md`) reference it symbolically and needed no edits — this completes the ledger-pin half DT-13 deferred to XC-4.
57
+ - **Peer-floor and manifest truth pass (recon DT-13).** One consistent vault-floor story: every doc restatement now says **≥ 0.5.0** — the floor `scripts/loom/manifest.py` (`version_pin="0.5"`) and `plugin.json` (`wicked_vault_version ^0.5.0`) have carried since 12.31.0 (checked by the peer registry's health probe: `loom doctor` reports a below-floor vault as `drift` and exits non-zero) — replacing the stale `≥ 0.4.0` (README, CONTRIBUTING, `skills/archetype/refs/{review,incident,migrate,modernize,specify}.md`) and `^0.3.0` (`docs/required-peers.md`) claims. manifest.py + plugin.json are declared the single source; restatements carry a greppable `<!-- vault-floor -->` marker, and `docs/required-peers.md` documents the bump procedure. `skills/core/refs/setup.md` now checks the probed vault version against the floor and tells a below-floor (e.g. 0.4.x) user to upgrade via `npm i -g wicked-vault@latest`.
58
+ - **`docs/required-peers.md` rewritten to the shipped truth.** The vault install command is now the working `npm i -g wicked-vault` form (was `npx wicked-vault-install`, which E404s on a fresh machine — no npm package of that name exists; it's a bin of `wicked-vault`). The loom row no longer presents a required external peer pinned `^0.2.0`: the engine has been absorbed in-package (`scripts/loom/`, dispatched in-process by `scripts/_loom.py`) since 12.27.0. **Decision (recon OQ-4):** the standalone `wicked-loom` npm package (0.4.0, not deprecated) is not a sanctioned install path — the pin is deleted, not bumped; `WICKED_LOOM_BIN` stays a debugging escape hatch.
59
+ - **`.claude-plugin/plugin.json`: deleted the retired `wicked_brain_version` pin** (`^0.18.0` — wicked-brain retired 2026-08, Phase 5-S7; nothing reads the key). The `wicked_ledger_version ^0.2.0` pin is deliberately untouched here — it moves with the coordinated wicked-ledger 2.1 floor-bump wave.
60
+ - **`.claude-plugin/marketplace.json`: retired-layers copy fixed** — "testing/brain/bus are opt-in layers" → estate/bus are the opt-in layers; wicked-testing and wicked-brain are retired (QE ships in-catalog as the `qe` domain; memory lives in wicked-estate).
61
+ - **`docs/brain-chunk-format.md`: retirement banner added** (recon DT-18) — the doc read as live instructions to write chunks into `~/.wicked-brain`, which is a frozen archive that must never be written; the format is preserved as historical reference for the chunks migrated into wicked-estate.
62
+ - **Site: the wicked-interactive card tells the document-engine story** (recon DT-12) — wicked-interactive moved planes rather than retiring: it is the foundation's document engine (storage, version lineage, HTML/PDF/PPTX/video rendering) that wicked-crew spawns and proxies, not a standalone visual builder. Install command unchanged (two-step marketplace add + install).
63
+ - **Backfilled the 12.30.0 and 12.31.0 changelog entries below** (recon DT-17) — the previous release entry was 12.29.1 while npm shipped 12.31.0; the vault-direct-peer entry that sat under [Unreleased] shipped in 12.31.0 and now lives there.
52
64
 
53
65
  ## [12.31.0] — 2026-08-25
54
66
 
package/README.md CHANGED
@@ -69,6 +69,14 @@ installs/updates the whole wicked-\* family (garden, its peers, and the rest).
69
69
  > and the previous copy is put back). Those transient dirs are **not plugins**; a leftover after an interrupted install is
70
70
  > safe to delete (`status` lists them).
71
71
 
72
+ **Other CLIs (Codex, OpenCode, Pi, Antigravity)** — `npx wicked-installer install-<cli> wicked-garden` copies
73
+ the skills only (flat, by name — no `scripts/`, no venv). Every skill's text works there as written: own files are
74
+ referenced relative to the skill's directory, other skills by name, and the shared runtime only through the
75
+ launcher — `wicked-garden run scripts/<x>.py …`. So for script-backed skills the runtime prerequisite on those
76
+ CLIs is `npm i -g wicked-garden` (or `npx wicked-garden`); the launcher resolves the plugin root and the Python
77
+ interpreter itself (`wicked-garden doctor` shows what it found) and never writes under the root. Prose-only
78
+ skills need nothing. Under wicked-crew the same launcher points at the run's snapshot via `WICKED_GARDEN_ROOT`.
79
+
72
80
  Then, in a Claude Code session:
73
81
 
74
82
  ```bash
@@ -1201,12 +1201,23 @@ def main():
1201
1201
  # Export CLAUDE_PLUGIN_ROOT to CLAUDE_ENV_FILE so Bash tool calls can access it.
1202
1202
  # Hooks receive CLAUDE_PLUGIN_ROOT from the plugin runtime, but Bash tool calls
1203
1203
  # do not inherit it. Writing to CLAUDE_ENV_FILE bridges the gap.
1204
+ # Since 12.33 (cross-CLI skills, F-079) skill text reaches scripts/ only through
1205
+ # the `wicked-garden` launcher, so the same bridge puts <root>/scripts on PATH
1206
+ # (the launcher twin lives there — no npm install needed on Claude Code) and
1207
+ # exports WICKED_GARDEN_ROOT, the launcher's first root candidate.
1204
1208
  env_file = os.environ.get("CLAUDE_ENV_FILE")
1205
1209
  plugin_root = os.environ.get("CLAUDE_PLUGIN_ROOT")
1206
1210
  if env_file and plugin_root:
1207
1211
  try:
1208
1212
  with open(env_file, "a") as f:
1209
1213
  f.write(f'export CLAUDE_PLUGIN_ROOT="{plugin_root}"\n')
1214
+ f.write(f'export WICKED_GARDEN_ROOT="{plugin_root}"\n')
1215
+ # idempotent: SessionStart also fires on reconnects, and the env file is
1216
+ # appended to — never let PATH grow one entry per fire
1217
+ f.write(
1218
+ f'case ":$PATH:" in *":{plugin_root}/scripts:"*) ;; '
1219
+ f'*) export PATH="{plugin_root}/scripts:$PATH" ;; esac\n'
1220
+ )
1210
1221
  except OSError:
1211
1222
  pass
1212
1223
 
package/install.mjs CHANGED
@@ -12,6 +12,11 @@
12
12
  * npx wicked-garden update [options] Same as install
13
13
  * npx wicked-garden status [options] Show the install state per config dir
14
14
  * npx wicked-garden pack <verb> Third-party pack tooling (check/register/list/…)
15
+ * npx wicked-garden run <path> [args] Launcher: run a plugin-root-relative script (delegates
16
+ * npx wicked-garden python <path|-|-c> to scripts/wicked-garden.mjs — root resolution
17
+ * npx wicked-garden path <path> WICKED_GARDEN_ROOT → CLAUDE_PLUGIN_ROOT → this package,
18
+ * npx wicked-garden root interpreter ladder .venv → uv → python3 → python → py -3;
19
+ * npx wicked-garden doctor this is how portable skill text reaches scripts/)
15
20
  * npx wicked-garden --version Print version
16
21
  * npx wicked-garden --help Print usage
17
22
  *
@@ -57,7 +62,9 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
57
62
  const pkg = JSON.parse(readFileSync(join(__dirname, "package.json"), "utf8"));
58
63
 
59
64
  const PLUGIN_DIRS = [".claude-plugin", "hooks", "scripts", "skills", "schemas"];
60
- const PLUGIN_FILES = ["ETHOS.md", "CHANGELOG.md", "README.md", "WICKED_GARDEN_BUS_EVENTS.md", "pyproject.toml"];
65
+ // uv.lock rides along so the copy's `uv sync` (and the launcher's `uv run --frozen`) resolve
66
+ // the same pins the release was tested with.
67
+ const PLUGIN_FILES = ["ETHOS.md", "CHANGELOG.md", "README.md", "WICKED_GARDEN_BUS_EVENTS.md", "pyproject.toml", "uv.lock"];
61
68
  const SKIP = [/__pycache__/, /\.pyc$/, /\.pyo$/, /\.DS_Store$/];
62
69
  // Dev-only subdirs within scripts/ — not needed at runtime
63
70
  const SCRIPTS_DEV = ["ci", "wg"];
@@ -109,6 +116,11 @@ function findBin(name) {
109
116
 
110
117
  class UsageError extends Error {}
111
118
 
119
+ // Launcher verbs — delegated verbatim to scripts/wicked-garden.mjs (the single implementation;
120
+ // scripts/wicked-garden and scripts/wicked-garden.cmd are its PATH twins for crew snapshots).
121
+ // Like `pack`, they own their flags: everything after the verb passes through untouched.
122
+ const LAUNCHER_VERBS = new Set(["run", "python", "path", "root", "doctor"]);
123
+
112
124
  // A value-taking flag never swallows an option, in either form: `--claude-home --dry-run`,
113
125
  // `--claude-home=--dry-run` and `--claude-home=-x` are errors, as are empty/blank values.
114
126
  // A directory whose name really starts with "-" is written `./-x` or as an absolute path.
@@ -128,7 +140,7 @@ function parseArgs(argv) {
128
140
  const opts = { cmd: undefined, rest: [], claudeHomes: [], dryRun: false };
129
141
  for (let i = 0; i < argv.length; i++) {
130
142
  const arg = argv[i];
131
- if (opts.cmd === "pack") { opts.rest.push(arg); continue; }
143
+ if (opts.cmd === "pack" || LAUNCHER_VERBS.has(opts.cmd)) { opts.rest.push(arg); continue; }
132
144
  if (arg === "--dry-run") {
133
145
  opts.dryRun = true;
134
146
  } else if (arg === "--claude-home") {
@@ -581,6 +593,11 @@ function usage() {
581
593
  " npx wicked-garden install [options] Install or update the plugin copy (`update` is an alias)",
582
594
  " npx wicked-garden status [options] Show the install state per config dir (read-only)",
583
595
  " npx wicked-garden pack <verb> Third-party pack tooling (check/register/list/floors/install)",
596
+ " npx wicked-garden run <path> [args] Launcher: run a plugin-root-relative script (.py/.mjs/.js/.sh)",
597
+ " npx wicked-garden python <path|-|-c> Launcher: force the python interpreter (stdin / -c pass through)",
598
+ " npx wicked-garden path <path> Launcher: print the absolute path under the plugin root",
599
+ " npx wicked-garden root Launcher: print the resolved plugin root",
600
+ " npx wicked-garden doctor Launcher: JSON report (root, source, python, node, uv)",
584
601
  " npx wicked-garden --version Show version",
585
602
  " npx wicked-garden --help Show this usage",
586
603
  "",
@@ -629,6 +646,15 @@ switch (opts.cmd) {
629
646
  case "pack":
630
647
  process.exit(cmdPack(opts.rest));
631
648
  break;
649
+ case "run":
650
+ case "python":
651
+ case "path":
652
+ case "root":
653
+ case "doctor": {
654
+ const { main: launcherMain } = await import("./scripts/wicked-garden.mjs");
655
+ process.exit(launcherMain([opts.cmd, ...opts.rest]));
656
+ break;
657
+ }
632
658
  case "--version":
633
659
  case "-v":
634
660
  console.log(pkg.version);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wicked-garden",
3
- "version": "12.32.2",
3
+ "version": "12.34.0",
4
4
  "type": "module",
5
5
  "description": "Curated toolkit for what AI coding agents can't do alone: evidence-gated work, codegraph relationships, deterministic multi-file refactor, multi-model second opinions, and cross-session memory. Installs as a Claude Code plugin.",
6
6
  "keywords": [
package/pyproject.toml CHANGED
@@ -1,6 +1,11 @@
1
1
  [project]
2
2
  name = "wicked-garden"
3
- version = "1.33.0"
3
+ # NOT a release anchor. The plugin's version lives in package.json and is synced into
4
+ # .claude-plugin/{plugin,marketplace}.json by `npm version` -> .github/scripts/sync-plugin-version.mjs
5
+ # when the vX.Y.Z tag runs release.yml. This Python project is never built or published (the hatch
6
+ # target exists only so uv can manage deps), nothing reads this field, and the release train does
7
+ # not bump it — PEP 621 requires a value, so it is pinned to the placeholder 0.0.0 (mirrored in uv.lock).
8
+ version = "0.0.0"
4
9
  description = "AI-Native SDLC delivered as a single Claude Code plugin"
5
10
  requires-python = ">=3.10"
6
11
  dependencies = [
@@ -5,7 +5,11 @@
5
5
  # Python may only be available as `python` or `py -3`.
6
6
  #
7
7
  # Usage:
8
- # sh "${CLAUDE_PLUGIN_ROOT}/scripts/_python.sh" script.py [args...]
8
+ # sh "${CLAUDE_PLUGIN_ROOT}/scripts/_python.sh" script.py [args...] # hooks (Claude Code substitutes the variable)
9
+ #
10
+ # Skill text does NOT use this shim: it is installed flat (no scripts/, no plugin root)
11
+ # on Codex/Pi/OpenCode/Antigravity, so it calls the launcher instead —
12
+ # wicked-garden run scripts/<x>.py [args...] (scripts/wicked-garden.mjs; see .claude/CLAUDE.md)
9
13
  #
10
14
  # This script tries python3, then python, then py -3, and exec's the
11
15
  # first one that exists. If none are found, exits with an error.
package/scripts/_run.py CHANGED
@@ -9,8 +9,9 @@ Two modes:
9
9
  Executes normally. On argparse errors (exit code 2),
10
10
  automatically appends --help output for self-correction.
11
11
 
12
- Script paths are resolved relative to CLAUDE_PLUGIN_ROOT (or this
13
- script's parent directory as fallback).
12
+ Script paths are resolved relative to CLAUDE_PLUGIN_ROOT — which the
13
+ `wicked-garden` launcher exports (alongside WICKED_GARDEN_ROOT) on every
14
+ host — or this script's parent directory as fallback.
14
15
 
15
16
  Examples:
16
17
  # Show usage before invoking
@@ -20,7 +21,7 @@ Examples:
20
21
  python3 scripts/_run.py scripts/crew/phase_manager.py create my-project --description "foo"
21
22
 
22
23
  # Works with uv for scripts that need deps
23
- cd "${CLAUDE_PLUGIN_ROOT}" && uv run python scripts/_run.py scripts/crew/phase_manager.py status my-project
24
+ wicked-garden run scripts/_run.py scripts/crew/phase_manager.py status my-project
24
25
  """
25
26
 
26
27
  import json
@@ -40,8 +40,7 @@ Usage (library):
40
40
  # directives -> [{"archetype": "build", "phases": [...], "next_action": ...}]
41
41
 
42
42
  Usage (CLI):
43
- sh "${CLAUDE_PLUGIN_ROOT}/scripts/_python.sh" \\
44
- "${CLAUDE_PLUGIN_ROOT}/scripts/crew/archetypes_v11.py" \\
43
+ wicked-garden run scripts/crew/archetypes_v11.py \\
45
44
  detect --prompt "add caching to the dashboard"
46
45
  """
47
46
 
@@ -21,8 +21,7 @@ Usage (library):
21
21
  # else -> r["gap_task"] = {title, body, ...}, dispatch is None
22
22
 
23
23
  Usage (CLI):
24
- sh "${CLAUDE_PLUGIN_ROOT}/scripts/_python.sh" \\
25
- "${CLAUDE_PLUGIN_ROOT}/scripts/crew/stack_registry.py" \\
24
+ wicked-garden run scripts/crew/stack_registry.py \\
26
25
  resolve --stack node-legacy-to-modern
27
26
  """
28
27
 
@@ -53,7 +53,8 @@ def pinned_version() -> str:
53
53
  own ``metadata.schema_version`` const (== its ``$id`` version segment).
54
54
  Deliberately NOT the vendored bundle ``VERSION`` file — that tracks the
55
55
  owner's whole 4-schema bundle and moves when ANY sibling schema changes
56
- (1.0.0→1.1.0 added conformance-rules.schema.json; this schema stayed 1.0.0)."""
56
+ (1.0.0→1.1.0 added conformance-rules.schema.json, 1.1.0→1.2.0 changed only
57
+ that sibling's steering fields; this schema stayed 1.0.0 throughout)."""
57
58
  schema = load_schema()
58
59
  return schema["properties"]["metadata"]["properties"]["schema_version"]["const"]
59
60
 
@@ -18,7 +18,7 @@
18
18
  * payload: run_id, project_id
19
19
  *
20
20
  * Usage (from a target repo's root):
21
- * node "${CLAUDE_PLUGIN_ROOT}/scripts/qe/lib/gate.mjs" \
21
+ * wicked-garden run scripts/qe/lib/gate.mjs \
22
22
  * --project-id <id> --run-id <id> --verdict <PASS|FAIL|CONDITIONAL|SYSTEM_ERROR> \
23
23
  * --verdict-summary "<text>" [--rationale-ref <path>] [--council-run-id <id>]
24
24
  * [--mode gate|event|manual|crew_integration] [--exclusions-from <scoreboard.json>]
@@ -5,8 +5,8 @@ Used by command prompts to avoid hardcoded ~/.something-wicked/ paths.
5
5
  Prints the resolved path to stdout.
6
6
 
7
7
  Usage:
8
- python3 "${CLAUDE_PLUGIN_ROOT}/scripts/resolve_path.py" wicked-delivery
9
- python3 "${CLAUDE_PLUGIN_ROOT}/scripts/resolve_path.py" wicked-garden:search extracted
8
+ wicked-garden run scripts/resolve_path.py wicked-delivery
9
+ wicked-garden run scripts/resolve_path.py wicked-garden:search extracted
10
10
  """
11
11
 
12
12
  import sys
@@ -0,0 +1,22 @@
1
+ #!/bin/sh
2
+ # wicked-garden launcher — POSIX twin of scripts/wicked-garden.mjs (the implementation).
3
+ # wicked-crew prepends <snapshot>/scripts to a seat's PATH so `wicked-garden run …` in
4
+ # skill text resolves here; it needs `node` (>= 20) on PATH and nothing else. When this
5
+ # file is reached through a symlink (`ln -s <root>/scripts/wicked-garden ~/bin/…`) the
6
+ # link is followed if `readlink` exists; otherwise $0 is used as-is. The logic lives
7
+ # once, in wicked-garden.mjs — never edit it here.
8
+ self=$0
9
+ n=0
10
+ while [ -h "$self" ] && [ "$n" -lt 16 ]; do
11
+ link=$(readlink "$self" 2>/dev/null) || break
12
+ case $link in
13
+ /*) self=$link ;;
14
+ *) self=${self%/*}/$link ;;
15
+ esac
16
+ n=$((n + 1))
17
+ done
18
+ case $self in
19
+ */*) dir=${self%/*} ;;
20
+ *) dir=. ;;
21
+ esac
22
+ exec node "$dir/wicked-garden.mjs" "$@"
@@ -0,0 +1,4 @@
1
+ @echo off
2
+ rem wicked-garden launcher - Windows twin of scripts\wicked-garden.mjs (the implementation).
3
+ rem Needs node (>= 20) on PATH. The logic lives once, in wicked-garden.mjs.
4
+ node "%~dp0wicked-garden.mjs" %*