@neikyun/ciel 6.10.1 → 6.11.1
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/assets/.claude/hooks/memory-engine.py +256 -0
- package/assets/commands/ciel-audit.md +42 -0
- package/assets/commands/ciel-create-skill.md +2 -2
- package/assets/commands/ciel-status.md +1 -1
- package/assets/platforms/opencode/.opencode/agents/ciel-improver.md +2 -2
- package/assets/platforms/opencode/.opencode/commands/ciel-create-skill.md +2 -2
- package/assets/platforms/opencode/.opencode/commands/ciel-memory-bootstrap.md +195 -0
- package/assets/skills/ciel/SKILL.md +2 -1
- package/assets/skills/workflow/adr-auto/SKILL.md +88 -0
- package/assets/skills/workflow/ai-failure-modes-detector/SKILL.md +180 -0
- package/assets/skills/workflow/ask-window/SKILL.md +119 -0
- package/assets/skills/workflow/avec-quoi-versioner/SKILL.md +111 -0
- package/assets/skills/workflow/ci-watcher/SKILL.md +194 -0
- package/assets/skills/workflow/critiquer-auditor/SKILL.md +135 -0
- package/assets/skills/workflow/critiquer-auditor/reference.md +134 -0
- package/assets/skills/workflow/debug-reasoning-rca/SKILL.md +174 -0
- package/assets/skills/workflow/depth-classifier/SKILL.md +118 -0
- package/assets/skills/workflow/diverge/SKILL.md +91 -0
- package/assets/skills/workflow/doc-validator-official/SKILL.md +196 -0
- package/assets/skills/workflow/evaluer-sizer/SKILL.md +112 -0
- package/assets/skills/workflow/faire-gatekeeper/SKILL.md +99 -0
- package/assets/skills/workflow/flux-narrator/SKILL.md +93 -0
- package/assets/skills/workflow/memoire/SKILL.md +198 -0
- package/assets/skills/workflow/memoire-consolidator/SKILL.md +91 -0
- package/assets/skills/workflow/meta-critiquer/SKILL.md +112 -0
- package/assets/skills/workflow/modern-patterns-checker/SKILL.md +166 -0
- package/assets/skills/workflow/pattern-fitness-check/SKILL.md +108 -0
- package/assets/skills/workflow/playwright-visual-critic/SKILL.md +98 -0
- package/assets/skills/workflow/pr-review-responder/SKILL.md +214 -0
- package/assets/skills/workflow/prouver-verifier/SKILL.md +184 -0
- package/assets/skills/workflow/prouver-verifier/reference.md +152 -0
- package/assets/skills/workflow/quoi-framer/SKILL.md +91 -0
- package/assets/skills/workflow/relire-critic/SKILL.md +99 -0
- package/assets/skills/workflow/security-regression-check/SKILL.md +86 -0
- package/assets/skills/workflow/self-consistency-verifier/SKILL.md +85 -0
- package/assets/skills/workflow/spike-mode/SKILL.md +101 -0
- package/assets/skills/workflow/stride-analyzer/SKILL.md +96 -0
- package/assets/skills/workflow/stride-analyzer/reference.md +144 -0
- package/assets/skills/workflow/test-strategy-vitest-playwright/SKILL.md +119 -0
- package/package.json +1 -1
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: memoire
|
|
3
|
+
description: Persists project knowledge in Ciel via cued-recall memory (etape 15 MEMOIRE). Captures interventions and decisions into .ciel/memory/{episodes,concepts,guards}/ with index.json mapping cues (paths, symbols, intents) to memories. Replayed automatically when matching cues fire. Replaces the legacy free-recall .ciel/learnings.md blob.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Persist Project Knowledge — Cued-Recall Memory (Ciel v6.5+)
|
|
7
|
+
|
|
8
|
+
## What this covers
|
|
9
|
+
|
|
10
|
+
How to save and retrieve project knowledge using **cued recall**: memories tagged with mechanical cues (file paths, symbols, intents) that fire automatically when those cues appear in the next task's context. The model never has to "remember to search" — the system surfaces relevant memory by mechanical match.
|
|
11
|
+
|
|
12
|
+
See `docs/adrs/0001-cued-recall-memory.md` for the full design rationale.
|
|
13
|
+
|
|
14
|
+
## Core principle
|
|
15
|
+
|
|
16
|
+
**Cued recall over free recall.** Don't ask the model "is there relevant memory?" — surface memory automatically when the context cue (file, symbol, intent) matches.
|
|
17
|
+
|
|
18
|
+
## Three persistence targets
|
|
19
|
+
|
|
20
|
+
### 1. Episodes — `.ciel/memory/episodes/<YYYY-MM-DD>-<slug>.md`
|
|
21
|
+
|
|
22
|
+
Dated events: human corrections, incidents, decisions discovered during a task.
|
|
23
|
+
|
|
24
|
+
Frontmatter:
|
|
25
|
+
```yaml
|
|
26
|
+
---
|
|
27
|
+
id: mem_012
|
|
28
|
+
title: Admin routes use admin-guard wrapper
|
|
29
|
+
languages: [typescript]
|
|
30
|
+
path_patterns:
|
|
31
|
+
- src/admin/**
|
|
32
|
+
- src/pages/admin/**
|
|
33
|
+
symbols: [AdminGuard, useAdminGuard]
|
|
34
|
+
intents: [new-route, admin]
|
|
35
|
+
captured_at: 2026-05-08T14:32:00Z
|
|
36
|
+
captured_from: user-intervention # or: incident, decision, bootstrap
|
|
37
|
+
trigger_count: 0
|
|
38
|
+
last_triggered: null
|
|
39
|
+
stale_after_days: 90
|
|
40
|
+
stale: false
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
# Admin routes use admin-guard wrapper
|
|
44
|
+
|
|
45
|
+
**Context:** when adding a route under `/admin/*`, do not use the standard
|
|
46
|
+
auth middleware. Use the project's `admin-guard` wrapper, which adds
|
|
47
|
+
audit logging and role-based checks.
|
|
48
|
+
|
|
49
|
+
**Why:** captured 2026-05-08 after the third incident where standard
|
|
50
|
+
middleware allowed read access without role check.
|
|
51
|
+
|
|
52
|
+
**How to apply:** import from `src/lib/auth/admin-guard.ts`. Wrap the
|
|
53
|
+
route handler. See `src/admin/users/page.tsx` for canonical usage.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Capture when:
|
|
57
|
+
- User corrects the model ("non, on utilise X ici")
|
|
58
|
+
- An incident is documented (build broke, prod paged, test flaked for non-obvious reason)
|
|
59
|
+
- A non-obvious decision is made (chose lib A over B because constraint C)
|
|
60
|
+
|
|
61
|
+
### 2. Concepts — `.ciel/memory/concepts/<topic>.md`
|
|
62
|
+
|
|
63
|
+
Stable conventions promoted from episodes that triggered ≥ N times. Same frontmatter, but with `captured_from: consolidation` and `promoted_from: [mem_012, mem_018]`.
|
|
64
|
+
|
|
65
|
+
Promotion rule (handled by `memoire-consolidator` skill):
|
|
66
|
+
- Episode triggered ≥ 5 times in last 60 days → candidate for promotion
|
|
67
|
+
- ≥ 2 episodes share ≥ 80% of tags + similar lesson → candidate for merge
|
|
68
|
+
|
|
69
|
+
### 3. Guards — `.ciel/memory/guards/<scope>.md`
|
|
70
|
+
|
|
71
|
+
Vigilance rules with narrow trigger scope and high-severity warnings. Same frontmatter, but with `severity: critical`. Used for:
|
|
72
|
+
- Foot-guns (commands that destroy prod)
|
|
73
|
+
- Forbidden patterns (editing a deployed migration)
|
|
74
|
+
- Mandatory checks before specific actions
|
|
75
|
+
|
|
76
|
+
## Index — `.ciel/memory/index.json`
|
|
77
|
+
|
|
78
|
+
The cue → memory mapping. Always loaded by `session-start.sh` at SessionStart.
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"version": 2,
|
|
83
|
+
"memories": {
|
|
84
|
+
"mem_012": { "title": "...", "file": "...", "languages": [...], "..." : "..." }
|
|
85
|
+
},
|
|
86
|
+
"by_path": { "src/admin/**": ["mem_012"] },
|
|
87
|
+
"by_symbol": { "AdminGuard": ["mem_012"] },
|
|
88
|
+
"by_intent": { "new-route": ["mem_012"] },
|
|
89
|
+
"by_language": { "typescript": ["mem_012"] }
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The index is rebuilt from frontmatter scans by `memoire-consolidator` whenever a memory is added/updated.
|
|
94
|
+
|
|
95
|
+
## Capture flow
|
|
96
|
+
|
|
97
|
+
1. User submits prompt
|
|
98
|
+
2. `user-prompt-submit.sh` hook scans for intervention patterns: "tu as oublié", "non en fait", "attention que", "rappelle-toi", "n'oublie pas", "wait", "stop", "non on fait plutôt", "ici on fait plutôt"
|
|
99
|
+
3. If matched → emits a context message: "INTERVENTION DETECTED — propose capture"
|
|
100
|
+
4. Model surfaces an `AskUserQuestion`: "Capture this correction as memory? [Title / Tags suggested / Skip]"
|
|
101
|
+
5. User confirms or skips
|
|
102
|
+
6. On confirm → write `.ciel/memory/episodes/<date>-<slug>.md`, update `index.json`
|
|
103
|
+
|
|
104
|
+
**Never auto-silent.** The user is the filter against cargo-cult capture.
|
|
105
|
+
|
|
106
|
+
## Recall flow
|
|
107
|
+
|
|
108
|
+
1. SessionStart or new task begins
|
|
109
|
+
2. `session-start.sh` hook reads:
|
|
110
|
+
- The user's prompt (extract keywords → intent cues)
|
|
111
|
+
- `.ciel/map.json` (current focus modules → path cues)
|
|
112
|
+
- Recently tracked files (`.ciel/tracked-files.json`) → path + symbol cues
|
|
113
|
+
3. Queries `index.json`: cues ∩ memories → candidate set
|
|
114
|
+
4. Scores by: `recency × trigger_count × tag-overlap`
|
|
115
|
+
5. Selects top-K under depth budget (Trivial 1K / Standard 3K / Critical 5K tokens)
|
|
116
|
+
6. Injects one-line previews:
|
|
117
|
+
```
|
|
118
|
+
[mem_012, fired 7×] Admin routes use admin-guard wrapper
|
|
119
|
+
[mem_007, fired 3×] Migration files are checksum-locked
|
|
120
|
+
```
|
|
121
|
+
7. Model can `Read` full content if relevant (cued exploration, not blanket dump)
|
|
122
|
+
|
|
123
|
+
## Bootstrap from existing docs
|
|
124
|
+
|
|
125
|
+
On first run, the slash command `/ciel-memory-bootstrap` ingests:
|
|
126
|
+
|
|
127
|
+
| Source | Format expected |
|
|
128
|
+
|---|---|
|
|
129
|
+
| `.ciel/learnings.md` | Legacy Ciel format with `[date] MISTAKE/RULE` entries |
|
|
130
|
+
| `.claude/lessons.md` or `lessons.md` | Same as above |
|
|
131
|
+
| `ciel-overlay.md` | "Key Lessons" section |
|
|
132
|
+
| `.claude/rules/*.md` | Each file = one rule |
|
|
133
|
+
| `AGENTS.md` | Rules sections |
|
|
134
|
+
|
|
135
|
+
Each ingested item becomes an episode with `captured_from: bootstrap`. Tags are inferred from content (file paths mentioned, symbols mentioned, language detected from imports).
|
|
136
|
+
|
|
137
|
+
If no source is found, the system reports it and waits for organic capture via interventions.
|
|
138
|
+
|
|
139
|
+
## Decay
|
|
140
|
+
|
|
141
|
+
- `last_triggered` is updated by `session-start.sh` whenever a memory is matched and injected
|
|
142
|
+
- After `stale_after_days` (default 90) without trigger → `stale: true`
|
|
143
|
+
- Stale memories excluded from auto-injection but kept on disk
|
|
144
|
+
- Skill `memoire-consolidator` periodically suggests purge or refresh
|
|
145
|
+
|
|
146
|
+
## Token budget (hard caps)
|
|
147
|
+
|
|
148
|
+
| Depth | Cap |
|
|
149
|
+
|---|---|
|
|
150
|
+
| Trivial | 1K tokens injected |
|
|
151
|
+
| Standard | 3K tokens injected |
|
|
152
|
+
| Critical | 5K tokens injected |
|
|
153
|
+
|
|
154
|
+
If candidate set exceeds cap, drop lowest-scoring entries first. Index itself is small (~50 tokens per entry); the cap concerns content previews and any auto-loaded full content.
|
|
155
|
+
|
|
156
|
+
## Common rationalizations
|
|
157
|
+
|
|
158
|
+
| Rationalization | Reality |
|
|
159
|
+
|---|---|
|
|
160
|
+
| "I'll remember this next session" | You won't. Even if you do, the next agent session won't. Capture or it's gone. |
|
|
161
|
+
| "The user corrected me, but it was obvious" | The fact that you missed it makes it non-obvious. Capture. |
|
|
162
|
+
| "All this is in CLAUDE.md already" | CLAUDE.md is loaded once and diluted by lost-in-the-middle (Liu 2023). Cued memory bypasses that. |
|
|
163
|
+
| "Capturing slows the user down" | One confirmation now vs. the same intervention next month. The math favors capture. |
|
|
164
|
+
|
|
165
|
+
## What to persist vs what to skip
|
|
166
|
+
|
|
167
|
+
PERSIST (becomes a memory):
|
|
168
|
+
- User corrections that aren't obvious from reading the code
|
|
169
|
+
- Incidents (what broke, root cause, fix that worked)
|
|
170
|
+
- Architecture decisions with their motivation
|
|
171
|
+
- Foot-guns (commands/patterns to avoid in this project)
|
|
172
|
+
- Wrappers / conventions that override library defaults
|
|
173
|
+
|
|
174
|
+
SKIP (don't pollute the corpus):
|
|
175
|
+
- The code itself (it's in git)
|
|
176
|
+
- Routine task completion ("I added a button")
|
|
177
|
+
- Anything trivially derivable by reading the file
|
|
178
|
+
- Personal style preferences (those go in `ciel-overlay.md`)
|
|
179
|
+
|
|
180
|
+
## How to verify (etape MEMOIRE)
|
|
181
|
+
|
|
182
|
+
- [ ] Did this session contain a user intervention/correction? If yes, was it captured?
|
|
183
|
+
- [ ] Did this session document a new pattern, foot-gun, or convention? If yes, episode created?
|
|
184
|
+
- [ ] Was the index.json updated by the capture flow?
|
|
185
|
+
- [ ] Are tags reasonable (paths actually exist, symbols are real)?
|
|
186
|
+
- [ ] If the same correction came up next month, would the cued recall fire? (Mental dry-run.)
|
|
187
|
+
|
|
188
|
+
## Migration from legacy `.ciel/learnings.md`
|
|
189
|
+
|
|
190
|
+
The legacy single-blob `learnings.md` is kept for backward compatibility but **deprecated**. New writes should go to `.ciel/memory/episodes/` via the capture flow. Run `/ciel-memory-bootstrap` to migrate existing entries — it parses the dated entries and converts each into an episode with inferred tags.
|
|
191
|
+
|
|
192
|
+
## Related
|
|
193
|
+
|
|
194
|
+
- `docs/adrs/0001-cued-recall-memory.md` — full design rationale and binding principles
|
|
195
|
+
- `skills/workflow/memoire-consolidator` — periodic maintenance: promote, merge, decay
|
|
196
|
+
- `commands/ciel-memory-bootstrap.md` — first-run scan + ingestion
|
|
197
|
+
- `hooks/user-prompt-submit.sh` — detects intervention patterns and proposes capture
|
|
198
|
+
- `hooks/session-start.sh` — injects matching memories at session start
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: memoire-consolidator
|
|
3
|
+
description: Periodic maintenance of .ciel/memory/ — promotes high-frequency episodes to concepts, merges duplicates, marks stale entries, rebuilds index.json. Run manually or via /ciel-improve. Keeps the cued-recall corpus from accumulating noise as projects age.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Consolidate Cued-Recall Memory
|
|
7
|
+
|
|
8
|
+
## What this covers
|
|
9
|
+
|
|
10
|
+
The corpus under `.ciel/memory/` grows over time. Without maintenance it accumulates duplicates, stale entries, and episodes that should have been promoted to stable concepts long ago. This skill is the maintenance pass.
|
|
11
|
+
|
|
12
|
+
See `skills/workflow/memoire/SKILL.md` for the capture/recall flow and `docs/adrs/0001-cued-recall-memory.md` for the full design.
|
|
13
|
+
|
|
14
|
+
## When to run
|
|
15
|
+
|
|
16
|
+
- Manually via `/ciel-improve` or direct invocation
|
|
17
|
+
- When `index.json` shows ≥ 50 episodes
|
|
18
|
+
- Quarterly on long-lived projects
|
|
19
|
+
- After any large bootstrap import (existing tribal docs ingested at once)
|
|
20
|
+
|
|
21
|
+
## Five operations
|
|
22
|
+
|
|
23
|
+
### 1. Promote frequent episodes → concepts
|
|
24
|
+
|
|
25
|
+
Criterion: episode with `trigger_count ≥ 5` AND `last_triggered` within 60 days.
|
|
26
|
+
|
|
27
|
+
Action: copy episode content to `.ciel/memory/concepts/<slug>.md`, set `captured_from: consolidation` and `promoted_from: [original_id]`. Mark original episode `superseded_by: <new_id>` and exclude from active index.
|
|
28
|
+
|
|
29
|
+
Why: concepts are stable conventions. Frequent triggers prove the rule has crystallized.
|
|
30
|
+
|
|
31
|
+
### 2. Merge similar episodes
|
|
32
|
+
|
|
33
|
+
Criterion: two or more episodes share ≥ 80% of tags AND describe the same lesson (semantic similarity, judged by reading content).
|
|
34
|
+
|
|
35
|
+
Action: create a new concept that subsumes them, mark all originals `merged_into: <concept_id>`.
|
|
36
|
+
|
|
37
|
+
Why: bootstrap or rapid capture often produces near-duplicates ("admin routes use admin-guard" + "always wrap admin in admin-guard"). Merging reduces noise without losing the signal.
|
|
38
|
+
|
|
39
|
+
### 3. Mark stale entries
|
|
40
|
+
|
|
41
|
+
Criterion: `last_triggered` is older than `stale_after_days` (default 90) OR null + `captured_at` older than 90 days.
|
|
42
|
+
|
|
43
|
+
Action: set `stale: true` in frontmatter and in `index.json`. Stale entries are excluded from auto-injection but remain on disk.
|
|
44
|
+
|
|
45
|
+
Why: untriggered memories may be obsolete (the file no longer exists, the convention changed). Auto-injecting them produces false positives.
|
|
46
|
+
|
|
47
|
+
### 4. Detect dead anchors
|
|
48
|
+
|
|
49
|
+
Criterion: a memory's `path_patterns` no longer match any file in the repo (deleted module, renamed convention).
|
|
50
|
+
|
|
51
|
+
Action: flag for human review in `.ciel/memory/review-queue.md`. Don't auto-delete — the user should decide whether the memory is obsolete or needs updated paths.
|
|
52
|
+
|
|
53
|
+
### 5. Rebuild `index.json`
|
|
54
|
+
|
|
55
|
+
Always done last. Scans all `*.md` under `.ciel/memory/{episodes,concepts,guards}/`, parses frontmatter, regenerates the cue indices (`by_path`, `by_symbol`, `by_intent`, `by_language`).
|
|
56
|
+
|
|
57
|
+
This guarantees the index never drifts from source-of-truth (the markdown files).
|
|
58
|
+
|
|
59
|
+
## Output report
|
|
60
|
+
|
|
61
|
+
After running, emit a summary:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
[memoire-consolidator] 2026-05-08
|
|
65
|
+
Promoted: 3 episodes → concepts
|
|
66
|
+
Merged: 2 episode pairs → 2 concepts
|
|
67
|
+
Stale: 7 entries flagged
|
|
68
|
+
Dead: 1 anchor needs review (see .ciel/memory/review-queue.md)
|
|
69
|
+
Index: rebuilt — 42 active memories, 9 stale, 51 total
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Anti-patterns to avoid
|
|
73
|
+
|
|
74
|
+
| Anti-pattern | Reason |
|
|
75
|
+
|---|---|
|
|
76
|
+
| Auto-deleting stale entries | User may want to revive; deletion is irreversible. Always flag, never delete. |
|
|
77
|
+
| Promoting on first trigger | One trigger isn't crystallization. Wait for repetition. |
|
|
78
|
+
| Merging without reading content | Tags may overlap by accident (two different `auth/**` rules). Read before merge. |
|
|
79
|
+
| Skipping index rebuild | Drift between index and markdown is worse than missing data — silent corruption. |
|
|
80
|
+
|
|
81
|
+
## Design principles inherited from ADR-0001
|
|
82
|
+
|
|
83
|
+
- Markdown is source of truth; index is derived
|
|
84
|
+
- User is the filter for irreversible actions (deletion, merge with conflict)
|
|
85
|
+
- Decay over accumulation: stale flag is automatic, but action on it is human
|
|
86
|
+
|
|
87
|
+
## Related skills
|
|
88
|
+
|
|
89
|
+
- `memoire` — capture/recall flow (writes the inputs this skill consumes)
|
|
90
|
+
- `meta-critiquer` — post-task reflection that may trigger consolidation if many captures occurred
|
|
91
|
+
- `learnings-capture` — older format, superseded by cued-recall memoire
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: meta-critiquer
|
|
3
|
+
description: How to reflect on completed work — 10-item post-task reflection checklist for Ciel v5. Covers depth match, failure mode detection, user corrections, stale branches, uncovered issues, context health, dead code, map update, parking lot, and boy-scout rule. Closes the feedback loop between execution and improvement.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Post-Task Reflection — 10-Item Checklist (Ciel v5)
|
|
7
|
+
|
|
8
|
+
## What this covers
|
|
9
|
+
|
|
10
|
+
How to reflect on completed work and capture learnings. In Ciel v5, this is the last pipeline step (etape 16: META). Always run after every task, even trivial ones.
|
|
11
|
+
|
|
12
|
+
## Core principle
|
|
13
|
+
|
|
14
|
+
**Always reflect, even after trivial tasks.** 30 seconds is cheap; missed reflections compound. In v5, the reflection covers not just the code but the project map, parking lot, and boy-scout rule.
|
|
15
|
+
|
|
16
|
+
## The 10 checks (v5)
|
|
17
|
+
|
|
18
|
+
### 1. Depth match?
|
|
19
|
+
|
|
20
|
+
Was the task processed at the right depth?
|
|
21
|
+
- Over-processed trivial = waste
|
|
22
|
+
- Under-processed critical = risk
|
|
23
|
+
- Wrong depth -> flag for future classifier refinement
|
|
24
|
+
|
|
25
|
+
### 2. New failure mode?
|
|
26
|
+
|
|
27
|
+
Did something go wrong that current gates didn't catch?
|
|
28
|
+
- Yes -> add a new gate immediately
|
|
29
|
+
- Capture the pattern for future reference (in .ciel/learnings.md)
|
|
30
|
+
|
|
31
|
+
### 3. User correction?
|
|
32
|
+
|
|
33
|
+
Did the user correct you during the task?
|
|
34
|
+
- Yes -> persist to .ciel/learnings.md
|
|
35
|
+
- Don't just note it -- save it so it doesn't happen again
|
|
36
|
+
|
|
37
|
+
### 4. Stale branches?
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git branch -r | wc -l
|
|
41
|
+
```
|
|
42
|
+
Excessive remote branches (> 30) -> consider cleanup of merged branches.
|
|
43
|
+
|
|
44
|
+
### 5. Uncovered issues?
|
|
45
|
+
|
|
46
|
+
Any recently closed issues with 0 comments? -> missing evidence comment -> add it now.
|
|
47
|
+
|
|
48
|
+
### 6. Context health?
|
|
49
|
+
|
|
50
|
+
After Critical task or 3+ agent dispatches: consider context compression or new session. Stacking Critical tasks in one context window degrades output quality.
|
|
51
|
+
|
|
52
|
+
### 7. Dead code sweep
|
|
53
|
+
|
|
54
|
+
Run language-specific linter:
|
|
55
|
+
- **Python**: `ruff check --select F401,F811,F841 . && vulture . --min-confidence 80`
|
|
56
|
+
- **TypeScript**: `npx knip` or manual grep for unused exports
|
|
57
|
+
- **Kotlin**: Detekt `UnusedPrivateMember` + `UnusedImport`
|
|
58
|
+
- **Go**: `go vet ./...`
|
|
59
|
+
- **Rust**: `cargo clippy -- -W unused`
|
|
60
|
+
|
|
61
|
+
### 8. Map update (v5)
|
|
62
|
+
|
|
63
|
+
Has the project map (.ciel/map.json) been updated with new modules, key files, or patterns discovered during this task?
|
|
64
|
+
- If exploration happened -> update map
|
|
65
|
+
- If new ADR was written -> reference it in map
|
|
66
|
+
|
|
67
|
+
### 9. Parking lot (v5)
|
|
68
|
+
|
|
69
|
+
Were any tangential discoveries made during the task?
|
|
70
|
+
- Yes -> note in .ciel/parking.md
|
|
71
|
+
- Don't act on them now -- just note them
|
|
72
|
+
|
|
73
|
+
### 10. Boy-scout rule (v5)
|
|
74
|
+
|
|
75
|
+
Did you leave the code better than you found it?
|
|
76
|
+
- Minor improvements count: better naming, removed dead code, added missing test, improved error message
|
|
77
|
+
- If you only modified what was required and nothing else -> acceptable but note it
|
|
78
|
+
|
|
79
|
+
## Output format
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
## REFLECTION
|
|
83
|
+
|
|
84
|
+
1. Depth match: <match | over/under-processed>
|
|
85
|
+
2. New failure mode: <none | detected>
|
|
86
|
+
3. User correction: <none | captured in .ciel/learnings.md>
|
|
87
|
+
4. Stale branches: <N branches | cleanup recommended>
|
|
88
|
+
5. Uncovered issues: <none | #N needs closure>
|
|
89
|
+
6. Context health: <N% | compact recommended>
|
|
90
|
+
7. Dead code: <0 findings | N fixed>
|
|
91
|
+
8. Map update: <up-to-date | needs update>
|
|
92
|
+
9. Parking: <none | N notes added>
|
|
93
|
+
10. Boy-scout: <improved | status quo>
|
|
94
|
+
|
|
95
|
+
### ACTION ITEMS
|
|
96
|
+
- <list or "none">
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## How to verify
|
|
100
|
+
|
|
101
|
+
- [ ] All 10 checks completed?
|
|
102
|
+
- [ ] >= 1 action item generated?
|
|
103
|
+
- [ ] User corrections captured (if any)?
|
|
104
|
+
- [ ] Stale branches flagged (if any)?
|
|
105
|
+
- [ ] Map checked for updates?
|
|
106
|
+
- [ ] Parking lot entries noted?
|
|
107
|
+
|
|
108
|
+
## Key rules
|
|
109
|
+
|
|
110
|
+
- **Always non-blocking**: reflection never blocks the commit/push
|
|
111
|
+
- **Persist, don't just report**: items 2 and 3 must trigger learnings capture
|
|
112
|
+
- **Map update (item 8) is mandatory after exploration**: without it, the next session starts with a stale map
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: modern-patterns-checker
|
|
3
|
+
description: Scans proposed or existing code for obsolete patterns that LLMs tend to reproduce from stale training data — React class components instead of hooks, sync-when-async-is-standard, callback hell, Python 2 idioms, old Go error handling, jQuery in React codebases, CommonJS in ESM projects. Flags each anti-pattern with the 2026 canonical replacement and a link to the migration note. Referenced by ThoughtWorks Technology Radar April 2026.
|
|
4
|
+
allowed-tools: Read, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# modern-patterns-checker — Don't ship 2019-era code in 2026
|
|
8
|
+
|
|
9
|
+
LLMs over-weight patterns that dominated their training set years ago. Without a guardrail, React class components, callback-based async, and sync-APIs-in-async-codebases keep leaking into new PRs. ThoughtWorks 2026 calls this "cognitive debt from AI autocompletion."
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Inputs (infer before asking — see orchestrator's Autonomy protocol)
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
CODE_UNDER_REVIEW: [file paths OR diff hunk]
|
|
17
|
+
TARGET_STACK: [language + framework + version — resolved from package manifests]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Auto-inference sources (exhaust BEFORE asking the user)
|
|
21
|
+
|
|
22
|
+
- **CODE_UNDER_REVIEW** → `git diff main...HEAD` for the branch under review; fall back to `git diff HEAD~1` for the latest commit; or the user-named file(s).
|
|
23
|
+
- **TARGET_STACK** → read `package.json` / `pyproject.toml` / `go.mod` / `Cargo.toml`; derive framework from dependencies (`react`, `vue`, `svelte`, `fastapi`, `django`, etc.). Read `tsconfig.json` / `pyproject.toml` for strictness settings. Cross-check with `ciel-overlay.md`.
|
|
24
|
+
|
|
25
|
+
Never ask the user for either. Both are deterministically inferable.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Anti-pattern catalogue (2026)
|
|
30
|
+
|
|
31
|
+
### TypeScript / JavaScript
|
|
32
|
+
|
|
33
|
+
| Anti-pattern | Canonical 2026 replacement |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `class Foo extends React.Component` | Functional component + hooks |
|
|
36
|
+
| `componentDidMount / componentDidUpdate` | `useEffect` (or Server Component for data fetching) |
|
|
37
|
+
| `.then().catch()` chains > 2 links | `async/await` with `try/catch` |
|
|
38
|
+
| `require()` in a project with `"type":"module"` | `import` (ESM) |
|
|
39
|
+
| `var` | `const` / `let` |
|
|
40
|
+
| `null`-checks everywhere | Discriminated unions + `?.` / `??` |
|
|
41
|
+
| `any` as escape hatch | `unknown` + narrowing, or proper type |
|
|
42
|
+
| `lodash.get` / `lodash.set` | Optional chaining `?.` + `??` |
|
|
43
|
+
| `fetch().then(r => r.json()).then(...)` | `await fetch()` + `await r.json()` |
|
|
44
|
+
| `moment.js` | `Temporal` API (Node 22+) or `date-fns` |
|
|
45
|
+
| Redux for local UI state | `useState` / `useReducer` / Zustand |
|
|
46
|
+
| PropTypes | TypeScript types |
|
|
47
|
+
|
|
48
|
+
### Python
|
|
49
|
+
|
|
50
|
+
| Anti-pattern | Canonical 2026 replacement |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `print` as debug | `logging` with structured fields |
|
|
53
|
+
| `%`-format or `.format()` | f-strings |
|
|
54
|
+
| `dict.has_key(k)` | `k in dict` |
|
|
55
|
+
| Nested `if` guards | Early-return pattern |
|
|
56
|
+
| Bare `except:` | `except SpecificError:` |
|
|
57
|
+
| `os.path.join` | `pathlib.Path` |
|
|
58
|
+
| Sync `requests` in async codebase | `httpx.AsyncClient` / `aiohttp` |
|
|
59
|
+
| `dataclass` without `slots=True` | `@dataclass(slots=True)` (3.10+) |
|
|
60
|
+
| `typing.List`, `typing.Dict` | Built-in `list`, `dict` (3.9+ PEP 585) |
|
|
61
|
+
| `from typing import Optional` | `X \| None` (3.10+ PEP 604) |
|
|
62
|
+
|
|
63
|
+
### Go
|
|
64
|
+
|
|
65
|
+
| Anti-pattern | Canonical 2026 replacement |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `if err != nil { return err }` without wrapping | `fmt.Errorf("context: %w", err)` |
|
|
68
|
+
| Bare `err == sql.ErrNoRows` | `errors.Is(err, sql.ErrNoRows)` |
|
|
69
|
+
| Passing request context implicitly | Explicit `ctx context.Context` first arg |
|
|
70
|
+
| `interface{}` | `any` (Go 1.18+), or typed interface |
|
|
71
|
+
| `sync.Mutex` wrapping a slice | `sync.Map` or channel |
|
|
72
|
+
|
|
73
|
+
### SQL
|
|
74
|
+
|
|
75
|
+
| Anti-pattern | Canonical 2026 replacement |
|
|
76
|
+
|---|---|
|
|
77
|
+
| String concatenation for queries | Parameterized queries / prepared statements |
|
|
78
|
+
| `SELECT *` in production queries | Explicit column list |
|
|
79
|
+
| `N+1` loop queries | JOIN or batched `IN (...)` |
|
|
80
|
+
| Missing indexes on FK | Index on every foreign key |
|
|
81
|
+
|
|
82
|
+
### React (post-19)
|
|
83
|
+
|
|
84
|
+
| Anti-pattern | Canonical 2026 replacement |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `useEffect` for data fetching | Server Components, `use()`, or TanStack Query |
|
|
87
|
+
| `useState` for derived values | `useMemo` or compute inline |
|
|
88
|
+
| Prop-drilling > 3 levels | Context, composition, or state library |
|
|
89
|
+
| Manual form state | `react-hook-form` or native `<form>` actions |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Detection method
|
|
94
|
+
|
|
95
|
+
1. **Regex pass** (fast) — grep for obvious markers: `extends Component`, `componentDidMount`, `require(`, `var `, `any`, `.then(.*).then(`, etc.
|
|
96
|
+
2. **AST pass** (accurate, optional) — if `tsc` / `ruff` / `go vet` configured in the repo, run with strict rules.
|
|
97
|
+
3. **Context pass** — read `tsconfig.json`, `pyproject.toml`, `go.mod` to confirm the stack is modern enough to allow the replacement. Don't suggest `Temporal` if Node is pinned to 18.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Report format
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
## MODERN-PATTERNS VERDICT
|
|
105
|
+
|
|
106
|
+
### Findings
|
|
107
|
+
[BLOCK] components/Profile.tsx:24 — class component
|
|
108
|
+
Replacement: functional + hooks
|
|
109
|
+
Migration: react.dev/reference/react/Component#alternatives
|
|
110
|
+
|
|
111
|
+
[WARN] lib/api.ts:55-70 — .then() chain (3 links)
|
|
112
|
+
Replacement: async/await
|
|
113
|
+
Rationale: readability + stack traces
|
|
114
|
+
|
|
115
|
+
[INFO] tests/user.test.ts:8 — `any` as escape hatch
|
|
116
|
+
Replacement: `unknown` + narrowing, or proper User type
|
|
117
|
+
Rationale: loses type safety in test-critical code
|
|
118
|
+
|
|
119
|
+
### Stack-compatibility confirmed
|
|
120
|
+
- Node: 22.3 ✓ allows Temporal
|
|
121
|
+
- TS: 5.5 ✓ allows `satisfies` operator
|
|
122
|
+
- React: 19.0.2 ✓ allows Server Components
|
|
123
|
+
|
|
124
|
+
### Summary
|
|
125
|
+
BLOCK: 1 (must fix)
|
|
126
|
+
WARN: 1 (strongly advised)
|
|
127
|
+
INFO: 1 (opportunistic)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Guardrails
|
|
133
|
+
|
|
134
|
+
- **Verify stack before recommending** — suggesting `Temporal` on Node 18 wastes a review cycle.
|
|
135
|
+
- **Don't aggregate-rewrite legacy** — flag, don't refactor wholesale. A single migration is a PR, not a silent edit.
|
|
136
|
+
- **Repo-level opt-outs respected** — if `.eslintrc` deliberately allows `var` or a deprecated pattern (grandfather clause for a legacy module), note and skip.
|
|
137
|
+
- **Citation required** — every suggestion links to the official migration doc or the MDN/React/Python guide. No link → drop the suggestion.
|
|
138
|
+
- **BLOCK only for compile-breaking or security-sensitive** — class components don't BLOCK a working PR; a missing parameterized query DOES.
|
|
139
|
+
- **Stop at 10 findings per file** — above 10, return "file needs a dedicated modernization task" rather than a linter dump.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## How to verify
|
|
144
|
+
|
|
145
|
+
- [ ] Anti-pattern catalogue checked for each language in stack?
|
|
146
|
+
- [ ] Each finding has 2026 canonical replacement?
|
|
147
|
+
- [ ] Stack compatibility confirmed?
|
|
148
|
+
- [ ] VERDICT issued (CLEAN / FINDINGS)?
|
|
149
|
+
- [ ] Migration notes provided for each finding?
|
|
150
|
+
|
|
151
|
+
## When triggered
|
|
152
|
+
|
|
153
|
+
- CODEBASE step after `explorer` reads the target files
|
|
154
|
+
- `@ciel-explorer` dispatched for PR review
|
|
155
|
+
- Before accepting LLM-generated code in a legacy codebase (high drift risk)
|
|
156
|
+
- After `@ciel-researcher` validates an API — this skill confirms the call site uses modern idioms
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## References
|
|
161
|
+
|
|
162
|
+
- ThoughtWorks Technology Radar April 2026 — "curated shared instructions" volume
|
|
163
|
+
- React 19 migration guide — react.dev/blog/2024/04/25/react-19
|
|
164
|
+
- PEP 585 / PEP 604 — Python builtin-generics + union syntax
|
|
165
|
+
- Go 1.18 — `any` alias, generics
|
|
166
|
+
- MDN Async/Await — developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pattern-fitness-check
|
|
3
|
+
description: For every existing code pattern being considered for reuse, applies a 3-question fitness check (same problem? same constraints? same volume?) before copying. Flags HUBs (high fan-in files), duplication candidates, and prior AI-generated patterns that contradict official docs. Invoked during the CODEBASE step of every Ciel task.
|
|
4
|
+
allowed-tools: Read, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# pattern-fitness-check — Don't copy patterns blindly
|
|
8
|
+
|
|
9
|
+
Part of CRÉER step 5 (CODEBASE). Pattern-matching without fitness checking is the single most common LLM coding failure (per Ciel's Guards table).
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 3-question fitness check
|
|
14
|
+
|
|
15
|
+
For EACH pattern considered for reuse, answer all 3:
|
|
16
|
+
|
|
17
|
+
1. **Same problem?** — What problem did this pattern solve originally? (git blame the commit)
|
|
18
|
+
- If the pattern was written for use case A and you're facing use case B → NOT the same problem.
|
|
19
|
+
|
|
20
|
+
2. **Same constraints?** — Volume, transport, sync/async, batch/single, cardinality
|
|
21
|
+
- Pagination pattern written for 1k items might fail at 100M items.
|
|
22
|
+
- Sync validation pattern might not fit async flow.
|
|
23
|
+
- REST pagination pattern doesn't fit WebSocket message stream.
|
|
24
|
+
|
|
25
|
+
3. **Same data shape?** — Is the input/output structure identical?
|
|
26
|
+
- Different field names → adapter needed
|
|
27
|
+
- Different nullable fields → null-safety differs
|
|
28
|
+
- Different ordering guarantees → might break downstream
|
|
29
|
+
|
|
30
|
+
→ **All yes** → APPLY. **Any no** → ADAPT or DO NOT USE.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Additional checks
|
|
35
|
+
|
|
36
|
+
### Prior AI-generated patterns
|
|
37
|
+
|
|
38
|
+
Treat existing code written during a prior AI session as a **suggestion, not law**. If it contradicts current official docs → likely an inherited anti-pattern. Flag and do not follow.
|
|
39
|
+
|
|
40
|
+
Signal: code with unusual structure, comments like `// AI-suggested` or `// TODO: verify this approach`.
|
|
41
|
+
|
|
42
|
+
### Duplication check
|
|
43
|
+
|
|
44
|
+
If 2+ copies of the pattern you're about to write ALREADY EXIST → extract a shared helper FIRST, then use it.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Find similar patterns
|
|
48
|
+
grep -rn "fun <functionName>" --include='*.kt' src/
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Mini repo-map (3 greps)
|
|
52
|
+
|
|
53
|
+
For impacted files, build a minimal map:
|
|
54
|
+
|
|
55
|
+
1. **Signatures** — `grep -n "^fun \|^class \|^interface \|^object " <file>`
|
|
56
|
+
2. **Dependents** — `grep -rln "import .*<filename>" src/`
|
|
57
|
+
3. **Hub check** — if step 2 returns 5+ files → **HUB WARNING**: changes ripple widely, proceed with caution
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Output format
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
## PATTERN FITNESS
|
|
65
|
+
|
|
66
|
+
### Patterns considered
|
|
67
|
+
- APPLY: <pattern at file:line> — same problem ✓ same constraints ✓ same shape ✓
|
|
68
|
+
- ADAPT: <pattern at file:line> — <what differs> → <how to adapt>
|
|
69
|
+
- DO NOT USE: <pattern at file:line> — <reason>
|
|
70
|
+
|
|
71
|
+
### Mini repo-map
|
|
72
|
+
- Impacted files: <list>
|
|
73
|
+
- Key signatures: <func/class at file:line>
|
|
74
|
+
- Dependents (1 hop): <list>
|
|
75
|
+
- Hub check: <NO — safe | YES — N files, changes ripple>
|
|
76
|
+
|
|
77
|
+
### Duplication check
|
|
78
|
+
- [None / Found N copies at file:line — extract helper first]
|
|
79
|
+
|
|
80
|
+
### Prior AI patterns
|
|
81
|
+
- [None / Flagged: <file:line> contradicts <doc URL> — do not follow]
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Guardrails
|
|
87
|
+
|
|
88
|
+
- **Git blame mandatory** for "same problem?" — don't rely on current code reading. Read the commit message where the pattern was introduced.
|
|
89
|
+
- **Numeric constraints**: quantify "volume" — "1k items" vs "1M items" matters. Don't say "big" or "small".
|
|
90
|
+
- **HUB threshold**: 5+ importers is the default; adjust per project size. A core util imported by 50+ files is extremely high-ripple — needs cross-team coordination.
|
|
91
|
+
- **Don't over-adapt**: if adaptation grows to > 50 lines different from the original, just write new code. Adapting is not saving effort.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## How to verify
|
|
96
|
+
|
|
97
|
+
- [ ] 3-question fitness check applied (same problem? same constraints? same volume)?
|
|
98
|
+
- [ ] Prior AI-generated patterns flagged?
|
|
99
|
+
- [ ] Duplication check performed (≥ 2 copies)?
|
|
100
|
+
- [ ] Mini repo-map generated (impacted files, key signatures, dependents)?
|
|
101
|
+
- [ ] Hub check performed (high fan-in files)?
|
|
102
|
+
|
|
103
|
+
## When triggered
|
|
104
|
+
|
|
105
|
+
- Standard/Critical tasks, during CODEBASE step
|
|
106
|
+
- Trivial tasks, if the fix is "use an existing pattern" (quickly — 1 pattern, 1 fitness check)
|
|
107
|
+
- When user says "we already have code for this" or "reuse X"
|
|
108
|
+
- When `explorer` agent identifies a candidate pattern
|