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/tests/state.test.sh
CHANGED
|
@@ -4,9 +4,40 @@
|
|
|
4
4
|
|
|
5
5
|
PASS=0
|
|
6
6
|
FAIL=0
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
# Windows portability — coerce shell-native MSYS paths (/d/a/..., /tmp/...) to
|
|
8
|
+
# Windows-native form (D:/a/..., C:/Users/.../Temp/...) before they get
|
|
9
|
+
# interpolated into Node `$NODE -e` snippets. Without coercion, Node receives
|
|
10
|
+
# the MSYS string literally and resolves it against the current drive, yielding
|
|
11
|
+
# non-existent paths like `D:\tmp\tmp.XXX\.planning\tracking.json`.
|
|
12
|
+
#
|
|
13
|
+
# Mechanism: `cygpath -m` is the canonical MSYS path converter and is present
|
|
14
|
+
# on Git Bash / MSYS2 (Windows GitHub runners use Git Bash for `shell: bash`).
|
|
15
|
+
# `pwd -W` doesn't work because bash's builtin pwd doesn't accept -W, and
|
|
16
|
+
# /usr/bin/pwd's -W support varies by MSYS distribution.
|
|
17
|
+
# On Linux/macOS, cygpath doesn't exist — fall through to plain pwd.
|
|
18
|
+
_pwd_native() {
|
|
19
|
+
local p
|
|
20
|
+
p=$(pwd)
|
|
21
|
+
if command -v cygpath >/dev/null 2>&1; then
|
|
22
|
+
cygpath -m "$p" 2>/dev/null || echo "$p"
|
|
23
|
+
else
|
|
24
|
+
echo "$p"
|
|
25
|
+
fi
|
|
26
|
+
}
|
|
27
|
+
_mktemp_native() {
|
|
28
|
+
local d
|
|
29
|
+
d=$(mktemp -d) || return 1
|
|
30
|
+
if command -v cygpath >/dev/null 2>&1; then
|
|
31
|
+
cygpath -m "$d" 2>/dev/null || echo "$d"
|
|
32
|
+
else
|
|
33
|
+
echo "$d"
|
|
34
|
+
fi
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Resolve STATE_JS to an ABSOLUTE Windows-native path so `cd` inside subshells
|
|
38
|
+
# doesn't break it.
|
|
39
|
+
STATE_JS="$(cd "$(dirname "$0")/../bin" && _pwd_native)/state.js"
|
|
40
|
+
FRAMEWORK_DIR="$(cd "$(dirname "$0")/.." && _pwd_native)"
|
|
10
41
|
STATE_LEDGER_JS="$FRAMEWORK_DIR/bin/state-ledger.js"
|
|
11
42
|
NODE="${NODE:-node}"
|
|
12
43
|
|
|
@@ -23,7 +54,7 @@ trap cleanup EXIT
|
|
|
23
54
|
# Prints the absolute path to the new tmp dir (does NOT cd).
|
|
24
55
|
make_project() {
|
|
25
56
|
local TMP
|
|
26
|
-
TMP=$(
|
|
57
|
+
TMP=$(_mktemp_native)
|
|
27
58
|
TMP_DIRS+=("$TMP")
|
|
28
59
|
(
|
|
29
60
|
cd "$TMP" || exit 1
|
|
@@ -75,6 +106,47 @@ Goal: Test goal
|
|
|
75
106
|
PLAN
|
|
76
107
|
}
|
|
77
108
|
|
|
109
|
+
make_valid_contract() {
|
|
110
|
+
local dir="$1"
|
|
111
|
+
local phase="${2:-1}"
|
|
112
|
+
cat > "$dir/.planning/phase-${phase}-contract.json" <<'JSON'
|
|
113
|
+
{
|
|
114
|
+
"version": 1,
|
|
115
|
+
"phase": 1,
|
|
116
|
+
"goal": "Test goal",
|
|
117
|
+
"why": "Exercise machine evidence",
|
|
118
|
+
"generated_at": "2026-05-23T00:00:00.000Z",
|
|
119
|
+
"generated_by": "manual",
|
|
120
|
+
"source_plan_hash": "",
|
|
121
|
+
"success_criteria": ["Machine check passes"],
|
|
122
|
+
"tasks": [
|
|
123
|
+
{
|
|
124
|
+
"id": "T1",
|
|
125
|
+
"title": "Machine check",
|
|
126
|
+
"wave": 1,
|
|
127
|
+
"depends_on": [],
|
|
128
|
+
"persona": "none",
|
|
129
|
+
"files_modify": [],
|
|
130
|
+
"files_create": [],
|
|
131
|
+
"files_delete": [],
|
|
132
|
+
"acceptance_criteria": ["Node command exits 0"],
|
|
133
|
+
"action": "Run deterministic evidence check",
|
|
134
|
+
"context_files": [],
|
|
135
|
+
"verification": [
|
|
136
|
+
{
|
|
137
|
+
"type": "command-exit",
|
|
138
|
+
"command": "node",
|
|
139
|
+
"args": ["-e", "process.exit(0)"],
|
|
140
|
+
"expected_exit": 0,
|
|
141
|
+
"timeout_ms": 5000
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
JSON
|
|
148
|
+
}
|
|
149
|
+
|
|
78
150
|
echo "=== state.js Behavioral Tests ==="
|
|
79
151
|
echo ""
|
|
80
152
|
|
|
@@ -88,7 +160,7 @@ fi
|
|
|
88
160
|
echo "basic I/O:"
|
|
89
161
|
|
|
90
162
|
# 1. cmdInit produces valid tracking.json + STATE.md
|
|
91
|
-
TMP=$(
|
|
163
|
+
TMP=$(_mktemp_native); TMP_DIRS+=("$TMP")
|
|
92
164
|
(
|
|
93
165
|
cd "$TMP" || exit 1
|
|
94
166
|
$NODE "$STATE_JS" init \
|
|
@@ -149,7 +221,7 @@ else
|
|
|
149
221
|
fi
|
|
150
222
|
|
|
151
223
|
# 3. cmdCheck with no project → ok:false NO_PROJECT, exit 1
|
|
152
|
-
TMP2=$(
|
|
224
|
+
TMP2=$(_mktemp_native); TMP_DIRS+=("$TMP2")
|
|
153
225
|
OUT=$(cd "$TMP2" && $NODE "$STATE_JS" check 2>&1)
|
|
154
226
|
CHECK_EXIT=$?
|
|
155
227
|
if [ "$CHECK_EXIT" -eq 1 ] \
|
|
@@ -213,6 +285,33 @@ else
|
|
|
213
285
|
fail_case "built → verified(pass) auto-advance" "exit=$EXIT out=$OUT"
|
|
214
286
|
fi
|
|
215
287
|
|
|
288
|
+
# 6b. verified(pass) refuses when a contract exists but machine evidence is missing
|
|
289
|
+
TMP=$(make_project)
|
|
290
|
+
make_valid_plan "$TMP" 1
|
|
291
|
+
make_valid_contract "$TMP" 1
|
|
292
|
+
(cd "$TMP" && $NODE "$STATE_JS" transition --to planned >/dev/null 2>&1)
|
|
293
|
+
(cd "$TMP" && $NODE "$STATE_JS" transition --to built --tasks-done 1 --tasks-total 1 >/dev/null 2>&1)
|
|
294
|
+
echo "result: PASS" > "$TMP/.planning/phase-1-verification.md"
|
|
295
|
+
OUT=$(cd "$TMP" && $NODE "$STATE_JS" transition --to verified --verification pass 2>&1)
|
|
296
|
+
EXIT=$?
|
|
297
|
+
if [ "$EXIT" -ne 0 ] && echo "$OUT" | grep -q '"error": "MISSING_EVIDENCE"'; then
|
|
298
|
+
pass "verified(pass) refuses missing machine evidence when contract exists"
|
|
299
|
+
else
|
|
300
|
+
fail_case "verified(pass) missing evidence guard" "exit=$EXIT out=$OUT"
|
|
301
|
+
fi
|
|
302
|
+
|
|
303
|
+
# 6c. verified(pass) succeeds after contract-runner writes passing evidence
|
|
304
|
+
(cd "$TMP" && $NODE "$FRAMEWORK_DIR/bin/contract-runner.js" .planning/phase-1-contract.json >/dev/null 2>&1)
|
|
305
|
+
OUT=$(cd "$TMP" && $NODE "$STATE_JS" transition --to verified --verification pass 2>&1)
|
|
306
|
+
EXIT=$?
|
|
307
|
+
if [ "$EXIT" -eq 0 ] \
|
|
308
|
+
&& echo "$OUT" | grep -q '"ok": true' \
|
|
309
|
+
&& echo "$OUT" | grep -q '"phase": 2'; then
|
|
310
|
+
pass "verified(pass) accepts passing machine evidence"
|
|
311
|
+
else
|
|
312
|
+
fail_case "verified(pass) with machine evidence" "exit=$EXIT out=$OUT"
|
|
313
|
+
fi
|
|
314
|
+
|
|
216
315
|
# 7. built → verified(fail) stays on phase 1, records verification=fail
|
|
217
316
|
TMP=$(make_project)
|
|
218
317
|
make_valid_plan "$TMP" 1
|
|
@@ -946,7 +1045,7 @@ else
|
|
|
946
1045
|
fi
|
|
947
1046
|
|
|
948
1047
|
# 49. First-time init (no existing tracking.json) sets lifetime to zeros
|
|
949
|
-
TMP=$(
|
|
1048
|
+
TMP=$(_mktemp_native); TMP_DIRS+=("$TMP")
|
|
950
1049
|
(cd "$TMP" && $NODE "$STATE_JS" init \
|
|
951
1050
|
--project "FreshProject" \
|
|
952
1051
|
--phases '[{"name":"P1","goal":"G1"}]' \
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: qualia-debug
|
|
3
|
-
description: "Investigation lane for unclear bugs and weird behavior. Parses symptoms, runs diagnostic scans, identifies root cause, and either reports insufficient evidence or routes actionable repair work to /qualia-fix. Trigger on 'debug', 'find bug', 'why is this broken', 'something is weird', 'investigate', 'root cause', 'not sure what's failing', 'CSS issue', 'slow page', 'performance'."
|
|
4
|
-
allowed-tools:
|
|
5
|
-
- Bash
|
|
6
|
-
- Read
|
|
7
|
-
- Edit
|
|
8
|
-
- Write
|
|
9
|
-
- Grep
|
|
10
|
-
- Glob
|
|
11
|
-
- Agent
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
# /qualia-debug — Investigative Debugging (one-shot)
|
|
15
|
-
|
|
16
|
-
Parse the symptom. Run diagnostics. Find root cause. Write report, or route to `/qualia-fix` when the repair is actionable. **One-shot — no mandatory user questions.**
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
- `/qualia-debug {symptom}` — investigate a specific symptom
|
|
21
|
-
- `/qualia-debug` — no symptom given: investigate recently-changed files for obvious bugs
|
|
22
|
-
- `/qualia-debug --frontend {symptom}` — layout/z-index/overflow bias
|
|
23
|
-
- `/qualia-debug --perf {symptom}` — performance bias
|
|
24
|
-
|
|
25
|
-
If the user says "fix it" and the expected behavior is known, prefer `/qualia-fix`. Debug is for uncertainty; fix is for repair.
|
|
26
|
-
|
|
27
|
-
## Tool Budget
|
|
28
|
-
|
|
29
|
-
Max 10 Read/Grep/Bash calls for investigation. If you haven't narrowed to root cause in 10, return `INSUFFICIENT EVIDENCE after 10 steps. Narrowed to: {files}. Recommend: {next diagnostic}.` Do not keep guessing.
|
|
30
|
-
|
|
31
|
-
## Process
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
node ${QUALIA_BIN}/qualia-ui.js banner debug
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### 1. Parse Symptom from $ARGUMENTS
|
|
38
|
-
|
|
39
|
-
- If arguments provided → that's the symptom. Extract: what's broken, where (file/page/feature), when (on click? on load? after change?).
|
|
40
|
-
- If arguments empty → run `git diff HEAD~3 --stat` to find recently-touched files. Treat those as the suspect set. Symptom = "something in recent changes".
|
|
41
|
-
|
|
42
|
-
### 2. Check Known Fixes First (cheap)
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
node ${QUALIA_BIN}/knowledge.js search "{symptom_keywords}"
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
If a known fix matches, apply it and jump to step 5 (verify). Known fixes are pre-verified patterns — no need to re-investigate.
|
|
49
|
-
|
|
50
|
-
### 3. Diagnostic Scan
|
|
51
|
-
|
|
52
|
-
Run the scan matching the symptom type. All commands in a scan block run as parallel Bash calls in a single response turn.
|
|
53
|
-
|
|
54
|
-
**General mode (default):**
|
|
55
|
-
```bash
|
|
56
|
-
# Compile errors
|
|
57
|
-
npx tsc --noEmit 2>&1 | grep "error TS" | head -20
|
|
58
|
-
|
|
59
|
-
# Empty catch / swallowed errors
|
|
60
|
-
grep -rn "catch\s*{}\|catch\s*(.*)\s*{\s*}" --include="*.ts" --include="*.tsx" app/ components/ src/ lib/ 2>/dev/null | head -10
|
|
61
|
-
|
|
62
|
-
# Recent console.error or thrown errors
|
|
63
|
-
grep -rn "console\.error\|throw new" --include="*.ts" --include="*.tsx" app/ components/ src/ lib/ 2>/dev/null | head -10
|
|
64
|
-
|
|
65
|
-
# Broken imports
|
|
66
|
-
npx tsc --noEmit 2>&1 | grep -i "Cannot find module\|has no exported"
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**Frontend mode (`--frontend`):**
|
|
70
|
-
```bash
|
|
71
|
-
# Stacking context audit (z-index issues)
|
|
72
|
-
grep -rn "z-index\|z-\[" --include="*.tsx" --include="*.css" app/ components/ src/ 2>/dev/null | head -20
|
|
73
|
-
|
|
74
|
-
# Overflow candidates (horizontal scroll, clipping)
|
|
75
|
-
grep -rn "100vw\|overflow.*hidden\|overflow-x\|position.*fixed" --include="*.tsx" --include="*.css" app/ components/ src/ 2>/dev/null | head -15
|
|
76
|
-
|
|
77
|
-
# Fixed dimensions breaking mobile
|
|
78
|
-
grep -rn "width:.*[0-9]\+px\|height:.*[0-9]\+px\|w-\[[0-9]\+px\|h-\[[0-9]\+px" --include="*.tsx" --include="*.css" app/ components/ src/ 2>/dev/null | grep -v "min-\|max-" | head -10
|
|
79
|
-
|
|
80
|
-
# Flex/grid blowout candidates
|
|
81
|
-
grep -rn "flex\|grid" --include="*.tsx" app/ components/ src/ 2>/dev/null | grep -v "min-w-0\|minmax(0" | wc -l
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**Perf mode (`--perf`):**
|
|
85
|
-
```bash
|
|
86
|
-
# Sequential awaits that should be Promise.all
|
|
87
|
-
grep -rn "const.*=.*await" --include="*.tsx" --include="*.ts" app/ src/ 2>/dev/null | grep -v "Promise.all\|Promise.allSettled" | head -15
|
|
88
|
-
|
|
89
|
-
# Large files
|
|
90
|
-
find app/ components/ src/ -name "*.tsx" -o -name "*.ts" 2>/dev/null | xargs wc -l 2>/dev/null | sort -rn | head -10
|
|
91
|
-
|
|
92
|
-
# Missing next/image
|
|
93
|
-
grep -rn "<img " --include="*.tsx" --include="*.jsx" app/ components/ src/ 2>/dev/null | grep -v "next/image" | wc -l
|
|
94
|
-
|
|
95
|
-
# No dynamic imports (possible big bundles)
|
|
96
|
-
grep -rn "import(\|next/dynamic" --include="*.tsx" --include="*.ts" app/ src/ 2>/dev/null | wc -l
|
|
97
|
-
|
|
98
|
-
# Client-boundary usage
|
|
99
|
-
grep -rln "'use client'" --include="*.tsx" app/ components/ src/ 2>/dev/null | wc -l
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### 4. Form Hypothesis + Route or Apply Minimal Fix
|
|
103
|
-
|
|
104
|
-
From the diagnostic output, state the root cause in one sentence with `file:line` citation. No hedging — either you have evidence or you write `INSUFFICIENT EVIDENCE` and return (step 6).
|
|
105
|
-
|
|
106
|
-
If the user explicitly asked for repair and the fix is <= 3 files, route to `/qualia-fix {symptom}` with the root cause summary. If this debug invocation is already mid-repair, apply the minimal fix here for backward compatibility.
|
|
107
|
-
|
|
108
|
-
Apply the minimal fix:
|
|
109
|
-
- Only edit files whose contents caused the symptom
|
|
110
|
-
- One concept per commit — don't fold in cleanup
|
|
111
|
-
- Don't refactor adjacent code
|
|
112
|
-
- If the fix touches > 3 files, stop and ask the user first (major refactor disguised as a debug)
|
|
113
|
-
|
|
114
|
-
### 5. Verify Fix
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
# TypeScript still compiles?
|
|
118
|
-
npx tsc --noEmit 2>&1 | grep -c "error TS" # Expect 0
|
|
119
|
-
|
|
120
|
-
# Symptom reproduction — ideally a grep that would have matched the bug
|
|
121
|
-
# and now returns empty:
|
|
122
|
-
grep -rn "{pattern that represented the bug}" {scope} 2>/dev/null
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
If the verification fails, revert and return to step 3 with narrower hypothesis.
|
|
126
|
-
|
|
127
|
-
### 6. Write DEBUG Report
|
|
128
|
-
|
|
129
|
-
Create the report directory and write to `.planning/reports/debug/DEBUG-{YYYY-MM-DD-HHMM}.md`:
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
mkdir -p .planning/reports/debug
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
```markdown
|
|
136
|
-
# Debug Report — {YYYY-MM-DD HH:MM}
|
|
137
|
-
|
|
138
|
-
**Symptom:** {user description or "recent changes" if no args}
|
|
139
|
-
**Mode:** general | frontend | perf
|
|
140
|
-
**Tool calls used:** {N}/10
|
|
141
|
-
|
|
142
|
-
## Investigation
|
|
143
|
-
- Diagnostic scans run: {list}
|
|
144
|
-
- Files examined: {list}
|
|
145
|
-
- Patterns searched: {list}
|
|
146
|
-
|
|
147
|
-
## Root Cause
|
|
148
|
-
{file:line} — "{quoted problematic code}" — {explanation of why it caused the symptom}
|
|
149
|
-
|
|
150
|
-
## Fix Applied
|
|
151
|
-
- Files: {list}
|
|
152
|
-
- Diff summary: {one paragraph}
|
|
153
|
-
- Verification: {commands run + results}
|
|
154
|
-
|
|
155
|
-
## Related Observations
|
|
156
|
-
- {any adjacent issues noticed but NOT fixed in this debug pass}
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### 7. Commit
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
git add {specific files you changed}
|
|
163
|
-
git commit -m "fix: {what was broken and why}"
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
## INSUFFICIENT EVIDENCE Return
|
|
167
|
-
|
|
168
|
-
If you exhaust the 10-call budget without a confident root cause:
|
|
169
|
-
|
|
170
|
-
```markdown
|
|
171
|
-
# Debug Report — {YYYY-MM-DD HH:MM}
|
|
172
|
-
|
|
173
|
-
**Symptom:** {description}
|
|
174
|
-
**Outcome:** INSUFFICIENT EVIDENCE after 10 inspection steps
|
|
175
|
-
|
|
176
|
-
## Narrowed To
|
|
177
|
-
- Files examined: {list}
|
|
178
|
-
- Ruled out: {list}
|
|
179
|
-
- Remaining suspects: {list}
|
|
180
|
-
|
|
181
|
-
## Recommended Next Diagnostic
|
|
182
|
-
- {specific next step for the user — e.g., "run `npm run dev` and watch browser console for the specific error", or "add console.log at file:line and reproduce"}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Do NOT apply a speculative fix. Return the report and stop.
|
|
186
|
-
|
|
187
|
-
## Rules
|
|
188
|
-
|
|
189
|
-
- **No mandatory questions.** This is one-shot. If symptom args are missing, investigate recent changes.
|
|
190
|
-
- **Root cause or INSUFFICIENT EVIDENCE** — no "probably" fixes.
|
|
191
|
-
- **Minimal fix only.** One concept, one commit. No refactors dressed as debug. Prefer `/qualia-fix` for explicit repair requests.
|
|
192
|
-
- **Tool budget is hard.** 10 calls, then stop.
|
|
193
|
-
- **Every investigation gets a DEBUG report in `.planning/reports/debug/`** — creates a searchable record without cluttering the root.
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: qualia-flush
|
|
3
|
-
description: "Promote daily-log raw entries to the curated knowledge tier — Karpathy-style raw→wiki flush. Reads ${QUALIA_KNOWLEDGE}/daily-log/*.md, identifies recurring patterns and decisions, writes them to ${QUALIA_KNOWLEDGE}/concepts/{topic}.md, updates index.md. Trigger on 'flush memory', 'promote learnings', 'consolidate logs', 'qualia-flush', 'process daily logs', or run weekly."
|
|
4
|
-
allowed-tools:
|
|
5
|
-
- Bash
|
|
6
|
-
- Read
|
|
7
|
-
- Write
|
|
8
|
-
- Edit
|
|
9
|
-
- Grep
|
|
10
|
-
- Glob
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# /qualia-flush — Promote Raw Daily Logs to Curated Concepts
|
|
14
|
-
|
|
15
|
-
Closes the **raw → wiki** loop in the Qualia memory layer. The Stop hook
|
|
16
|
-
(`hooks/stop-session-log.js`) appends mechanical session checkpoints to
|
|
17
|
-
`${QUALIA_KNOWLEDGE}/daily-log/{date}.md`.
|
|
18
|
-
Those entries accumulate but stay raw — they describe what happened, not
|
|
19
|
-
what to do about it. This skill reads the recent daily-log entries with an
|
|
20
|
-
LLM (you) and writes durable concepts that the builder, planner, and
|
|
21
|
-
debug skills will surface later via `node ${QUALIA_BIN}/knowledge.js`.
|
|
22
|
-
|
|
23
|
-
Inspired by Karpathy's LLM knowledge bases and Cole Medin's self-evolving
|
|
24
|
-
Claude memory pattern (NotebookLM, 2026-04-25). Both run a daily/weekly
|
|
25
|
-
flush that promotes raw observations into structured wiki articles. We do
|
|
26
|
-
the same — manually-triggered, internal-data only, no vector DB.
|
|
27
|
-
|
|
28
|
-
## When to run
|
|
29
|
-
|
|
30
|
-
- **Manually:** `/qualia-flush` whenever the daily-log feels rich. Once a week
|
|
31
|
-
is the recommended cadence. More than once a day is wasteful — the
|
|
32
|
-
signal-to-noise ratio is too low at single-day windows.
|
|
33
|
-
- **CLI runner:** `qualia-framework flush` wraps the cron-friendly
|
|
34
|
-
`bin/knowledge-flush.js` non-interactive runner.
|
|
35
|
-
|
|
36
|
-
## Inputs
|
|
37
|
-
|
|
38
|
-
- `--days N` (optional, default 14) — how many days of daily-log to consider
|
|
39
|
-
- `--project NAME` (optional) — only flush entries for one project
|
|
40
|
-
- `--dry-run` (optional) — print the proposed writes, don't touch disk
|
|
41
|
-
|
|
42
|
-
If the user invokes the skill bare (no args), default to `--days 14` and
|
|
43
|
-
all projects. Show a one-line preview before writing anything destructive.
|
|
44
|
-
|
|
45
|
-
## Process
|
|
46
|
-
|
|
47
|
-
### 1. Banner + check the floor
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
node ${QUALIA_BIN}/qualia-ui.js banner flush 2>/dev/null || true
|
|
51
|
-
|
|
52
|
-
# Resolve the knowledge dir. Fail loud if it doesn't exist — flush is
|
|
53
|
-
# meaningless without a daily-log to read.
|
|
54
|
-
KNOWLEDGE_DIR="$HOME/.claude/knowledge"
|
|
55
|
-
DAILY_DIR="$KNOWLEDGE_DIR/daily-log"
|
|
56
|
-
if [ ! -d "$DAILY_DIR" ]; then
|
|
57
|
-
echo "QUALIA: No daily-log at $DAILY_DIR — Stop hook hasn't run yet, or knowledge layer wasn't initialized."
|
|
58
|
-
echo "Run: npx qualia-framework@latest install"
|
|
59
|
-
exit 1
|
|
60
|
-
fi
|
|
61
|
-
|
|
62
|
-
# Default 14-day window. Date math is cross-platform-safe with Node.
|
|
63
|
-
WINDOW_DAYS="${WINDOW_DAYS:-14}"
|
|
64
|
-
node -e "
|
|
65
|
-
const d = new Date();
|
|
66
|
-
d.setDate(d.getDate() - $WINDOW_DAYS);
|
|
67
|
-
console.log(d.toISOString().split('T')[0]);
|
|
68
|
-
" > /tmp/qualia-flush-cutoff
|
|
69
|
-
CUTOFF=$(cat /tmp/qualia-flush-cutoff)
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### 2. Collect the daily-log entries in window
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# Iterate every file in daily-log/ whose name (YYYY-MM-DD.md) is >= CUTOFF.
|
|
76
|
-
# Concatenate them into one stream so the LLM (you) can scan as one corpus.
|
|
77
|
-
ls "$DAILY_DIR"/*.md 2>/dev/null | while read -r f; do
|
|
78
|
-
base=$(basename "$f" .md)
|
|
79
|
-
if [ "$base" \> "$CUTOFF" ] || [ "$base" = "$CUTOFF" ]; then
|
|
80
|
-
echo "=== $base ==="
|
|
81
|
-
cat "$f"
|
|
82
|
-
echo ""
|
|
83
|
-
fi
|
|
84
|
-
done
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
You now have the raw stream. Read it.
|
|
88
|
-
|
|
89
|
-
### 3. Identify what's worth promoting
|
|
90
|
-
|
|
91
|
-
Read every entry. Group by project. Look for these signals — these are
|
|
92
|
-
the things that promote into the wiki:
|
|
93
|
-
|
|
94
|
-
| Signal in raw entry | What to extract | Goes to |
|
|
95
|
-
|---|---|---|
|
|
96
|
-
| Same fix appears in 2+ sessions | A common fix recipe | `common-fixes.md` (via `knowledge.js append --type fix`) |
|
|
97
|
-
| A pattern shows up in 3+ projects | A reusable pattern | `learned-patterns.md` (via `knowledge.js append --type pattern`) |
|
|
98
|
-
| A client-name or project preference recurs | A client preference | `client-prefs.md` (via `knowledge.js append --type client`) |
|
|
99
|
-
| A new technology/library used successfully | A stack note | `concepts/{tech}.md` (new file, Write directly) |
|
|
100
|
-
| A recurring failure mode (verify-fail, regression) | A pitfall | `learned-patterns.md` framed as "anti-pattern: …" |
|
|
101
|
-
|
|
102
|
-
Things to **NOT** promote:
|
|
103
|
-
- Single-occurrence quirks (they're noise until they recur).
|
|
104
|
-
- Bare commit/branch info — that's already in git, no value duplicating.
|
|
105
|
-
- Anything containing secrets, tokens, customer PII. The knowledge layer
|
|
106
|
-
is plain markdown, never put secrets here.
|
|
107
|
-
- Entries from `--dry-run` runs of other skills (they'll show as activity
|
|
108
|
-
but didn't actually do anything).
|
|
109
|
-
|
|
110
|
-
### 4. Write the promotions
|
|
111
|
-
|
|
112
|
-
For each thing worth promoting, use the loader's `append`:
|
|
113
|
-
|
|
114
|
-
```bash
|
|
115
|
-
node ${QUALIA_BIN}/knowledge.js append \
|
|
116
|
-
--type {pattern|fix|client} \
|
|
117
|
-
--title "{Concise title — what's the recurring thing?}" \
|
|
118
|
-
--body "{The promoted lesson. Be specific. Include the project name(s) and dates where this pattern was observed so future you can verify.}" \
|
|
119
|
-
--project "{specific project, or 'general' if cross-project}" \
|
|
120
|
-
--context "Promoted by /qualia-flush from daily-log entries on {dates}"
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
For a brand-new topic that doesn't fit pattern/fix/client (e.g. a Stripe
|
|
124
|
-
integration approach worth its own file), Write to
|
|
125
|
-
`${QUALIA_KNOWLEDGE}/concepts/{topic}.md`. Then **update `index.md`** so the
|
|
126
|
-
new file is reachable — list it under "What's where" with one line:
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
# After writing concepts/stripe-checkout.md:
|
|
130
|
-
node ${QUALIA_BIN}/knowledge.js path stripe-checkout
|
|
131
|
-
# Returned path = ${QUALIA_KNOWLEDGE}/stripe-checkout.md (NOTE: top-level, not concepts/)
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
> **Loader behavior:** `knowledge.js load <name>` resolves bare names by walking
|
|
135
|
-
> top-level + subdirectories (`concepts/`, `daily-log/`) for an exact match.
|
|
136
|
-
> Write durable entries to `concepts/{topic}.md`; the loader will find them.
|
|
137
|
-
|
|
138
|
-
### 5. Mark the window as flushed
|
|
139
|
-
|
|
140
|
-
Write a stamp file so subsequent flushes can default to "since the last
|
|
141
|
-
flush" instead of "last 14 days":
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
date -u +%Y-%m-%dT%H:%M:%SZ > "$HOME/.claude/.qualia-last-flush"
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### 6. Summarize
|
|
148
|
-
|
|
149
|
-
Print to the user, in plain language:
|
|
150
|
-
|
|
151
|
-
- N daily-log files scanned (date range)
|
|
152
|
-
- M promotions written (with file:title for each)
|
|
153
|
-
- K things considered but not promoted (single-occurrence — wait for them to recur)
|
|
154
|
-
|
|
155
|
-
Format:
|
|
156
|
-
|
|
157
|
-
```
|
|
158
|
-
⬢ Flushed daily-log {start} → {end} ({N} files, {total entries} entries)
|
|
159
|
-
Promoted to wiki:
|
|
160
|
-
+ learned-patterns.md "Supabase RLS in same migration" (3 sessions, 2 projects)
|
|
161
|
-
+ common-fixes.md "next/font crash on Vercel" (2 sessions)
|
|
162
|
-
+ concepts/voice-agent-call-state.md (new file)
|
|
163
|
-
Skipped {K} single-occurrence entries — will revisit if they recur.
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
## Style
|
|
167
|
-
|
|
168
|
-
- **Be conservative.** False-positive promotions (writing noise as if it's a
|
|
169
|
-
pattern) pollute the wiki and erode trust. Better to skip a candidate and
|
|
170
|
-
let it recur next week than to inflate the curated tier.
|
|
171
|
-
- **Cite your sources.** Every promoted entry should reference the
|
|
172
|
-
daily-log dates that sourced it, in the `--context` field. If a future
|
|
173
|
-
flush wants to update it, the trail is there.
|
|
174
|
-
- **Keep titles short.** `--title "Supabase RLS same migration"` not `"You should always remember that when working with Supabase you need to..."`. The body is for nuance.
|
|
175
|
-
- **Don't promote private projects across boundaries.** A pattern from
|
|
176
|
-
Project A is fine to promote as cross-project ONLY if it generalizes.
|
|
177
|
-
Client-specific things stay client-specific (`--type client --project X`).
|
|
178
|
-
|
|
179
|
-
## Anti-patterns
|
|
180
|
-
|
|
181
|
-
- **Mass-promoting everything:** if you found "promotions" for 90% of
|
|
182
|
-
daily-log entries, you're labeling, not promoting. Be selective.
|
|
183
|
-
- **Re-promoting on every flush:** before appending, run
|
|
184
|
-
`node ${QUALIA_BIN}/knowledge.js search "{title keywords}"` to check if
|
|
185
|
-
the pattern already exists. If it does, either update it (find by `**ID:**`
|
|
186
|
-
line) or skip — never duplicate.
|
|
187
|
-
- **Hand-writing to `learned-patterns.md` etc. directly:** always go
|
|
188
|
-
through `knowledge.js append` so the canonical entry format and ID
|
|
189
|
-
generation stay consistent. This skill is the only sanctioned promoter,
|
|
190
|
-
but even it uses the loader for writes.
|
|
191
|
-
|
|
192
|
-
## Output contract
|
|
193
|
-
|
|
194
|
-
If invoked with `--dry-run`, print the proposed writes and exit without
|
|
195
|
-
touching disk. Otherwise, after step 6 returns the summary, the skill is
|
|
196
|
-
done — no follow-up prompts. The user sees the summary and the wiki tier
|
|
197
|
-
has new entries that are immediately reachable to every other skill via
|
|
198
|
-
the loader.
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: qualia-help
|
|
3
|
-
description: "Open the BROWSER HTML reference for the Qualia Framework — themed page with all commands, rules, services, and the road. The default when a browser is available. For terminal-only output (SSH, headless), use /qualia-road. Triggers: 'help', 'how does this work', 'show me the commands', 'qualia help', 'reference', 'open the docs'."
|
|
4
|
-
allowed-tools:
|
|
5
|
-
- Bash
|
|
6
|
-
- Read
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# /qualia-help — Framework Reference
|
|
10
|
-
|
|
11
|
-
Opens a Qualia-themed HTML reference guide in your default browser.
|
|
12
|
-
|
|
13
|
-
## Process
|
|
14
|
-
|
|
15
|
-
### 1. Generate the HTML
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
# Read the template and inject the current version.
|
|
19
|
-
# Prefer .qualia-config.json; fall back to the framework package.json; last resort is the
|
|
20
|
-
# literal string "latest" so the UI never lies about a specific version.
|
|
21
|
-
VERSION=$(node -e "
|
|
22
|
-
const fs = require('fs'), path = require('path'), os = require('os');
|
|
23
|
-
const cfg = path.join(os.homedir(), '.claude', '.qualia-config.json');
|
|
24
|
-
const pkg = path.join(os.homedir(), '.claude', 'qualia-framework', 'package.json');
|
|
25
|
-
try { const v = JSON.parse(fs.readFileSync(cfg,'utf8')).version; if (v) { console.log(v); process.exit(0); } } catch {}
|
|
26
|
-
try { const v = JSON.parse(fs.readFileSync(pkg,'utf8')).version; if (v) { console.log('v'+v); process.exit(0); } } catch {}
|
|
27
|
-
console.log('latest');
|
|
28
|
-
" 2>/dev/null || echo "latest")
|
|
29
|
-
TEMPLATE="$HOME/.claude/qualia-templates/help.html"
|
|
30
|
-
OUTPUT="/tmp/qualia-help.html"
|
|
31
|
-
|
|
32
|
-
# If template doesn't exist in the user home, check the installed framework copy.
|
|
33
|
-
if [ ! -f "$TEMPLATE" ]; then
|
|
34
|
-
for CANDIDATE in "$HOME/.claude/qualia-framework/templates/help.html"; do
|
|
35
|
-
if [ -f "$CANDIDATE" ]; then TEMPLATE="$CANDIDATE"; break; fi
|
|
36
|
-
done
|
|
37
|
-
fi
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### 2. Inject version and open
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
# Replace {{VERSION}} placeholder with actual version
|
|
44
|
-
sed "s/{{VERSION}}/$VERSION/g" "$TEMPLATE" > "$OUTPUT"
|
|
45
|
-
|
|
46
|
-
# Open in default browser (cross-platform)
|
|
47
|
-
if command -v xdg-open &>/dev/null; then
|
|
48
|
-
xdg-open "$OUTPUT" # Linux
|
|
49
|
-
elif command -v open &>/dev/null; then
|
|
50
|
-
open "$OUTPUT" # macOS
|
|
51
|
-
elif command -v start &>/dev/null; then
|
|
52
|
-
start "$OUTPUT" # Windows (Git Bash)
|
|
53
|
-
else
|
|
54
|
-
echo "Open this file in your browser: $OUTPUT"
|
|
55
|
-
fi
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### 3. Confirm
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
node ${QUALIA_BIN}/qualia-ui.js banner router
|
|
62
|
-
node ${QUALIA_BIN}/qualia-ui.js ok "Reference guide opened in browser"
|
|
63
|
-
node ${QUALIA_BIN}/qualia-ui.js info "File: /tmp/qualia-help.html"
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
If the browser does not open automatically, tell the user the file path so they can open it manually.
|
|
67
|
-
|
|
68
|
-
## Notes
|
|
69
|
-
|
|
70
|
-
- The HTML file is self-contained — no external dependencies except Google Fonts
|
|
71
|
-
- Works offline after first load (fonts cache)
|
|
72
|
-
- Qualia-themed: dark background, teal accents, Outfit + Inter fonts
|
|
73
|
-
- Shows: The Road, all commands grouped, verification scoring, rules, stack, GitHub orgs
|
|
74
|
-
- Version is injected dynamically from .qualia-config.json
|