wicked-garden 12.28.1 → 12.29.1
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/.claude-plugin/components.json +8 -3
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.product/DES-001-technical-design.md +309 -0
- package/.product/RAID.md +62 -0
- package/.product/REQ-001-application-overview.md +94 -0
- package/.product/REQ-002-technology-constraints.md +103 -0
- package/.product/REQ-003-domain-model.md +191 -0
- package/.product/REQ-004-ways-of-working.md +189 -0
- package/.product/REQ-005-dod-criteria.md +129 -0
- package/.product/TEST-001-test-strategy.md +165 -0
- package/.product/evidence/.gitkeep +0 -0
- package/.product/reviews/.gitkeep +0 -0
- package/.product/reviews/adversarial-review-v12.28.1.md +211 -0
- package/CHANGELOG.md +20 -0
- package/README.md +1 -1
- package/WICKED_GARDEN_BUS_EVENTS.md +62 -51
- package/docs/required-peers.md +1 -1
- package/hooks/hooks.json +1 -0
- package/hooks/scripts/post_tool.py +4 -4
- package/hooks/scripts/pre_tool.py +15 -15
- package/hooks/scripts/session_end.py +14 -3
- package/hooks/scripts/stop.py +50 -14
- package/hooks/scripts/subagent_lifecycle.py +2 -2
- package/hooks/scripts/subscribers/on_gate_decided.py +4 -4
- package/hooks/subscriptions/on_gate_decided.json +1 -1
- package/package.json +2 -1
- package/scripts/_brain_ingest/session_fact_extractor.py +1 -1
- package/scripts/_bus.py +102 -66
- package/scripts/_bus_catalog_gen.py +8 -5
- package/scripts/_bus_consumers.json +6 -6
- package/scripts/_bus_emit.py +2 -2
- package/scripts/_event_log_reader.py +1 -1
- package/scripts/_heavy_cadence.py +134 -21
- package/scripts/_loom.py +3 -1
- package/scripts/_validate_registry.py +27 -20
- package/scripts/classify/persist.py +1 -1
- package/scripts/crew/archetypes_v11.py +5 -0
- package/scripts/crew/phase_manager.py +12 -7
- package/scripts/crew/stack_registry.py +4 -4
- package/scripts/delivery/drift.py +1 -1
- package/scripts/domain/__init__.py +9 -0
- package/scripts/domain/_clients.py +434 -0
- package/scripts/domain/_mocks.py +157 -0
- package/scripts/domain/_rule_extractor.py +155 -0
- package/scripts/domain/emit_domain_model.py +410 -0
- package/scripts/domain/extract_loop.py +209 -0
- package/scripts/domain/validate_domain_model.py +294 -0
- package/scripts/jam/_bus_consumers.py +7 -7
- package/scripts/platform/guard_pipeline.py +140 -7
- package/scripts/platform/guard_profiles.py +1 -0
- package/scripts/qe/coverage_tracker.py +4 -4
- package/scripts/qe/registry_store.py +2 -2
- package/scripts/sentinel/invariants.py +9 -4
- package/scripts/smaht/_bus_consumers.py +3 -3
- package/skills/archetype/refs/modernize.md +16 -1
- package/skills/core/SKILL.md +1 -0
- package/skills/domain/SKILL.md +148 -0
- package/skills/domain/refs/domain-model-emit.md +129 -0
- package/skills/domain/refs/extraction-flow.md +112 -0
- package/skills/domain/refs/fixtures/example-domain-model.json +225 -0
- package/skills/domain/vendor/README.md +37 -0
- package/skills/domain/vendor/VERSION +1 -0
- package/skills/domain/vendor/domain-model.schema.json +224 -0
- package/skills/domain-coverage/SKILL.md +77 -0
- package/skills/domain-extractor/SKILL.md +92 -0
- package/skills/domain-modeler/SKILL.md +86 -0
- package/skills/engineering-conformance-reviewer/SKILL.md +83 -0
- package/skills/jam-brainstorm-facilitator/SKILL.md +3 -3
- package/skills/jam-council/SKILL.md +1 -1
- package/skills/platform/audit/refs/audit.md +2 -2
- package/skills/platform/compliance/refs/compliance.md +2 -2
- package/skills/platform-compliance-officer/SKILL.md +3 -3
- package/skills/platform-security-engineer/SKILL.md +1 -1
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"_comment": "Issue #328: Component declarations for wicked-garden plugin. Claude Code plugin.json does not yet support inline component declarations beyond path overrides. This manifest documents all components for tooling, validation, and future schema support. When plugin.json gains a 'components' field, merge this data into plugin.json. The plugin is skills-only: former commands/ became actions of consolidated per-domain skills, and former agents/ became standalone context:fork worker skills (enumerated under fork_skills). Regenerate derived blocks with scripts/ci/sync_components.py.",
|
|
3
3
|
"domains": ["agentic", "crew", "data", "engineering", "jam", "mem", "persona", "platform", "product", "qe", "search", "smaht"],
|
|
4
4
|
"summary": {
|
|
5
|
-
"skills":
|
|
6
|
-
"fork_skills":
|
|
5
|
+
"skills": 99,
|
|
6
|
+
"fork_skills": 38,
|
|
7
7
|
"hooks": 13,
|
|
8
8
|
"specialists": 7
|
|
9
9
|
},
|
|
@@ -21,8 +21,13 @@
|
|
|
21
21
|
"data": ["data"],
|
|
22
22
|
"data-engineer": ["data-engineer"],
|
|
23
23
|
"deliberate": ["deliberate"],
|
|
24
|
+
"domain": ["domain"],
|
|
25
|
+
"domain-coverage": ["domain-coverage"],
|
|
26
|
+
"domain-extractor": ["domain-extractor"],
|
|
27
|
+
"domain-modeler": ["domain-modeler"],
|
|
24
28
|
"engineering": ["architecture", "backend", "debugging", "docs", "engineering", "frontend", "integration", "large-scale-migration", "patch", "system-design", "unit-test-quality"],
|
|
25
29
|
"engineering-api-documentarian": ["engineering-api-documentarian"],
|
|
30
|
+
"engineering-conformance-reviewer": ["engineering-conformance-reviewer"],
|
|
26
31
|
"engineering-migration-engineer": ["engineering-migration-engineer"],
|
|
27
32
|
"engineering-solution-architect": ["engineering-solution-architect"],
|
|
28
33
|
"ground": ["ground"],
|
|
@@ -53,7 +58,7 @@
|
|
|
53
58
|
"workflow": ["workflow"],
|
|
54
59
|
"worktrees": ["worktrees"]
|
|
55
60
|
},
|
|
56
|
-
"fork_skills": ["wicked-garden-agentic-architect", "wicked-garden-agentic-performance-analyst", "wicked-garden-agentic-safety-reviewer", "wicked-garden-archetype", "wicked-garden-classify", "wicked-garden-crew-implementer", "wicked-garden-crew-researcher", "wicked-garden-crew-reviewer", "wicked-garden-data-engineer", "wicked-garden-engineering-api-documentarian", "wicked-garden-engineering-debugging", "wicked-garden-engineering-migration-engineer", "wicked-garden-engineering-solution-architect", "wicked-garden-ground", "wicked-garden-integration-discovery", "wicked-garden-jam-brainstorm-facilitator", "wicked-garden-jam-council", "wicked-garden-multi-model", "wicked-garden-persona-agent", "wicked-garden-platform-compliance-officer", "wicked-garden-platform-privacy-expert", "wicked-garden-platform-security-engineer", "wicked-garden-product-a11y-expert", "wicked-garden-product-requirements-analyst", "wicked-garden-product-ui-reviewer", "wicked-garden-product-ux-designer", "wicked-garden-product-value-strategist", "wicked-garden-qe-semantic-reviewer", "wicked-garden-runtime-exec", "wicked-garden-smaht", "wicked-garden-swarm", "wicked-garden-wickedizer", "wicked-garden-workflow", "wicked-garden-worktrees"],
|
|
61
|
+
"fork_skills": ["wicked-garden-agentic-architect", "wicked-garden-agentic-performance-analyst", "wicked-garden-agentic-safety-reviewer", "wicked-garden-archetype", "wicked-garden-classify", "wicked-garden-crew-implementer", "wicked-garden-crew-researcher", "wicked-garden-crew-reviewer", "wicked-garden-data-engineer", "wicked-garden-domain-coverage", "wicked-garden-domain-extractor", "wicked-garden-domain-modeler", "wicked-garden-engineering-api-documentarian", "wicked-garden-engineering-conformance-reviewer", "wicked-garden-engineering-debugging", "wicked-garden-engineering-migration-engineer", "wicked-garden-engineering-solution-architect", "wicked-garden-ground", "wicked-garden-integration-discovery", "wicked-garden-jam-brainstorm-facilitator", "wicked-garden-jam-council", "wicked-garden-multi-model", "wicked-garden-persona-agent", "wicked-garden-platform-compliance-officer", "wicked-garden-platform-privacy-expert", "wicked-garden-platform-security-engineer", "wicked-garden-product-a11y-expert", "wicked-garden-product-requirements-analyst", "wicked-garden-product-ui-reviewer", "wicked-garden-product-ux-designer", "wicked-garden-product-value-strategist", "wicked-garden-qe-semantic-reviewer", "wicked-garden-runtime-exec", "wicked-garden-smaht", "wicked-garden-swarm", "wicked-garden-wickedizer", "wicked-garden-workflow", "wicked-garden-worktrees"],
|
|
57
62
|
"hooks": ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostToolUse", "PostToolUseFailure", "TaskCompleted", "SubagentStart", "SubagentStop", "PermissionRequest", "Notification", "PreCompact", "Stop", "SessionEnd"],
|
|
58
63
|
"specialists": [
|
|
59
64
|
{
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"name": "wicked-garden",
|
|
9
9
|
"source": "./",
|
|
10
10
|
"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 (auto-installed via wicked-testing) and re-derives through garden's built-in engine; testing/brain/bus are opt-in layers.",
|
|
11
|
-
"version": "12.
|
|
11
|
+
"version": "12.29.1"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
14
|
-
"version": "12.
|
|
14
|
+
"version": "12.29.1"
|
|
15
15
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wicked-garden",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.29.1",
|
|
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 codegraph + injected bus/dispatch/capability edges power blast-radius & lineage. Plus deterministic multi-file refactor (wicked-patch), cross-session memory (wicked-brain), real multi-model second opinions (jam:council), portable expertise as on-demand skill-refs, and evidence-gated testing (wicked-testing). 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 (installed automatically via wicked-testing); wicked-testing, wicked-brain, and wicked-bus are opt-in layers \u2014 install what you'll use, the toolkit works without the rest.",
|
|
5
5
|
"wicked_testing_version": "^0.8.0",
|
|
6
6
|
"wicked_vault_version": "^0.4.0",
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: DES-001-technical-design
|
|
3
|
+
title: wicked-garden — Technical Design
|
|
4
|
+
status: draft
|
|
5
|
+
version: 0.1
|
|
6
|
+
date: 2026-07-21
|
|
7
|
+
author: mike.parcewski@gmail.com
|
|
8
|
+
review-required: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# DES-001 — Technical Design
|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
wicked-garden is delivered as a Claude Code plugin. Its runtime is the Claude Code harness; its surfaces are skills (Markdown files with YAML frontmatter loaded by the harness). Imperative logic — archetype detection, evidence gate, compiler, domain store, session state, event bus integration — lives in Python scripts under `scripts/` and `hooks/scripts/`. No server-side component is required for core function (the Flask daemon is opt-in).
|
|
16
|
+
|
|
17
|
+
The plugin is **skills-only** as of v12.25. There are no slash commands in the distributed artifact. Three hook types fire at harness lifecycle events. A daemon provides optional long-running operation support.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Plugin Architecture
|
|
22
|
+
|
|
23
|
+
### Directory Structure
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
wicked-garden/
|
|
27
|
+
├── .claude-plugin/
|
|
28
|
+
│ ├── plugin.json # version, peer ranges, metadata
|
|
29
|
+
│ ├── marketplace.json # listing metadata
|
|
30
|
+
│ ├── archetypes.json # v11 archetype catalog (source of truth)
|
|
31
|
+
│ ├── components.json # derived skill surface manifest (generated)
|
|
32
|
+
│ └── specialist.json # specialist resolver registry
|
|
33
|
+
├── skills/
|
|
34
|
+
│ ├── archetype/ # v11 entry point + 10 ref playbooks
|
|
35
|
+
│ │ └── refs/{archetype}.md # one playbook per work-shape
|
|
36
|
+
│ ├── {domain}/ # domain router skills (user-invocable)
|
|
37
|
+
│ │ ├── SKILL.md # frontmatter + slim body
|
|
38
|
+
│ │ └── refs/ # on-demand rubrics and content
|
|
39
|
+
│ └── {domain}-{role}/ # fork worker skills (context:fork)
|
|
40
|
+
│ └── SKILL.md
|
|
41
|
+
├── hooks/
|
|
42
|
+
│ ├── hooks.json # hook registration
|
|
43
|
+
│ └── scripts/ # stdlib-only Python scripts
|
|
44
|
+
│ ├── bootstrap.py # SessionStart
|
|
45
|
+
│ ├── prompt_submit.py # UserPromptSubmit → archetype detection
|
|
46
|
+
│ └── stop.py # Stop → teardown
|
|
47
|
+
├── scripts/
|
|
48
|
+
│ ├── crew/
|
|
49
|
+
│ │ ├── archetypes_v11.py # detector + steering engine
|
|
50
|
+
│ │ ├── phase_manager.py # slim project state
|
|
51
|
+
│ │ ├── scope_delta.py # HITL scope-delta heuristic
|
|
52
|
+
│ │ ├── specialist_resolver.py
|
|
53
|
+
│ │ ├── _task_reader.py
|
|
54
|
+
│ │ ├── _task_audit_writer.py
|
|
55
|
+
│ │ └── detectors/ # per-archetype detection helpers
|
|
56
|
+
│ ├── qe/
|
|
57
|
+
│ │ ├── vault_gate.py # ProducesGate: shells wicked-loom gate
|
|
58
|
+
│ │ ├── prove.py # evidence recording with actor logic
|
|
59
|
+
│ │ └── evidence_tracker.py # legacy claim-only tracker (fallback/bookkeeping)
|
|
60
|
+
│ ├── compiler/
|
|
61
|
+
│ │ ├── compile.py # top-level compiler entry
|
|
62
|
+
│ │ └── phase0/detect.py # ecosystem/binding detection
|
|
63
|
+
│ ├── _domain_store.py # local JSON persistence with optional MCP routing
|
|
64
|
+
│ ├── _session.py # per-session shared state
|
|
65
|
+
│ ├── _bus.py # wicked-bus event emission
|
|
66
|
+
│ └── _paths.py # project-scoped path resolution
|
|
67
|
+
├── daemon/ # optional Flask server
|
|
68
|
+
└── tests/ # unit tests (pytest)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Skill Loading and Progressive Disclosure
|
|
72
|
+
|
|
73
|
+
All skill SKILL.md files are loaded into the harness context on invocation. Frontmatter is always loaded. The body is loaded when the skill is invoked. Refs are loaded on demand via `Skill()` dispatch from the body.
|
|
74
|
+
|
|
75
|
+
The slim body contract enforces three body patterns:
|
|
76
|
+
- **Pattern A** (≤ 8 lines): state mutation, advisory output. No dispatch.
|
|
77
|
+
- **Pattern B** (≤ 30 lines): write a session-specific brief, then dispatch to a ref or worker.
|
|
78
|
+
- **Pattern C** (≤ 35 lines): interactive branch to get a user decision, then dispatch.
|
|
79
|
+
|
|
80
|
+
Refs files are the heavy content layer (200-300 lines). Subagent contexts are short-lived and isolated; loading refs in them via `Skill()` is the intended pattern. Parent-context bloat is the problem being avoided.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Archetype Detection Flow
|
|
85
|
+
|
|
86
|
+
The archetype detection pipeline runs on every user prompt via the `UserPromptSubmit` hook.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
User submits prompt
|
|
90
|
+
→ Claude Code fires UserPromptSubmit event
|
|
91
|
+
→ hooks/scripts/prompt_submit.py
|
|
92
|
+
→ calls scripts/crew/archetypes_v11.py::detect_archetypes(prompt_text)
|
|
93
|
+
→ detector scores prompt against all 10 archetype definitions
|
|
94
|
+
(each archetype definition is in archetypes.json; per-archetype
|
|
95
|
+
helpers in scripts/crew/detectors/ refine scores)
|
|
96
|
+
→ returns sorted list of (archetype_name, score) pairs above threshold
|
|
97
|
+
→ hook script emits system-reminder:
|
|
98
|
+
<wg archetype="migrate" score="0.91" />
|
|
99
|
+
(or multi-archetype: <wg archetype="build,migrate" score="0.85,0.72" />)
|
|
100
|
+
→ hook returns {"continue": true}
|
|
101
|
+
|
|
102
|
+
Harness injects system-reminder into context
|
|
103
|
+
→ harness (or agent) invokes wicked-garden-archetype skill
|
|
104
|
+
with detected work-shape name
|
|
105
|
+
→ skill body dispatches to skills/archetype/refs/{archetype}.md
|
|
106
|
+
→ playbook defines phase shape, produces contract, HITL discipline
|
|
107
|
+
→ agent executes phases; invokes domain skills for expertise
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The detector is a scoring function, not a classifier — it returns a set with scores, not a single label. Multi-archetype is normal. The harness executes archetypes in dependency order declared by `next_archetypes` in `archetypes.json`.
|
|
111
|
+
|
|
112
|
+
Archetype detection is **steering, not blocking**. The system-reminder is advisory; the harness decides whether to invoke the archetype skill. No gate blocks execution based on classification alone.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Evidence Gate Mechanics
|
|
117
|
+
|
|
118
|
+
The evidence gate is the v12 loom cutover architecture: loom is the sole gate/resolve engine. The in-process vault re-derivation path was removed at v12 loom cutover.
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
agent/skill calls gate_satisfied() in scripts/qe/vault_gate.py
|
|
122
|
+
→ (require=True, the default: fail-closed stance)
|
|
123
|
+
→ resolves wicked-loom binary:
|
|
124
|
+
WICKED_LOOM_BIN env → config → PATH → node_modules/.bin → npx
|
|
125
|
+
→ if WICKED_LOOM_CUTOVER=off:
|
|
126
|
+
return {"gate": "unavailable", "reason": "loom cutover disabled"}
|
|
127
|
+
→ shells: wicked-loom gate [--archetype X] [--with-attestations]
|
|
128
|
+
→ wicked-loom shells: wicked-vault cross-check [--actor WICKED_VAULT_ACTOR]
|
|
129
|
+
→ wicked-vault:
|
|
130
|
+
re-hashes evidence payload (content hash)
|
|
131
|
+
re-runs the evidence verifier
|
|
132
|
+
checks actor identity for attestation requests:
|
|
133
|
+
- explicit actor → acceptable
|
|
134
|
+
- env-user → rejected (vault >= 0.4.0 breaking change)
|
|
135
|
+
→ wicked-loom returns structured gate result
|
|
136
|
+
→ gate_satisfied() interprets:
|
|
137
|
+
green: verifier passed, hash matched, actor acceptable
|
|
138
|
+
fail-closed: any failure → {"gate": "unavailable"} or {"gate": "fail"}
|
|
139
|
+
never: vacuous pass when evidence is missing
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Actor identity for hard gates**: the `WICKED_VAULT_ACTOR` env var (default `garden-prove`) is the identity under which evidence is recorded and attested. `scripts/qe/prove.py::_prove_actor()` is the reference for resolving the actor at runtime. Hard-gate playbooks pass `--actor "${WICKED_VAULT_ACTOR:-garden-prove}"` explicitly.
|
|
143
|
+
|
|
144
|
+
**Legacy path**: `evidence_tracker.py` (claim-only, no re-derivation) remains as a fallback and bookkeeping layer. `gate_satisfied(require=False)` opts back to the claim-only path. This path does not satisfy any hard gate.
|
|
145
|
+
|
|
146
|
+
**Kill switches**:
|
|
147
|
+
- `WICKED_LOOM_CUTOVER=off` — disables the gate. Gate returns `unavailable`.
|
|
148
|
+
- `WICKED_VAULT_BIN=""` — kills the vault behind loom. Gate fails closed.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Multi-Model Council Flow
|
|
153
|
+
|
|
154
|
+
The council is a structured independent evaluation, not a simulation of multiple viewpoints by a single model.
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
Developer/skill invokes wicked-garden-jam council <target>
|
|
158
|
+
→ wicked-garden-jam-council fork worker skill activated
|
|
159
|
+
→ worker enumerates available external LLM CLIs
|
|
160
|
+
(Claude Code via Antigravity, Codex, local models — configured per session)
|
|
161
|
+
→ for each available participant:
|
|
162
|
+
Task(subagent_type=..., prompt=council_prompt_for(participant, target))
|
|
163
|
+
→ isolated context: no shared state with invoking session
|
|
164
|
+
→ participant evaluates target and returns structured verdict
|
|
165
|
+
(findings, concerns, confidence)
|
|
166
|
+
→ council skill collects all verdicts
|
|
167
|
+
→ synthesizes: agreement points, disagreement points, unresolved tensions
|
|
168
|
+
→ returns multi-perspective evaluation to invoking skill or developer
|
|
169
|
+
|
|
170
|
+
Harness (or invoking archetype) decides how to weight verdicts:
|
|
171
|
+
→ unanimous failure may be treated as a hard gate
|
|
172
|
+
→ mixed results surface as findings for developer resolution
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The council is the only mechanism in wicked-garden for genuine independent multi-model evaluation. The `quick` action in the jam skill is a single-model lightweight exploration — not a council.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## wicked-patch: Graph-Driven Multi-File Refactor
|
|
180
|
+
|
|
181
|
+
wicked-patch is the deterministic multi-file transformation engine. It is exposed as the nested `wicked-garden-engineering-patch` skill under the engineering domain.
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
Developer invokes patch action: /wicked-garden-engineering patch-plan OldName
|
|
185
|
+
→ engineering-patch skill reads codegraph from wicked-brain:
|
|
186
|
+
.codegraph/codegraph.db (structural graph, tree-sitter)
|
|
187
|
+
+ injected edges (bus producer→consumer, dispatch, capability)
|
|
188
|
+
→ computes full affected file set:
|
|
189
|
+
direct references (grep-visible)
|
|
190
|
+
+ injected-edge references (not grep-visible)
|
|
191
|
+
→ returns patch plan: files × change-kinds × risk surface
|
|
192
|
+
|
|
193
|
+
Developer approves (or scopes) the plan
|
|
194
|
+
|
|
195
|
+
Developer invokes apply: /wicked-garden-engineering apply <patch-file>
|
|
196
|
+
→ for each affected file:
|
|
197
|
+
selects language generator (Python, TypeScript, Java, Go, SQL,
|
|
198
|
+
Rust, Kotlin, C#, PHP, Ruby — out of the box)
|
|
199
|
+
generator applies the transformation (rename, add-field, remove)
|
|
200
|
+
writes the changed file
|
|
201
|
+
→ result: deterministic, complete, consistent transformation
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
New language support: `/wicked-garden-engineering new-generator` creates a generator for an additional language. Generators implement a documented interface; adding one requires no change to the patch core.
|
|
205
|
+
|
|
206
|
+
wicked-patch and wicked-brain share the same codegraph database (`.codegraph/codegraph.db`). The `wicked-garden-search index` action refreshes both layers — brain (semantic) and codegraph (structural).
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Compiler Architecture
|
|
211
|
+
|
|
212
|
+
The compiler emits a self-contained vault-backed gate into any repo — no wicked-garden or wicked-loom runtime required in the target.
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
Developer invokes: /wicked-garden-prove compile <repo> [--trigger hook,ci]
|
|
216
|
+
→ scripts/compiler/compile.py entry point
|
|
217
|
+
→ Phase 0 detection (scripts/compiler/phase0/detect.py):
|
|
218
|
+
identifies ecosystem (Node, Python, Rust, ...)
|
|
219
|
+
locates test/lint/build commands (binding detection)
|
|
220
|
+
identifies claims documents (files with claims: frontmatter)
|
|
221
|
+
maps risk surfaces
|
|
222
|
+
→ derives multi-claim contract
|
|
223
|
+
→ writes to <repo>/.wicked/:
|
|
224
|
+
contract.json — the derived contract
|
|
225
|
+
gate.py — stdlib-only, vault-direct gate script
|
|
226
|
+
bindings.json — ecosystem bindings
|
|
227
|
+
README.md — usage instructions
|
|
228
|
+
claims_lint.py — written when claims: frontmatter doc is detected
|
|
229
|
+
→ if --trigger hook:
|
|
230
|
+
installs git pre-push hook that runs gate.py
|
|
231
|
+
→ if --trigger ci:
|
|
232
|
+
writes GitHub Actions workflow that runs gate.py
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
The emitted `gate.py` is vault-direct: it resolves `wicked-vault` via `npx`, not loom. This is intentional — the compiled gate cannot assume wicked-loom is present in the target repo. The garden's own gate uses loom; the emitted gate does not.
|
|
236
|
+
|
|
237
|
+
AST enforcement: `tests/compiler/test_compile.py` verifies that the emitted `gate.py` is stdlib-only (no third-party imports, no wicked-garden imports). This test is part of CI.
|
|
238
|
+
|
|
239
|
+
The on-switch rule: **compile the trigger and the enforcement; never compile the tool**. The vault is a runtime-resolved utility, not a compiled-in dependency. The guarantee is self-contained without shipping wicked-garden.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Storage and State
|
|
244
|
+
|
|
245
|
+
### DomainStore (`scripts/_domain_store.py`)
|
|
246
|
+
|
|
247
|
+
Local JSON files with optional integration-discovery routing to MCP tools. Project-scoped paths via `scripts/_paths.py`. Path structure: `~/.something-wicked/wicked-garden/projects/{slug}/{domain}/{subpath}`. Do not hardcode the base path in consumer code.
|
|
248
|
+
|
|
249
|
+
### SessionState (`scripts/_session.py`)
|
|
250
|
+
|
|
251
|
+
Per-session ephemeral shared state. Not persisted across process restarts. Used for in-session coordination between skills and hooks.
|
|
252
|
+
|
|
253
|
+
### Event Store (`scripts/_bus.py`)
|
|
254
|
+
|
|
255
|
+
wicked-bus integration. Emits events in 4-segment format (`wicked.<domain>.<noun>.<past-tense-verb>`). The bus provides at-least-once delivery, append-only event records, and FTS5 search via the wicked-bus backing store.
|
|
256
|
+
|
|
257
|
+
### codegraph.db
|
|
258
|
+
|
|
259
|
+
Structural code graph built and maintained by wicked-brain at `.codegraph/codegraph.db`. Consumed by wicked-patch. The `search:index` action refreshes it.
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Hook Architecture
|
|
264
|
+
|
|
265
|
+
Thirteen registered hook events across all `command` type scripts, dispatched through `hooks/scripts/invoke.py`:
|
|
266
|
+
|
|
267
|
+
| Hook | Event(s) | Script arg | Purpose |
|
|
268
|
+
|------|---------|------------|---------|
|
|
269
|
+
| Bootstrap | `SessionStart` | `bootstrap` | Environment setup; peer verification (`/wicked-garden-core setup` flow); session initialization |
|
|
270
|
+
| Prompt Submit | `UserPromptSubmit` | `prompt_submit` | Archetype detection; system-reminder injection |
|
|
271
|
+
| Pre-Tool | `PreToolUse` | `pre_tool` | Tool input validation; MEMORY.md write guard; plan-mode intercept |
|
|
272
|
+
| Post-Tool | `PostToolUse`, `PostToolUseFailure` | `post_tool` | Task state sync; file-change tracking; search index invalidation |
|
|
273
|
+
| Task Completed | `TaskCompleted` | `task_completed` | Task audit write |
|
|
274
|
+
| Subagent Lifecycle | `SubagentStart`, `SubagentStop` | `subagent_lifecycle start\|stop` | Subagent session tracking |
|
|
275
|
+
| Permission Request | `PermissionRequest` | `permission_request` | Permission audit |
|
|
276
|
+
| Notification | `Notification` | `notification` | Background notification handling |
|
|
277
|
+
| Pre-Compact | `PreCompact` | `pre_compact` | Context-window checkpoint before compaction |
|
|
278
|
+
| Stop | `Stop` | `stop` | Session teardown; audit write; event flush |
|
|
279
|
+
| Session End | `SessionEnd` | `session_end` | Final session cleanup |
|
|
280
|
+
|
|
281
|
+
Hook scripts are stdlib-only Python — no third-party imports. Bootstrap and Stop hooks return `{"ok": true}` on success; `{"ok": false, "reason": "..."}` blocks the triggering event. The UserPromptSubmit hook (`prompt_submit.py`) returns `{"continue": true}` to proceed and carries injected context in `hookSpecificOutput`; `{"continue": false}` blocks the prompt. The Stop hook uses `"async": true` to avoid blocking session shutdown.
|
|
282
|
+
|
|
283
|
+
Hook scripts access `CLAUDE_PLUGIN_ROOT` to construct paths. All shell variables are quoted. Temp paths use `tempfile.gettempdir()`.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Daemon (Optional)
|
|
288
|
+
|
|
289
|
+
The Flask daemon (`daemon/`) provides:
|
|
290
|
+
- Long-running operation support for indexing and background event processing.
|
|
291
|
+
- A local HTTP API for skills to dispatch work that exceeds hook timeout limits.
|
|
292
|
+
- Not required for any core plugin capability.
|
|
293
|
+
|
|
294
|
+
Skills check for daemon availability before dispatching to it. If the daemon is absent, skills fall back to synchronous inline execution.
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Peer Integration Points
|
|
299
|
+
|
|
300
|
+
| Peer | Integration Point | How Resolved |
|
|
301
|
+
|------|------------------|-------------|
|
|
302
|
+
| wicked-vault | `scripts/qe/vault_gate.py`, `scripts/qe/prove.py` | `WICKED_VAULT_BIN` env → PATH → `npx wicked-vault` |
|
|
303
|
+
| wicked-loom | `scripts/qe/vault_gate.py` | `WICKED_LOOM_BIN` env → config → PATH → `node_modules/.bin` → `npx` |
|
|
304
|
+
| wicked-testing | `scripts/qe/` (acceptance pipeline) | Installed peer; invoked by acceptance skills |
|
|
305
|
+
| wicked-brain | `scripts/crew/`, search/smaht skills | Brain server on port 4243; auto-starts on skill invocation |
|
|
306
|
+
| wicked-bus | `scripts/_bus.py` | Installed peer; event emit/consume |
|
|
307
|
+
| codegraph | `.codegraph/codegraph.db` | Built by wicked-brain; consumed by patch skill |
|
|
308
|
+
|
|
309
|
+
All peers degrade gracefully on absence — except the evidence gate, which fails closed when vault or loom is unreachable. A transient peer outage never invents a pass.
|
package/.product/RAID.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: RAID
|
|
3
|
+
title: wicked-garden — Risks, Assumptions, Issues, Dependencies
|
|
4
|
+
status: draft
|
|
5
|
+
version: 0.1
|
|
6
|
+
date: 2026-07-21
|
|
7
|
+
author: mike.parcewski@gmail.com
|
|
8
|
+
review-required: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# RAID Log
|
|
12
|
+
|
|
13
|
+
## Risks
|
|
14
|
+
|
|
15
|
+
| ID | Risk | Likelihood | Impact | Mitigation |
|
|
16
|
+
|----|------|-----------|--------|------------|
|
|
17
|
+
| RISK-001 | Archetype detection accuracy degrades for ambiguous or very short prompts | Medium | Medium | Detector returns confidence score; low-confidence prompts prompt for clarification. Multi-archetype output handles mixed-intent work. |
|
|
18
|
+
| RISK-002 | wicked-loom/wicked-vault peer absent → evidence gate fails closed | High (setup) | Low (expected) | Failing closed is the intended behavior. `/wg-check` validates peers at setup; setup skill guides installation. |
|
|
19
|
+
| RISK-003 | codegraph not built → blast-radius/lineage/wicked-patch unavailable | High (optional) | Medium | codegraph is explicitly opt-in; skills degrade gracefully to text-search when graph is absent. |
|
|
20
|
+
| RISK-004 | Plugin not loaded in `claude -p` non-interactive mode | Medium | High | Documented mitigation: user must add `--plugin-dir` via clis.toml override (garden#994 resolution). Long-term fix: persistent worker sessions (core#13). |
|
|
21
|
+
| RISK-005 | Council seat (Antigravity/Codex) unavailable or returns garbage | Medium | Low | Council aggregation tolerates partial failures; the skill surfaces which seats failed. |
|
|
22
|
+
| RISK-006 | Hook scripts fail on Windows without correct Python fallback | Low | High | All scripts use cross-platform patterns (tempfile.gettempdir, python fallback chain). CI must include Windows runner. |
|
|
23
|
+
| RISK-007 | Slim Body Contract violated → parent context bloat | Low | Medium | `/wg-check --full` enforces the limit. CI validates component manifest on every PR. |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Assumptions
|
|
28
|
+
|
|
29
|
+
| ID | Assumption |
|
|
30
|
+
|----|-----------|
|
|
31
|
+
| ASS-001 | The host harness (Claude Code, Codex, Cursor, …) handles all planning, parallelism, and LLM calls. wicked-garden does not re-implement harness capabilities. |
|
|
32
|
+
| ASS-002 | Users install the required peers (`wicked-testing`/`wicked-vault`, `wicked-loom`) before using the evidence gate. The setup skill validates this. |
|
|
33
|
+
| ASS-003 | The codegraph (`.codegraph/codegraph.db`) is built and up-to-date when blast-radius/lineage/wicked-patch are used. |
|
|
34
|
+
| ASS-004 | Harness plugins are loaded in interactive mode; non-interactive (`claude -p`) mode requires explicit plugin-dir configuration. |
|
|
35
|
+
| ASS-005 | The `WICKED_VAULT_ACTOR` environment variable is set to a meaningful, stable actor identity for hard-gate evidence recording (not OS `$USER`). |
|
|
36
|
+
| ASS-006 | wicked-bus is optional; garden emits events fail-open when bus is unavailable. |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Issues
|
|
41
|
+
|
|
42
|
+
| ID | Issue | Status | Resolution |
|
|
43
|
+
|----|-------|--------|-----------|
|
|
44
|
+
| ISS-001 | Plugin not loaded in `claude -p` subprocess (garden#994) | Closed | User-level clis.toml override; add `--plugin-dir ~/.claude/plugins` to claude seat's `headless_invocation`. |
|
|
45
|
+
| ISS-002 | Schema drift risk: domain-model schema vendored in 3 places (brain canonical, wicked-core/tests/, garden skills/domain/vendor/) | Open | Drift guard test pending; garden's vendor copy must match canonical on each release. |
|
|
46
|
+
| ISS-003 | Harness drift test for garden's schema vendor skips rather than fails when canonical path absent | Open | Fix: convert `pytest.skip` to `pytest.fail` so the drift guard is fail-closed. |
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Dependencies
|
|
51
|
+
|
|
52
|
+
| Dependency | Type | Required | Notes |
|
|
53
|
+
|-----------|------|----------|-------|
|
|
54
|
+
| Claude Code (or compatible harness) | Runtime | Yes | Plugin host. Must support `context: fork`, hooks, skills. |
|
|
55
|
+
| wicked-vault ≥ 0.4.0 | Runtime | Yes (for evidence gate) | Evidence backend. `0.4.0` introduced fail-closed `attest` on weak identity. |
|
|
56
|
+
| wicked-loom | Runtime | Yes (for evidence gate) | Gate/resolve engine. Resolved via `WICKED_LOOM_BIN` → config → PATH → `npx`. |
|
|
57
|
+
| wicked-testing | Runtime | Yes (for acceptance) | The acceptance pipeline is the standard gate mechanism. |
|
|
58
|
+
| wicked-brain | Runtime | Optional | Cross-session memory + codegraph. Required for blast-radius, lineage, wicked-patch. |
|
|
59
|
+
| wicked-bus | Runtime | Optional | Event audit trail. Garden emits events fail-open without it. |
|
|
60
|
+
| codegraph (`@colbymchenry/codegraph`) | Runtime | Optional | Static graph builder. Powers blast-radius/lineage/wicked-patch. |
|
|
61
|
+
| Python ≥ 3.9 | Runtime | Yes | Required for all hook scripts and CLI tools. |
|
|
62
|
+
| node.js ≥ 18 | Runtime | Yes | Required for npm peer installs and wicked-vault/loom. |
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: REQ-001-application-overview
|
|
3
|
+
title: wicked-garden — Application Overview
|
|
4
|
+
status: draft
|
|
5
|
+
version: 0.1
|
|
6
|
+
date: 2026-07-21
|
|
7
|
+
author: mike.parcewski@gmail.com
|
|
8
|
+
review-required: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# REQ-001 — Application Overview
|
|
12
|
+
|
|
13
|
+
## Purpose
|
|
14
|
+
|
|
15
|
+
wicked-garden is a Claude Code plugin (v12.28.1) that fills the gaps modern coding-agent harnesses cannot close alone. The premise is direct: harnesses — Claude Code, Codex, Cursor, Aider, OpenCode, Zed/ACP, and others — already plan, parallelize, and execute well. wicked-garden does not compete with that; it adds only what a planner-executor genuinely cannot do on its own:
|
|
16
|
+
|
|
17
|
+
- **Evidence-gated done** — re-derives "done" from recorded evidence via the internal loom engine and wicked-vault; a self-asserted "tests pass" cannot lie its way green.
|
|
18
|
+
- **Relationships grep cannot see** — codegraph + injected event-bus/dispatch/capability edges power blast-radius and lineage analysis.
|
|
19
|
+
- **Deterministic multi-file refactor** — wicked-patch applies graph-driven renames and field additions across an entire codebase without leaving silent half-applied states.
|
|
20
|
+
- **Cross-session memory** — wicked-brain persists decisions, patterns, and gotchas across sessions; knowledge that only lives in chat history does not exist.
|
|
21
|
+
- **Real multi-model second opinions** — the jam:council skill convenes external LLM CLIs (Claude Code, Antigravity, Codex, local models) for independent evaluation; it is not the model talking to itself.
|
|
22
|
+
- **Portable evidence gates** — the compiler (`/wicked-garden-prove compile`) emits a self-contained vault-backed gate into any repo that re-derives claims with no wicked-garden runtime present.
|
|
23
|
+
|
|
24
|
+
The core invariant: **done is re-derived, not asserted.** A gate does not go green because an agent or human said so. Evidence is re-hashed and its verifier re-run through wicked-loom on every gate check. A missing evidence backend fails closed — it never invents a pass.
|
|
25
|
+
|
|
26
|
+
Work-shape detection is how wicked-garden applies the right rigor without imposing a fixed pipeline. Each prompt classifies into one or more of **ten work-shape archetypes** (triage, explore, specify, decide, ship, review, incident, build, migrate, modernize). Each archetype owns its own phase shape, produces contract, and HITL discipline. The harness drives; wicked-garden steers by archetype.
|
|
27
|
+
|
|
28
|
+
The plugin installs via `/plugin install wicked-garden` into any Claude Code session. It is skills-only: user entry points are consolidated per-domain skills. There are no slash commands in the distributed plugin — the `.claude/` dev tools (`/wg-*`) are development-only surfaces not shipped to marketplace users.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Core User Flows
|
|
33
|
+
|
|
34
|
+
### Flow 1 — Archetype-steered session: from prompt to phased execution
|
|
35
|
+
|
|
36
|
+
1. Developer submits a prompt in Claude Code (e.g., "add a NOT NULL column to the users table and backfill existing rows").
|
|
37
|
+
2. The `UserPromptSubmit` hook fires `hooks/scripts/prompt_submit.py`, which calls `scripts/crew/archetypes_v11.py::detect_archetypes()`.
|
|
38
|
+
3. The detector scores the prompt against all ten archetype definitions and emits a `<wg archetype="migrate" score="0.91" />` system-reminder (or a multi-archetype set, e.g., `build+migrate`).
|
|
39
|
+
4. The harness invokes the `wicked-garden-archetype` skill with the detected work-shape name. The skill loads `skills/archetype/refs/migrate.md` — the migrate playbook.
|
|
40
|
+
5. The playbook defines the phase shape (plan → expand → backfill → cutover → contract), produces contract (shape change artifact, rollback proof), HITL gate at cutover (hard gate: requires explicit approval), and cost band (high).
|
|
41
|
+
6. The harness executes the phases. At the cutover hard gate, execution pauses and surfaces the gate to the user. Approval unblocks; rejection rolls back.
|
|
42
|
+
7. At phase completion the produces-gate re-derives the claim via wicked-loom. A missing verifier or unresolvable evidence backend fails closed.
|
|
43
|
+
|
|
44
|
+
**Outcome**: the developer gets appropriately-scaled rigor for a schema migration — not the same lightweight flow as a typo fix, and not an arbitrary fixed pipeline.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### Flow 2 — Evidence gate: re-deriving done from recorded evidence
|
|
49
|
+
|
|
50
|
+
1. A build phase completes. The agent records evidence via `wicked-vault record --actor garden-prove --run <test-suite>`. Evidence is stored in the vault's append-only store with a content hash and the actor identity.
|
|
51
|
+
2. At the produces gate, the agent invokes `scripts/qe/vault_gate.py::gate_satisfied()`. The gate shells `wicked-loom gate`, which in turn shells `wicked-vault cross-check`.
|
|
52
|
+
3. wicked-vault re-hashes the recorded evidence and re-runs the verifier. If the evidence hash matches and the verifier passes, the gate returns green. If evidence is missing, the hash does not match, or loom/vault is unresolvable, the gate **fails closed** — it returns `gate: "unavailable"`, never a vacuous pass.
|
|
53
|
+
4. For hard gates (review, incident, migrate archetypes), the gate additionally requires an independent attestation recorded under a distinct `--actor` identity. Evidence recorded under the ambient OS `$USER` (`created_by_source='env-user'`) cannot satisfy an attestation gate — the evaluator-must-not-equal-creator constraint is enforced structurally, not by convention.
|
|
54
|
+
5. The gate verdict is appended to the session's audit trail. Subsequent sessions resume from the recorded verdict without re-running the gate unless evidence changes.
|
|
55
|
+
|
|
56
|
+
**Outcome**: "done" is a re-derived claim backed by tamper-evident evidence, not a self-assertion that can lie its way green.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### Flow 3 — Compiler: emitting a portable gate into a foreign repo
|
|
61
|
+
|
|
62
|
+
1. A developer in a repo that does not have wicked-garden installed wants a build gate that re-derives claims on push and in CI.
|
|
63
|
+
2. They (or an agent with wicked-garden) invoke the `wicked-garden-prove` skill's `compile` action: `/wicked-garden-prove compile <repo> --trigger hook,ci`.
|
|
64
|
+
3. The compiler (`scripts/compiler/compile.py`) runs Phase 0 detection: it identifies the ecosystem (Node, Python, Rust, etc.), locates test/lint/build commands, identifies claims documents (files with `claims:` frontmatter), and maps risk surfaces.
|
|
65
|
+
4. It derives a multi-claim contract and writes four files into `<repo>/.wicked/`: `contract.json`, `gate.py`, `README.md`, `bindings.json`. When a claims document is detected, it also writes `claims_lint.py`.
|
|
66
|
+
5. The emitted `gate.py` is stdlib-only, imports nothing from wicked-garden, and resolves `wicked-vault` via `npx` — so it runs in any repo with neither wicked-garden nor wicked-loom present.
|
|
67
|
+
6. With `--trigger hook,ci`, the compiler also installs a git pre-push hook and a GitHub Actions workflow. Every push re-derives the gate claims; a failing gate blocks the push.
|
|
68
|
+
|
|
69
|
+
**Outcome**: the evidence-gate guarantee outlives the session that created it and requires no wicked-garden runtime in the target repo.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
### Flow 4 — Multi-model council: independent second opinion
|
|
74
|
+
|
|
75
|
+
1. An agent or developer wants a structural evaluation of an architecture proposal that is not self-graded — the model should not review its own work.
|
|
76
|
+
2. They invoke the jam:council action: `/wicked-garden-jam council <proposal>`.
|
|
77
|
+
3. The `wicked-garden-jam-council` fork worker skill convenes an evaluation session. It dispatches the proposal to available external LLM CLIs (Claude Code via Antigravity/Codex, and any locally-configured model) using `Task()` dispatch with isolated contexts.
|
|
78
|
+
4. Each model evaluates the proposal independently, returning a structured verdict (findings, concerns, confidence). The council skill synthesizes the responses: agreement, disagreement, and unresolved tensions.
|
|
79
|
+
5. The synthesized output is returned as a multi-perspective evaluation. The harness can treat a unanimous council failure as a hard gate.
|
|
80
|
+
|
|
81
|
+
**Outcome**: the developer receives an independent evaluation from models that did not produce the work, structurally preventing self-grading.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### Flow 5 — wicked-patch: deterministic multi-file refactor
|
|
86
|
+
|
|
87
|
+
1. A developer needs to rename a domain type across a large codebase — source files, tests, migration files, configuration, and documentation.
|
|
88
|
+
2. They invoke the patch skill: `/wicked-garden-engineering rename OldName NewName`.
|
|
89
|
+
3. The `wicked-garden-engineering-patch` nested skill reads the codegraph from wicked-brain (`.codegraph/codegraph.db`), identifies all nodes referencing `OldName`, and computes the full set of affected files including injected edges (bus producer→consumer, dispatch links) that grep cannot see.
|
|
90
|
+
4. The skill shows the patch plan (files affected, kinds of change, risk surface). The developer approves or scopes the change.
|
|
91
|
+
5. On approval, the patch applies deterministically using the language-specific generator for each file type. Generators exist out of the box for Python, TypeScript, Java, Go, SQL, Rust, Kotlin, C#, PHP, and Ruby. A `new-generator` action lets contributors add additional languages.
|
|
92
|
+
6. The result is a complete, consistent rename across every file that references the symbol — including the relationships grep cannot see.
|
|
93
|
+
|
|
94
|
+
**Outcome**: multi-file refactor is a graph operation, not a search-and-replace that leaves injected-edge references broken.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: REQ-002-technology-constraints
|
|
3
|
+
title: wicked-garden — Technology Constraints
|
|
4
|
+
status: draft
|
|
5
|
+
version: 0.1
|
|
6
|
+
date: 2026-07-21
|
|
7
|
+
author: mike.parcewski@gmail.com
|
|
8
|
+
review-required: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# REQ-002 — Technology Constraints
|
|
12
|
+
|
|
13
|
+
## Runtime Environment
|
|
14
|
+
|
|
15
|
+
**Claude Code plugin API** — wicked-garden is delivered as a Claude Code plugin (`/plugin install wicked-garden`). All user-facing surfaces are Claude Code skills (frontmatter-described SKILL.md files). The plugin exposes no slash commands in its distributed form; the `.claude/` developer tools (`/wg-*`) are development-only.
|
|
16
|
+
|
|
17
|
+
**Node.js / Python dual runtime** — skills are Markdown files loaded by Claude Code; imperative logic lives in Python scripts under `scripts/` and `hooks/scripts/`. Node.js is required for wicked-bus (the event audit substrate) and for npm-installed peers. Python 3 is required for all hook scripts, the archetype detector, the compiler, the evidence gate, and domain store utilities. Both runtimes must be present in the agent's execution environment.
|
|
18
|
+
|
|
19
|
+
**Cross-platform requirement** — all skills, hook scripts, and shell commands must work on macOS, Linux (x86_64 and arm64), and Windows (Git Bash and WSL). Native PowerShell is a secondary target. Specific constraints:
|
|
20
|
+
- Hook scripts use `python3 -c "..."` with `2>/dev/null || python -c "..."` fallback.
|
|
21
|
+
- Temp paths use `tempfile.gettempdir()`, not hardcoded `/tmp`.
|
|
22
|
+
- JSON output in hooks uses Python, not shell builtins (`printf`, `echo`), which differ across platforms.
|
|
23
|
+
- Python scripts are invoked via `sh "${CLAUDE_PLUGIN_ROOT}/scripts/_python.sh"` for cross-platform resolution.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Required Peers
|
|
28
|
+
|
|
29
|
+
Two peers are required for the evidence gate to function. Both are verified by `/wicked-garden-core setup`:
|
|
30
|
+
|
|
31
|
+
| Peer | npm Package | Required Version | Role |
|
|
32
|
+
|------|-------------|-----------------|------|
|
|
33
|
+
| wicked-vault | `wicked-vault` | `>= 0.4.0` | Evidence backend — records, re-hashes, and verifies evidence attestations |
|
|
34
|
+
| wicked-loom | `wicked-loom` | resolved at runtime | Gate engine — shells `wicked-vault cross-check`; the sole gate/resolve path since v12 loom cutover |
|
|
35
|
+
|
|
36
|
+
wicked-vault `>= 0.4.0` is a breaking-change floor for hard gates: `attest` now fails closed on a weak/ambient worker identity (`created_by_source='env-user'`). Evidence for hard-gate attestation must be recorded under an explicit `--actor` (default: `WICKED_VAULT_ACTOR` env var, fallback `garden-prove`).
|
|
37
|
+
|
|
38
|
+
wicked-loom is resolved at runtime in this order: `WICKED_LOOM_BIN` env var → config → PATH → `node_modules/.bin` → `npx`. Setting `WICKED_LOOM_CUTOVER=off` disables the gate (fails closed). Setting `WICKED_VAULT_BIN=""` kill-switches the vault behind loom.
|
|
39
|
+
|
|
40
|
+
Three additional peers are opt-in:
|
|
41
|
+
|
|
42
|
+
| Peer | npm Package | Required Version | Role |
|
|
43
|
+
|------|-------------|-----------------|------|
|
|
44
|
+
| wicked-testing | `wicked-testing` | `^0.8.0` | Acceptance testing gate; also installs wicked-vault as a transitive dependency |
|
|
45
|
+
| wicked-brain | `wicked-brain` | `^0.18.0` | Cross-session memory, code graph, semantic search |
|
|
46
|
+
| wicked-bus | `wicked-bus` | `^2.0.0` | Event audit trail, append-only event store, FTS5 search |
|
|
47
|
+
|
|
48
|
+
wicked-understanding (repo playbooks from HEAD) and codegraph (structural code intelligence) are additional optional integrations.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Storage
|
|
53
|
+
|
|
54
|
+
**Local JSON files** — default persistence layer via `DomainStore` (`scripts/_domain_store.py`). Paths are project-scoped: `~/.something-wicked/wicked-garden/projects/{slug}/{domain}/{subpath}` where `slug` is derived from `cwd` hash. Consumer code must use `get_local_path()` from `_paths.py` or `_domain_store.py` — never hardcode the base path.
|
|
55
|
+
|
|
56
|
+
**SQLite (via peers)** — wicked-brain provides FTS5 + BM25 search over the code graph and indexed content. wicked-bus provides an append-only event store with FTS5 search. wicked-vault provides an append-only evidence store. No standalone SQLite module in wicked-garden itself.
|
|
57
|
+
|
|
58
|
+
**SessionState** (`scripts/_session.py`) — per-session ephemeral shared state. Does not persist across process restarts.
|
|
59
|
+
|
|
60
|
+
**codegraph.db** — wicked-brain builds and maintains this structural code graph at `.codegraph/codegraph.db`. wicked-patch consumes it for multi-file refactor operations.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Plugin Architecture Constraints
|
|
65
|
+
|
|
66
|
+
**Skills-only** — the plugin exposes only skills. Former command surfaces and agent surfaces were absorbed into consolidated domain skills (domain router skills) and fork worker skills respectively as of v12.25. A domain router skill is user-invocable (`wicked-garden-{domain}`); a fork worker skill carries `context: fork` and is reached only via `Skill()`/`Task()` dispatch from another skill.
|
|
67
|
+
|
|
68
|
+
**Slim body contract** — skill body files must stay slim (loaded into parent context permanently). Three patterns apply:
|
|
69
|
+
- Pattern A (Advisory/State): ≤ 8 lines. For state mutation with no dispatch.
|
|
70
|
+
- Pattern B (Write Brief + Dispatch): ≤ 30 lines. For session-specific work.
|
|
71
|
+
- Pattern C (Interactive Branch + Dispatch): ≤ 35 lines. For user-decision-before-dispatch flows.
|
|
72
|
+
|
|
73
|
+
Refs (the detailed content) live in `skills/{domain}/refs/` files (200-300 lines each) and are loaded on demand.
|
|
74
|
+
|
|
75
|
+
**Hooks** — 13 registered hook events across all `command` type scripts, dispatched through `hooks/scripts/invoke.py`. Primary lifecycle hooks: `SessionStart` (bootstrap: environment setup, peer verification), `UserPromptSubmit` (archetype detection, system-reminder injection), `Stop` (teardown: session audit write). Tool-intercept hooks: `PreToolUse` (tool input validation; MEMORY.md write guard), `PostToolUse`/`PostToolUseFailure` (task sync; file-change tracking). Additional hooks: `TaskCompleted`, `SubagentStart`/`SubagentStop`, `PermissionRequest`, `Notification`, `PreCompact`, `SessionEnd`. Stop and `SessionEnd` hooks use `"async": true`. Bootstrap and Stop hooks return `{"ok": true}` on success; `{"ok": false, "reason": "..."}` blocks the event. The UserPromptSubmit hook returns `{"continue": true}` to proceed (with `hookSpecificOutput` for injected context) or `{"continue": false}` to block. All hook scripts are stdlib-only Python.
|
|
76
|
+
|
|
77
|
+
**Daemon** (`daemon/`) — a Flask server for long-running operations (e.g., indexing, background event processing). Not required for core plugin function; opt-in for operations that exceed hook timeout limits.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Dependency and Versioning Constraints
|
|
82
|
+
|
|
83
|
+
**No mandatory cloud infrastructure** — all storage is local-first. No API keys required for wicked-garden itself (LLM calls go through the harness; external LLM CLIs for the council are the user's responsibility to configure).
|
|
84
|
+
|
|
85
|
+
**Offline operation** — the plugin must function without network access except for LLM inference calls (which the harness manages). The evidence gate, compiler, archetype detector, wicked-patch, and all skill logic operate offline.
|
|
86
|
+
|
|
87
|
+
**Plugin install path** — `npm install -g wicked-garden` or `/plugin install wicked-garden` via the Claude Code marketplace. The plugin does not require a global npm install to function; the marketplace path is the primary distribution channel.
|
|
88
|
+
|
|
89
|
+
**Peer version pins** — pinned in `plugin.json` as version ranges (`^` or `>=`). The wicked-vault floor (`>= 0.4.0`) is a hard constraint for hard gates; running an older vault behind loom silently degrades to `gate: "unavailable"`.
|
|
90
|
+
|
|
91
|
+
**Event naming** — all wicked-garden events on the bus follow the 4-segment format `wicked.<domain>.<noun>.<past-tense-verb>` per the ecosystem event grammar (WICKED_GARDEN_BUS_EVENTS.md). Divergence from this format is a contribution defect.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Non-Functional Constraints
|
|
96
|
+
|
|
97
|
+
**Gate semantics: fail-closed** — a gate that cannot re-derive its claim must not pass. `gate: "unavailable"` is the only valid non-green verdict when the backend is unreachable. There is no fallback to self-assertion.
|
|
98
|
+
|
|
99
|
+
**Audit trail: append-only** — all evidence records and gate verdicts are append-only. No verdict is overwritten or deleted.
|
|
100
|
+
|
|
101
|
+
**Actor identity for hard gates** — evidence recorded under ambient OS identity (`$USER`) cannot satisfy a hard-gate attestation (vault `>= 0.4.0` enforcement). The `WICKED_VAULT_ACTOR` env var (default: `garden-prove`) must be set correctly for hard-gate paths. `scripts/qe/prove.py::_prove_actor` is the reference.
|
|
102
|
+
|
|
103
|
+
**Compiler emits stdlib-only gate** — the emitted `gate.py` from the compiler must be stdlib-only (AST-enforced in `tests/compiler/test_compile.py`). It resolves wicked-vault via `npx`, not loom. This constraint ensures the compiled gate runs in any repo with no wicked-garden or wicked-loom present.
|