qualia-framework 6.2.10 → 6.4.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 +8 -7
- package/CLAUDE.md +5 -4
- package/README.md +27 -56
- package/bin/cli.js +113 -18
- package/bin/command-surface.js +75 -0
- package/bin/harness-eval.js +296 -0
- package/bin/install.js +43 -31
- package/bin/knowledge-flush.js +21 -10
- package/bin/knowledge.js +1 -1
- package/bin/learning-candidates.js +217 -0
- package/bin/project-snapshot.js +20 -0
- package/bin/prune-deprecated.js +64 -0
- package/bin/report-payload.js +18 -0
- package/bin/runtime-manifest.js +7 -0
- package/bin/security-scan.js +409 -0
- package/bin/state.js +31 -0
- package/bin/status-snapshot.js +363 -0
- package/bin/trust-score.js +3 -11
- package/bin/work-packet.js +228 -0
- package/docs/erp-contract.md +81 -1
- package/docs/onboarding.html +0 -11
- package/guide.md +15 -38
- package/hooks/fawzi-approval-guard.js +143 -0
- package/hooks/pre-compact.js +232 -0
- package/hooks/pre-deploy-gate.js +74 -1
- package/hooks/session-start.js +29 -1
- package/package.json +1 -1
- package/qualia-design/frontend.md +2 -2
- package/rules/codex-goal.md +1 -1
- package/rules/one-opinion.md +2 -2
- package/rules/speed.md +0 -1
- package/skills/qualia/SKILL.md +4 -4
- package/skills/qualia-build/SKILL.md +1 -1
- package/skills/qualia-discuss/SKILL.md +1 -1
- package/skills/qualia-doctor/SKILL.md +1 -1
- package/skills/qualia-feature/SKILL.md +2 -2
- package/skills/qualia-fix/SKILL.md +4 -4
- package/skills/qualia-idk/SKILL.md +133 -54
- package/skills/qualia-learn/SKILL.md +2 -2
- package/skills/qualia-map/SKILL.md +1 -1
- package/skills/qualia-milestone/SKILL.md +1 -1
- package/skills/qualia-new/SKILL.md +1 -1
- package/skills/qualia-optimize/SKILL.md +1 -1
- package/skills/qualia-plan/SKILL.md +1 -1
- package/skills/qualia-polish/REFERENCE.md +1 -1
- package/skills/qualia-polish/SKILL.md +19 -4
- package/skills/{qualia-vibe/scripts/extract.mjs → qualia-polish/scripts/vibe-extract.mjs} +4 -4
- package/skills/{qualia-vibe/scripts/tokens.mjs → qualia-polish/scripts/vibe-tokens.mjs} +6 -6
- package/skills/qualia-postmortem/SKILL.md +1 -1
- package/skills/qualia-report/SKILL.md +1 -1
- package/skills/qualia-research/SKILL.md +1 -1
- package/skills/qualia-review/SKILL.md +1 -1
- package/skills/qualia-road/SKILL.md +15 -20
- package/skills/qualia-secure/SKILL.md +105 -0
- package/skills/qualia-ship/SKILL.md +12 -5
- package/skills/qualia-test/SKILL.md +1 -1
- package/skills/qualia-verify/SKILL.md +10 -2
- package/skills/zoho-workflow/SKILL.md +1 -1
- package/templates/help.html +1 -12
- package/tests/bin.test.sh +147 -75
- package/tests/hooks.test.sh +81 -1
- package/tests/install-smoke.test.sh +14 -4
- package/tests/lib.test.sh +145 -3
- package/tests/published-install-smoke.test.sh +5 -4
- package/tests/refs.test.sh +32 -20
- package/tests/runner.js +30 -29
- package/tests/state.test.sh +106 -7
- package/skills/qualia-debug/SKILL.md +0 -193
- package/skills/qualia-flush/SKILL.md +0 -198
- package/skills/qualia-help/SKILL.md +0 -74
- package/skills/qualia-hook-gen/SKILL.md +0 -206
- package/skills/qualia-issues/SKILL.md +0 -151
- package/skills/qualia-pause/SKILL.md +0 -68
- package/skills/qualia-resume/SKILL.md +0 -52
- package/skills/qualia-skill-new/SKILL.md +0 -173
- package/skills/qualia-triage/SKILL.md +0 -152
- package/skills/qualia-vibe/SKILL.md +0 -229
- package/skills/qualia-zoom/SKILL.md +0 -51
package/hooks/pre-deploy-gate.js
CHANGED
|
@@ -21,6 +21,8 @@ function qualiaHome() {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
const QUALIA_HOME = qualiaHome();
|
|
24
|
+
const CONFIG = path.join(QUALIA_HOME, ".qualia-config.json");
|
|
25
|
+
let HOOK_COMMAND = null;
|
|
24
26
|
|
|
25
27
|
// Self-filter on the proposed bash command — only act when the user is
|
|
26
28
|
// actually trying to deploy. Claude Code's `if: "Bash(vercel --prod*)"` does
|
|
@@ -44,7 +46,8 @@ const QUALIA_HOME = qualiaHome();
|
|
|
44
46
|
}
|
|
45
47
|
} catch {}
|
|
46
48
|
if (command === null) return; // malformed or empty stdin — run full gate
|
|
47
|
-
|
|
49
|
+
HOOK_COMMAND = command;
|
|
50
|
+
if (!/^\s*(?:[A-Za-z_][A-Za-z0-9_]*=\S+\s+)*(npx\s+)?vercel\s+(--prod|deploy\s+--prod)\b/.test(command)) {
|
|
48
51
|
process.exit(0);
|
|
49
52
|
}
|
|
50
53
|
})();
|
|
@@ -107,6 +110,76 @@ function hasScript(name) {
|
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
112
|
|
|
113
|
+
function readConfig() {
|
|
114
|
+
try {
|
|
115
|
+
return JSON.parse(fs.readFileSync(CONFIG, "utf8"));
|
|
116
|
+
} catch {
|
|
117
|
+
return {};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function readTrackingState() {
|
|
122
|
+
try {
|
|
123
|
+
const tracking = JSON.parse(fs.readFileSync(path.join(process.cwd(), ".planning", "tracking.json"), "utf8"));
|
|
124
|
+
return {
|
|
125
|
+
status: tracking.status || "",
|
|
126
|
+
verification: tracking.verification || "",
|
|
127
|
+
next_command: tracking.next_command || "",
|
|
128
|
+
};
|
|
129
|
+
} catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function readState() {
|
|
135
|
+
const stateJs = path.join(QUALIA_HOME, "bin", "state.js");
|
|
136
|
+
if (fs.existsSync(stateJs)) {
|
|
137
|
+
try {
|
|
138
|
+
const r = spawnSync(process.execPath, [stateJs, "check"], {
|
|
139
|
+
encoding: "utf8",
|
|
140
|
+
timeout: 3000,
|
|
141
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
142
|
+
});
|
|
143
|
+
if (r.status === 0 && r.stdout) return JSON.parse(r.stdout);
|
|
144
|
+
} catch {}
|
|
145
|
+
}
|
|
146
|
+
return readTrackingState();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function blockDeploy(reason, nextCommand) {
|
|
150
|
+
console.error(`BLOCKED: ${reason}`);
|
|
151
|
+
if (nextCommand) console.error(`Run: ${nextCommand}`);
|
|
152
|
+
_trace("pre-deploy-gate", "block", { reason, next_command: nextCommand || "" });
|
|
153
|
+
process.exit(2);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function enforceShipPolicy() {
|
|
157
|
+
if (!HOOK_COMMAND) return;
|
|
158
|
+
|
|
159
|
+
const config = readConfig();
|
|
160
|
+
const role = String(config.role || "").toUpperCase();
|
|
161
|
+
const force = process.env.QUALIA_SHIP_FORCE === "1" || /\bQUALIA_SHIP_FORCE=1\b/.test(HOOK_COMMAND);
|
|
162
|
+
const state = readState();
|
|
163
|
+
const status = state && state.status ? String(state.status) : "";
|
|
164
|
+
const verification = state && state.verification ? String(state.verification) : "";
|
|
165
|
+
const nextCommand = (state && state.next_command) || "/qualia";
|
|
166
|
+
|
|
167
|
+
if (force && role !== "OWNER") {
|
|
168
|
+
blockDeploy("QUALIA_SHIP_FORCE is OWNER-only.", nextCommand);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// If this is not a Qualia-managed project, keep the legacy behavior: run the
|
|
172
|
+
// quality/security gates but do not invent state.
|
|
173
|
+
if (!state || !status) return;
|
|
174
|
+
|
|
175
|
+
const shippable = status === "polished" || (status === "verified" && verification === "pass");
|
|
176
|
+
if (!shippable && !force) {
|
|
177
|
+
blockDeploy(`Ship refused from state '${status}' (verification: ${verification || "none"}).`, nextCommand);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
enforceShipPolicy();
|
|
182
|
+
|
|
110
183
|
// Directories that should never be walked (build outputs, deps, caches).
|
|
111
184
|
const EXCLUDED_DIRS = new Set([
|
|
112
185
|
"node_modules",
|
package/hooks/session-start.js
CHANGED
|
@@ -25,6 +25,9 @@ function qualiaHome() {
|
|
|
25
25
|
if (process.env.QUALIA_HOME) return process.env.QUALIA_HOME;
|
|
26
26
|
const parent = path.basename(path.dirname(__dirname));
|
|
27
27
|
if (parent === ".codex" || parent === ".claude") return path.dirname(__dirname);
|
|
28
|
+
if (fs.existsSync(path.join(path.dirname(__dirname), "bin", "qualia-ui.js"))) {
|
|
29
|
+
return path.dirname(__dirname);
|
|
30
|
+
}
|
|
28
31
|
return path.join(HOME, ".claude");
|
|
29
32
|
}
|
|
30
33
|
|
|
@@ -36,6 +39,7 @@ const NOTIF_FILE = path.join(QUALIA_HOME, ".qualia-update-available.json");
|
|
|
36
39
|
const HEALTH_FILE = path.join(QUALIA_HOME, ".qualia-install-health.json");
|
|
37
40
|
const ERP_RETRY = path.join(QUALIA_HOME, "bin", "erp-retry.js");
|
|
38
41
|
const ERP_QUEUE = path.join(QUALIA_HOME, ".erp-retry-queue.json");
|
|
42
|
+
const WORK_PACKET_BIN = path.join(QUALIA_HOME, "bin", "work-packet.js");
|
|
39
43
|
|
|
40
44
|
// Critical files referenced by skills via @-import. If any are missing, skills
|
|
41
45
|
// silently get empty context and produce ungrounded output. We spot-check these
|
|
@@ -97,6 +101,29 @@ function getNextCommand() {
|
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
103
|
|
|
104
|
+
function readWorkPacket() {
|
|
105
|
+
try {
|
|
106
|
+
if (!fs.existsSync(WORK_PACKET_BIN)) return null;
|
|
107
|
+
const mod = require(WORK_PACKET_BIN);
|
|
108
|
+
if (!mod || typeof mod.readLocalWorkPacket !== "function") return null;
|
|
109
|
+
return mod.readLocalWorkPacket(process.cwd());
|
|
110
|
+
} catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function renderWorkPacketContext() {
|
|
116
|
+
const packet = readWorkPacket();
|
|
117
|
+
if (!packet) return;
|
|
118
|
+
const project = packet.project && packet.project.name ? packet.project.name : "ERP mission";
|
|
119
|
+
const deadline = packet.deadline_date || "no deadline";
|
|
120
|
+
const next = packet.next_command || "/qualia";
|
|
121
|
+
const employee = packet.employee && packet.employee.name ? ` · ${packet.employee.name}` : "";
|
|
122
|
+
const text = `${project}: due ${deadline} · next ${next}${employee}`;
|
|
123
|
+
if (fs.existsSync(UI)) runUi("info", text);
|
|
124
|
+
else console.log(`QUALIA: ${text}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
100
127
|
function readConfig() {
|
|
101
128
|
try {
|
|
102
129
|
return JSON.parse(fs.readFileSync(path.join(QUALIA_HOME, ".qualia-config.json"), "utf8"));
|
|
@@ -178,6 +205,7 @@ try {
|
|
|
178
205
|
fallbackText();
|
|
179
206
|
} else if (fs.existsSync(STATE_FILE)) {
|
|
180
207
|
runUi("banner", "router");
|
|
208
|
+
renderWorkPacketContext();
|
|
181
209
|
const next = getNextCommand();
|
|
182
210
|
if (next) {
|
|
183
211
|
console.log("");
|
|
@@ -185,7 +213,7 @@ try {
|
|
|
185
213
|
}
|
|
186
214
|
} else if (fs.existsSync(CONTINUE_HERE)) {
|
|
187
215
|
runUi("banner", "resume");
|
|
188
|
-
runUi("warn", "Previous session found — type /qualia
|
|
216
|
+
runUi("warn", "Previous session found — type /qualia to pick up where you left off");
|
|
189
217
|
console.log("");
|
|
190
218
|
} else {
|
|
191
219
|
// No project — show a welcoming first-run experience
|
package/package.json
CHANGED
|
@@ -115,8 +115,8 @@ For redesigns and full-app polish, also read:
|
|
|
115
115
|
|
|
116
116
|
## Qualia design commands
|
|
117
117
|
- `/qualia-polish` — design pass, scope-adaptive (component / section / app / redesign / critique / quick / loop)
|
|
118
|
-
- `/qualia-vibe` — fast aesthetic pivot (swap tokens, keep layout) + reverse-engineer from URL + code↔DESIGN.md sync
|
|
118
|
+
- `/qualia-polish --vibe` — fast aesthetic pivot (swap tokens, keep layout) + reverse-engineer from URL + code↔DESIGN.md sync
|
|
119
119
|
- `/qualia-review` — scored production audit
|
|
120
120
|
|
|
121
121
|
### Recommended workflow
|
|
122
|
-
1. Build feature → 2. `/qualia-polish` to polish within the current vibe → 3. `/qualia-vibe` when the vibe itself needs to change → 4. `/qualia-polish --redesign` when the whole surface needs stronger visual concept/graphics → 5. `/qualia-polish --loop` for autonomous visual QA → ship.
|
|
122
|
+
1. Build feature → 2. `/qualia-polish` to polish within the current vibe → 3. `/qualia-polish --vibe` when the vibe itself needs to change → 4. `/qualia-polish --redesign` when the whole surface needs stronger visual concept/graphics → 5. `/qualia-polish --loop` for autonomous visual QA → ship.
|
package/rules/codex-goal.md
CHANGED
|
@@ -39,7 +39,7 @@ If the answer is `claude`, **skip this entire rule** — Claude Code has no equi
|
|
|
39
39
|
|
|
40
40
|
- The user is on Claude Code (no `/goal` surface).
|
|
41
41
|
- A goal is already active for this thread (Codex rejects `update_goal` when one exists — call `thread/goal/get` first if you're using the tool API directly).
|
|
42
|
-
- The work is open-ended exploration with no clear objective (e.g. `/qualia
|
|
42
|
+
- The work is open-ended exploration with no clear objective (e.g. `/qualia`, `/qualia-discuss`). Goals are for executing a defined scope.
|
|
43
43
|
|
|
44
44
|
## Why
|
|
45
45
|
|
package/rules/one-opinion.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# One Opinion (design-decision discipline)
|
|
2
2
|
|
|
3
|
-
Loaded on demand by design-adjacent skills: `/qualia-vibe`, `/qualia-polish`, `/qualia-new` (DESIGN.md creation step), `/qualia-discuss` PROJECT MODE. Not always-on — most skills don't need it.
|
|
3
|
+
Loaded on demand by design-adjacent skills: `/qualia-polish --vibe`, `/qualia-polish`, `/qualia-new` (DESIGN.md creation step), `/qualia-discuss` PROJECT MODE. Not always-on — most skills don't need it.
|
|
4
4
|
|
|
5
5
|
## The rule
|
|
6
6
|
|
|
@@ -34,7 +34,7 @@ Owners and clients have a strong sense of what they DON'T want and a weaker sens
|
|
|
34
34
|
- The user explicitly asked for options ("show me 3 directions", "give me a menu").
|
|
35
35
|
- The decision is technical, not aesthetic (e.g. "use Postgres or MongoDB?" — those have objectively different tradeoffs and should be discussed, not opinionated).
|
|
36
36
|
- A locked decision in `.planning/decisions/*.md` already exists — surface it, don't re-decide.
|
|
37
|
-
- The framework command explicitly supports a `--variants` mode (e.g. `/qualia-vibe --variants 3`), which is the user opting into the menu surface.
|
|
37
|
+
- The framework command explicitly supports a `--variants` mode (e.g. `/qualia-polish --vibe --variants 3`), which is the user opting into the menu surface.
|
|
38
38
|
|
|
39
39
|
## Output shape
|
|
40
40
|
|
package/rules/speed.md
CHANGED
|
@@ -50,5 +50,4 @@ When a Qualia command exists for the situation, use it — don't reinvent:
|
|
|
50
50
|
- `/qualia-feature` — single feature, auto-scoped: inline for trivia, fresh builder spawn for 1-5 file features
|
|
51
51
|
- `/qualia-ship` — full deploy pipeline (quality gates → commit → deploy → verify)
|
|
52
52
|
- `/qualia-review` — production audit
|
|
53
|
-
- `/qualia-pause` — save context before clearing the conversation
|
|
54
53
|
- `/qualia-learn` — save a lesson from a mistake
|
package/skills/qualia/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia
|
|
3
|
-
description: "
|
|
3
|
+
description: "Mechanical state-driven router — reads state.js, returns the exact next command. Cheap and instant. Triggers: '/qualia', 'what next', 'what now'. For deeper situational confusion use /qualia-idk."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -39,7 +39,7 @@ Use the state.js JSON output plus gathered context:
|
|
|
39
39
|
|-----------|-----------|-------|
|
|
40
40
|
| `no-project` | state.js returns NO_PROJECT | → `/qualia-new` |
|
|
41
41
|
| `handoff` | `.continue-here.md` exists | → Read it, summarize, route to next step |
|
|
42
|
-
| `mid-work` | Uncommitted changes + phase in progress | → Continue or
|
|
42
|
+
| `mid-work` | Uncommitted changes + phase in progress | → Continue, or write `.continue-here.md` if the user wants to pause |
|
|
43
43
|
| `ready-to-plan` | status == "setup" | → `/qualia-plan {N}` |
|
|
44
44
|
| `ready-to-build` | status == "planned" | → `/qualia-build {N}` |
|
|
45
45
|
| `ready-to-verify` | status == "built" | → `/qualia-verify {N}` |
|
|
@@ -50,8 +50,8 @@ Use the state.js JSON output plus gathered context:
|
|
|
50
50
|
| `polished` | status == "polished" | → `/qualia-ship` |
|
|
51
51
|
| `shipped` | status == "shipped" | → `/qualia-handoff` |
|
|
52
52
|
| `handed-off` | status == "handed_off" | → `/qualia-report` then done |
|
|
53
|
-
| `blocked` | STATE.md lists blockers or same error 3+ times | →
|
|
54
|
-
| `bug-loop` | Same files edited 3+ times, user frustrated | →
|
|
53
|
+
| `blocked` | STATE.md lists blockers or same error 3+ times | → Diagnose the evidence; `/qualia-fix` if expected behavior is known, `/qualia-review` if broader audit is needed |
|
|
54
|
+
| `bug-loop` | Same files edited 3+ times, user frustrated | → Stop patching; summarize root cause evidence and route to `/qualia-fix` or `/qualia-review` |
|
|
55
55
|
| `need-tests` | User mentions "tests", "coverage", "test this" | → `/qualia-test` |
|
|
56
56
|
|
|
57
57
|
**Employee escalation:** If role is EMPLOYEE and situation is `gap-limit` or `bug-loop`, suggest: "Want to flag this for Fawzi?"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-build
|
|
3
|
-
description: "
|
|
3
|
+
description: "Execute a planned phase — fresh builder subagents per task, wave-based parallelization, atomic commits, per-task validation. Triggers: 'build this phase', 'execute the plan', 'start building', 'qualia-build'."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-discuss
|
|
3
|
-
description: "Alignment interview
|
|
3
|
+
description: "Alignment interview — PROJECT MODE before /qualia-new, PHASE MODE before /qualia-plan N. Triggers: 'discuss', 'kickoff interview', 'grill me', 'stress test this plan', 'I'm not sure how to approach this'."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-doctor
|
|
3
|
-
description: "
|
|
3
|
+
description: "Framework health check — install, project state, contracts, hooks, memory, ERP queue. Suggests safe repair commands. Triggers: 'doctor', 'health check', 'framework broken', 'hooks not running', 'ERP queue stuck'."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-feature
|
|
3
|
-
description: "Auto-scoped single
|
|
3
|
+
description: "Auto-scoped single-feature build (inline for trivia, fresh spawn for 1-5 files). Routes phase-sized work to /qualia-plan, broken behavior to /qualia-fix. Triggers: 'build this one thing', 'add a component', 'implement this feature', 'small change', 'tweak'."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -35,7 +35,7 @@ One command for adding a small new capability outside the planned Road. Auto-det
|
|
|
35
35
|
- 5+ files or multiple subsystems touched → `/qualia-plan`
|
|
36
36
|
- Part of a planned phase → `/qualia-build`
|
|
37
37
|
- Broken existing behavior, regression, failing test, or hotfix → `/qualia-fix`
|
|
38
|
-
- Investigating a symptom you can't name yet → `/qualia-
|
|
38
|
+
- Investigating a symptom you can't name yet → `/qualia-review`
|
|
39
39
|
- Optimization or polish pass → `/qualia-optimize` or `/qualia-polish`
|
|
40
40
|
|
|
41
41
|
## Process
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-fix
|
|
3
|
-
description: "Practical repair lane for broken
|
|
3
|
+
description: "Practical repair lane for broken behavior — root-cause investigation + /qualia-feature execution. Triggers: 'fix this', 'bug', 'broken', 'error', 'failing test', 'regression', 'hotfix', 'layout broken', 'slow page'."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -14,7 +14,7 @@ argument-hint: "[--quick|--frontend|--perf|--test|--no-commit] <symptom>"
|
|
|
14
14
|
|
|
15
15
|
# /qualia-fix - Repair Broken Existing Behavior
|
|
16
16
|
|
|
17
|
-
Fix is the practical lane for "this used to work, or should work, and now it does not." It combines
|
|
17
|
+
Fix is the practical lane for "this used to work, or should work, and now it does not." It combines root-cause evidence gathering with the small-work execution path of `/qualia-feature`.
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
@@ -38,9 +38,9 @@ Fix is the practical lane for "this used to work, or should work, and now it doe
|
|
|
38
38
|
- Net-new capability -> `/qualia-feature`
|
|
39
39
|
- Phase-sized work or 5+ likely files -> `/qualia-plan`
|
|
40
40
|
- Read-only audit -> `/qualia-review`
|
|
41
|
-
- No concrete symptom and no failing command -> `/qualia-
|
|
41
|
+
- No concrete symptom and no failing command -> `/qualia-review`
|
|
42
42
|
- Visual craft/design quality with no functional bug -> `/qualia-polish`
|
|
43
|
-
- Whole-site aesthetic pivot -> `/qualia-vibe`
|
|
43
|
+
- Whole-site aesthetic pivot -> `/qualia-polish --vibe`
|
|
44
44
|
|
|
45
45
|
## Process
|
|
46
46
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-idk
|
|
3
|
-
description: "
|
|
3
|
+
description: "Deep diagnostic for 'I don't know what's going on.' Reads conversation context + the planning folder + the codebase in three isolated scans, cross-references against the user's confusion, then returns plain-language guidance PLUS a paste-ready Qualia command sequence to unstick them. Use whenever the user says 'I don't know', 'something feels off', 'not sure what to do', 'am I doing this right', 'what's happening', 'help me understand', 'where am I', 'lost'."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -11,18 +11,18 @@ allowed-tools:
|
|
|
11
11
|
|
|
12
12
|
# /qualia-idk — "I Don't Know What's Going On"
|
|
13
13
|
|
|
14
|
-
Not a router. A **diagnostician**. Use when the user isn't stuck on a command — they're stuck on
|
|
14
|
+
Not a router. A **diagnostician**. Use when the user isn't stuck on a single command — they're stuck on **understanding the situation**. Returns guidance + a Qualia command sequence the user can paste.
|
|
15
15
|
|
|
16
16
|
## How This Differs from `/qualia`
|
|
17
17
|
|
|
18
18
|
| `/qualia` | `/qualia-idk` |
|
|
19
19
|
|---|---|
|
|
20
|
-
| Mechanical: reads state.js, returns `/qualia-X` | Interpretive: reads
|
|
21
|
-
| "What
|
|
22
|
-
| Always returns a skill name | Returns
|
|
23
|
-
| Cheap, instant |
|
|
20
|
+
| Mechanical: reads state.js, returns one `/qualia-X` | Interpretive: reads conversation + planning + code |
|
|
21
|
+
| "What's my next command?" | "What is happening, and what sequence gets me unstuck?" |
|
|
22
|
+
| Always returns a skill name | Returns plain-language guidance + a multi-command sequence |
|
|
23
|
+
| Cheap, instant (~2s) | Three parallel scans, ~30–45s |
|
|
24
24
|
|
|
25
|
-
Run `/qualia`
|
|
25
|
+
Run `/qualia` when the user knows what they're trying to do. Run `/qualia-idk` when the user's confusion is about **the situation itself** — scope, drift, or where to even begin.
|
|
26
26
|
|
|
27
27
|
## Process
|
|
28
28
|
|
|
@@ -30,28 +30,52 @@ Run `/qualia` first when the user knows what they're trying to do. Run `/qualia-
|
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
node ${QUALIA_BIN}/qualia-ui.js banner router
|
|
33
|
-
node ${QUALIA_BIN}/qualia-ui.js spawn "diagnostic" "Reading planning and codebase in isolation..."
|
|
33
|
+
node ${QUALIA_BIN}/qualia-ui.js spawn "diagnostic" "Reading conversation, planning, and codebase in isolation..."
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
Say: **"Let me take a proper look."**
|
|
37
37
|
|
|
38
|
-
### Step 1.
|
|
38
|
+
### Step 1. Capture the User's Confusion
|
|
39
39
|
|
|
40
|
-
Look at the conversation
|
|
40
|
+
Look at the recent conversation. Note:
|
|
41
41
|
- What did the user just say or ask?
|
|
42
42
|
- Any recent errors, failed commands, surprising output?
|
|
43
43
|
- Any mismatch between what they expected and what happened?
|
|
44
|
+
- Sentiment cues: "lost", "stuck", "weird", "broken", "where am I" — record verbatim.
|
|
44
45
|
|
|
45
|
-
If
|
|
46
|
+
If conversation context is thin, ask:
|
|
46
47
|
- header: "What's unclear?"
|
|
47
48
|
- question: "Where are you stuck? (one sentence is fine)"
|
|
48
49
|
- Free text.
|
|
49
50
|
|
|
50
|
-
Store
|
|
51
|
+
Store as `<user_confusion>`.
|
|
51
52
|
|
|
52
|
-
### Step 2.
|
|
53
|
+
### Step 2. Capture Session Context (local, fast)
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
Before spawning scans, gather cheap session signals:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Where is the user right now?
|
|
59
|
+
test -f .continue-here.md && head -30 .continue-here.md
|
|
60
|
+
test -f .planning/STATE.md && head -20 .planning/STATE.md
|
|
61
|
+
git log --oneline -5 2>/dev/null
|
|
62
|
+
git status --short 2>/dev/null | head -10
|
|
63
|
+
|
|
64
|
+
# Recent planning artifacts (mtime tells us what was last touched)
|
|
65
|
+
ls -lt .planning/phase-*-*.md 2>/dev/null | head -8
|
|
66
|
+
ls -lt .planning/decisions/*.md 2>/dev/null | head -5
|
|
67
|
+
|
|
68
|
+
# Is there a halt / FAIL we should know about?
|
|
69
|
+
grep -l "FAIL\|INSUFFICIENT EVIDENCE\|HALT" .planning/phase-*-verification.md 2>/dev/null
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Store as `<session_context>`.
|
|
73
|
+
|
|
74
|
+
### Step 3. Spawn Three Isolated Scans (Parallel)
|
|
75
|
+
|
|
76
|
+
Three fresh subagents. Each sees ONLY its scope — no cross-contamination. They run in parallel; wait for all three.
|
|
77
|
+
|
|
78
|
+
**Agent A — Planning View** (broader than v1: now reads CONTEXT, REQUIREMENTS, decisions/, all phase artifacts, not just the latest):
|
|
55
79
|
|
|
56
80
|
```
|
|
57
81
|
Agent(prompt="
|
|
@@ -59,14 +83,18 @@ You are a read-only diagnostic scanner for the .planning/ folder only.
|
|
|
59
83
|
|
|
60
84
|
Read ALL of the following if present:
|
|
61
85
|
- .planning/PROJECT.md
|
|
86
|
+
- .planning/CONTEXT.md (domain glossary)
|
|
62
87
|
- .planning/JOURNEY.md
|
|
63
88
|
- .planning/REQUIREMENTS.md
|
|
64
89
|
- .planning/ROADMAP.md
|
|
65
90
|
- .planning/STATE.md
|
|
66
91
|
- .planning/tracking.json
|
|
67
|
-
- .planning/phase-*-plan.md (latest
|
|
68
|
-
- .planning/phase-*-verification.md (
|
|
92
|
+
- .planning/phase-*-plan.md (ALL, not just latest)
|
|
93
|
+
- .planning/phase-*-verification.md (ALL — flag any FAILs)
|
|
94
|
+
- .planning/phase-*-context.md (from /qualia-discuss PHASE MODE, if any)
|
|
95
|
+
- .planning/phase-*-research.md (if any)
|
|
69
96
|
- .planning/DESIGN.md (skim)
|
|
97
|
+
- .planning/decisions/*.md (ADRs — short read)
|
|
70
98
|
- .continue-here.md (if present)
|
|
71
99
|
|
|
72
100
|
DO NOT read any source code — no src/, app/, components/, lib/, etc.
|
|
@@ -74,14 +102,20 @@ DO NOT run any build tools.
|
|
|
74
102
|
|
|
75
103
|
Produce a 'Plan View' report answering:
|
|
76
104
|
1. What is this project? (one sentence from PROJECT.md)
|
|
77
|
-
2. Where does the plan say we ARE? (current milestone + phase + status)
|
|
78
|
-
3. What
|
|
79
|
-
4. What
|
|
80
|
-
5.
|
|
81
|
-
|
|
82
|
-
|
|
105
|
+
2. Where does the plan say we ARE? (current milestone N of M + phase P of Q + status)
|
|
106
|
+
3. What SHOULD be true right now? (current phase's acceptance criteria)
|
|
107
|
+
4. What's UNFINISHED? (upcoming phases / unresolved gaps from latest verification)
|
|
108
|
+
5. Plan-level inconsistencies? (tracking.json vs STATE.md mismatch, JOURNEY.md missing, roadmap drift)
|
|
109
|
+
6. Has any verification FAILED recently? Quote the FAIL summary if so.
|
|
110
|
+
7. Are there hard decisions (ADRs in decisions/) that constrain the next step?
|
|
111
|
+
|
|
112
|
+
Keep it under 350 words. Be specific. No filler. Quote file:line for anything you assert.
|
|
83
113
|
", subagent_type="Explore", description="Plan-view scan")
|
|
114
|
+
```
|
|
84
115
|
|
|
116
|
+
**Agent B — Code View** (unchanged from v1):
|
|
117
|
+
|
|
118
|
+
```
|
|
85
119
|
Agent(prompt="
|
|
86
120
|
You are a read-only diagnostic scanner for the source code only.
|
|
87
121
|
|
|
@@ -91,75 +125,120 @@ Scan the repo:
|
|
|
91
125
|
- Package/framework detection (package.json, requirements.txt, etc.)
|
|
92
126
|
- Entry points (app/, src/, pages/, index.*)
|
|
93
127
|
- Key files referenced in recent commits (git log --oneline -5, then inspect)
|
|
94
|
-
-
|
|
95
|
-
-
|
|
128
|
+
- Quick static checks: 'npx tsc --noEmit' output, lint errors, test status
|
|
129
|
+
- Stubs: grep for TODO, FIXME, 'not implemented', empty catch blocks, unused exports
|
|
130
|
+
- Dev server / deploy markers (vercel link, .env.local, supabase project ref)
|
|
96
131
|
|
|
97
132
|
Produce a 'Code View' report answering:
|
|
98
|
-
1. What does the code
|
|
99
|
-
2. What ACTUALLY WORKS right now? (compile status, recent
|
|
100
|
-
3. What's STUBBED
|
|
101
|
-
4. What's RUNNING locally or deployed?
|
|
102
|
-
5.
|
|
133
|
+
1. What does the code LOOK LIKE it's building? (inferred from structure + imports)
|
|
134
|
+
2. What ACTUALLY WORKS right now? (compile status, recent commits, smoke signals)
|
|
135
|
+
3. What's STUBBED / INCOMPLETE? (concrete file:line citations)
|
|
136
|
+
4. What's RUNNING locally or deployed?
|
|
137
|
+
5. Code-level inconsistencies? (imports that don't resolve, routes referenced but not defined)
|
|
103
138
|
|
|
104
|
-
|
|
139
|
+
Under 300 words. Cite file:line. No filler.
|
|
105
140
|
", subagent_type="Explore", description="Code-view scan")
|
|
106
141
|
```
|
|
107
142
|
|
|
108
|
-
|
|
143
|
+
**Agent C — Conversation & Memory View** (new in v2):
|
|
109
144
|
|
|
110
|
-
|
|
145
|
+
```
|
|
146
|
+
Agent(prompt="
|
|
147
|
+
You are a read-only diagnostic scanner for the user's recent activity. Do NOT read .planning/ or source code.
|
|
111
148
|
|
|
112
|
-
|
|
149
|
+
Read:
|
|
150
|
+
- ${QUALIA_HOME}/knowledge/daily-log/<latest 1-2 dates>.md (recent session entries)
|
|
151
|
+
- ${QUALIA_HOME}/knowledge/concepts/<files referenced by the user's confusion>
|
|
152
|
+
- .continue-here.md (if present)
|
|
153
|
+
- git log --since='3 days ago' --oneline
|
|
154
|
+
- git diff main...HEAD --stat (work in flight)
|
|
113
155
|
|
|
114
|
-
|
|
156
|
+
Cross-reference against the user's stated confusion: ${user_confusion}
|
|
115
157
|
|
|
158
|
+
Produce a 'Session View' report answering:
|
|
159
|
+
1. What has the user been doing recently? (1-3 bullets from daily log + git)
|
|
160
|
+
2. Is the user's CURRENT confusion consistent with their recent activity, or is there a discontinuity? (e.g. they were in M2-P3 yesterday but today they're asking about M3 setup)
|
|
161
|
+
3. Are there saved learnings or ADRs that directly answer the user's confusion?
|
|
162
|
+
4. Was there a recent halt, FAIL, or pause we should foreground?
|
|
163
|
+
|
|
164
|
+
Under 250 words. Quote daily-log line numbers or commit SHAs.
|
|
165
|
+
", subagent_type="Explore", description="Session-view scan")
|
|
116
166
|
```
|
|
167
|
+
|
|
168
|
+
### Step 4. Synthesize — Diagnosis + Command Sequence
|
|
169
|
+
|
|
170
|
+
With all three reports + `<user_confusion>` + `<session_context>` in hand, produce **exactly this shape**:
|
|
171
|
+
|
|
172
|
+
```markdown
|
|
117
173
|
## What I see
|
|
118
174
|
|
|
119
175
|
**The plan says:** {1-2 sentences — current milestone/phase/status, what should be true}
|
|
120
176
|
|
|
121
177
|
**The code says:** {1-2 sentences — what actually exists, what works, what's stubbed}
|
|
122
178
|
|
|
123
|
-
**
|
|
179
|
+
**Your recent activity:** {1-2 sentences — last 2-3 days of work in flight, last commit, last skill run}
|
|
180
|
+
|
|
181
|
+
**The mismatch (if any):** {1-2 sentences — where plan / code / activity disagree. If consistent, say "all three views align".}
|
|
124
182
|
|
|
125
183
|
## What I think is happening
|
|
126
184
|
|
|
127
|
-
{3-5 sentences, plain language. Tie the user's confusion to what you found.
|
|
185
|
+
{3-5 sentences, plain language. Tie the user's confusion to what you found. No jargon. If the user said "the login is broken", don't say "the auth middleware has a type inference issue" — say "you're seeing the login fail because the signin function isn't actually imported into the login page, even though phase-2-plan.md says it should be. Someone wrote the helper but forgot to wire it up — that's why verification went FAIL yesterday."}
|
|
128
186
|
|
|
129
|
-
## What to do next
|
|
187
|
+
## What to do next — paste-ready command sequence
|
|
130
188
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
189
|
+
```
|
|
190
|
+
{command 1} # {one-line reason}
|
|
191
|
+
{command 2} # {one-line reason}
|
|
192
|
+
{command 3} # {one-line reason}
|
|
193
|
+
```
|
|
134
194
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
195
|
+
{One sentence on what this sequence accomplishes end-to-end.}
|
|
196
|
+
|
|
197
|
+
## Or, if you'd rather hand-pick:
|
|
198
|
+
|
|
199
|
+
1. **{action}** — {why}
|
|
200
|
+
2. **{action}** — {why}
|
|
201
|
+
3. **{optional}** — {why}
|
|
141
202
|
```
|
|
142
203
|
|
|
143
|
-
|
|
204
|
+
**Command-sequence picking rules** — choose from these established patterns:
|
|
205
|
+
|
|
206
|
+
| Situation found | Sequence |
|
|
207
|
+
|---|---|
|
|
208
|
+
| Plan says built but code has stubs | `/qualia-plan {N} --gaps` → `/qualia-build` → `/qualia-verify` |
|
|
209
|
+
| Verify FAILed and no postmortem ran | `/qualia-postmortem` → `/qualia-plan {N} --gaps` → `/qualia-build` |
|
|
210
|
+
| Stale `.continue-here.md`, ongoing context | `/qualia-resume` → `/qualia` |
|
|
211
|
+
| Brownfield drift (plan and code diverged hard) | `/qualia-map` → `/qualia-plan {N} --gaps` |
|
|
212
|
+
| Phase context missing (no `/qualia-discuss` ran) | `/qualia-discuss {N}` → `/qualia-plan {N}` |
|
|
213
|
+
| Specific error, scope clear | `/qualia-fix '<symptom>'` |
|
|
214
|
+
| Performance feels off, no profile | `/qualia-fix --perf '<route>'` or `/qualia-optimize --perf` |
|
|
215
|
+
| Design feels off | `/qualia-polish --critique` then `/qualia-polish` |
|
|
216
|
+
| User is overwhelmed | `/qualia-pause` (save handoff), come back later |
|
|
217
|
+
| Truly nothing actionable found | Ask one specific question; don't invent a sequence |
|
|
218
|
+
|
|
219
|
+
Pick the sequence that fits the actual evidence. Substitute real `{N}` from the Plan-view scan.
|
|
220
|
+
|
|
221
|
+
### Step 5. Close
|
|
144
222
|
|
|
145
223
|
```bash
|
|
146
224
|
node ${QUALIA_BIN}/qualia-ui.js divider
|
|
147
|
-
node ${QUALIA_BIN}/qualia-ui.js end "DIAGNOSED" "{
|
|
225
|
+
node ${QUALIA_BIN}/qualia-ui.js end "DIAGNOSED" "{first command in the sequence, if any}"
|
|
148
226
|
```
|
|
149
227
|
|
|
150
228
|
## Rules
|
|
151
229
|
|
|
152
|
-
1. **
|
|
230
|
+
1. **Three isolated scans, always.** Plan view never peeks at code or session. Code view never peeks at planning. Session view never peeks at code. This is what keeps the diagnosis honest — each agent sees one slice, the synthesis catches the delta.
|
|
153
231
|
2. **Plain language over jargon.** If you can't explain it to a non-dev, rewrite it.
|
|
154
|
-
3. **No fake certainty.** If the scans come back thin (
|
|
155
|
-
4. **Never invent facts.** If
|
|
156
|
-
5. **
|
|
157
|
-
6. **
|
|
232
|
+
3. **No fake certainty.** If the scans come back thin (brand-new repo, no planning artifacts yet), say so explicitly: "I don't have enough signal yet — here's what I'd do to gather more."
|
|
233
|
+
4. **Never invent facts.** If a scan didn't find something, don't claim it. Cite files.
|
|
234
|
+
5. **Command sequence > single recommendation.** The user came here because one command isn't enough. Give them a chain.
|
|
235
|
+
6. **The sequence must be paste-ready.** Real `{N}` values, real route names, no `<placeholder>` text outside the optional "if you'd rather hand-pick" section.
|
|
236
|
+
7. **Don't re-run if `/qualia` already knows.** If the user's confusion is purely "what's my next command", `/qualia` handles it cheaper — gently suggest it and stop.
|
|
158
237
|
|
|
159
238
|
## When NOT to Use
|
|
160
239
|
|
|
161
240
|
- User knows what they're doing and just wants the next command → `/qualia`
|
|
162
|
-
- User has a specific error message → `/qualia-
|
|
241
|
+
- User has a specific error message they want fixed → `/qualia-fix '<symptom>'`
|
|
163
242
|
- User wants to review code quality → `/qualia-review`
|
|
164
243
|
- User wants to pause and come back → `/qualia-pause`
|
|
165
244
|
|