qualia-framework 5.4.0 → 5.5.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/README.md +4 -4
- package/agents/builder.md +25 -8
- package/agents/plan-checker.md +50 -2
- package/agents/planner.md +25 -1
- package/bin/install.js +2 -2
- package/bin/plan-contract.js +32 -1
- package/docs/erp-contract.md +11 -0
- package/guide.md +3 -3
- package/package.json +1 -1
- package/skills/qualia-discuss/SKILL.md +17 -3
- package/skills/qualia-report/SKILL.md +8 -6
- package/templates/CONTEXT.md +3 -2
- package/templates/help.html +1 -1
- package/templates/phase-context.md +5 -4
- package/tests/bin.test.sh +30 -0
- package/tests/lib.test.sh +21 -0
- package/docs/archive/session-report-2026-04-18.md +0 -199
- package/docs/install-redesign-builder-prompt.md +0 -290
- package/docs/install-redesign-pilot.md +0 -234
- package/docs/instruction-budget-audit.md +0 -113
- package/docs/journey-demo.html +0 -1008
- package/docs/playwright-loop-builder-prompt.md +0 -185
- package/docs/playwright-loop-design-notes.md +0 -108
- package/docs/playwright-loop-tester-prompt.md +0 -213
- package/docs/polish-loop-supervised-run.md +0 -111
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ Open Claude Code in any project directory.
|
|
|
53
53
|
/qualia-polish # Design pass — flexible scope: component, route, app, redesign, critique, quick
|
|
54
54
|
/qualia-ship # Deploy to production
|
|
55
55
|
/qualia-handoff # Enforce the 4 mandatory handoff deliverables
|
|
56
|
-
/qualia-report # Mandatory
|
|
56
|
+
/qualia-report # Mandatory shift report + ERP upload before clock-out
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
### The Road — auto mode
|
|
@@ -127,8 +127,8 @@ Every project has a `.planning/JOURNEY.md` — the North Star document that maps
|
|
|
127
127
|
Project
|
|
128
128
|
└─ Journey (all milestones defined upfront)
|
|
129
129
|
└─ Milestone (a release — 2-5 total, Handoff is always last)
|
|
130
|
-
└─ Phase (a feature-sized deliverable, 2-5 tasks)
|
|
131
|
-
└─ Task (
|
|
130
|
+
└─ Phase (a feature-sized deliverable, 2-5 internal tasks)
|
|
131
|
+
└─ Task (framework-internal unit, one commit, one verification contract)
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
**Hard rules:**
|
|
@@ -137,7 +137,7 @@ Project
|
|
|
137
137
|
- Every non-Handoff milestone needs **≥ 2 phases** (enforced by `state.js close-milestone`).
|
|
138
138
|
- Milestone numbering is contiguous.
|
|
139
139
|
|
|
140
|
-
**Why it matters:** non-technical team members can follow the ladder from any entry point. `/qualia` and `/qualia-milestone` render JOURNEY.md as a visual ladder with current position highlighted.
|
|
140
|
+
**Why it matters:** non-technical team members can follow the ladder from any entry point. `/qualia` and `/qualia-milestone` render JOURNEY.md as a visual ladder with current position highlighted. In the ERP, the primary operational dates are project deadline, milestone deadline, and employee shift submission date; framework tasks stay internal to agent execution.
|
|
141
141
|
|
|
142
142
|
## What's Inside (v5.3.0)
|
|
143
143
|
|
package/agents/builder.md
CHANGED
|
@@ -93,18 +93,26 @@ which is fine and means there is nothing to apply yet.
|
|
|
93
93
|
- If the plan says "use library X" — use library X
|
|
94
94
|
- If something in the plan seems wrong, flag it but still follow the plan
|
|
95
95
|
|
|
96
|
-
### 4. Self-Verify Your Work
|
|
96
|
+
### 4. Self-Verify Your Work (Auto-Heal Loop)
|
|
97
97
|
|
|
98
|
-
Before committing
|
|
98
|
+
Before committing, run the checks below. If any fail, **fix and retry up to 2 times** before giving up. This is a tight self-heal loop — moving correctness checks here saves a verifier round.
|
|
99
99
|
|
|
100
|
-
1. Run every command in **Validation:** — they must pass
|
|
100
|
+
1. Run every command in **Validation:** — they must pass.
|
|
101
101
|
2. Mentally walk through each **Acceptance Criterion** — does the code actually produce that observable behavior?
|
|
102
|
-
3. Run `npx tsc --noEmit` if you touched TypeScript files
|
|
103
|
-
4. **If you touched any `.tsx/.jsx/.css/.scss/.html` file: run `node bin/slop-detect.mjs {touched paths}`. Exit 1 (critical findings) BLOCKS the commit.** Fix the findings (apply the rewrite recipe in the script's output), re-run, repeat until exit 0.
|
|
104
|
-
5. No `// TODO`, no placeholder text, no stub functions
|
|
105
|
-
6. Imports are wired — not just declared but actually used
|
|
102
|
+
3. Run `npx tsc --noEmit` if you touched TypeScript files. On failure, capture the first 50 lines of error output, fix the offending file(s), re-run. Cap at 2 retries.
|
|
103
|
+
4. **If you touched any `.tsx/.jsx/.css/.scss/.html` file: run `node bin/slop-detect.mjs {touched paths}`. Exit 1 (critical findings) BLOCKS the commit.** Fix the findings (apply the rewrite recipe in the script's output), re-run, repeat until exit 0 (also capped at 2 retries before BLOCKED).
|
|
104
|
+
5. No `// TODO`, no placeholder text, no stub functions.
|
|
105
|
+
6. Imports are wired — not just declared but actually used.
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
**Auto-heal protocol:**
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
attempt 1: run validation → fix what failed → run again
|
|
111
|
+
attempt 2: run validation → fix what failed → run again
|
|
112
|
+
attempt 3: if still failing, return BLOCKED — do not commit broken code
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
If any Validation command fails after 2 retries, slop-detect returns 1 after 2 retries, or any AC is not met after a fix attempt, return `BLOCKED — {validation failure}: {first 20 lines of last error output}`. Do not commit and hope the verifier catches it.
|
|
108
116
|
|
|
109
117
|
### 5. Commit
|
|
110
118
|
One atomic commit per task:
|
|
@@ -115,6 +123,15 @@ git commit -m "{concise description of what was built}"
|
|
|
115
123
|
|
|
116
124
|
Stage specific files — never `git add .` or `git add -A`.
|
|
117
125
|
|
|
126
|
+
## Scope Reduction Prohibition
|
|
127
|
+
|
|
128
|
+
The plan was written with the full spec in mind. Don't simplify it. If a task says "validate with Zod schema X covering 6 fields" don't ship 3 fields. If it says "redirect on success" don't ship a console.log placeholder.
|
|
129
|
+
|
|
130
|
+
**Banned phrases in code, comments, and commit messages:**
|
|
131
|
+
`v1`, `// for now`, `// TODO: wire this up later`, `// hardcoded for now`, `// stub`, `// placeholder`, `// minimal version`, `// will improve later`, `mock for now` (in production code paths).
|
|
132
|
+
|
|
133
|
+
If you cannot deliver the full spec because a dependency is genuinely missing, return `BLOCKED — dependency missing: {what}` per the deviation table. Do NOT ship a watered-down version with a TODO note.
|
|
134
|
+
|
|
118
135
|
## Scope Discipline
|
|
119
136
|
|
|
120
137
|
Before writing or editing any file, check: Is this file listed in the task's **Files** section?
|
package/agents/plan-checker.md
CHANGED
|
@@ -132,6 +132,54 @@ Every frontend task MUST include a `**Design:**` field with:
|
|
|
132
132
|
|
|
133
133
|
Non-frontend tasks (backend, migrations, API routes without UI) MUST NOT have a `**Design:**` field. Warn but don't fail if one is mistakenly added.
|
|
134
134
|
|
|
135
|
+
### Rule 11: Requirement Coverage (when ROADMAP.md lists REQ-IDs)
|
|
136
|
+
|
|
137
|
+
If `.planning/ROADMAP.md` exists and the current phase's section lists `Requirements covered:` with `REQ-ID`s (format `[A-Z]+-\d+`, e.g. `AUTH-01`, `BILLING-03`), every REQ-ID must be covered by at least one task. Coverage = the task's `**Why:**`, `**Acceptance Criteria:**`, or `**Action:**` field references the REQ-ID, OR the task's content directly implements that requirement (read the requirement description from `.planning/REQUIREMENTS.md` and confirm).
|
|
138
|
+
|
|
139
|
+
**FAIL if:**
|
|
140
|
+
- A REQ-ID listed for the current phase appears nowhere in the plan.
|
|
141
|
+
- A task claims a REQ-ID but its Action/AC obviously doesn't implement it.
|
|
142
|
+
|
|
143
|
+
**How to detect:**
|
|
144
|
+
```bash
|
|
145
|
+
# Extract REQ-IDs for this phase from ROADMAP.md
|
|
146
|
+
awk '/^### Phase {N}:/,/^---|^### Phase/' .planning/ROADMAP.md | grep -oE '[A-Z]+-[0-9]+' | sort -u
|
|
147
|
+
# Check each appears in the plan
|
|
148
|
+
grep -oE '[A-Z]+-[0-9]+' .planning/phase-{N}-plan.md | sort -u
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The set difference (REQ-IDs in roadmap minus REQ-IDs in plan) must be empty.
|
|
152
|
+
|
|
153
|
+
If a REQ-ID is missing from the plan, REVISE: "REQ AUTH-03 is in scope for this phase per ROADMAP.md but no task implements it." Plan-wide, not task-specific.
|
|
154
|
+
|
|
155
|
+
### Rule 9: Decision Coverage (when phase-context.md exists)
|
|
156
|
+
|
|
157
|
+
If `.planning/phase-{N}-context.md` exists with a `## Locked Decisions` section, every `D-NN` row must be covered by at least one task. Coverage = the task references the ID in its `**Why:**` or `**Action:**` field, OR the task's Action implements the decision content directly (read the task and confirm).
|
|
158
|
+
|
|
159
|
+
**FAIL if:**
|
|
160
|
+
- A `D-NN` row exists in phase-context.md but no task in the plan references it or implements it.
|
|
161
|
+
- A row from `## Deferred Ideas` is being implemented by a task (deferred = explicitly out-of-scope).
|
|
162
|
+
|
|
163
|
+
**How to detect:**
|
|
164
|
+
```bash
|
|
165
|
+
grep -E '^\| D-[0-9]+' .planning/phase-{N}-context.md # extract decision IDs
|
|
166
|
+
grep -E 'D-[0-9]+' .planning/phase-{N}-plan.md # check IDs appear in plan
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
If a decision ID appears in phase-context.md but not the plan, REVISE: "D-03 is locked but no task implements it." Plus the deferred check: if a task's Action matches a Deferred-Ideas row, REVISE.
|
|
170
|
+
|
|
171
|
+
### Rule 10: Scope Reduction Detection
|
|
172
|
+
|
|
173
|
+
LLMs systematically simplify specs. Scan the plan for banned phrases that signal scope reduction:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
grep -niE '\b(v1|v2|simplified version|static for now|hardcoded for now|placeholder|basic version|minimal implementation|will be wired later|dynamic in future phase|skip for now|stub|mock for now|we can improve this later|quick win for now)\b' .planning/phase-{N}-plan.md
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**FAIL if:** any match. Quote the offending line in the issue. The planner must rewrite the task to deliver the actual thing, OR explicitly justify the split using one of the three legitimate reasons (context cost > 50%, missing info, dependency conflict).
|
|
180
|
+
|
|
181
|
+
Exception: `v1` / `v2` is fine when referring to the project's actual versioning (e.g., `migrate to API v2`). Distinguish by context.
|
|
182
|
+
|
|
135
183
|
### Rule 8: Validation commands test behavior, not just existence
|
|
136
184
|
|
|
137
185
|
Each task's `**Validation:**` list must contain at least one `grep-match` or `command-exit` check — a command that proves the code DOES something. A task whose ONLY validation is `test -f {file}` will pass even if the file contains only `// TODO`.
|
|
@@ -152,7 +200,7 @@ Each task's `**Validation:**` list must contain at least one `grep-match` or `co
|
|
|
152
200
|
|
|
153
201
|
## Tool Budget
|
|
154
202
|
|
|
155
|
-
Read the plan file once. Grep the
|
|
203
|
+
Read the plan file once. Read `.planning/phase-{N}-context.md` once if it exists (Rules 7 + 9). Read `.planning/ROADMAP.md` once if it exists (Rules 4 + 11). Grep the plan for scope-reduction phrases (Rule 10), decision IDs (Rule 9), and REQ-IDs (Rule 11). Do NOT speculatively check whether files listed in the plan already exist — that's the builder's job. Max 14 tool calls per invocation.
|
|
156
204
|
|
|
157
205
|
## Output Format
|
|
158
206
|
|
|
@@ -215,6 +263,6 @@ Before returning, self-check:
|
|
|
215
263
|
- [ ] Every issue has a specific task reference
|
|
216
264
|
- [ ] Every issue has a concrete fix instruction
|
|
217
265
|
- [ ] No issue is "make it better" or "be more specific" without saying how
|
|
218
|
-
- [ ] If plan passes, you actually verified all
|
|
266
|
+
- [ ] If plan passes, you actually verified all 11 rules (not just 1-2)
|
|
219
267
|
|
|
220
268
|
Don't pass a plan you didn't fully check. Don't fail a plan for style preferences.
|
package/agents/planner.md
CHANGED
|
@@ -212,12 +212,36 @@ When a phase involves frontend work (pages, components, layouts, UI):
|
|
|
212
212
|
- Include responsive: "works on 375px mobile and 1440px desktop"
|
|
213
213
|
4. **Reference `@.planning/DESIGN.md`** in the Context field of every frontend task so builders read it before coding
|
|
214
214
|
|
|
215
|
+
## Scope Reduction Prohibition
|
|
216
|
+
|
|
217
|
+
LLMs systematically simplify specs. You will not. If a locked decision or success criterion says X, the plan delivers X — not a watered-down version that "we can extend later."
|
|
218
|
+
|
|
219
|
+
**Banned phrases in task Action / Acceptance Criteria / Why fields:**
|
|
220
|
+
`v1`, `v2`, `simplified version`, `static for now`, `hardcoded for now`, `placeholder`, `basic version`, `minimal implementation`, `will be wired later`, `dynamic in future phase`, `skip for now`, `stub`, `mock for now`, `we can improve this later`, `quick win for now`.
|
|
221
|
+
|
|
222
|
+
**The only legitimate reasons to split scope across phases:**
|
|
223
|
+
1. Implementing it would force a single task above ~50% builder context.
|
|
224
|
+
2. Required information genuinely does not exist (data shape unknown, external API not yet specified).
|
|
225
|
+
3. A dependency is owned by a future phase and the wave-graph cannot resolve it.
|
|
226
|
+
|
|
227
|
+
If none of these apply, deliver the full spec. A self-check before returning the plan: grep your draft for the banned phrases. If you find one, rewrite the task to deliver the actual thing.
|
|
228
|
+
|
|
229
|
+
## Decision Coverage Audit
|
|
230
|
+
|
|
231
|
+
If `.planning/phase-{N}-context.md` exists with a `## Locked Decisions` section, every decision row carries an ID (e.g., `D-01`, `D-02`). Before returning the plan, confirm:
|
|
232
|
+
|
|
233
|
+
- Every `D-XX` is covered by at least one task whose Action implements it. Reference the ID in that task's Why or Action (e.g., `Why: D-03 requires session tokens stored database-side, not in JWT`).
|
|
234
|
+
- No `Deferred Ideas` row appears in any task. Deferred = out-of-scope for this phase.
|
|
235
|
+
- `Discretion` items are the planner's call — no audit needed.
|
|
236
|
+
|
|
237
|
+
If a locked decision has no covering task, add one. If you genuinely cannot, the phase scope is wrong and the plan-checker will block — STOP and surface the gap to the user.
|
|
238
|
+
|
|
215
239
|
## Rules
|
|
216
240
|
|
|
217
241
|
1. **Plans complete within ~50% context.** More plans with smaller scope = consistent quality. 2-3 tasks per plan is ideal.
|
|
218
242
|
2. **Tasks are atomic.** Each task = one commit. If a task touches 10+ files, split it.
|
|
219
243
|
3. **"Done when" must be testable.** Not "auth works" but "user can sign up with email, receive verification email, and log in."
|
|
220
|
-
4. **Honor locked decisions.** If PROJECT.md says "use library X" — the plan uses library X.
|
|
244
|
+
4. **Honor locked decisions.** If PROJECT.md or phase-context.md says "use library X" — the plan uses library X.
|
|
221
245
|
5. **No enterprise patterns.** No RACI, no stakeholder management, no sprint ceremonies. One person + Claude.
|
|
222
246
|
6. **Context references are explicit.** Use `@filepath` so the builder knows exactly what to read.
|
|
223
247
|
|
package/bin/install.js
CHANGED
|
@@ -894,7 +894,7 @@ Client-specific preferences, design choices, and requirements. Loaded by \`/qual
|
|
|
894
894
|
tips: [
|
|
895
895
|
"⬢ Lost? Type /qualia for the next step",
|
|
896
896
|
"⬢ Small fix? Use /qualia-quick to skip planning",
|
|
897
|
-
"⬢ End of day? /qualia-report before
|
|
897
|
+
"⬢ End of day? /qualia-report submits your shift before clock-out",
|
|
898
898
|
"⬢ Context isolation: every task gets a fresh AI brain",
|
|
899
899
|
"⬢ The verifier doesn't trust claims — it greps the code",
|
|
900
900
|
"⬢ Plans are prompts — the plan IS what the builder reads",
|
|
@@ -1105,7 +1105,7 @@ function printSummary({ member, target, claudeInstalled }) {
|
|
|
1105
1105
|
console.log("");
|
|
1106
1106
|
console.log(` ${DIM}New project?${RESET} ${TEAL}/qualia-new${RESET}`);
|
|
1107
1107
|
console.log(` ${DIM}Quick fix?${RESET} ${TEAL}/qualia-quick${RESET}`);
|
|
1108
|
-
console.log(` ${DIM}End of day?${RESET} ${TEAL}/qualia-report${RESET} ${DIM}(
|
|
1108
|
+
console.log(` ${DIM}End of day?${RESET} ${TEAL}/qualia-report${RESET} ${DIM}(shift submission)${RESET}`);
|
|
1109
1109
|
console.log(` ${DIM}Stuck?${RESET} ${TEAL}/qualia${RESET}`);
|
|
1110
1110
|
console.log("");
|
|
1111
1111
|
console.log(` ${DIM2}${RULE}${RESET}`);
|
package/bin/plan-contract.js
CHANGED
|
@@ -21,6 +21,28 @@ const CHECK_TYPES = new Set([
|
|
|
21
21
|
"file-exists", "grep-match", "command-exit", "behavioral",
|
|
22
22
|
]);
|
|
23
23
|
|
|
24
|
+
// Scope-reduction detection — phrases that signal an LLM has watered down the
|
|
25
|
+
// spec. The plan-checker agent does the same scan on the markdown plan; this
|
|
26
|
+
// function does it on the JSON contract's free-text fields (action +
|
|
27
|
+
// acceptance_criteria) so both paths catch the same failure mode.
|
|
28
|
+
const SCOPE_REDUCTION_PHRASES = [
|
|
29
|
+
/\bv1\b/i, /\bv2\b/i, /simplified version/i, /static for now/i,
|
|
30
|
+
/hardcoded for now/i, /\bplaceholder\b/i, /basic version/i,
|
|
31
|
+
/minimal implementation/i, /will be wired later/i,
|
|
32
|
+
/dynamic in future phase/i, /skip for now/i, /\bstub\b/i,
|
|
33
|
+
/mock for now/i, /we can improve this later/i, /quick win for now/i,
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
function findScopeReductionPhrases(text) {
|
|
37
|
+
if (typeof text !== "string") return [];
|
|
38
|
+
const hits = [];
|
|
39
|
+
for (const re of SCOPE_REDUCTION_PHRASES) {
|
|
40
|
+
const m = text.match(re);
|
|
41
|
+
if (m) hits.push(m[0]);
|
|
42
|
+
}
|
|
43
|
+
return hits;
|
|
44
|
+
}
|
|
45
|
+
|
|
24
46
|
function isStringArray(v) {
|
|
25
47
|
return Array.isArray(v) && v.every((x) => typeof x === "string");
|
|
26
48
|
}
|
|
@@ -98,7 +120,15 @@ function validateTask(task, idx, allIds) {
|
|
|
98
120
|
errs.push(`${where}.acceptance_criteria: must be a non-empty string[]`);
|
|
99
121
|
}
|
|
100
122
|
if (typeof task.action !== "string") errs.push(`${where}.action: required string`);
|
|
101
|
-
else
|
|
123
|
+
else {
|
|
124
|
+
if (task.action.length > 500) errs.push(`${where}.action: must be ≤ 500 characters (got ${task.action.length})`);
|
|
125
|
+
const actionHits = findScopeReductionPhrases(task.action);
|
|
126
|
+
if (actionHits.length) errs.push(`${where}.action: scope-reduction phrase(s) detected: ${actionHits.join(", ")} — rewrite to deliver the actual spec, or split via locked-decision channel`);
|
|
127
|
+
}
|
|
128
|
+
for (let i = 0; i < (task.acceptance_criteria || []).length; i++) {
|
|
129
|
+
const acHits = findScopeReductionPhrases(task.acceptance_criteria[i]);
|
|
130
|
+
if (acHits.length) errs.push(`${where}.acceptance_criteria[${i}]: scope-reduction phrase(s) detected: ${acHits.join(", ")}`);
|
|
131
|
+
}
|
|
102
132
|
if (!isStringArray(task.context_files || [])) errs.push(`${where}.context_files: must be string[]`);
|
|
103
133
|
if (!Array.isArray(task.verification) || task.verification.length === 0) {
|
|
104
134
|
errs.push(`${where}.verification: must be a non-empty array`);
|
|
@@ -217,4 +247,5 @@ module.exports = {
|
|
|
217
247
|
parseSafely,
|
|
218
248
|
hashPlan,
|
|
219
249
|
checkDrift,
|
|
250
|
+
findScopeReductionPhrases,
|
|
220
251
|
};
|
package/docs/erp-contract.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
The Qualia Framework optionally uploads session reports to the company ERP at `https://portal.qualiasolutions.net`. This document specifies the API shape.
|
|
4
4
|
|
|
5
|
+
## Operating Model
|
|
6
|
+
|
|
7
|
+
The ERP treats `/qualia-report` as an employee shift submission, not proof that an assigned task was finished. Employees clock out after their fixed daily hours and submit what happened during the shift: shipped work, partial progress, blockers, investigation, meetings, or no-code work.
|
|
8
|
+
|
|
9
|
+
Primary ERP planning dates are:
|
|
10
|
+
- Project deadline
|
|
11
|
+
- Milestone deadline
|
|
12
|
+
- Employee submission date from the uploaded report
|
|
13
|
+
|
|
14
|
+
Phase and task counters remain framework telemetry. They help agents plan/build/verify, but they should not become the ERP's primary navigation, deadline model, or employee-performance label.
|
|
15
|
+
|
|
5
16
|
## Configuration
|
|
6
17
|
|
|
7
18
|
Stored in `~/.claude/.qualia-config.json`:
|
package/guide.md
CHANGED
|
@@ -109,7 +109,7 @@ If neither helps, paste the error and ask Claude directly. If Claude can't fix i
|
|
|
109
109
|
## Session Start / End
|
|
110
110
|
|
|
111
111
|
**Start:** Claude loads your project context automatically. The router banner shows your journey position ("M2 of 4 · P2 of 3").
|
|
112
|
-
**End:** Run `/qualia-report` — this is mandatory
|
|
112
|
+
**End:** Run `/qualia-report` — this is the mandatory clock-out submission. It reports what happened during the work shift, even if the work is unfinished. The report is committed to git and (if ERP is enabled) uploaded to https://portal.qualiasolutions.net.
|
|
113
113
|
|
|
114
114
|
## How It Works (you don't need to know this, but if curious)
|
|
115
115
|
|
|
@@ -120,7 +120,7 @@ If neither helps, paste the error and ask Claude directly. If Claude can't fix i
|
|
|
120
120
|
- **Story-file plans:** Every task has Why / Acceptance Criteria / Depends on / Validation inline — the plan IS the brief.
|
|
121
121
|
- **Wave execution:** Independent tasks run in parallel. Dependent tasks wait.
|
|
122
122
|
- **Milestone-boundary pauses:** In `--auto` mode, the framework pauses only at real decision points. Everything else runs on rails.
|
|
123
|
-
- **tracking.json:** Updated on every push. The ERP reads it automatically. Includes `milestone_name` + `milestones[]` so the ERP
|
|
123
|
+
- **tracking.json:** Updated on every push. The ERP reads it automatically. Includes `milestone_name` + `milestones[]` so the ERP can show project and milestone progress without exposing framework tasks as the main employee workflow.
|
|
124
124
|
|
|
125
125
|
## Quick Reference
|
|
126
126
|
|
|
@@ -134,4 +134,4 @@ If neither helps, paste the error and ask Claude directly. If Claude can't fix i
|
|
|
134
134
|
| Finished the last phase of a milestone | `/qualia-milestone` |
|
|
135
135
|
| About to ship | `/qualia-ship` |
|
|
136
136
|
| Client is ready to take over | `/qualia-handoff` |
|
|
137
|
-
| End of workday | `/qualia-report` (mandatory) |
|
|
137
|
+
| End of workday / clock-out | `/qualia-report` (mandatory shift submission) |
|
package/package.json
CHANGED
|
@@ -67,10 +67,24 @@ Wait for response. Then:
|
|
|
67
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
68
|
- Drill deeper if the answer opens new branches
|
|
69
69
|
|
|
70
|
-
### 4. Build the locked-decisions list
|
|
70
|
+
### 4. Build the locked-decisions list (with IDs — machine-parseable downstream)
|
|
71
71
|
|
|
72
|
-
For each resolved decision, capture
|
|
73
|
-
|
|
72
|
+
For each resolved decision, capture as a row with a stable ID `D-NN` (zero-padded, sequential within the phase). The planner's Decision Coverage Audit checks every `D-NN` is implemented; the plan-checker BLOCKS if any is missing.
|
|
73
|
+
|
|
74
|
+
**Locked Decision row format:**
|
|
75
|
+
|
|
76
|
+
| ID | Decision | Rationale | Source |
|
|
77
|
+
|----|----------|-----------|--------|
|
|
78
|
+
| D-01 | Use Supabase RLS for authorization, not middleware | Compliance requires database-level checks | discuss session 2026-05-09 |
|
|
79
|
+
| D-02 | Store session tokens server-side, not in JWT | OWASP guidance + revocation requirement | ADR-0007 |
|
|
80
|
+
|
|
81
|
+
Also track:
|
|
82
|
+
- **Discretion items** — planner decides based on best practice (no IDs needed).
|
|
83
|
+
- **Deferred ideas** — explicitly NOT this phase. The plan-checker will REVISE if any of these appears in a task.
|
|
84
|
+
- **Risk flags** — watch during build (no IDs).
|
|
85
|
+
- **Open questions** — still unresolved. Cannot lock until resolved.
|
|
86
|
+
|
|
87
|
+
When you reference a decision later (in commit messages, task Why fields, ADRs), use its ID — `D-03` is shorter than the full decision text and cross-checkable.
|
|
74
88
|
|
|
75
89
|
### 5. Decision gate
|
|
76
90
|
|
|
@@ -9,9 +9,11 @@ allowed-tools:
|
|
|
9
9
|
- AskUserQuestion
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
# /qualia-report — Daily
|
|
12
|
+
# /qualia-report — Daily Shift Report
|
|
13
13
|
|
|
14
|
-
The end-of-day flow. Generates a report, commits it, pushes, uploads to the ERP, and tells the employee they can stop. Designed so Hasan and Moayad never get stuck on it.
|
|
14
|
+
The end-of-day clock-out flow. Generates a shift report, commits it, pushes, uploads to the ERP, and tells the employee they can stop. Designed so Hasan and Moayad never get stuck on it.
|
|
15
|
+
|
|
16
|
+
This is not a task-completion ceremony. The report records what happened during the employee's fixed work shift: shipped work, partial progress, blockers, investigation, meetings, or no-code work. A valid report can say "not finished yet" as long as it clearly explains the shift outcome and next step.
|
|
15
17
|
|
|
16
18
|
## Flags
|
|
17
19
|
- `/qualia-report` — normal flow (generate, commit, push, upload to ERP)
|
|
@@ -60,18 +62,18 @@ None. ← or list 1–N actual blockers (NOT "had to read docs" — that's nor
|
|
|
60
62
|
2. ...
|
|
61
63
|
```
|
|
62
64
|
|
|
63
|
-
**If `COUNT == 0`** — ask the employee gracefully (don't force a fake report):
|
|
65
|
+
**If `COUNT == 0`** — ask the employee gracefully (don't force a fake report or fake completed task):
|
|
64
66
|
|
|
65
67
|
Use `AskUserQuestion`:
|
|
66
68
|
- header: "Empty day?"
|
|
67
|
-
- question: "No commits in the last 8 hours. What
|
|
69
|
+
- question: "No commits in the last 8 hours. What happened during your shift?"
|
|
68
70
|
- options:
|
|
69
71
|
- "Investigation / research only"
|
|
70
72
|
- "Meetings / calls (no code)"
|
|
71
73
|
- "Blocked — tell me on what"
|
|
72
74
|
- "Time off / partial day"
|
|
73
75
|
|
|
74
|
-
Capture the answer as the report body. Empty days are still valid clock-outs — the ERP needs
|
|
76
|
+
Capture the answer as the report body. Empty days and unfinished work are still valid clock-outs — the ERP needs a truthful employee submission date and shift summary.
|
|
75
77
|
|
|
76
78
|
### Step 3 — Write report file
|
|
77
79
|
|
|
@@ -139,7 +141,7 @@ fi
|
|
|
139
141
|
|
|
140
142
|
node ~/.claude/bin/qualia-ui.js divider
|
|
141
143
|
node ~/.claude/bin/qualia-ui.js ok "Report $CLIENT_REPORT_ID complete."
|
|
142
|
-
node ~/.claude/bin/qualia-ui.js info "You can clock out now.
|
|
144
|
+
node ~/.claude/bin/qualia-ui.js info "Shift report submitted. You can clock out now."
|
|
143
145
|
```
|
|
144
146
|
|
|
145
147
|
## Common errors (read this when something goes wrong)
|
package/templates/CONTEXT.md
CHANGED
|
@@ -18,14 +18,15 @@ A unit of work inside a milestone. 2–5 tasks. Ends in a verification gate.
|
|
|
18
18
|
**Avoid:** epic, story, ticket, sprint.
|
|
19
19
|
|
|
20
20
|
### Task
|
|
21
|
-
A
|
|
22
|
-
**Avoid:**
|
|
21
|
+
A framework-internal execution unit: one commit-sized work item with one verification contract.
|
|
22
|
+
**Avoid:** using "task" as an ERP assignment or employee performance label unless the product domain explicitly needs it.
|
|
23
23
|
|
|
24
24
|
## Relationships
|
|
25
25
|
- Project holds many Milestones
|
|
26
26
|
- Milestone holds many Phases
|
|
27
27
|
- Phase holds many Tasks
|
|
28
28
|
- Task carries one Verification Contract
|
|
29
|
+
- ERP tracks project deadlines, milestone deadlines, and employee shift submissions; framework tasks stay internal.
|
|
29
30
|
- {{add domain-specific relationships, e.g. "Customer holds many Orders"}}
|
|
30
31
|
|
|
31
32
|
## Flagged ambiguities
|
package/templates/help.html
CHANGED
|
@@ -479,7 +479,7 @@
|
|
|
479
479
|
<li><span class="rule-icon">1</span> Feature branches by default — OWNER overrides must be explicit</li>
|
|
480
480
|
<li><span class="rule-icon">2</span> Read before write — understand files before editing</li>
|
|
481
481
|
<li><span class="rule-icon">3</span> MVP first — build what's asked, nothing extra</li>
|
|
482
|
-
<li><span class="rule-icon">4</span> /qualia-report before clock-out — mandatory
|
|
482
|
+
<li><span class="rule-icon">4</span> /qualia-report before clock-out — mandatory shift submission in ERP</li>
|
|
483
483
|
<li><span class="rule-icon">5</span> Secrets through approved flows — use set-erp-key or ask Fawzi</li>
|
|
484
484
|
<li><span class="rule-icon">6</span> Stuck 30+ minutes? Ask Fawzi</li>
|
|
485
485
|
</ul>
|
|
@@ -13,11 +13,12 @@ Captured during `/qualia-discuss {N}` — decisions, trade-offs, and constraints
|
|
|
13
13
|
|
|
14
14
|
## Locked Decisions
|
|
15
15
|
|
|
16
|
-
Non-negotiable choices. Planner must honor these exactly.
|
|
16
|
+
Non-negotiable choices. Planner must honor these exactly. Every row has a stable ID (`D-NN`) — the planner's Decision Coverage Audit checks each is implemented; the plan-checker BLOCKS if any is missing.
|
|
17
17
|
|
|
18
|
-
| Decision | Rationale | Source |
|
|
19
|
-
|
|
20
|
-
| {e.g., "Use Supabase RLS for authorization, not middleware"} | {e.g., "Client compliance requires database-level checks"} | {who/when} |
|
|
18
|
+
| ID | Decision | Rationale | Source |
|
|
19
|
+
|----|----------|-----------|--------|
|
|
20
|
+
| D-01 | {e.g., "Use Supabase RLS for authorization, not middleware"} | {e.g., "Client compliance requires database-level checks"} | {who/when} |
|
|
21
|
+
| D-02 | {next decision} | {rationale} | {source} |
|
|
21
22
|
|
|
22
23
|
## Discretion (Planner Chooses)
|
|
23
24
|
|
package/tests/bin.test.sh
CHANGED
|
@@ -1583,6 +1583,36 @@ else
|
|
|
1583
1583
|
fail_case "package.json version not 5.x" "got=$PKG_V"
|
|
1584
1584
|
fi
|
|
1585
1585
|
|
|
1586
|
+
echo ""
|
|
1587
|
+
echo "--- ERP shift-report contract ---"
|
|
1588
|
+
|
|
1589
|
+
# 144. qualia-report describes clock-out as truthful shift submission, not task completion
|
|
1590
|
+
if grep -qi "daily shift report" "$TMP/.claude/skills/qualia-report/SKILL.md" \
|
|
1591
|
+
&& grep -qi "not a task-completion ceremony" "$TMP/.claude/skills/qualia-report/SKILL.md" \
|
|
1592
|
+
&& grep -qi "What happened during your shift" "$TMP/.claude/skills/qualia-report/SKILL.md"; then
|
|
1593
|
+
pass "qualia-report frames clock-out as shift submission, not task completion"
|
|
1594
|
+
else
|
|
1595
|
+
fail_case "qualia-report missing shift-submission contract"
|
|
1596
|
+
fi
|
|
1597
|
+
|
|
1598
|
+
# 145. ERP contract documents the date model: project, milestone, employee submission
|
|
1599
|
+
if grep -q "Project deadline" "$FRAMEWORK_DIR/docs/erp-contract.md" \
|
|
1600
|
+
&& grep -q "Milestone deadline" "$FRAMEWORK_DIR/docs/erp-contract.md" \
|
|
1601
|
+
&& grep -q "Employee submission date" "$FRAMEWORK_DIR/docs/erp-contract.md" \
|
|
1602
|
+
&& grep -q "Phase and task counters remain framework telemetry" "$FRAMEWORK_DIR/docs/erp-contract.md"; then
|
|
1603
|
+
pass "ERP contract documents project/milestone/submission date model"
|
|
1604
|
+
else
|
|
1605
|
+
fail_case "ERP contract missing date-model clarification"
|
|
1606
|
+
fi
|
|
1607
|
+
|
|
1608
|
+
# 146. Project glossary keeps framework tasks internal to agent execution
|
|
1609
|
+
if grep -q "framework-internal execution unit" "$FRAMEWORK_DIR/templates/CONTEXT.md" \
|
|
1610
|
+
&& grep -q "ERP tracks project deadlines, milestone deadlines, and employee shift submissions" "$FRAMEWORK_DIR/templates/CONTEXT.md"; then
|
|
1611
|
+
pass "CONTEXT template distinguishes internal tasks from ERP workflow"
|
|
1612
|
+
else
|
|
1613
|
+
fail_case "CONTEXT template missing framework-task vs ERP-workflow distinction"
|
|
1614
|
+
fi
|
|
1615
|
+
|
|
1586
1616
|
echo ""
|
|
1587
1617
|
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
1588
1618
|
[ "$FAIL" -eq 0 ] && exit 0 || exit 1
|
package/tests/lib.test.sh
CHANGED
|
@@ -57,6 +57,27 @@ console.log(errs.length > 0 ? "REJECTED" : "ACCEPTED");
|
|
|
57
57
|
')
|
|
58
58
|
[ "$OUT" = "REJECTED" ] && ok "rejects malformed contract" || fail "malformed accepted"
|
|
59
59
|
|
|
60
|
+
OUT=$($NODE -e '
|
|
61
|
+
const pc = require("'"$PC"'");
|
|
62
|
+
const slop = {
|
|
63
|
+
version: 1, phase: 1, goal: "x", why: "y",
|
|
64
|
+
generated_at: "t", generated_by: "planner", source_plan_hash: "h",
|
|
65
|
+
success_criteria: ["sc"],
|
|
66
|
+
tasks: [{
|
|
67
|
+
id: "T1", title: "t", wave: 1, depends_on: [],
|
|
68
|
+
files_modify: [], files_create: [], files_delete: [],
|
|
69
|
+
acceptance_criteria: ["minimal implementation of login"],
|
|
70
|
+
action: "Add hardcoded for now placeholder, will be wired later",
|
|
71
|
+
context_files: [],
|
|
72
|
+
verification: [{ type: "file-exists", path: "a.ts" }]
|
|
73
|
+
}]
|
|
74
|
+
};
|
|
75
|
+
const errs = pc.validate(slop);
|
|
76
|
+
const hits = errs.filter(e => /scope-reduction/.test(e));
|
|
77
|
+
console.log(hits.length >= 2 ? "DETECTED" : "MISSED:" + errs.join(";"));
|
|
78
|
+
')
|
|
79
|
+
[ "$OUT" = "DETECTED" ] && ok "detects scope-reduction phrases in action + acceptance_criteria" || fail "scope-reduction missed: $OUT"
|
|
80
|
+
|
|
60
81
|
OUT=$($NODE -e '
|
|
61
82
|
const pc = require("'"$PC"'");
|
|
62
83
|
const c = {
|