create-ccc-tutor 0.1.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 +41 -0
- package/bin/cli.js +76 -0
- package/package.json +28 -0
- package/template/.claude/commands/abandon.md +7 -0
- package/template/.claude/commands/add-anti-flag.md +7 -0
- package/template/.claude/commands/add-constitution-clause.md +7 -0
- package/template/.claude/commands/audit-spec.md +7 -0
- package/template/.claude/commands/commit.md +7 -0
- package/template/.claude/commands/constitution-edit.md +7 -0
- package/template/.claude/commands/db-schema.md +7 -0
- package/template/.claude/commands/exam.md +66 -0
- package/template/.claude/commands/execution-plan.md +7 -0
- package/template/.claude/commands/feature-draft.md +7 -0
- package/template/.claude/commands/handoff.md +7 -0
- package/template/.claude/commands/implement.md +7 -0
- package/template/.claude/commands/init.md +7 -0
- package/template/.claude/commands/next.md +7 -0
- package/template/.claude/commands/offload.md +7 -0
- package/template/.claude/commands/pickup.md +7 -0
- package/template/.claude/commands/recall.md +7 -0
- package/template/.claude/commands/remember.md +7 -0
- package/template/.claude/commands/slide.md +87 -0
- package/template/.claude/commands/spec-finalize.md +7 -0
- package/template/.claude/commands/test-fix.md +7 -0
- package/template/.claude/commands/uninstall.md +7 -0
- package/template/.claude/settings.json +161 -0
- package/template/.claude-plugin/plugin.json +41 -0
- package/template/.codex/config.toml +24 -0
- package/template/.codex/hooks.json +4 -0
- package/template/.codex/install-skills.sh +18 -0
- package/template/.codex/skills/exam/SKILL.md +61 -0
- package/template/.codex/skills/slide/SKILL.md +69 -0
- package/template/.harness/agents/README.md +70 -0
- package/template/.harness/agents/_template/junior-agent-template.md +116 -0
- package/template/.harness/agents/backend-reviewer.md +153 -0
- package/template/.harness/agents/frontend-reviewer.md +158 -0
- package/template/.harness/agents/security-reviewer.md +148 -0
- package/template/.harness/agents/test-fixer.md +147 -0
- package/template/.harness/docs/doc-sync.md +29 -0
- package/template/.harness/docs/git-hygiene.md +56 -0
- package/template/.harness/docs/spec-model.md +47 -0
- package/template/.harness/docs/tool-map.md +120 -0
- package/template/.harness/docs/workflow.md +59 -0
- package/template/.harness/scripts/README.md +70 -0
- package/template/.harness/scripts/auditor-gate.sh +388 -0
- package/template/.harness/scripts/bootstrap-check.sh +103 -0
- package/template/.harness/scripts/budget-monitor.sh +223 -0
- package/template/.harness/scripts/check-prereqs.sh +165 -0
- package/template/.harness/scripts/checkpoint-recall.sh +136 -0
- package/template/.harness/scripts/checkpoint-write.sh +281 -0
- package/template/.harness/scripts/decision-log-append.sh +90 -0
- package/template/.harness/scripts/env-check.sh +286 -0
- package/template/.harness/scripts/format-edit.sh +80 -0
- package/template/.harness/scripts/lint-bans.sh +110 -0
- package/template/.harness/scripts/memory-archive.sh +129 -0
- package/template/.harness/scripts/memory-recall.sh +197 -0
- package/template/.harness/scripts/memory-snapshot.sh +124 -0
- package/template/.harness/scripts/post-migration.sh +58 -0
- package/template/.harness/scripts/precommit-cycles.sh +74 -0
- package/template/.harness/scripts/precommit-typecheck.sh +69 -0
- package/template/.harness/scripts/scratchpad-recall.sh +83 -0
- package/template/.harness/scripts/scratchpad-update.sh +39 -0
- package/template/.harness/scripts/standalone-bootstrap.md +443 -0
- package/template/.harness/skills/abandon/SKILL.md +157 -0
- package/template/.harness/skills/add-anti-flag/SKILL.md +205 -0
- package/template/.harness/skills/add-constitution-clause/SKILL.md +244 -0
- package/template/.harness/skills/audit-spec/SKILL.md +395 -0
- package/template/.harness/skills/commit/SKILL.md +270 -0
- package/template/.harness/skills/constitution-edit/SKILL.md +292 -0
- package/template/.harness/skills/db-schema/SKILL.md +145 -0
- package/template/.harness/skills/db-schema/references/methodology.md +202 -0
- package/template/.harness/skills/execution-plan/SKILL.md +346 -0
- package/template/.harness/skills/feature-draft/SKILL.md +426 -0
- package/template/.harness/skills/handoff/SKILL.md +211 -0
- package/template/.harness/skills/implement/SKILL.md +355 -0
- package/template/.harness/skills/init/SKILL.md +805 -0
- package/template/.harness/skills/next/SKILL.md +245 -0
- package/template/.harness/skills/offload/SKILL.md +134 -0
- package/template/.harness/skills/pickup/SKILL.md +213 -0
- package/template/.harness/skills/recall/SKILL.md +159 -0
- package/template/.harness/skills/remember/SKILL.md +205 -0
- package/template/.harness/skills/spec-finalize/SKILL.md +196 -0
- package/template/.harness/skills/test-fix/SKILL.md +363 -0
- package/template/.harness/skills/uninstall/SKILL.md +370 -0
- package/template/.harness/state/install.json +83 -0
- package/template/AGENTS.md +262 -0
- package/template/CCC_MAGI_LICENSE +201 -0
- package/template/CCC_MAGI_README.md +986 -0
- package/template/CLAUDE.md +658 -0
- package/template/codex.md +39 -0
- package/template/constitution.md +164 -0
- package/template/course/README.md +15 -0
- package/template/course/course_code(example)/exam/README.md +2 -0
- package/template/course/course_code(example)/slide/slide_example-1.pdf +40 -0
- package/template/course/course_code(example)/slide/slide_example-2.pdf +40 -0
- package/template/docs/features/slide-query-implementation.md +79 -0
- package/template/docs/features/slide-query.md +211 -0
- package/template/docs-harness/README.md +42 -0
- package/template/docs-harness/adoption-playbook.md +373 -0
- package/template/docs-harness/ccc-step1-driver-template.md +288 -0
- package/template/docs-harness/cli-configs-README.md +78 -0
- package/template/docs-harness/context-architecture-v2.md +249 -0
- package/template/docs-harness/design-spec.md +437 -0
- package/template/docs-harness/memory-layer.md +135 -0
- package/template/docs-harness/retrospective-notes.md +204 -0
- package/template/gitignore +106 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: recall
|
|
3
|
+
description: |
|
|
4
|
+
Fetch a recall/archive memory entry by id, feature, tag, or deep query. Companion to the manifest-mode memory-recall hook — the manifest only injects index lines; this skill pulls full bodies on demand.
|
|
5
|
+
|
|
6
|
+
Trigger when:
|
|
7
|
+
- User explicitly references prior context: "上次 / 之前 / 上回 / before / previously / we decided / 之前我们定的"
|
|
8
|
+
- Current task's feature exactly matches a manifest entry's feature
|
|
9
|
+
- User says "查一下半年前 / search history / older / archive" → use --deep
|
|
10
|
+
- User invokes /recall <id>, /recall <feature|tag>, /recall --deep <query>
|
|
11
|
+
|
|
12
|
+
HARD CAPS per session (CLAUDE.md § Memory Calling Rules):
|
|
13
|
+
- ≤ 3 body fetches from Tier 2 (recall)
|
|
14
|
+
- ≤ 1 deep search from Tier 3 (archive)
|
|
15
|
+
- Do NOT fetch "for completeness". One trigger = one fetch.
|
|
16
|
+
allowed-tools: Bash(jq:*), Bash(grep:*), Bash(ls:*), Bash(cat:*), Bash(wc:*), Read
|
|
17
|
+
argument-hint: <id> | <feature|tag> | --deep <query>
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# /recall
|
|
21
|
+
|
|
22
|
+
Just-in-time memory retrieval. The SessionStart hook only shows you the **manifest** (one index line per entry). When you need a body, you call this skill explicitly.
|
|
23
|
+
|
|
24
|
+
## When to call (HARD rules)
|
|
25
|
+
|
|
26
|
+
Per `CLAUDE.md § Memory Calling Rules`, you may call `/recall` only when **one** of these is true:
|
|
27
|
+
|
|
28
|
+
1. **User explicit reference**: words like "之前 / 上次 / 上回 / before / previously / we decided / 之前定的"
|
|
29
|
+
2. **Feature exact match**: current task's feature tag matches a manifest entry's feature
|
|
30
|
+
3. **Focus overlap**: a manifest entry's `focus="..."` indicates a prior decision relevant to the action you're about to take
|
|
31
|
+
|
|
32
|
+
You may **not** call `/recall` because:
|
|
33
|
+
- "It might be useful"
|
|
34
|
+
- "For completeness"
|
|
35
|
+
- "Multiple manifest entries look interesting"
|
|
36
|
+
|
|
37
|
+
Hard caps: ≤ 3 recall-body fetches and ≤ 1 archive deep search per session.
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
### Form 1: by id (most common)
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
/recall SS-2026053001
|
|
45
|
+
/recall OBS-2026052901
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Reads `.harness/memory/sessions/recall/snapshots.jsonl` or `observations.jsonl`, locates the entry whose `id` matches, prints the full body (pretty-printed JSON).
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Internal:
|
|
52
|
+
jq -c "select(.id == \"$ID\")" .harness/memory/sessions/recall/*.jsonl
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Form 2: by feature or tag
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
/recall auth
|
|
59
|
+
/recall rls
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Lists all manifest lines in recall whose `feature == auth` OR `tags` includes `auth` (or `rls`). Output format is the same one-line manifest. User picks one, then calls `/recall <id>`.
|
|
63
|
+
|
|
64
|
+
### Form 3: deep search (archive tier)
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
/recall --deep auth
|
|
68
|
+
/recall --deep "rate limit"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Greps across `.harness/memory/sessions/archive/*.jsonl` for matching entries. Output: manifest lines, oldest visible. **Hard cap: 1 per session.**
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Internal:
|
|
75
|
+
grep -l "$QUERY" .harness/memory/sessions/archive/*.jsonl | xargs -I{} jq -r '
|
|
76
|
+
"[" + .id + "] feature=" + (.feature // "general") + " kind=" + .kind + " date=" + (.ts[0:10]) + " focus=\"" + (.focus // .summary // "")[0:80] + "\""
|
|
77
|
+
' {}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Output format
|
|
81
|
+
|
|
82
|
+
For `/recall <id>` (body fetch):
|
|
83
|
+
```
|
|
84
|
+
─── Recall: SS-2026053001 ──────────────────────────────
|
|
85
|
+
|
|
86
|
+
ts: 2026-05-30T18:30:00Z
|
|
87
|
+
kind: session-snapshot
|
|
88
|
+
feature: auth
|
|
89
|
+
focus: Resolve OTP race condition in middleware
|
|
90
|
+
next_intent:Implement advisory lock in src/auth/middleware.ts
|
|
91
|
+
|
|
92
|
+
decisions:
|
|
93
|
+
- [d-001] WHEN form submits with code, THE SYSTEM SHALL validate before navigation
|
|
94
|
+
|
|
95
|
+
open_problems:
|
|
96
|
+
- [p-001] Concurrent submissions cause double-charge (blocked_by: need DB advisory lock)
|
|
97
|
+
|
|
98
|
+
files_touched:
|
|
99
|
+
- src/auth/middleware.ts (added validation hook)
|
|
100
|
+
|
|
101
|
+
prev_session_id: SS-2026052801
|
|
102
|
+
source: handoff
|
|
103
|
+
|
|
104
|
+
─── 1/3 recall fetches used this session ───────────────
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
For `/recall <feature|tag>` (search recall):
|
|
108
|
+
```
|
|
109
|
+
Matching entries in recall tier:
|
|
110
|
+
|
|
111
|
+
[SS-2026053001] feature=auth kind=session-snapshot date=2026-05-30 focus="OTP race condition"
|
|
112
|
+
[DEC-2026052801] feature=auth kind=decision date=2026-05-28 focus="Use Supabase RLS not middleware"
|
|
113
|
+
[OBS-2026052501] feature=auth kind=observation date=2026-05-25 focus="JWT expiry causes silent logout"
|
|
114
|
+
|
|
115
|
+
To read the body: /recall <id>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
For `/recall --deep <query>` (archive):
|
|
119
|
+
```
|
|
120
|
+
Matching entries in archive tier:
|
|
121
|
+
|
|
122
|
+
[2026-03] OBS-2026031501 feature=auth focus="Old token format deprecated"
|
|
123
|
+
[2026-02] DEC-2026021001 feature=auth focus="Switch from sessions to JWT"
|
|
124
|
+
|
|
125
|
+
To read the body: /recall <id> (note: archived; fetch returns from archive)
|
|
126
|
+
|
|
127
|
+
─── Archive deep-search used this session (1/1) ──────
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Counter tracking
|
|
131
|
+
|
|
132
|
+
This skill is best-effort about cap enforcement. Maintain `.harness/state/_recall-count-<session-id>` (a 2-line file: `body_fetches:N` and `deep_searches:M`). Increment on each call. If exceeded, refuse:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
⚠️ Recall cap reached this session (3/3 body fetches).
|
|
136
|
+
Per CLAUDE.md § Memory Calling Rules, no more recall fetches this session.
|
|
137
|
+
If this is genuinely critical, ask the user to confirm an override.
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Path resolution
|
|
141
|
+
|
|
142
|
+
Always use `${CLAUDE_PROJECT_DIR:-$(pwd)}` for paths. Files live at:
|
|
143
|
+
- `.harness/memory/sessions/recall/observations.jsonl`
|
|
144
|
+
- `.harness/memory/sessions/recall/snapshots.jsonl`
|
|
145
|
+
- `.harness/memory/sessions/archive/<YYYY-MM>.jsonl`
|
|
146
|
+
|
|
147
|
+
## Trust contract
|
|
148
|
+
|
|
149
|
+
- Read-only. Never writes to memory files.
|
|
150
|
+
- Never re-summarizes or translates body content — prints `decisions`, `open_problems`, `files_touched`, `next_intent`, `focus` **verbatim** as written in the jsonl entry. The recall body is a forensic record; translating it later breaks the "AI quote vs original" audit trail (same id, different language = trust broken).
|
|
151
|
+
- Only the structural wrapper (header line "─── Recall: <id> ───", field labels like "decisions:", footer like "X/3 fetches used") translates to the user's OS locale.
|
|
152
|
+
- If the body was originally written in a non-English language (e.g., CEO's locale at handoff time), present it in that original language — do not normalize to user's current locale.
|
|
153
|
+
- Never silently fetches when caps are exceeded.
|
|
154
|
+
|
|
155
|
+
## Completion criteria
|
|
156
|
+
|
|
157
|
+
- Body fetched and printed in the format above, OR
|
|
158
|
+
- No matching entry found → tell the user, suggest `/recall --deep` if Tier 2 came up empty, OR
|
|
159
|
+
- Cap reached → refuse with explanation.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: remember
|
|
3
|
+
description: Append an observation, decision, or failure to .harness/memory/observations.jsonl for future Claude Code sessions to recall. Reads $ARGUMENTS as the summary text; asks the user to clarify kind / feature / details if missing. Trigger when the user invokes /remember, says "remember this", "note for later", "save this decision", "记一下", "记到 memory", or similar intent.
|
|
4
|
+
allowed-tools: Bash(git rev-parse:*), Bash(git branch:*), Bash(git status:*), Bash(echo:*), Bash(mkdir:*), Bash(date:*), Bash(jq:*), Bash(cat:*), Read, Edit
|
|
5
|
+
argument-hint: <summary text>
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /remember
|
|
9
|
+
|
|
10
|
+
Manually capture a decision, failure, or observation into the project's memory layer so future Claude Code sessions can recall it.
|
|
11
|
+
|
|
12
|
+
> *Companion to the automatic capture path (`PreCompaction` hook). This skill is the user-curated entry point — what the human explicitly wants persisted, not what an LLM guesses is important.*
|
|
13
|
+
|
|
14
|
+
## Language Awareness
|
|
15
|
+
|
|
16
|
+
This skill's instructions are in English. When you talk to the user (proposing values, confirming the entry), use the user's OS locale language. See `CLAUDE.md § Language Awareness`. The JSON written to `observations.jsonl` defaults to English unless the user explicitly enters non-English content; do not translate user-entered strings.
|
|
17
|
+
|
|
18
|
+
## What this skill produces
|
|
19
|
+
|
|
20
|
+
A single new line appended to `.harness/memory/observations.jsonl`:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{"ts":"2026-05-22T14:00:00Z","kind":"decision","summary":"<one-line, ≤200 chars>","details":"<optional longer text>","feature":"<name or null>","files":["..."],"tags":["..."],"source":"manual"}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If `.harness/memory/` or `observations.jsonl` doesn't exist, this skill creates them.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Step 0 — Parse `$ARGUMENTS`
|
|
31
|
+
|
|
32
|
+
Treat `$ARGUMENTS` as the proposed `summary` text. If `$ARGUMENTS` is empty, ask the user:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
What do you want to remember?
|
|
36
|
+
(One sentence, ≤200 chars. Examples:
|
|
37
|
+
- "Use Supabase RLS, not middleware — middleware p99 was 800ms"
|
|
38
|
+
- "Google Vision API too expensive at our scale; use local model"
|
|
39
|
+
- "FlashList is 5x faster than FlatList here")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Wait for user response before continuing.**
|
|
43
|
+
|
|
44
|
+
If the user-provided summary exceeds 200 chars, propose splitting: keep the first ≤200 chars in `summary`, move the rest into `details`. Ask the user to confirm or rewrite.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Step 1 — Auto-extract `feature` from current git branch
|
|
49
|
+
|
|
50
|
+
Use the same logic as `.harness/scripts/memory-recall.sh`:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then derive `FEATURE`:
|
|
57
|
+
|
|
58
|
+
- If `BRANCH` matches `feat/<name>-*` or `fix/<name>-*` → `<name>` is everything between the prefix and the first dash (or the whole rest if no dash).
|
|
59
|
+
- Else if `BRANCH` matches `<name>/...` → `<name>` is the segment before the first slash.
|
|
60
|
+
- Else `FEATURE=""` (will be written as `null` in JSON).
|
|
61
|
+
|
|
62
|
+
Example: branch `feat/auth-rls-migration` → `FEATURE=auth`.
|
|
63
|
+
Example: branch `main` → `FEATURE=""`.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Step 2 — Propose `kind` based on summary phrasing
|
|
68
|
+
|
|
69
|
+
Heuristic (case-insensitive):
|
|
70
|
+
|
|
71
|
+
| Phrase pattern in summary | Proposed kind |
|
|
72
|
+
|---------------------------|---------------|
|
|
73
|
+
| starts with "use X", "we use", "switch to", "chose", "decided" | `decision` |
|
|
74
|
+
| contains "didn't work", "failed", "broke", "too expensive", "too slow", "regression" | `failure` |
|
|
75
|
+
| anything else (general note, perf comparison, gotcha) | `observation` |
|
|
76
|
+
|
|
77
|
+
Don't over-engineer this — if it's ambiguous, default to `observation`.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Step 3 — Auto-propose `files`
|
|
82
|
+
|
|
83
|
+
Run `git status --short` in the project root. Take the first 3 modified/staged paths as the proposed `files` array. If `git status` is empty, propose `[]`.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Step 4 — Propose `tags`
|
|
88
|
+
|
|
89
|
+
Pick 1-3 short tags from the summary's key nouns. Examples:
|
|
90
|
+
|
|
91
|
+
- "Use Supabase RLS, not middleware" → `["auth", "rls", "supabase"]`
|
|
92
|
+
- "FlashList is 5x faster than FlatList here" → `["perf", "list-rendering"]`
|
|
93
|
+
|
|
94
|
+
If you can't infer meaningful tags, propose `[]`.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Step 5 — Propose `details` (optional)
|
|
99
|
+
|
|
100
|
+
If the summary is self-explanatory (e.g., "FlashList is 5x faster than FlatList here"), propose `details=""`. Otherwise propose a short rationale line that adds context the summary couldn't fit (e.g., the "why" or the measurement).
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Step 6 — Confirm the proposed entry with the user
|
|
105
|
+
|
|
106
|
+
**Path resolution**: use `${CLAUDE_PROJECT_DIR:-$(pwd)}` (not raw `$CLAUDE_PROJECT_DIR`) for all filesystem paths in this skill — the env var may be empty in some Bash subshell contexts.
|
|
107
|
+
|
|
108
|
+
Display the full proposed JSON entry in the user's locale, formatted for human reading:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
About to append this entry to .harness/memory/observations.jsonl:
|
|
112
|
+
|
|
113
|
+
ts : <ISO 8601 UTC of now>
|
|
114
|
+
kind : decision
|
|
115
|
+
summary : Use Supabase RLS, not middleware — middleware p99 was 800ms
|
|
116
|
+
details : (empty)
|
|
117
|
+
feature : auth
|
|
118
|
+
files : ["src/auth.ts", "supabase/migrations/0042_rls.sql"]
|
|
119
|
+
tags : ["auth", "rls", "supabase"]
|
|
120
|
+
source : manual
|
|
121
|
+
|
|
122
|
+
Looks right?
|
|
123
|
+
[1] Yes, append it
|
|
124
|
+
[2] Edit one or more fields
|
|
125
|
+
[3] Cancel
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Wait for user response before continuing.**
|
|
129
|
+
|
|
130
|
+
If `[2]`, ask which field(s) to edit, accept new values, re-show the confirmation. Loop until `[1]` or `[3]`.
|
|
131
|
+
|
|
132
|
+
If `[3]`, abort silently — write nothing.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Step 7 — Append to observations.jsonl
|
|
137
|
+
|
|
138
|
+
On `[1]`:
|
|
139
|
+
|
|
140
|
+
1. Ensure the directory exists:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
mkdir -p "${CLAUDE_PROJECT_DIR:-$(pwd)}/.harness/memory"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
2. Compute the ISO 8601 UTC timestamp:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
3. Build the JSON line. Prefer `jq -c -n` to avoid quoting bugs:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
ENTRY=$(jq -c -n \
|
|
156
|
+
--arg ts "$TS" \
|
|
157
|
+
--arg kind "$KIND" \
|
|
158
|
+
--arg summary "$SUMMARY" \
|
|
159
|
+
--arg details "$DETAILS" \
|
|
160
|
+
--arg feature "$FEATURE" \
|
|
161
|
+
--argjson files "$FILES_JSON" \
|
|
162
|
+
--argjson tags "$TAGS_JSON" \
|
|
163
|
+
'{ts:$ts, kind:$kind, summary:$summary, details:$details, feature:(if $feature=="" then null else $feature end), files:$files, tags:$tags, source:"manual"}')
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
4. Append:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
echo "$ENTRY" >> "${CLAUDE_PROJECT_DIR:-$(pwd)}/.harness/memory/observations.jsonl"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
5. Confirm to the user (in their locale):
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
✓ Remembered at <TS>.
|
|
176
|
+
File: .harness/memory/observations.jsonl (now <N> entries)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Trust contract
|
|
182
|
+
|
|
183
|
+
- This skill writes to **exactly one file**: `.harness/memory/observations.jsonl`.
|
|
184
|
+
- It never reads, modifies, or deletes any other project file.
|
|
185
|
+
- The entry is always `source: "manual"` (auto-capture entries use `source: "session"`).
|
|
186
|
+
- If the user cancels at Step 6, nothing is written.
|
|
187
|
+
- If `jq` is missing, surface the error and abort — do not fall back to hand-rolled JSON (quoting bugs would corrupt the file).
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Anti-patterns the skill blocks
|
|
192
|
+
|
|
193
|
+
- **Writing without user confirmation** → always show the JSON and wait for `[1]`.
|
|
194
|
+
- **Translating user-entered summary/details into English** → write what the user typed, verbatim.
|
|
195
|
+
- **Inferring `feature` from the summary text** → only the git branch is authoritative; if branch doesn't yield a feature, ask the user or use `null`.
|
|
196
|
+
- **Setting `source: "session"`** → this skill is the manual path; auto-capture is a separate mechanism.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Completion criteria
|
|
201
|
+
|
|
202
|
+
`/remember` is complete when:
|
|
203
|
+
|
|
204
|
+
- Either a single new line has been appended to `observations.jsonl` and the user has seen the confirmation message, **or**
|
|
205
|
+
- The user explicitly cancelled at Step 6 (nothing written).
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-finalize
|
|
3
|
+
description: This skill should be used at stage 2 of the feature workflow, after stage 1 has landed a CEO-confirmed plain-language spec (via /feature-draft for a new feature or /audit-spec for an existing one). It verifies the two-file model is in shape, every scenario is classified, the spec is plain-language end-to-end, marks the CEO spec FINALIZED, and runs a different-model auditor cross-check focused on integration consistency. Use this always to close stage 2 — spec errors caught here cost much less than spec errors caught during implementation. Trigger when the user invokes /spec-finalize, says "finalize the spec", "mark spec as ready", "stage 2 done", or moves from spec discussion to schema design (or to execution-plan if no backend).
|
|
4
|
+
argument-hint: [feature-name]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /spec-finalize
|
|
8
|
+
|
|
9
|
+
Drive Stage 2 of the feature workflow: confirm Stage 1's output is in shape, mark the CEO spec finalized, and run a final cross-model pass.
|
|
10
|
+
|
|
11
|
+
Stage 1 already did the heavy lifting (paraphrase + edge-case sweep + {{auditor_model}} review; in audit mode also code reading + delta reconciliation). Stage 2 is largely a formality that prevents premature finalization — it catches sloppy hand-offs from Stage 1.
|
|
12
|
+
|
|
13
|
+
## Authoritative sources
|
|
14
|
+
|
|
15
|
+
1. `{{spec_dir}}<feature>.md` — the CEO spec from Stage 1
|
|
16
|
+
2. `{{implementation_dir}}<feature>-implementation.md` — the manager-domain notes (when present)
|
|
17
|
+
3. `constitution.md` § 5 (Spec and reality stay in sync) — why this stage exists
|
|
18
|
+
4. `.harness/scripts/auditor-gate.sh` — the cross-check gate
|
|
19
|
+
5. Root `CLAUDE.md` — two-file model, lane definitions
|
|
20
|
+
6. `AGENTS.md` (root) — the auditor's standing context
|
|
21
|
+
|
|
22
|
+
## Invocation
|
|
23
|
+
|
|
24
|
+
- Typical: `/spec-finalize <feature-name>` (e.g., `/spec-finalize auth`)
|
|
25
|
+
- `$ARGUMENTS` identifies the feature; reads `{{spec_dir}}$ARGUMENTS.md`
|
|
26
|
+
|
|
27
|
+
If `$ARGUMENTS` is missing, identify the active feature from context (most recently created/edited spec under `{{spec_dir}}`). If you cannot confidently identify it, ask explicitly.
|
|
28
|
+
|
|
29
|
+
## Step 1 — Two-file shape check
|
|
30
|
+
|
|
31
|
+
Read both:
|
|
32
|
+
|
|
33
|
+
- `{{spec_dir}}<feature>.md` (must exist; this is the CEO spec)
|
|
34
|
+
- `{{implementation_dir}}<feature>-implementation.md` (may or may not exist)
|
|
35
|
+
|
|
36
|
+
Confirm the CEO spec has all required sections per the spec template:
|
|
37
|
+
|
|
38
|
+
- Status
|
|
39
|
+
- What this feature is for
|
|
40
|
+
- Happy path
|
|
41
|
+
- Edge-case behavior
|
|
42
|
+
- Who can use this
|
|
43
|
+
- External dependencies
|
|
44
|
+
- Deferred / unresolved
|
|
45
|
+
- Out of scope
|
|
46
|
+
- Decision history
|
|
47
|
+
- Audit-mode delta section (populated only for audits, empty for new-feature mode)
|
|
48
|
+
|
|
49
|
+
Then confirm:
|
|
50
|
+
|
|
51
|
+
1. The CEO spec does **not** carry a `## Open questions` section with unanswered numbered items.
|
|
52
|
+
2. The implementation file, when present, references the CEO spec at the top (`**Spec:** {{spec_dir}}<feature>.md`).
|
|
53
|
+
|
|
54
|
+
If shape is wrong, halt and surface the issue:
|
|
55
|
+
|
|
56
|
+
- Missing section → ask the user to fill it
|
|
57
|
+
- Open questions remain → halt; CEO answers, then re-invoke
|
|
58
|
+
- CEO spec contains an `#### Automated test ID` block or any `scenario-X-Y — <path>` test-mapping line → halt; the test-ID index is manager-domain and belongs in the implementation file's "Scenario → automated test map" section
|
|
59
|
+
- Implementation file missing for a complex feature → recommend producing one (not blocking; CEO can override)
|
|
60
|
+
|
|
61
|
+
**Manager-file functional requirements**: When the manager file has a "Functional requirements" section, ensure each requirement uses EARS notation per `CLAUDE.md § Two-file feature spec model > EARS notation`. The primary pattern is `WHEN [trigger] THE SYSTEM SHALL [response]`. Other variants (Ubiquitous / Unwanted / State-driven / Optional) are available — see CLAUDE.md for the full table.
|
|
62
|
+
|
|
63
|
+
If existing functional requirements in the file are in prose form, do NOT rewrite them aggressively. Surface to the user: "The manager file has N prose-style functional requirements. Convert them to EARS now (recommended for testability), or leave as-is (acceptable for legacy)?" Wait for user response before continuing.
|
|
64
|
+
|
|
65
|
+
## Step 2 — Plain-language and classification check
|
|
66
|
+
|
|
67
|
+
Skim the CEO spec for tech-term creep. Categorical bans per Constitution + CLAUDE.md "Two-file feature spec model":
|
|
68
|
+
|
|
69
|
+
- Library / framework names
|
|
70
|
+
- Code identifiers (hook / function / store / state names)
|
|
71
|
+
- File paths
|
|
72
|
+
- Backend identifiers (RPC / function / table / column names)
|
|
73
|
+
- Framework jargon (router / navigation API names, lifecycle terms)
|
|
74
|
+
- SDK error type names
|
|
75
|
+
- HTTP status codes as primary verbs
|
|
76
|
+
- Test file paths and test descriptions (e.g., `scenario-3-X — <path>/*.test.* > describe > test name`)
|
|
77
|
+
- Query key constants, payload shapes (JSON field lists), migration timestamps
|
|
78
|
+
|
|
79
|
+
Surface every match to the CEO with a plain-language replacement suggestion. The CEO confirms the rewrite or rejects ("this term is fine to keep — users see it in the UI"). Don't silently rewrite. Test-ID matches are NOT optional — they relocate to the implementation file's "Scenario → automated test map" section, no CEO confirmation needed.
|
|
80
|
+
|
|
81
|
+
Confirm every scenario in the Edge-case section has a `Classification` line — `[Required automated test]` or `[Smoke test only]`. If any classification is missing, halt and ask the CEO to classify.
|
|
82
|
+
|
|
83
|
+
## Step 3 — Mark the CEO spec FINALIZED
|
|
84
|
+
|
|
85
|
+
When shape is right, plain language is clean, and every scenario is classified, surface the proposed change to the user:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
Proposing to replace the spec's Status line with:
|
|
89
|
+
|
|
90
|
+
## Status: FINALIZED <YYYY-MM-DD>
|
|
91
|
+
|
|
92
|
+
This marks Stage 2 closure (auditable). The auditor cross-check at Step 4 follows.
|
|
93
|
+
|
|
94
|
+
Approve?
|
|
95
|
+
[a] approve
|
|
96
|
+
[b] cancel (return to drafting)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Wait for user response before continuing.**
|
|
100
|
+
|
|
101
|
+
On approval, replace the Status line with `## Status: FINALIZED <YYYY-MM-DD>` (today's date in ISO format) and write the file back. The FINALIZED line makes Stage 2 closure auditable.
|
|
102
|
+
|
|
103
|
+
## Step 4 — Auditor final cross-check
|
|
104
|
+
|
|
105
|
+
Invoke the gate:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
bash .harness/scripts/auditor-gate.sh review <feature> 2 \
|
|
109
|
+
"Review this finalized two-file feature spec. Stage 1 already ran an edge-case round with auditor external review (and in audit mode, an as-built reading and delta reconciliation). Stage 2's job is the final cross-check on the integrated artifact. Look for: spec-internal contradictions between sections (a happy path that contradicts an edge-case behavior, an external-dependency note that contradicts a scenario classification); plain-language hygiene gaps (tech terms that slipped through); scenario classification anomalies (something marked [Smoke test only] that is clearly data-correctness or security-sensitive and should be [Required automated test]); CEO-spec / implementation-notes inconsistency (a routing rule in the implementation file that doesn't match a scenario in the CEO spec); missing scenarios that subsequent Stage 5 implementers would have to invent unilaterally. Do NOT flag: writing style, section ordering, suggestions to extend scope beyond declared, opinions on technical architecture, anything that would have been caught at Stage 1 (we're past that round)." \
|
|
110
|
+
{{spec_dir}}<feature>.md
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Read the gate's exit code:
|
|
114
|
+
|
|
115
|
+
- **Exit 0 (PASS / CONCERNS / WAIVED)** — surface `✓ Stage 2 complete: spec FINALIZED; auditor cross-check advanced.` Mention any advisory items. For CONCERNS, also surface the logged warning path (`.harness/audits/concerns-*.json`) and remind the CEO to review before commit. For WAIVED, surface the `waiver_reason`. Recommend the next step (`/db-schema <feature>` if the spec implies data-layer work AND `backend_db_type` is configured, otherwise `/execution-plan <feature>`).
|
|
116
|
+
- **Exit 2 (FAIL)** — see Step 5.
|
|
117
|
+
- **Exit 1 (script error / Universal Core WAIVED rejected / missing waiver_reason / legacy verdict)** — surface stderr, halt.
|
|
118
|
+
|
|
119
|
+
## Step 5 — On FAIL
|
|
120
|
+
|
|
121
|
+
Blocking findings indicate Stage 1 left gaps a reasonable implementer could not resolve unilaterally.
|
|
122
|
+
|
|
123
|
+
1. Surface every blocking item from the auditor verbatim to the CEO.
|
|
124
|
+
2. **Roll back the FINALIZED line.** Replace `## Status: FINALIZED <date>` with `## Status: DRAFT <YYYY-MM-DD> (pending stage-2 fixes)`. The spec is not finalized after all; the rollback prevents stale-status drift.
|
|
125
|
+
3. Append the blocking findings to a `## Open questions` section as new numbered items, prefixed with `(from stage-2 auditor review)`. The CEO answers, the spec is updated, the user re-invokes `/spec-finalize`.
|
|
126
|
+
4. Halt. No silent advance.
|
|
127
|
+
|
|
128
|
+
This routes auditor findings back through the same loop the CEO used during Stage 1. The shape stays uniform: there is no separate "auditor feedback resolution" stage.
|
|
129
|
+
|
|
130
|
+
## Trust contract
|
|
131
|
+
|
|
132
|
+
- **Auditor is unconditional.** Skill cannot skip the cross-check because "the spec looks fine." (Per Constitution § 1.)
|
|
133
|
+
- **Verdict is parsed deterministically from the gate's exit code.** No prose interpretation. The four verdicts are `PASS` (advance silently), `CONCERNS` (advance with logged warning at `.harness/audits/concerns-*.json` for CEO commit-time review), `FAIL` (halt), and `WAIVED` (CEO override only; rejected by the gate if any blocking item cites Universal Core).
|
|
134
|
+
- **No silent finalize.** If the auditor returns FAIL, the FINALIZED line comes off — the spec does not retain a stale status.
|
|
135
|
+
- **Plain-language audit is enforced at Stage 2** (Step 2). Tech terms in the CEO file are caught here, not at smoke time.
|
|
136
|
+
- **Implementation file is optional** — its absence is acceptable for simple features; its presence is checked only for cross-consistency with the CEO spec.
|
|
137
|
+
|
|
138
|
+
## Completion criteria
|
|
139
|
+
|
|
140
|
+
Stage 2 is complete when:
|
|
141
|
+
|
|
142
|
+
- The two-file shape is correct (CEO spec present and well-formed; implementation file present when warranted)
|
|
143
|
+
- Every scenario in the Edge-case section is classified (`[Required automated test]` / `[Smoke test only]`)
|
|
144
|
+
- The CEO spec is plain language end-to-end
|
|
145
|
+
- `## Status: FINALIZED <date>` is present at the top of the CEO spec
|
|
146
|
+
- `.harness/scripts/auditor-gate.sh` returned exit 0 (`PASS`, `CONCERNS`, or `WAIVED`)
|
|
147
|
+
- `.harness/state/auditor-approvals/<feature>-stage2.json` exists with a non-FAIL `verdict`
|
|
148
|
+
|
|
149
|
+
Next step: `/db-schema <feature>` (if the spec implies data-layer work AND `backend_db_type` is configured) or `/execution-plan <feature>`.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Checkpoint + decision-log integration (MAGI Archivist)
|
|
154
|
+
|
|
155
|
+
After Status: FINALIZED is set and the auditor-gate passes:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
.harness/scripts/checkpoint-write.sh \
|
|
159
|
+
--feature <feature-slug> \
|
|
160
|
+
--stage 3 \
|
|
161
|
+
--stage-complete 2 \
|
|
162
|
+
--append-audit "$(jq -c '{stage:2, verdict, risk:.risk_score, at:now|todate}' .harness/state/auditor-approvals/<feature>-stage2.json)"
|
|
163
|
+
|
|
164
|
+
# If MAGI Verdict returned CONCERNS and CEO chose to advance anyway:
|
|
165
|
+
.harness/scripts/decision-log-append.sh \
|
|
166
|
+
--feature <feature-slug> --stage 2 --by "CEO" \
|
|
167
|
+
--decision "advance despite CONCERNS verdict" \
|
|
168
|
+
--evidence ".harness/audits/concerns-<feature>-stage2-<ts>.json"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Final message to CEO (natural-language, not slash-command)
|
|
174
|
+
|
|
175
|
+
After Stage 2 completes (Status: FINALIZED + auditor PASS/CONCERNS/WAIVED), display (in CEO's OS locale):
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
✅ Stage 2 完成 — <feature> 的需求已锁定
|
|
179
|
+
状态: FINALIZED
|
|
180
|
+
MAGI Verdict: <PASS/CONCERNS/WAIVED>, risk = N
|
|
181
|
+
|
|
182
|
+
接下来可以:
|
|
183
|
+
👉 「继续」/「下一步」 — 我决定走 Stage 3 (设计数据库) 还是 Stage 4 (执行计划)
|
|
184
|
+
- 如果这个功能涉及数据存储 → 我走 /db-schema
|
|
185
|
+
- 如果只改前端/逻辑 → 我直接走 /execution-plan
|
|
186
|
+
👉 「先看 verdict」 — 我把 MAGI Verdict 的发现念给你听
|
|
187
|
+
👉 「先停一下」 — 我等你
|
|
188
|
+
👉 「放弃」 — 不做这个功能了
|
|
189
|
+
|
|
190
|
+
(直接告诉我你想干嘛 — 我帮你判断走哪一支)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Decision logic for "继续":
|
|
194
|
+
- If feature spec mentions data persistence / schema / migration AND `backend_db_type` is configured → invoke `/db-schema <feature>` silently
|
|
195
|
+
- Else → invoke `/execution-plan <feature>` directly
|
|
196
|
+
- Surface your decision to CEO: *"这个功能涉及数据库,我先做 Stage 3 (设计 schema)"* — let them override if you guessed wrong.
|