@cleocode/skills 2026.4.70 → 2026.4.72

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/skills",
3
- "version": "2026.4.70",
3
+ "version": "2026.4.72",
4
4
  "description": "CLEO skill definitions - bundled with CLEO monorepo",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -9,130 +9,6 @@ CLEO is the task management protocol for AI coding agents. It provides structure
9
9
 
10
10
  **Operation set**: 164 operations (97 query + 67 mutate) across 10 canonical domains.
11
11
 
12
- ## CLI-First Workflow
13
-
14
- CLI (`cleo` / `ct`) is the **only** dispatch method. All operations use `cleo <command>` syntax.
15
-
16
- ### Tier-0 Read Operations — Always Available
17
-
18
- | Domain | Operation | Description |
19
- |--------|-----------|-------------|
20
- | `tasks` | `show` | Get task details (`params: { taskId }`) |
21
- | `tasks` | `find` | Search tasks (`params: { query }` or `{ id }`) |
22
- | `tasks` | `next` | Auto-select highest-priority next task |
23
- | `tasks` | `plan` | Composite planning view: upcoming tasks, blockers, dependencies |
24
- | `tasks` | `current` | Show currently active (started) task |
25
- | `session` | `status` | Current session state — **mandatory first call** |
26
- | `session` | `handoff.show` | Resume prior context from last session |
27
- | `session` | `briefing.show` | Composite cold-start briefing (status + handoff combined) |
28
- | `memory` | `find` | Search brain for past observations, decisions, patterns (`params: { query }`) |
29
- | `admin` | `version` | CLEO version number |
30
- | `admin` | `health` | Installation health check |
31
- | `admin` | `dash` | Project dashboard — mandatory efficiency sequence step 2 |
32
- | `admin` | `help` | Discover available operations; use `{tier:2}` to reveal advanced ops |
33
- | `tools` | `skill.list` | List all installed agent skills |
34
- | `tools` | `provider.list` | List all known LLM/agent providers |
35
- | `tools` | `provider.detect` | Detect currently active provider |
36
-
37
- ### Tier-1 Read Operations — After Session Init
38
-
39
- | Domain | Operation | Description |
40
- |--------|-----------|-------------|
41
- | `tasks` | `list` | List direct children (`--parent <id>`) — **requires parent filter; prefer `cleo find` for discovery** |
42
- | `tasks` | `tree` | Full subtask hierarchy (`params: { taskId }`) |
43
- | `tasks` | `analyze` | Leverage-sorted task discovery |
44
- | `tasks` | `blockers` | Tasks blocking a specific task (`params: { taskId }`) |
45
- | `tasks` | `depends` | Full dependency graph for a task (`params: { taskId }`) |
46
- | `session` | `list` | List sessions (prefer `session.find` for discovery) |
47
- | `session` | `decision.log` | Recorded decisions for the current session |
48
- | `session` | `find` | Search sessions (`params: { query }`) |
49
- | `session` | `show` | Full session record (`params: { sessionId }`) |
50
- | `session` | `context.drift` | Inspect context drift during long sessions |
51
- | `memory` | `timeline` | Context around an anchor entry (`params: { anchorId }`) |
52
- | `memory` | `fetch` | Batch-fetch brain entries (`params: { ids: [...] }`) |
53
- | `memory` | `decision.find` | Search stored decisions (`params: { query, taskId? }`) |
54
- | `memory` | `pattern.find` | Search stored patterns (`params: { query, type? }`) |
55
- | `memory` | `learning.find` | Search stored learnings (`params: { query, minConfidence? }`) |
56
- | `orchestrate` | `analyze` | Dependency wave analysis (`params: { epicId }`) |
57
- | `orchestrate` | `ready` | Tasks ready to spawn (`params: { epicId }`) |
58
- | `orchestrate` | `next` | Next task suggestion (`params: { epicId }`) |
59
- | `orchestrate` | `status` | Current orchestration state |
60
- | `check` | `schema` | Validate task data schema integrity |
61
- | `check` | `protocol` | Protocol compliance for a task (`params: { taskId, protocolType? }`) |
62
- | `check` | `task` | Validate task fields (`params: { taskId }`) |
63
- | `check` | `compliance.summary` | Overall compliance summary |
64
- | `check` | `test` | Test status or coverage (`params: { format: "status" | "coverage" }`) |
65
- | `check` | `gate.status` | Lifecycle gate status |
66
- | `pipeline` | `stage.status` | Pipeline stage for epic (`params: { epicId }`) |
67
- | `pipeline` | `stage.validate` | Validate gate before advancing |
68
- | `pipeline` | `manifest.show` | Read manifest entry (`params: { id }`) |
69
- | `pipeline` | `manifest.list` | List manifest entries (`params: { filter?: "pending" }`) |
70
- | `pipeline` | `manifest.find` | Search manifest entries (`params: { query }`) |
71
- | `nexus` | `status` | Check if nexus is initialized |
72
- | `nexus` | `list` | List registered projects |
73
- | `admin` | `config.show` | Inspect current configuration |
74
- | `admin` | `adr.find` | Search architecture decision records |
75
- | `tools` | `skill.show` | Skill details (`params: { skillId }`) |
76
- | `sticky` | `list` | List sticky notes (`params: { status?, tag? }`) |
77
- | `sticky` | `show` | Show sticky details (`params: { stickyId }`) |
78
-
79
- ### Tier-0 Write Operations — Always Available
80
-
81
- | Domain | Operation | Description |
82
- |--------|-----------|-------------|
83
- | `tasks` | `add` | Create task (`params: { title, description, parentId?, status? }`) |
84
- | `tasks` | `update` | Update task (`params: { taskId, title?, status?, notes? }`) |
85
- | `tasks` | `complete` | Mark task done (`params: { taskId }`) |
86
- | `tasks` | `start` | Start working on a task (`params: { taskId }`) |
87
- | `tasks` | `stop` | Stop working on current task |
88
- | `session` | `start` | Start session (`params: { scope }`) — scope is **required** |
89
- | `session` | `end` | End session (`params: { note? }`) |
90
- | `memory` | `observe` | Save observation to brain (`params: { text, title? }`) |
91
-
92
- ### Tier-1 Write Operations — After Session Init
93
-
94
- | Domain | Operation | Description |
95
- |--------|-----------|-------------|
96
- | `tasks` | `cancel` | Cancel task (`params: { taskId }`) |
97
- | `tasks` | `archive` | Archive completed task (`params: { taskId }`) |
98
- | `tasks` | `restore` | Restore from done/archive (`params: { taskId, from: "done" \| "archive" }`) |
99
- | `tasks` | `delete` | Hard delete — irreversible (`params: { taskId }`) |
100
- | `tasks` | `reparent` | Move to different parent (`params: { taskId, newParentId }`) |
101
- | `tasks` | `reorder` | Reorder tasks within their parent (`params: { taskId, position }`) |
102
- | `session` | `resume` | Resume a prior session (`params: { sessionId }`) |
103
- | `session` | `suspend` | Pause session without ending it |
104
- | `session` | `record.decision` | Record a session decision (`params: { text, rationale }`) |
105
- | `session` | `record.assumption` | Record a session assumption (`params: { text }`) |
106
- | `admin` | `context.inject` | Inject protocol content into context (`params: { protocolType }`) — **moved from session domain** |
107
- | `memory` | `link` | Link memory entry to task (`params: { memoryId, taskId }`) |
108
- | `memory` | `decision.store` | Store structured decision (`params: { decision, rationale, taskId, alternatives? }`) |
109
- | `memory` | `pattern.store` | Store recurring pattern (`params: { name, type, impact, success, antiPattern? }`) |
110
- | `memory` | `learning.store` | Store a learning (`params: { text, confidence, taskId? }`) |
111
- | `orchestrate` | `start` | Start orchestrating an epic (`params: { epicId }`) |
112
- | `orchestrate` | `spawn` | Spawn prep for a task (`params: { taskId, skillIds? }`) |
113
- | `orchestrate` | `spawn.execute` | Execute spawn via adapter registry (`params: { taskId }`) |
114
- | `orchestrate` | `handoff` | Hand off context to subagent (`params: { taskId, context }`) |
115
- | `orchestrate` | `validate` | Pre-spawn gate check (`params: { taskId }`) |
116
- | `orchestrate` | `parallel` | Run parallel agent wave (`params: { action: "start" \| "end", waveId? }`) |
117
- | `check` | `test.run` | Run tests |
118
- | `check` | `gate.set` | Set or reset a lifecycle gate |
119
- | `pipeline` | `stage.record` | Record pipeline stage progress |
120
- | `pipeline` | `stage.gate.pass` | Pass a pipeline gate (`params: { stageId, gateId }`) |
121
- | `pipeline` | `stage.gate.fail` | Fail a gate with reason (`params: { stageId, gateId, reason }`) |
122
- | `pipeline` | `manifest.append` | Append manifest entry (`params: { entry }`) — **MANDATORY per BASE protocol** |
123
- | `pipeline` | `phase.set` | Set pipeline phase (`params: { phaseId, action: "start" \| "complete" }`) |
124
- | `pipeline` | `release.ship` | Ship a release (`params: { step? }`) |
125
- | `admin` | `config.set` | Update configuration (`params: { key, value }`) |
126
- | `tools` | `skill.install` | Install a skill (`params: { skillId }`) |
127
- | `tools` | `skill.uninstall` | Uninstall a skill (`params: { skillId }`) |
128
- | `tools` | `skill.refresh` | Bulk update all installed skills |
129
- | `sticky` | `add` | Create sticky note (`params: { content, tags?, color?, priority? }`) |
130
- | `sticky` | `convert` | Convert to task/memory (`params: { stickyId, targetType }`) |
131
- | `sticky` | `archive` | Archive sticky (`params: { stickyId }`) |
132
- | `sticky` | `purge` | Permanently delete sticky notes (`params: { stickyId }`) |
133
-
134
- ---
135
-
136
12
  ## Canonical Decision Tree
137
13
 
138
14
  Every agent MUST use this tree to select the minimum-cost operation path.
@@ -162,6 +38,22 @@ Agent starts work
162
38
 
163
39
  ---
164
40
 
41
+ ### Phase Mapping (RCASD-IVTR+C)
42
+
43
+ Each task lives in a lifecycle phase. Match your tooling to the current phase:
44
+
45
+ | Phase | When | Key Commands |
46
+ |-------|------|--------------|
47
+ | `research` | Gathering information, reading docs, exploring codebase | `cleo memory find`, `cleo docs add`, `cleo show` |
48
+ | `implement` | Writing code, making changes, building features | `cleo start`, `cleo verify`, code tools |
49
+ | `validate` | Verifying correctness, running acceptance criteria | `cleo verify <id> --run`, `cleo check gate.status` |
50
+ | `test` | Running test suites, asserting coverage | `pnpm run test`, `cleo check test` |
51
+ | `release` | Versioning, changelog, publishing | `cleo release ship`, `cleo pipeline stage.record` |
52
+
53
+ **Check current phase**: `cleo show <id>` → `pipelineStage` field.
54
+
55
+ ---
56
+
165
57
  ### Goal: Discover Work
166
58
 
167
59
  ```
@@ -200,7 +92,7 @@ I need to find what to work on
200
92
  I need to save or recall information across sessions
201
93
 
202
94
  ├── Save an observation right now (free-form)
203
- │ └── cleo observe "text" --title "title" [tier 0]
95
+ │ └── cleo memory observe "text" --title "title" [tier 0]
204
96
 
205
97
  ├── Search for something I or a prior agent observed
206
98
  │ └── cleo memory find "..." [tier 0] ← ALWAYS start here (cheap)
@@ -220,28 +112,6 @@ I need to save or recall information across sessions
220
112
 
221
113
  ---
222
114
 
223
- ### Goal: Multi-Agent Coordination
224
-
225
- ```
226
- I need to coordinate agent work (orchestrator role)
227
-
228
- ├── I am the orchestrator — start coordinating an epic
229
- │ └── cleo orchestrator start --epic {epicId} [tier 1]
230
- │ └── cleo orchestrator status [tier 1] → current orchestration state
231
-
232
- ├── Spawn a subagent for a task
233
- │ └── (1) cleo orchestrator validate {taskId} [tier 1] → pre-spawn gate check
234
- │ (2) cleo orchestrator spawn {taskId} [tier 1] → spawn prep
235
-
236
- └── I am a subagent — complete my work and report
237
- └── cleo manifest append {entry} [tier 1] ← MANDATORY per BASE protocol
238
- cleo complete {taskId} [tier 0]
239
- ```
240
-
241
- **Subagent BASE protocol**: Every subagent MUST append one entry to MANIFEST.jsonl via `pipeline.manifest.append` BEFORE calling `tasks.complete`. Omitting this is a protocol violation (exit code 62).
242
-
243
- ---
244
-
245
115
  ### Goal: Track Session Context
246
116
 
247
117
  ```
@@ -303,7 +173,215 @@ I need system or configuration info
303
173
 
304
174
  ---
305
175
 
306
- ## CLI Reference (Primary)
176
+ ## Pre-Complete Gate Ritual
177
+
178
+ MANDATORY before every `cleo complete <id>`:
179
+
180
+ 1. `cleo show <id>` — inspect gates
181
+ 2. Run each acceptance criterion verifiable (tests, lint, file checks)
182
+ 3. `cleo verify <id> --run` — executes programmatic gates
183
+ 4. `cleo memory observe "..." --title "..."` — capture learnings
184
+ 5. `cleo complete <id>` — should pass cleanly
185
+
186
+ Anti-patterns:
187
+ - `cleo complete` without `cleo verify --run`
188
+ - `cleo verify --all` to bypass programmatic gates
189
+ - Skipping memory observe on non-trivial work
190
+ - Self-attesting without programmatic proof (IVTR validate phase exists to prevent this)
191
+
192
+ ---
193
+
194
+ ## Multi-Agent Coordination
195
+
196
+ FIRST: do I have >= 5 tasks under one epic?
197
+
198
+ ```
199
+ Do I have an epic with >= 5 tasks?
200
+
201
+ ├── YES → cleo orchestrate start <epicId> (auto-inits LOOM) — MANDATORY before touching any child task
202
+ │ │
203
+ │ └── For each wave:
204
+ │ cleo orchestrate ready --epic <id> → get parallel-safe task set
205
+ │ │
206
+ │ └── For each task in wave:
207
+ │ cleo orchestrate spawn <taskId> → get resolved prompt
208
+ │ Dispatch subagent via Agent tool
209
+ │ On return: cleo manifest show <id> → read key_findings
210
+
211
+ └── NO → continue as solo executor
212
+ └── proceed through standard work loop (cleo next → cleo show → implement → cleo complete)
213
+ ```
214
+
215
+ **Gate-failure loop (IVTR)**:
216
+
217
+ ```
218
+ Task returns blocked
219
+
220
+ ├── Read failure in manifest (cleo manifest show <id>)
221
+
222
+ └── cleo orchestrate ivtr <id> --loop-back --phase implement --reason "..." → re-spawn
223
+ ├── Max 2 retries → escalate to HITL
224
+ └── Document blocker in manifest before escalating
225
+ ```
226
+
227
+ ---
228
+
229
+ ## Greenfield Bootstrap (new project)
230
+
231
+ Copy-paste sequence:
232
+
233
+ ```bash
234
+ cd /path/to/new-project
235
+ cleo init # creates .cleo/, tasks.db, brain.db
236
+ cleo session start --scope global
237
+ cleo add "Epic: <your goal>" --type epic --lifecycle auto \
238
+ --description "..." \
239
+ --acceptance "REQ-1|REQ-2|REQ-3|REQ-4|REQ-5"
240
+ EPIC_ID=$(cleo current | jq -r '.data.currentTask.id')
241
+
242
+ # Attach research/spec documents
243
+ cleo docs add $EPIC_ID ./spec.md --desc "initial spec" --labels spec
244
+
245
+ # Decompose into atomic tasks with typed gates
246
+ cleo add "Task A" --type task --parent $EPIC_ID
247
+ cleo req add <taskA-id> IMPL-01 --gate '{"kind":"test","command":"npm test","expect":"pass","description":"..."}'
248
+
249
+ # Start orchestrator — auto-inits LOOM
250
+ cleo orchestrate start $EPIC_ID
251
+
252
+ # Drive IVTR on first task
253
+ cleo orchestrate ivtr <taskA-id> --start # begins Implement phase
254
+ ```
255
+
256
+ ---
257
+
258
+ ## Reference
259
+
260
+ ### CLI-First Workflow
261
+
262
+ CLI (`cleo` / `ct`) is the **only** dispatch method. All operations use `cleo <command>` syntax.
263
+
264
+ #### Tier-0 Read Operations — Always Available
265
+
266
+ | Domain | Operation | Description |
267
+ |--------|-----------|-------------|
268
+ | `tasks` | `show` | Get task details (`params: { taskId }`) |
269
+ | `tasks` | `find` | Search tasks (`params: { query }` or `{ id }`) |
270
+ | `tasks` | `next` | Auto-select highest-priority next task |
271
+ | `tasks` | `plan` | Composite planning view: upcoming tasks, blockers, dependencies |
272
+ | `tasks` | `current` | Show currently active (started) task |
273
+ | `session` | `status` | Current session state — **mandatory first call** |
274
+ | `session` | `handoff.show` | Resume prior context from last session |
275
+ | `session` | `briefing.show` | Composite cold-start briefing (status + handoff combined) |
276
+ | `memory` | `find` | Search brain for past observations, decisions, patterns (`params: { query }`) |
277
+ | `admin` | `version` | CLEO version number |
278
+ | `admin` | `health` | Installation health check |
279
+ | `admin` | `dash` | Project dashboard — mandatory efficiency sequence step 2 |
280
+ | `admin` | `help` | Discover available operations; use `{tier:2}` to reveal advanced ops |
281
+ | `tools` | `skill.list` | List all installed agent skills |
282
+ | `tools` | `provider.list` | List all known LLM/agent providers |
283
+ | `tools` | `provider.detect` | Detect currently active provider |
284
+
285
+ #### Tier-1 Read Operations — After Session Init
286
+
287
+ | Domain | Operation | Description |
288
+ |--------|-----------|-------------|
289
+ | `tasks` | `list` | List direct children (`--parent <id>`) — **requires parent filter; prefer `cleo find` for discovery** |
290
+ | `tasks` | `tree` | Full subtask hierarchy (`params: { taskId }`) |
291
+ | `tasks` | `analyze` | Leverage-sorted task discovery |
292
+ | `tasks` | `blockers` | Tasks blocking a specific task (`params: { taskId }`) |
293
+ | `tasks` | `depends` | Full dependency graph for a task (`params: { taskId }`) |
294
+ | `session` | `list` | List sessions (prefer `session.find` for discovery) |
295
+ | `session` | `decision.log` | Recorded decisions for the current session |
296
+ | `session` | `find` | Search sessions (`params: { query }`) |
297
+ | `session` | `show` | Full session record (`params: { sessionId }`) |
298
+ | `session` | `context.drift` | Inspect context drift during long sessions |
299
+ | `memory` | `timeline` | Context around an anchor entry (`params: { anchorId }`) |
300
+ | `memory` | `fetch` | Batch-fetch brain entries (`params: { ids: [...] }`) |
301
+ | `memory` | `decision.find` | Search stored decisions (`params: { query, taskId? }`) |
302
+ | `memory` | `pattern.find` | Search stored patterns (`params: { query, type? }`) |
303
+ | `memory` | `learning.find` | Search stored learnings (`params: { query, minConfidence? }`) |
304
+ | `orchestrate` | `analyze` | Dependency wave analysis (`params: { epicId }`) |
305
+ | `orchestrate` | `ready` | Tasks ready to spawn (`params: { epicId }`) |
306
+ | `orchestrate` | `next` | Next task suggestion (`params: { epicId }`) |
307
+ | `orchestrate` | `status` | Current orchestration state |
308
+ | `check` | `schema` | Validate task data schema integrity |
309
+ | `check` | `protocol` | Protocol compliance for a task (`params: { taskId, protocolType? }`) |
310
+ | `check` | `task` | Validate task fields (`params: { taskId }`) |
311
+ | `check` | `compliance.summary` | Overall compliance summary |
312
+ | `check` | `test` | Test status or coverage (`params: { format: "status" | "coverage" }`) |
313
+ | `check` | `gate.status` | Lifecycle gate status |
314
+ | `pipeline` | `stage.status` | Pipeline stage for epic (`params: { epicId }`) |
315
+ | `pipeline` | `stage.validate` | Validate gate before advancing |
316
+ | `pipeline` | `manifest.show` | Read manifest entry (`params: { id }`) |
317
+ | `pipeline` | `manifest.list` | List manifest entries (`params: { filter?: "pending" }`) |
318
+ | `pipeline` | `manifest.find` | Search manifest entries (`params: { query }`) |
319
+ | `nexus` | `status` | Check if nexus is initialized |
320
+ | `nexus` | `list` | List registered projects |
321
+ | `admin` | `config.show` | Inspect current configuration |
322
+ | `admin` | `adr.find` | Search architecture decision records |
323
+ | `tools` | `skill.show` | Skill details (`params: { skillId }`) |
324
+ | `sticky` | `list` | List sticky notes (`params: { status?, tag? }`) |
325
+ | `sticky` | `show` | Show sticky details (`params: { stickyId }`) |
326
+
327
+ #### Tier-0 Write Operations — Always Available
328
+
329
+ | Domain | Operation | Description |
330
+ |--------|-----------|-------------|
331
+ | `tasks` | `add` | Create task (`params: { title, description, parentId?, status? }`) |
332
+ | `tasks` | `update` | Update task (`params: { taskId, title?, status?, notes? }`) |
333
+ | `tasks` | `complete` | Mark task done (`params: { taskId }`) |
334
+ | `tasks` | `start` | Start working on a task (`params: { taskId }`) |
335
+ | `tasks` | `stop` | Stop working on current task |
336
+ | `session` | `start` | Start session (`params: { scope }`) — scope is **required** |
337
+ | `session` | `end` | End session (`params: { note? }`) |
338
+ | `memory` | `observe` | Save observation to brain (`params: { text, title? }`) |
339
+
340
+ #### Tier-1 Write Operations — After Session Init
341
+
342
+ | Domain | Operation | Description |
343
+ |--------|-----------|-------------|
344
+ | `tasks` | `cancel` | Cancel task (`params: { taskId }`) |
345
+ | `tasks` | `archive` | Archive completed task (`params: { taskId }`) |
346
+ | `tasks` | `restore` | Restore from done/archive (`params: { taskId, from: "done" \| "archive" }`) |
347
+ | `tasks` | `delete` | Hard delete — irreversible (`params: { taskId }`) |
348
+ | `tasks` | `reparent` | Move to different parent (`params: { taskId, newParentId }`) |
349
+ | `tasks` | `reorder` | Reorder tasks within their parent (`params: { taskId, position }`) |
350
+ | `session` | `resume` | Resume a prior session (`params: { sessionId }`) |
351
+ | `session` | `suspend` | Pause session without ending it |
352
+ | `session` | `record.decision` | Record a session decision (`params: { text, rationale }`) |
353
+ | `session` | `record.assumption` | Record a session assumption (`params: { text }`) |
354
+ | `admin` | `context.inject` | Inject protocol content into context (`params: { protocolType }`) — **moved from session domain** |
355
+ | `memory` | `link` | Link memory entry to task (`params: { memoryId, taskId }`) |
356
+ | `memory` | `decision.store` | Store structured decision (`params: { decision, rationale, taskId, alternatives? }`) |
357
+ | `memory` | `pattern.store` | Store recurring pattern (`params: { name, type, impact, success, antiPattern? }`) |
358
+ | `memory` | `learning.store` | Store a learning (`params: { text, confidence, taskId? }`) |
359
+ | `orchestrate` | `start` | Start orchestrating an epic (`params: { epicId }`) |
360
+ | `orchestrate` | `spawn` | Spawn prep for a task (`params: { taskId, skillIds? }`) |
361
+ | `orchestrate` | `spawn.execute` | Execute spawn via adapter registry (`params: { taskId }`) |
362
+ | `orchestrate` | `handoff` | Hand off context to subagent (`params: { taskId, context }`) |
363
+ | `orchestrate` | `validate` | Pre-spawn gate check (`params: { taskId }`) |
364
+ | `orchestrate` | `parallel` | Run parallel agent wave (`params: { action: "start" \| "end", waveId? }`) |
365
+ | `check` | `test.run` | Run tests |
366
+ | `check` | `gate.set` | Set or reset a lifecycle gate |
367
+ | `pipeline` | `stage.record` | Record pipeline stage progress |
368
+ | `pipeline` | `stage.gate.pass` | Pass a pipeline gate (`params: { stageId, gateId }`) |
369
+ | `pipeline` | `stage.gate.fail` | Fail a gate with reason (`params: { stageId, gateId, reason }`) |
370
+ | `pipeline` | `manifest.append` | Append manifest entry (`params: { entry }`) — **MANDATORY per BASE protocol** |
371
+ | `pipeline` | `phase.set` | Set pipeline phase (`params: { phaseId, action: "start" \| "complete" }`) |
372
+ | `pipeline` | `release.ship` | Ship a release (`params: { step? }`) |
373
+ | `admin` | `config.set` | Update configuration (`params: { key, value }`) |
374
+ | `tools` | `skill.install` | Install a skill (`params: { skillId }`) |
375
+ | `tools` | `skill.uninstall` | Uninstall a skill (`params: { skillId }`) |
376
+ | `tools` | `skill.refresh` | Bulk update all installed skills |
377
+ | `sticky` | `add` | Create sticky note (`params: { content, tags?, color?, priority? }`) |
378
+ | `sticky` | `convert` | Convert to task/memory (`params: { stickyId, targetType }`) |
379
+ | `sticky` | `archive` | Archive sticky (`params: { stickyId }`) |
380
+ | `sticky` | `purge` | Permanently delete sticky notes (`params: { stickyId }`) |
381
+
382
+ ---
383
+
384
+ ### CLI Reference (Primary)
307
385
 
308
386
  Use `ct` (alias for `cleo`) as the interface. CLI is the only dispatch method.
309
387
 
@@ -323,7 +401,7 @@ ct sticky show SN-001 # Show sticky details
323
401
 
324
402
  ---
325
403
 
326
- ## Task Discovery (Context Efficiency)
404
+ ### Task Discovery (Context Efficiency)
327
405
 
328
406
  **MUST** use efficient commands — `find` for discovery, `show` for details:
329
407
 
@@ -331,7 +409,7 @@ ct sticky show SN-001 # Show sticky details
331
409
  - `find` returns minimal fields only (99% less context)
332
410
  - Use `show` only when you need full details for a specific task
333
411
 
334
- ### Context Bloat Anti-Patterns
412
+ #### Context Bloat Anti-Patterns
335
413
 
336
414
  | Anti-Pattern | Token Cost | Efficient Alternative | Savings |
337
415
  |-------------|-----------|----------------------|---------|
@@ -344,7 +422,7 @@ ct sticky show SN-001 # Show sticky details
344
422
 
345
423
  ---
346
424
 
347
- ## Anti-Pattern Reference
425
+ ### Anti-Pattern Reference
348
426
 
349
427
  | Bad Pattern | Correct Pattern | Why |
350
428
  |-------------|----------------|-----|
@@ -365,10 +443,11 @@ ct sticky show SN-001 # Show sticky details
365
443
  | `memory.fetch` without `memory.find` | `memory.find` → filter → `memory.fetch` | fetch without filter returns everything |
366
444
  | Completing task without manifest append | `pipeline.manifest.append` then `tasks.complete` | BASE protocol violation (exit 62) |
367
445
  | Skipping `session.status` at start | Always check `session.status` first | loses prior context, causes duplicate work |
446
+ | `cleo observe` | `cleo memory observe` | observe is not a top-level command |
368
447
 
369
448
  ---
370
449
 
371
- ## Progressive Disclosure
450
+ ### Progressive Disclosure
372
451
 
373
452
  Load only what you need. Escalate tiers when the task demands it:
374
453
 
@@ -391,11 +470,11 @@ Load only what you need. Escalate tiers when the task demands it:
391
470
 
392
471
  ---
393
472
 
394
- ## Session Protocol
473
+ ### Session Protocol
395
474
 
396
475
  Sessions track work context across agent interactions.
397
476
 
398
- ### Quick Start
477
+ #### Quick Start
399
478
 
400
479
  ```bash
401
480
  # 1. CHECK session state first (always)
@@ -416,7 +495,7 @@ ct session end
416
495
 
417
496
  ---
418
497
 
419
- ## Error Handling
498
+ ### Error Handling
420
499
 
421
500
  **CRITICAL: NEVER ignore exit codes. Failed commands = tasks NOT created/updated.**
422
501
 
@@ -436,13 +515,13 @@ After EVERY command:
436
515
 
437
516
  ---
438
517
 
439
- ## RCASD-IVTR+C Lifecycle (LOOM)
518
+ ### RCASD-IVTR+C Lifecycle (LOOM)
440
519
 
441
520
  **LOOM** (Logical Order of Operations Methodology) is the systematic framework for how CLEO processes project threads through the RCASD-IVTR+C pipeline. See `docs/concepts/CLEO-VISION.md` for the complete LOOM framework.
442
521
 
443
522
  **Lifecycle**: See `references/loom-lifecycle.md` for gate enforcement and subagent architecture.
444
523
 
445
- ## Pipeline Awareness
524
+ ### Pipeline Awareness
446
525
 
447
526
  Epics follow the RCASD-IVTR+C lifecycle managed through pipeline stages. Use `pipeline.stage.status` to check where an epic is in its lifecycle:
448
527
 
@@ -461,7 +540,7 @@ Epics follow the RCASD-IVTR+C lifecycle managed through pipeline stages. Use `pi
461
540
 
462
541
  ---
463
542
 
464
- ## Time Estimates Prohibited
543
+ ### Time Estimates Prohibited
465
544
 
466
545
  - **MUST NOT** estimate hours, days, weeks, or temporal duration
467
546
  - **MUST** use relative sizing: `small` / `medium` / `large`
@@ -469,7 +548,7 @@ Epics follow the RCASD-IVTR+C lifecycle managed through pipeline stages. Use `pi
469
548
 
470
549
  ---
471
550
 
472
- ## References
551
+ ### Further Reading
473
552
 
474
553
  For detailed guidance on specific topics, see:
475
554
 
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Regression tests for ct-cleo/SKILL.md (SKILL-14).
3
+ *
4
+ * Asserts that all required protocol markers are present in the skill file,
5
+ * protecting against content drift as the file evolves.
6
+ *
7
+ * Checks:
8
+ * - Required section markers exist: Decision Tree, Pre-Complete Gate Ritual,
9
+ * Multi-Agent Coordination, Greenfield Bootstrap
10
+ * - `cleo memory observe` is used (not the deprecated bare `cleo observe`)
11
+ * - `cleo orchestrate ivtr` is referenced at least once
12
+ * - At least 4 distinct `cleo <verb>` command patterns exist
13
+ *
14
+ * @task T808
15
+ * @skill-version SKILL-14
16
+ */
17
+
18
+ import { readFileSync } from 'node:fs';
19
+ import { dirname, join, resolve } from 'node:path';
20
+ import { fileURLToPath } from 'node:url';
21
+ import { describe, expect, it } from 'vitest';
22
+
23
+ // ---------------------------------------------------------------------------
24
+ // Setup
25
+ // ---------------------------------------------------------------------------
26
+
27
+ const thisFile = fileURLToPath(import.meta.url);
28
+
29
+ /** Absolute path to the ct-cleo skill root directory */
30
+ const skillRoot = resolve(dirname(thisFile), '..');
31
+
32
+ /** Full path to the SKILL.md file under test */
33
+ const skillPath = join(skillRoot, 'SKILL.md');
34
+
35
+ /** Read once — all assertions operate on this string */
36
+ const skillContent = readFileSync(skillPath, 'utf-8');
37
+
38
+ // ---------------------------------------------------------------------------
39
+ // Required section markers (SKILL-10 through SKILL-13)
40
+ // ---------------------------------------------------------------------------
41
+
42
+ describe('ct-cleo SKILL.md — required section markers', () => {
43
+ it('contains "Decision Tree" section', () => {
44
+ expect(skillContent).toContain('Decision Tree');
45
+ });
46
+
47
+ it('contains "Pre-Complete Gate Ritual" section', () => {
48
+ expect(skillContent).toContain('Pre-Complete Gate Ritual');
49
+ });
50
+
51
+ it('contains "Multi-Agent Coordination" section', () => {
52
+ expect(skillContent).toContain('Multi-Agent Coordination');
53
+ });
54
+
55
+ it('contains "Greenfield Bootstrap" section', () => {
56
+ expect(skillContent).toContain('Greenfield Bootstrap');
57
+ });
58
+
59
+ it('Decision Tree is the first H2 heading', () => {
60
+ // Find the position of the first H2 (## ...) after the frontmatter
61
+ const afterFrontmatter = skillContent.replace(/^---[\s\S]*?---\n/, '');
62
+ const firstH2Match = /^## (.+)$/m.exec(afterFrontmatter);
63
+ expect(firstH2Match).not.toBeNull();
64
+ expect(firstH2Match![1]).toContain('Decision Tree');
65
+ });
66
+ });
67
+
68
+ // ---------------------------------------------------------------------------
69
+ // Command usage correctness (SKILL-11 / SKILL-12)
70
+ // ---------------------------------------------------------------------------
71
+
72
+ describe('ct-cleo SKILL.md — command correctness', () => {
73
+ it('uses "cleo memory observe" not bare "cleo observe" for memory writes', () => {
74
+ // Must contain the correct form
75
+ expect(skillContent).toContain('cleo memory observe');
76
+
77
+ // The bare `cleo observe` form should only appear as a deprecated anti-pattern
78
+ // in a table row (prefixed with `| `), never as an instruction to execute.
79
+ // Count bare `cleo observe` occurrences that are NOT inside table pipe columns.
80
+ const lines = skillContent.split('\n');
81
+ const badLines = lines.filter((line) => {
82
+ // Skip table rows — those document deprecated patterns intentionally
83
+ if (/^\s*\|/.test(line)) return false;
84
+ // Skip comment-style lines and code-block lines showing anti-patterns
85
+ return /\bcleo observe\b/.test(line);
86
+ });
87
+ expect(badLines).toHaveLength(0);
88
+ });
89
+
90
+ it('references "cleo orchestrate ivtr" at least once', () => {
91
+ expect(skillContent).toMatch(/cleo orchestrate ivtr/);
92
+ });
93
+ });
94
+
95
+ // ---------------------------------------------------------------------------
96
+ // Command diversity — at least 4 distinct cleo <verb> patterns
97
+ // ---------------------------------------------------------------------------
98
+
99
+ describe('ct-cleo SKILL.md — command diversity', () => {
100
+ it('contains at least 4 distinct "cleo <verb>" command patterns', () => {
101
+ // Extract all `cleo <word>` patterns (first word after cleo)
102
+ const verbs = new Set<string>();
103
+ const pattern = /\bcleo\s+([a-z][a-z0-9-]*)/g;
104
+ let match: RegExpExecArray | null;
105
+
106
+ // eslint-disable-next-line no-cond-assign
107
+ while ((match = pattern.exec(skillContent)) !== null) {
108
+ verbs.add(match[1]);
109
+ }
110
+
111
+ expect(verbs.size).toBeGreaterThanOrEqual(4);
112
+ });
113
+ });
114
+
115
+ // ---------------------------------------------------------------------------
116
+ // Phase mapping (SKILL-10 enhancement)
117
+ // ---------------------------------------------------------------------------
118
+
119
+ describe('ct-cleo SKILL.md — phase mapping', () => {
120
+ it('includes phase mapping for research phase', () => {
121
+ expect(skillContent).toContain('research');
122
+ });
123
+
124
+ it('includes phase mapping for implement phase', () => {
125
+ expect(skillContent).toMatch(/implement/i);
126
+ });
127
+
128
+ it('includes phase mapping for validate phase', () => {
129
+ expect(skillContent).toMatch(/validate|validation/i);
130
+ });
131
+
132
+ it('includes phase mapping for test phase', () => {
133
+ expect(skillContent).toMatch(/\btest\b/i);
134
+ });
135
+
136
+ it('includes phase mapping for release phase', () => {
137
+ expect(skillContent).toContain('release');
138
+ });
139
+ });