qualia-framework 4.5.0 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +24 -0
- package/CLAUDE.md +12 -75
- package/README.md +23 -16
- package/agents/builder.md +9 -21
- package/agents/planner.md +8 -0
- package/agents/verifier.md +8 -0
- package/agents/visual-evaluator.md +132 -0
- package/bin/cli.js +54 -18
- package/bin/install.js +369 -29
- package/bin/qualia-ui.js +208 -1
- package/bin/slop-detect.mjs +5 -0
- package/bin/state.js +34 -1
- package/docs/install-redesign-builder-prompt.md +290 -0
- package/docs/install-redesign-pilot.md +234 -0
- package/docs/playwright-loop-builder-prompt.md +185 -0
- package/docs/playwright-loop-design-notes.md +108 -0
- package/docs/playwright-loop-pilot-results.md +170 -0
- package/docs/playwright-loop-tester-prompt.md +213 -0
- package/docs/polish-loop-supervised-run.md +111 -0
- package/docs/reviews/matt-pocock-skills-analysis.md +300 -0
- package/guide.md +9 -5
- package/hooks/env-empty-guard.js +74 -0
- package/hooks/pre-compact.js +19 -9
- package/hooks/pre-deploy-gate.js +8 -2
- package/hooks/pre-push.js +26 -12
- package/hooks/supabase-destructive-guard.js +62 -0
- package/hooks/vercel-account-guard.js +91 -0
- package/package.json +2 -1
- package/rules/design-brand.md +4 -0
- package/rules/design-laws.md +4 -0
- package/rules/design-product.md +4 -0
- package/rules/design-rubric.md +4 -0
- package/rules/grounding.md +4 -0
- package/skills/qualia-build/SKILL.md +40 -46
- package/skills/qualia-discuss/SKILL.md +51 -68
- package/skills/qualia-handoff/SKILL.md +1 -0
- package/skills/qualia-hook-gen/SKILL.md +206 -0
- package/skills/qualia-issues/SKILL.md +151 -0
- package/skills/qualia-map/SKILL.md +78 -35
- package/skills/qualia-new/REFERENCE.md +139 -0
- package/skills/qualia-new/SKILL.md +45 -121
- package/skills/qualia-optimize/REFERENCE.md +265 -0
- package/skills/qualia-optimize/SKILL.md +92 -232
- package/skills/qualia-plan/SKILL.md +58 -65
- package/skills/qualia-polish-loop/REFERENCE.md +265 -0
- package/skills/qualia-polish-loop/SKILL.md +201 -0
- package/skills/qualia-polish-loop/fixtures/broken.html +117 -0
- package/skills/qualia-polish-loop/fixtures/clean.html +196 -0
- package/skills/qualia-polish-loop/scripts/loop.mjs +323 -0
- package/skills/qualia-polish-loop/scripts/playwright-capture.mjs +206 -0
- package/skills/qualia-polish-loop/scripts/score.mjs +176 -0
- package/skills/qualia-prd/SKILL.md +199 -0
- package/skills/qualia-report/SKILL.md +141 -200
- package/skills/qualia-research/SKILL.md +28 -33
- package/skills/qualia-road/SKILL.md +103 -0
- package/skills/qualia-ship/SKILL.md +1 -0
- package/skills/qualia-task/SKILL.md +1 -1
- package/skills/qualia-test/SKILL.md +50 -2
- package/skills/qualia-triage/SKILL.md +152 -0
- package/skills/qualia-verify/SKILL.md +63 -104
- package/skills/qualia-zoom/SKILL.md +51 -0
- package/skills/zoho-workflow/SKILL.md +1 -1
- package/templates/CONTEXT.md +36 -0
- package/templates/decisions/ADR-template.md +30 -0
- package/tests/bin.test.sh +598 -7
- package/tests/state.test.sh +58 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ~/.claude/hooks/vercel-account-guard.js — block deploys from wrong Vercel account.
|
|
3
|
+
//
|
|
4
|
+
// PreToolUse hook on `Bash`. Reads the proposed command from the Claude Code
|
|
5
|
+
// hook payload (stdin JSON: tool_input.command) and exits 2 to BLOCK, 0 to
|
|
6
|
+
// allow. Triggers only when the command matches `vercel --prod` or `vercel deploy`.
|
|
7
|
+
//
|
|
8
|
+
// Allowed teams are read from ~/.claude/.vercel-allowed-teams (one slug per
|
|
9
|
+
// line, mode 0600). Missing config file = fail-open with stderr warning.
|
|
10
|
+
//
|
|
11
|
+
// Cross-platform (Windows/macOS/Linux). No external dependencies.
|
|
12
|
+
|
|
13
|
+
const fs = require("fs");
|
|
14
|
+
const path = require("path");
|
|
15
|
+
const os = require("os");
|
|
16
|
+
const { spawnSync } = require("child_process");
|
|
17
|
+
|
|
18
|
+
const _traceStart = Date.now();
|
|
19
|
+
|
|
20
|
+
function _trace(result, extra) {
|
|
21
|
+
try {
|
|
22
|
+
const traceDir = path.join(os.homedir(), ".claude", ".qualia-traces");
|
|
23
|
+
if (!fs.existsSync(traceDir)) fs.mkdirSync(traceDir, { recursive: true });
|
|
24
|
+
const entry = {
|
|
25
|
+
hook: "vercel-account-guard",
|
|
26
|
+
result,
|
|
27
|
+
timestamp: new Date().toISOString(),
|
|
28
|
+
duration_ms: Date.now() - _traceStart,
|
|
29
|
+
...extra,
|
|
30
|
+
};
|
|
31
|
+
const file = path.join(traceDir, `${new Date().toISOString().split("T")[0]}.jsonl`);
|
|
32
|
+
fs.appendFileSync(file, JSON.stringify(entry) + "\n");
|
|
33
|
+
} catch {}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Read hook payload from stdin.
|
|
37
|
+
let command = "";
|
|
38
|
+
try {
|
|
39
|
+
if (!process.stdin.isTTY) {
|
|
40
|
+
const raw = fs.readFileSync(0, "utf8");
|
|
41
|
+
if (raw) command = (JSON.parse(raw).tool_input || {}).command || "";
|
|
42
|
+
}
|
|
43
|
+
} catch {}
|
|
44
|
+
|
|
45
|
+
if (!command) {
|
|
46
|
+
_trace("allow", { reason: "no-command" });
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Only act on vercel deploy commands.
|
|
51
|
+
if (!/vercel\s+(--prod|deploy)/.test(command)) {
|
|
52
|
+
_trace("allow", { reason: "not-vercel-deploy" });
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Read allowed teams (one slug per line).
|
|
57
|
+
const teamsFile = path.join(os.homedir(), ".claude", ".vercel-allowed-teams");
|
|
58
|
+
let allowed;
|
|
59
|
+
try {
|
|
60
|
+
allowed = fs.readFileSync(teamsFile, "utf8").split(/\r?\n/).map(l => l.trim()).filter(Boolean);
|
|
61
|
+
} catch {
|
|
62
|
+
allowed = [];
|
|
63
|
+
}
|
|
64
|
+
if (allowed.length === 0) {
|
|
65
|
+
console.error("No .vercel-allowed-teams configured -- skipping account check");
|
|
66
|
+
_trace("skipped", { reason: "no-config" });
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Run `vercel whoami` to get the active account (fail-open on error).
|
|
71
|
+
const r = spawnSync("vercel", ["whoami"], {
|
|
72
|
+
encoding: "utf8", timeout: 5000, shell: process.platform === "win32",
|
|
73
|
+
});
|
|
74
|
+
const actual = ((r.status === 0 && !r.error) ? (r.stdout || "") : "").trim();
|
|
75
|
+
if (!actual) {
|
|
76
|
+
console.error("vercel whoami failed or empty -- skipping account check");
|
|
77
|
+
_trace("skipped", { reason: "whoami-unavailable" });
|
|
78
|
+
process.exit(0);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (allowed.includes(actual)) {
|
|
82
|
+
_trace("allow", { actual, allowed_count: allowed.length });
|
|
83
|
+
process.exit(0);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Block: wrong account.
|
|
87
|
+
const msg = `BLOCKED: Wrong Vercel account/team. Active: '${actual}'. Allowed: ${allowed.join(", ")}. Run \`vercel switch ${allowed[0]}\` first, or add this team to ~/.claude/.vercel-allowed-teams.`;
|
|
88
|
+
console.error(msg);
|
|
89
|
+
console.log(msg);
|
|
90
|
+
_trace("block", { actual, allowed_count: allowed.length, reason: "wrong-account" });
|
|
91
|
+
process.exit(2);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qualia-framework",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "Claude Code workflow framework by Qualia Solutions. Plan, build, verify, ship.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"qualia-framework": "./bin/cli.js"
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"tests/",
|
|
43
43
|
"docs/",
|
|
44
44
|
"CLAUDE.md",
|
|
45
|
+
"AGENTS.md",
|
|
45
46
|
"guide.md"
|
|
46
47
|
],
|
|
47
48
|
"engines": {
|
package/rules/design-brand.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
globs: ["*.tsx", "*.jsx", "*.css", "*.scss", "*.html", "*.vue", "*.svelte"]
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Design — Brand register
|
|
2
6
|
|
|
3
7
|
**When this register applies:** marketing pages, landing pages, campaign sites, portfolios, brand microsites, anything where the design IS the product.
|
package/rules/design-laws.md
CHANGED
package/rules/design-product.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
globs: ["*.tsx", "*.jsx", "*.css", "*.scss", "*.html", "*.vue", "*.svelte"]
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Design — Product register
|
|
2
6
|
|
|
3
7
|
**When this register applies:** app UI, admin consoles, dashboards, internal tools, settings pages, anything where the design SERVES the product.
|
package/rules/design-rubric.md
CHANGED
package/rules/grounding.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-build
|
|
3
|
-
description: "
|
|
3
|
+
description: "Executes a planned phase by spawning fresh builder subagents per task with wave-based parallelization. Each task gets isolated context, commits atomically, and runs its own validation. Use when the user says 'build this phase', 'execute the plan', 'start building', 'run the build', 'qualia-build', or after /qualia-plan approves a phase plan."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -15,12 +15,12 @@ allowed-tools:
|
|
|
15
15
|
|
|
16
16
|
# /qualia-build — Build a Phase
|
|
17
17
|
|
|
18
|
-
Execute
|
|
18
|
+
Execute phase plan. Each task = fresh subagent. Independent tasks run parallel.
|
|
19
19
|
|
|
20
20
|
## Usage
|
|
21
|
-
`/qualia-build` — build
|
|
21
|
+
`/qualia-build` — build current planned phase
|
|
22
22
|
`/qualia-build {N}` — build specific phase
|
|
23
|
-
`/qualia-build {N} --auto` — build + chain into `/qualia-verify {N} --auto`
|
|
23
|
+
`/qualia-build {N} --auto` — build + chain into `/qualia-verify {N} --auto` (no human gate)
|
|
24
24
|
|
|
25
25
|
## Process
|
|
26
26
|
|
|
@@ -30,11 +30,11 @@ Execute the phase plan. Each task runs in a fresh subagent context. Independent
|
|
|
30
30
|
cat .planning/phase-{N}-plan.md
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
Parse
|
|
33
|
+
Parse tasks, waves, file refs.
|
|
34
34
|
|
|
35
|
-
### 1b.
|
|
35
|
+
### 1b. Recovery Reference
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Tag HEAD before executing. Reference only, no auto-rollback.
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
git tag -f "pre-build-phase-{N}" HEAD 2>/dev/null
|
|
@@ -44,7 +44,7 @@ git tag -f "pre-build-phase-{N}" HEAD 2>/dev/null
|
|
|
44
44
|
node ~/.claude/bin/qualia-ui.js info "Recovery point: pre-build-phase-{N}"
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
Wave fail → stop, inspect status + output. Preserve work; fix forward or ask before reverting.
|
|
48
48
|
```bash
|
|
49
49
|
git status --short
|
|
50
50
|
git diff --stat
|
|
@@ -62,33 +62,32 @@ node ~/.claude/bin/qualia-ui.js banner build {N} "{phase name}"
|
|
|
62
62
|
node ~/.claude/bin/qualia-ui.js wave {W} {total_waves} {tasks_in_wave}
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
**
|
|
65
|
+
**Per task in wave: spawn ALL as separate `Agent()` calls in SAME turn (concurrent). Do NOT await one before spawning next.**
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
68
|
node ~/.claude/bin/qualia-ui.js task {task_num} "{task title}"
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
**Pre-inline context
|
|
71
|
+
**Pre-inline context** (saves 3-5 Read calls per builder):
|
|
72
72
|
|
|
73
|
-
1. Parse
|
|
73
|
+
1. Parse task `Context:` → `@file` refs
|
|
74
74
|
2. Read PROJECT.md
|
|
75
|
-
3. Read DESIGN.md if
|
|
76
|
-
4. Read each `@file`
|
|
77
|
-
5. Inline all
|
|
75
|
+
3. Read DESIGN.md if task touches `.tsx`/`.jsx`/`.css`/`.scss`
|
|
76
|
+
4. Read each `@file` from Context
|
|
77
|
+
5. Inline all into prompt under `<pre-loaded-context>`
|
|
78
78
|
|
|
79
|
-
Spawn
|
|
79
|
+
Spawn builder:
|
|
80
80
|
|
|
81
81
|
```
|
|
82
82
|
Agent(prompt="
|
|
83
|
-
|
|
84
|
-
Grounding + rubrics: @~/.claude/rules/grounding.md
|
|
83
|
+
Role: @~/.claude/agents/builder.md
|
|
85
84
|
|
|
86
85
|
<phase_context>
|
|
87
86
|
# PROJECT.md
|
|
88
|
-
{inlined
|
|
87
|
+
{inlined .planning/PROJECT.md}
|
|
89
88
|
|
|
90
89
|
# DESIGN.md (if frontend task)
|
|
91
|
-
{inlined
|
|
90
|
+
{inlined .planning/DESIGN.md}
|
|
92
91
|
</phase_context>
|
|
93
92
|
|
|
94
93
|
<task_context>
|
|
@@ -97,40 +96,35 @@ Grounding + rubrics: @~/.claude/rules/grounding.md
|
|
|
97
96
|
</task_context>
|
|
98
97
|
|
|
99
98
|
<wave_context>
|
|
100
|
-
|
|
101
|
-
- Task {N}:
|
|
102
|
-
- Task {M}:
|
|
103
|
-
(
|
|
99
|
+
Parallel tasks Wave {W} (do NOT touch their files):
|
|
100
|
+
- Task {N}: {title} -- files: {files}
|
|
101
|
+
- Task {M}: {title} -- files: {files}
|
|
102
|
+
(Omit if sole task in wave.)
|
|
104
103
|
</wave_context>
|
|
105
104
|
|
|
106
105
|
<task>
|
|
107
|
-
{
|
|
106
|
+
{task block from plan: title, wave, persona, files, depends-on, why, AC, action, validation, context}
|
|
108
107
|
</task>
|
|
109
108
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
Execute the task. Commit when done. Return DONE/BLOCKED/PARTIAL per your Output Contract.
|
|
109
|
+
Context tags already loaded. Only Read project code you modify.
|
|
110
|
+
Execute. Commit. Return DONE/BLOCKED/PARTIAL.
|
|
113
111
|
", subagent_type="qualia-builder", description="Task {N}: {title}")
|
|
114
112
|
```
|
|
115
113
|
|
|
116
|
-
**
|
|
117
|
-
|
|
118
|
-
**Why pre-inline at all:** without it, the builder's first actions are 3-5 Read tool calls to orient itself. With pre-inline, the builder starts already oriented and spends its context budget on the actual task.
|
|
114
|
+
**Cache ordering:** Role + grounding FIRST, phase_context SECOND, task_context LAST. Stable prefix ~2-5k tokens → 92% cache hit. Pre-inline eliminates 3-5 Read calls per builder.
|
|
119
115
|
|
|
120
|
-
**After each task
|
|
121
|
-
- Verify
|
|
122
|
-
- Show
|
|
116
|
+
**After each task:**
|
|
117
|
+
- Verify commit: `git log --oneline -1`
|
|
118
|
+
- Show:
|
|
123
119
|
```bash
|
|
124
120
|
node ~/.claude/bin/qualia-ui.js done {task_num} "{title}" {commit_hash}
|
|
125
121
|
```
|
|
126
122
|
|
|
127
|
-
**After each wave
|
|
128
|
-
- Move to next wave
|
|
129
|
-
- Show wave summary
|
|
123
|
+
**After each wave:** move to next, show summary.
|
|
130
124
|
|
|
131
125
|
### 3. Wave Completion
|
|
132
126
|
|
|
133
|
-
|
|
127
|
+
All waves done:
|
|
134
128
|
|
|
135
129
|
```bash
|
|
136
130
|
node ~/.claude/bin/qualia-ui.js divider
|
|
@@ -141,30 +135,30 @@ node ~/.claude/bin/qualia-ui.js ok "Waves: {count}"
|
|
|
141
135
|
|
|
142
136
|
### 4. Handle Failures
|
|
143
137
|
|
|
144
|
-
|
|
145
|
-
- **Minor
|
|
146
|
-
- **Major
|
|
147
|
-
- **Blocker:** Show
|
|
138
|
+
Builder returns deviation/blocker:
|
|
139
|
+
- **Minor:** Log, continue
|
|
140
|
+
- **Major:** Show to employee, ask how to proceed
|
|
141
|
+
- **Blocker:** Show, suggest fix or escalation
|
|
148
142
|
|
|
149
143
|
### 5. Update State
|
|
150
144
|
|
|
151
145
|
```bash
|
|
152
146
|
node ~/.claude/bin/state.js transition --to built --phase {N} --tasks-done {done} --tasks-total {total} --wave {wave}
|
|
153
147
|
```
|
|
154
|
-
|
|
155
|
-
Do NOT
|
|
148
|
+
Error → show, stop.
|
|
149
|
+
Do NOT edit STATE.md or tracking.json manually; state.js handles both.
|
|
156
150
|
|
|
157
151
|
### 6. Route (auto-chain aware)
|
|
158
152
|
|
|
159
|
-
|
|
153
|
+
**`--auto`:** invoke `/qualia-verify {N} --auto` inline. No pause.
|
|
160
154
|
|
|
161
155
|
```bash
|
|
162
156
|
node ~/.claude/bin/qualia-ui.js info "Auto mode — chaining into /qualia-verify {N}"
|
|
163
157
|
```
|
|
164
158
|
|
|
165
|
-
Then invoke
|
|
159
|
+
Then invoke `qualia-verify` inline with `--auto`.
|
|
166
160
|
|
|
167
|
-
**
|
|
161
|
+
**Guided mode:** stop, show next step:
|
|
168
162
|
|
|
169
163
|
```bash
|
|
170
164
|
node ~/.claude/bin/qualia-ui.js end "PHASE {N} BUILT" "/qualia-verify {N}"
|
|
@@ -1,121 +1,104 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-discuss
|
|
3
|
-
description: "
|
|
3
|
+
description: "Aggressive alignment interview before planning a phase — asks ONE question at a time, proposes a recommended answer with each, walks every branch of the decision tree until resolved. Updates .planning/CONTEXT.md inline as terms crystallize and writes ADRs for hard-to-reverse decisions. Output: .planning/phase-{N}-context.md (locked input the planner honors). Use BEFORE /qualia-plan for high-stakes phases (regulatory, auth, payments, multi-tenant, architectural forks), or when the user says 'discuss', 'grill me', 'stress test this plan', 'wait let's think about this one', 'I'm not sure how to approach this'."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
7
7
|
- Write
|
|
8
8
|
- Edit
|
|
9
|
+
- Grep
|
|
10
|
+
- Glob
|
|
9
11
|
- AskUserQuestion
|
|
10
12
|
---
|
|
11
13
|
|
|
12
|
-
# /qualia-discuss —
|
|
14
|
+
# /qualia-discuss — Alignment Interview Before Planning
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## When to Use
|
|
16
|
+
Surface and lock the decisions, trade-offs, and constraints that must inform a phase plan. Output: `.planning/phase-{N}-context.md` (locked input). Side effects: `.planning/CONTEXT.md` gains new terms; `.planning/decisions/` may gain ADRs.
|
|
17
17
|
|
|
18
|
+
## When to use
|
|
18
19
|
- Regulated domains (legal, medical, financial) where wrong choices have legal cost
|
|
19
|
-
- Phases with architectural forks (
|
|
20
|
+
- Phases with architectural forks ("auth via middleware or RLS?")
|
|
20
21
|
- Phases with external dependencies you want to lock first
|
|
21
|
-
-
|
|
22
|
+
- User says "wait, let's think about this one"
|
|
22
23
|
|
|
23
|
-
##
|
|
24
|
+
## The four grilling rules
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
1. **One question at a time.** Wait for the answer before asking the next. Never batch.
|
|
27
|
+
2. **Propose your recommended answer first.** Format every question as `Question / Recommendation / Trade-offs`. The user accepts, edits, or rejects — way faster than open interview.
|
|
28
|
+
3. **If the codebase can answer, explore instead of asking.** Don't make the user say what `git grep` could tell you.
|
|
29
|
+
4. **Walk every branch.** When the user picks A over B, the next question is the one that A makes load-bearing. Resolve dependencies one-by-one until the tree is fully traversed.
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
node ~/.claude/bin/state.js check 2>/dev/null
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
If a phase number was passed as argument, use it. Otherwise use the current phase from STATE.md.
|
|
31
|
+
## Process
|
|
32
32
|
|
|
33
|
-
###
|
|
33
|
+
### 1. Load substrate
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
|
|
37
|
-
cat .planning/ROADMAP.md 2>/dev/null
|
|
36
|
+
node ~/.claude/bin/state.js check 2>/dev/null
|
|
37
|
+
cat .planning/PROJECT.md .planning/ROADMAP.md .planning/CONTEXT.md 2>/dev/null
|
|
38
|
+
ls .planning/decisions/ 2>/dev/null
|
|
38
39
|
cat .planning/research/SUMMARY.md 2>/dev/null
|
|
39
40
|
```
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
-
|
|
43
|
-
- Requirements covered by this phase
|
|
44
|
-
- Research flags for this phase (from SUMMARY.md)
|
|
42
|
+
If `.planning/CONTEXT.md` is missing, copy `~/.claude/qualia-templates/CONTEXT.md` to `.planning/CONTEXT.md` first.
|
|
43
|
+
If `.planning/decisions/` is missing, create it. Copy `~/.claude/qualia-templates/decisions/ADR-template.md` next to it for reference.
|
|
45
44
|
|
|
46
|
-
###
|
|
45
|
+
### 2. Open the conversation
|
|
47
46
|
|
|
48
|
-
Print the banner:
|
|
49
47
|
```bash
|
|
50
48
|
node ~/.claude/bin/qualia-ui.js banner discuss {N} "{phase name from ROADMAP.md}"
|
|
51
49
|
```
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
**"We're about to plan {phase name}. The goal is: {goal from ROADMAP.md}. Before I hand this to the planner, what decisions, trade-offs, or constraints should be locked in?"**
|
|
51
|
+
Then state the goal in one sentence and the open questions you found in priority order (highest-stakes / hardest-to-reverse first).
|
|
56
52
|
|
|
57
|
-
|
|
53
|
+
### 3. Grill, one question at a time
|
|
58
54
|
|
|
59
|
-
|
|
55
|
+
Format:
|
|
60
56
|
|
|
61
|
-
|
|
57
|
+
```
|
|
58
|
+
**Question {N}/{total}:** {the question}
|
|
62
59
|
|
|
63
|
-
|
|
64
|
-
- If they mention a constraint → "What happens if we don't honor this?"
|
|
65
|
-
- If they mention a trade-off → "Which side do you want to land on, and why?"
|
|
66
|
-
- If they mention a concern → "What's the worst case?"
|
|
60
|
+
**My recommendation:** {your proposed answer + 1-sentence why}
|
|
67
61
|
|
|
68
|
-
|
|
62
|
+
**Trade-offs:** {what gets harder if we go this way}
|
|
63
|
+
```
|
|
69
64
|
|
|
70
|
-
|
|
65
|
+
Wait for response. Then:
|
|
66
|
+
- Update `.planning/CONTEXT.md` inline if a term crystallized (add definition + `Avoid:` line for rejected synonyms)
|
|
67
|
+
- Write an ADR in `.planning/decisions/ADR-{NNNN}-{slug}.md` ONLY when the decision is hard-to-reverse, surprising-without-context, AND involves real trade-offs (use the template — keep it scarce)
|
|
68
|
+
- Drill deeper if the answer opens new branches
|
|
71
69
|
|
|
72
|
-
|
|
73
|
-
- The choice (what)
|
|
74
|
-
- The rationale (why)
|
|
75
|
-
- The source (who/when)
|
|
70
|
+
### 4. Build the locked-decisions list
|
|
76
71
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
- **Deferred ideas** — good ideas that are NOT in this phase
|
|
80
|
-
- **Risk flags** — things to watch during building
|
|
81
|
-
- **Open questions** — things that still need resolution
|
|
72
|
+
For each resolved decision, capture: choice (what) / rationale (why) / source (who/when).
|
|
73
|
+
Also track: **Discretion items** (planner decides) / **Deferred ideas** (NOT this phase) / **Risk flags** (watch during build) / **Open questions** (still unresolved).
|
|
82
74
|
|
|
83
|
-
###
|
|
75
|
+
### 5. Decision gate
|
|
84
76
|
|
|
85
|
-
When
|
|
77
|
+
When the tree is fully traversed:
|
|
86
78
|
|
|
87
79
|
- header: "Ready to lock?"
|
|
88
|
-
- question: "
|
|
89
|
-
- options:
|
|
90
|
-
- "Lock it in" — Write phase-{N}-context.md and done
|
|
91
|
-
- "Keep exploring" — I have more to say
|
|
80
|
+
- question: "Lock these decisions and move to /qualia-plan {N}?"
|
|
81
|
+
- options: "Lock it in" / "Keep exploring"
|
|
92
82
|
|
|
93
83
|
Loop until "Lock it in".
|
|
94
84
|
|
|
95
|
-
###
|
|
96
|
-
|
|
97
|
-
Use the template at `~/.claude/qualia-templates/phase-context.md`. Fill every section with concrete content.
|
|
85
|
+
### 6. Write phase-{N}-context.md
|
|
98
86
|
|
|
99
|
-
|
|
100
|
-
# Write the file to .planning/phase-{N}-context.md
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### 8. Commit
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
git add .planning/phase-{N}-context.md
|
|
107
|
-
git commit -m "docs(phase-{N}): capture phase context before planning"
|
|
108
|
-
```
|
|
87
|
+
Fill `~/.claude/qualia-templates/phase-context.md` with concrete content. Reference any ADRs written, any CONTEXT.md terms added.
|
|
109
88
|
|
|
110
|
-
###
|
|
89
|
+
### 7. Commit and route
|
|
111
90
|
|
|
112
91
|
```bash
|
|
92
|
+
git add .planning/phase-{N}-context.md .planning/CONTEXT.md .planning/decisions/
|
|
93
|
+
git commit -m "docs(phase-{N}): lock context, glossary terms, ADRs"
|
|
113
94
|
node ~/.claude/bin/qualia-ui.js end "PHASE {N} CONTEXT LOCKED" "/qualia-plan {N}"
|
|
114
95
|
```
|
|
115
96
|
|
|
116
97
|
## Rules
|
|
117
98
|
|
|
118
|
-
1. **One session, one phase.** Don't
|
|
119
|
-
2. **Locked decisions are NON-NEGOTIABLE.** The planner
|
|
120
|
-
3. **Don't redo research.** If
|
|
121
|
-
4. **
|
|
99
|
+
1. **One session, one phase.** Don't discuss phases 1 and 2 in the same invocation.
|
|
100
|
+
2. **Locked decisions are NON-NEGOTIABLE.** The planner honors them exactly. Don't lock what you're unsure of — defer it instead.
|
|
101
|
+
3. **Don't redo research.** If a question requires research you don't have, suggest `/qualia-research {N}` and pause.
|
|
102
|
+
4. **CONTEXT.md is precious — keep entries terse.** One sentence each. It's loaded into every spawn; bloat costs tokens.
|
|
103
|
+
5. **ADRs are scarce on purpose.** Three criteria all required. If any is missing, put it in CONTEXT.md or the phase-context.md instead.
|
|
104
|
+
6. **Short context files are fine.** A 30-line context for a simple phase beats a forced 200-line one.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-handoff
|
|
3
|
+
disable-model-invocation: true
|
|
3
4
|
description: "Client delivery — produces the 4 mandatory Handoff deliverables (production URL, documentation, client assets archive, ERP finalization). Triggered at the end of the Handoff milestone."
|
|
4
5
|
allowed-tools:
|
|
5
6
|
- Bash
|