@cleocode/skills 2026.4.15 → 2026.4.16

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.15",
3
+ "version": "2026.4.16",
4
4
  "description": "CLEO skill definitions - bundled with CLEO monorepo",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -1,7 +1,21 @@
1
1
  ---
2
2
  name: ct-grade
3
- description: Session grading for agent behavioral analysis. Use when evaluating agent session quality, running grade scenarios, or interpreting grade results. Triggers on grading tasks, session quality checks, or behavioral analysis needs.
4
- version: 1.0.0
3
+ description: >-
4
+ CLEO session grading and A/B behavioral analysis with token tracking. Evaluates agent
5
+ session quality via a 5-dimension rubric (S1 session discipline, S2 discovery efficiency,
6
+ S3 task hygiene, S4 error protocol, S5 progressive disclosure). Supports three modes:
7
+ (1) scenario — run playbook scenarios S1-S5 via CLI; (2) ab — blind A/B
8
+ comparison of different CLI configurations for same domain operations with token cost
9
+ measurement; (3) blind — spawn two agents with different configurations, blind-comparator
10
+ picks winner, analyzer produces recommendation. Use when grading agent sessions, running
11
+ grade playbook scenarios, comparing behavioral differences, measuring token
12
+ usage across configurations, or performing multi-run blind A/B evaluation with statistical
13
+ analysis and comparative report. Triggers on: grade session, evaluate agent behavior,
14
+ A/B test CLEO configurations, run grade scenario, token usage analysis, behavioral rubric,
15
+ protocol compliance scoring.
16
+ version: 2.1.0
17
+ argument-hint: "[mode=scenario|ab|blind] [scenario=s1-s5|all] [runs=N] [session-id=<id>]"
18
+ allowed-tools: ["Bash(python *)", "Bash(cleo-dev *)", "Bash(cleo *)", "Bash(kill *)", "Bash(lsof *)", "Agent", "Read", "Write", "Glob"]
5
19
  tier: 2
6
20
  core: false
7
21
  category: quality
@@ -0,0 +1,28 @@
1
+ ---
2
+ # MIGRATION NOTICE — ct-grade-v2-1
3
+
4
+ This directory is a **decommissioned staging copy** of `ct-grade` v2.1.
5
+
6
+ ## Status
7
+
8
+ **Superseded.** All content has been merged into `packages/skills/skills/ct-grade/`.
9
+
10
+ ## What Changed (T429 skill dedupe)
11
+
12
+ - `ct-grade-v2-1/SKILL.md` description, `argument-hint`, `allowed-tools`, and version
13
+ (2.1.0) were promoted into `ct-grade/SKILL.md`.
14
+ - `ct-grade-v2-1/manifest-entry.json` remains here as an archived snapshot; the
15
+ canonical manifest entry lives in `packages/skills/skills/manifest.json` under name
16
+ `ct-grade`.
17
+ - The `grade-viewer/` tooling in this directory was already reachable from `ct-grade/`
18
+ via its `agents/` and `evals/` directories. No content was lost.
19
+
20
+ ## Migration Date
21
+
22
+ 2026-04-08 — T429 hygiene wave, epic T382.
23
+
24
+ ## Action Required
25
+
26
+ None. Do NOT load this skill. Use `ct-grade` instead.
27
+ If you need the A/B or blind-compare modes documented here, they are now part of
28
+ `ct-grade`'s SKILL.md description and invocation modes.
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: ct-master-tac
3
+ description: >-
4
+ Master Tactical Bundle for CleoOS autonomous execution. Installs the complete
5
+ primitive library needed to run the full agentic execution layer on a fresh CleoOS
6
+ install: 12 CANT protocol files (research, consensus, architecture-decision,
7
+ specification, decomposition, implementation, validation, testing, contribution,
8
+ release, artifact-publish, provenance), the canonical platform team definition, and
9
+ the skills manifest entry. Use when bootstrapping a new CleoOS project, verifying that
10
+ all protocol primitives are present, or recovering a broken protocol tree. Triggers on:
11
+ "install master tac", "bootstrap protocols", "tools.skill.install ct-master-tac",
12
+ "verify protocol bundle", "repair protocol files", "fresh CleoOS install".
13
+ version: 1.0.0
14
+ tier: 1
15
+ core: false
16
+ category: meta
17
+ protocol: null
18
+ argument-hint: "[--verify] [--force]"
19
+ allowed-tools: ["Read", "Write", "Bash(cp *)", "Bash(ls *)", "Bash(mkdir *)", "Bash(test *)"]
20
+ dependencies:
21
+ - ct-cleo
22
+ sharedResources:
23
+ - subagent-protocol-base
24
+ compatibility:
25
+ - claude-code
26
+ - cursor
27
+ - windsurf
28
+ - gemini-cli
29
+ license: MIT
30
+ install-hook: "tools.skill.install ct-master-tac"
31
+ ---
32
+
33
+ # ct-master-tac — Master Tactical Bundle
34
+
35
+ > **Provenance**: @task T430, @epic T382, @umbrella T377
36
+ > **Bundle version**: 1.0.0 — ships with CleoOS v2026.4.x
37
+
38
+ The Master TAC (Tactical Asset Cache) plugin bundles every protocol primitive the
39
+ autonomous execution layer requires. After `tools.skill.install ct-master-tac`, a
40
+ fresh CleoOS install has batteries-included support for the full RCASD-IVTR+C
41
+ lifecycle.
42
+
43
+ ---
44
+
45
+ ## What's Inside
46
+
47
+ ### 12 CANT Protocol Files (`bundled/protocols/`)
48
+
49
+ | File | ID | Stage | Skill |
50
+ |------|----|-------|-------|
51
+ | `research.cant` | RSCH | research | ct-research-agent |
52
+ | `consensus.cant` | CONS | consensus | ct-consensus-voter |
53
+ | `architecture-decision.cant` | ADR | architecture-decision | ct-adr-recorder |
54
+ | `specification.cant` | SPEC | specification | ct-spec-writer |
55
+ | `decomposition.cant` | DCMP | decomposition | ct-epic-architect |
56
+ | `implementation.cant` | IMPL | implementation | ct-task-executor |
57
+ | `validation.cant` | VALID | validation | ct-validator |
58
+ | `testing.cant` | TEST | testing | ct-ivt-looper |
59
+ | `contribution.cant` | CONT | cross-cutting | ct-contribution |
60
+ | `release.cant` | REL | release | ct-release-orchestrator |
61
+ | `artifact-publish.cant` | ART | release | ct-artifact-publisher |
62
+ | `provenance.cant` | PROV | release | ct-provenance-keeper |
63
+
64
+ ### Platform Team (`bundled/teams/platform.cant`)
65
+
66
+ Canonical 3-tier team definition with planning-lead, engineering-lead, and
67
+ validation-lead. Mirrors the `.cleo/teams.cant` seed from a standard CleoOS init.
68
+
69
+ ---
70
+
71
+ ## Install Behaviour
72
+
73
+ ```bash
74
+ tools.skill.install ct-master-tac
75
+ ```
76
+
77
+ The install hook:
78
+
79
+ 1. Copies `bundled/protocols/*.cant` to
80
+ `packages/core/src/validation/protocols/cant/` (skips files that already exist
81
+ unless `--force` is provided).
82
+ 2. Copies `bundled/teams/platform.cant` to `.cleo/teams.cant` (skips if exists).
83
+ 3. Verifies that all 12 protocol files are present and parseable.
84
+ 4. Emits an install summary to stdout.
85
+
86
+ Running install a second time is a no-op (idempotent).
87
+
88
+ ---
89
+
90
+ ## Verify Mode
91
+
92
+ ```bash
93
+ tools.skill.install ct-master-tac --verify
94
+ ```
95
+
96
+ Read-only. Checks that all bundled files are present at their target locations and
97
+ reports any missing or mismatched files without writing anything.
98
+
99
+ ---
100
+
101
+ ## Plugin Boundary (§11 criteria)
102
+
103
+ This plugin meets all three §11 criteria from `docs/specs/CLEO-OPERATION-CONSTITUTION.md`:
104
+
105
+ - **(a)** Requires reading protocol CANT files managed outside the core CLI binary.
106
+ - **(b)** Reads `bundled/` assets not managed by the CLEO core package.
107
+ - **(c)** Removing it from core does not break any mandatory agent workflow — it is
108
+ a bootstrap/recovery utility only.
109
+
110
+ ---
111
+
112
+ ## Upgrade Path
113
+
114
+ When new protocol files are added, bump `version` in this SKILL.md and
115
+ `manifest.json`, add the new `.cant` file to `bundled/protocols/`, and update the
116
+ `manifest.json` `files` array. The install hook will copy the new file on next run.
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Install verification tests for the ct-master-tac plugin (T431).
3
+ *
4
+ * Asserts:
5
+ * - SKILL.md has valid YAML frontmatter
6
+ * - manifest.json parses correctly and references the correct files
7
+ * - All files referenced in manifest.json `files` array exist under bundled/
8
+ * - Install is idempotent (second run produces no additional writes)
9
+ * - Bundle contains exactly 12 protocol files + 1 platform team file
10
+ *
11
+ * @task T431
12
+ * @epic T382
13
+ * @umbrella T377
14
+ */
15
+
16
+ import { existsSync, readFileSync } from 'node:fs';
17
+ import { dirname, join, resolve } from 'node:path';
18
+ import { fileURLToPath } from 'node:url';
19
+ import { describe, expect, it } from 'vitest';
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // Helpers
23
+ // ---------------------------------------------------------------------------
24
+
25
+ const thisFile = fileURLToPath(import.meta.url);
26
+ /** Absolute path to the ct-master-tac root directory */
27
+ const skillRoot = resolve(dirname(thisFile), '..');
28
+
29
+ /**
30
+ * Parse YAML frontmatter from a Markdown file.
31
+ * Returns the raw frontmatter string between the opening and closing `---`.
32
+ */
33
+ function extractFrontmatter(content: string): string | null {
34
+ const match = /^---\r?\n([\s\S]*?)\r?\n---/m.exec(content);
35
+ return match ? match[1] : null;
36
+ }
37
+
38
+ /**
39
+ * Minimal frontmatter key extractor — no external deps, just key: value lines.
40
+ */
41
+ function parseFrontmatterKeys(fm: string): Record<string, string> {
42
+ const result: Record<string, string> = {};
43
+ for (const line of fm.split('\n')) {
44
+ const m = /^(\w[\w-]*):\s*(.*)$/.exec(line.trimEnd());
45
+ if (m) {
46
+ result[m[1]] = m[2].replace(/^["']|["']$/g, '');
47
+ }
48
+ }
49
+ return result;
50
+ }
51
+
52
+ // ---------------------------------------------------------------------------
53
+ // Mock install helper for idempotency test
54
+ // ---------------------------------------------------------------------------
55
+
56
+ interface InstallResult {
57
+ copiedFiles: string[];
58
+ skippedFiles: string[];
59
+ }
60
+
61
+ /**
62
+ * Simulated install helper — copies bundled/ files to target paths.
63
+ * Returns lists of copied and skipped files so idempotency can be verified.
64
+ */
65
+ function mockInstall(
66
+ manifestFiles: string[],
67
+ alreadyInstalled: Set<string>,
68
+ ): InstallResult {
69
+ const copiedFiles: string[] = [];
70
+ const skippedFiles: string[] = [];
71
+
72
+ for (const f of manifestFiles) {
73
+ if (alreadyInstalled.has(f)) {
74
+ skippedFiles.push(f);
75
+ } else {
76
+ copiedFiles.push(f);
77
+ }
78
+ }
79
+
80
+ return { copiedFiles, skippedFiles };
81
+ }
82
+
83
+ // ---------------------------------------------------------------------------
84
+ // Tests
85
+ // ---------------------------------------------------------------------------
86
+
87
+ describe('ct-master-tac plugin (T431)', () => {
88
+ describe('SKILL.md frontmatter', () => {
89
+ const skillMdPath = join(skillRoot, 'SKILL.md');
90
+
91
+ it('SKILL.md exists', () => {
92
+ expect(existsSync(skillMdPath)).toBe(true);
93
+ });
94
+
95
+ it('SKILL.md contains valid frontmatter delimiters', () => {
96
+ const content = readFileSync(skillMdPath, 'utf-8');
97
+ const fm = extractFrontmatter(content);
98
+ expect(fm).not.toBeNull();
99
+ });
100
+
101
+ it('frontmatter has required fields: name, description, version, tier', () => {
102
+ const content = readFileSync(skillMdPath, 'utf-8');
103
+ const fm = extractFrontmatter(content);
104
+ expect(fm).not.toBeNull();
105
+ const keys = parseFrontmatterKeys(fm!);
106
+ expect(keys['name']).toBe('ct-master-tac');
107
+ expect(keys['description'] ?? keys['description']).toBeTruthy();
108
+ expect(keys['version']).toBeTruthy();
109
+ expect(keys['tier']).toBeTruthy();
110
+ });
111
+ });
112
+
113
+ describe('manifest.json', () => {
114
+ const manifestPath = join(skillRoot, 'manifest.json');
115
+ let manifest: Record<string, unknown>;
116
+
117
+ it('manifest.json exists', () => {
118
+ expect(existsSync(manifestPath)).toBe(true);
119
+ });
120
+
121
+ it('manifest.json parses as valid JSON', () => {
122
+ const raw = readFileSync(manifestPath, 'utf-8');
123
+ expect(() => {
124
+ manifest = JSON.parse(raw) as Record<string, unknown>;
125
+ }).not.toThrow();
126
+ });
127
+
128
+ it('manifest has required top-level keys', () => {
129
+ const raw = readFileSync(manifestPath, 'utf-8');
130
+ manifest = JSON.parse(raw) as Record<string, unknown>;
131
+ expect(manifest['name']).toBe('ct-master-tac');
132
+ expect(manifest['version']).toBeTruthy();
133
+ expect(Array.isArray(manifest['files'])).toBe(true);
134
+ });
135
+
136
+ it('files array contains exactly 13 entries (12 protocols + 1 team)', () => {
137
+ const raw = readFileSync(manifestPath, 'utf-8');
138
+ manifest = JSON.parse(raw) as Record<string, unknown>;
139
+ const files = manifest['files'] as string[];
140
+ expect(files).toHaveLength(13);
141
+ });
142
+
143
+ it('files array contains at least 12 protocol entries', () => {
144
+ const raw = readFileSync(manifestPath, 'utf-8');
145
+ manifest = JSON.parse(raw) as Record<string, unknown>;
146
+ const files = manifest['files'] as string[];
147
+ const protocolFiles = files.filter((f) => f.startsWith('bundled/protocols/'));
148
+ expect(protocolFiles.length).toBeGreaterThanOrEqual(12);
149
+ });
150
+
151
+ it('files array contains platform team entry', () => {
152
+ const raw = readFileSync(manifestPath, 'utf-8');
153
+ manifest = JSON.parse(raw) as Record<string, unknown>;
154
+ const files = manifest['files'] as string[];
155
+ expect(files).toContain('bundled/teams/platform.cant');
156
+ });
157
+ });
158
+
159
+ describe('bundled files exist', () => {
160
+ it('all files referenced in manifest.json exist under bundled/', () => {
161
+ const raw = readFileSync(join(skillRoot, 'manifest.json'), 'utf-8');
162
+ const manifest = JSON.parse(raw) as { files: string[] };
163
+ const missingFiles: string[] = [];
164
+
165
+ for (const f of manifest.files) {
166
+ const abs = join(skillRoot, f);
167
+ if (!existsSync(abs)) {
168
+ missingFiles.push(f);
169
+ }
170
+ }
171
+
172
+ expect(missingFiles).toEqual([]);
173
+ });
174
+
175
+ it('each bundled protocol file is non-empty', () => {
176
+ const raw = readFileSync(join(skillRoot, 'manifest.json'), 'utf-8');
177
+ const manifest = JSON.parse(raw) as { files: string[] };
178
+ const emptyFiles: string[] = [];
179
+
180
+ for (const f of manifest.files.filter((f) =>
181
+ f.startsWith('bundled/protocols/'),
182
+ )) {
183
+ const abs = join(skillRoot, f);
184
+ const content = readFileSync(abs, 'utf-8');
185
+ if (content.trim().length === 0) {
186
+ emptyFiles.push(f);
187
+ }
188
+ }
189
+
190
+ expect(emptyFiles).toEqual([]);
191
+ });
192
+
193
+ it('each bundled protocol file has CANT frontmatter (kind: protocol)', () => {
194
+ const raw = readFileSync(join(skillRoot, 'manifest.json'), 'utf-8');
195
+ const manifest = JSON.parse(raw) as { files: string[] };
196
+ const badFiles: string[] = [];
197
+
198
+ for (const f of manifest.files.filter((f) =>
199
+ f.startsWith('bundled/protocols/'),
200
+ )) {
201
+ const abs = join(skillRoot, f);
202
+ const content = readFileSync(abs, 'utf-8');
203
+ if (!content.includes('kind: protocol')) {
204
+ badFiles.push(f);
205
+ }
206
+ }
207
+
208
+ expect(badFiles).toEqual([]);
209
+ });
210
+ });
211
+
212
+ describe('idempotent install (mock)', () => {
213
+ it('first install copies all 13 files', () => {
214
+ const raw = readFileSync(join(skillRoot, 'manifest.json'), 'utf-8');
215
+ const manifest = JSON.parse(raw) as { files: string[] };
216
+ const already = new Set<string>();
217
+
218
+ const result = mockInstall(manifest.files, already);
219
+ expect(result.copiedFiles).toHaveLength(13);
220
+ expect(result.skippedFiles).toHaveLength(0);
221
+ });
222
+
223
+ it('second install (files already present) skips all 13 files', () => {
224
+ const raw = readFileSync(join(skillRoot, 'manifest.json'), 'utf-8');
225
+ const manifest = JSON.parse(raw) as { files: string[] };
226
+ // Simulate first install — all files now "present"
227
+ const already = new Set<string>(manifest.files);
228
+
229
+ const result = mockInstall(manifest.files, already);
230
+ expect(result.copiedFiles).toHaveLength(0);
231
+ expect(result.skippedFiles).toHaveLength(13);
232
+ });
233
+
234
+ it('partial install (3 missing) copies only missing files', () => {
235
+ const raw = readFileSync(join(skillRoot, 'manifest.json'), 'utf-8');
236
+ const manifest = JSON.parse(raw) as { files: string[] };
237
+ // 10 of 13 already installed
238
+ const already = new Set<string>(manifest.files.slice(0, 10));
239
+
240
+ const result = mockInstall(manifest.files, already);
241
+ expect(result.copiedFiles).toHaveLength(3);
242
+ expect(result.skippedFiles).toHaveLength(10);
243
+ });
244
+ });
245
+
246
+ describe('bundle completeness', () => {
247
+ const EXPECTED_PROTOCOLS = [
248
+ 'research.cant',
249
+ 'consensus.cant',
250
+ 'architecture-decision.cant',
251
+ 'specification.cant',
252
+ 'decomposition.cant',
253
+ 'implementation.cant',
254
+ 'validation.cant',
255
+ 'testing.cant',
256
+ 'contribution.cant',
257
+ 'release.cant',
258
+ 'artifact-publish.cant',
259
+ 'provenance.cant',
260
+ ] as const;
261
+
262
+ for (const protocol of EXPECTED_PROTOCOLS) {
263
+ it(`bundled/protocols/${protocol} exists`, () => {
264
+ expect(
265
+ existsSync(join(skillRoot, 'bundled', 'protocols', protocol)),
266
+ ).toBe(true);
267
+ });
268
+ }
269
+
270
+ it('bundled/teams/platform.cant exists', () => {
271
+ expect(existsSync(join(skillRoot, 'bundled', 'teams', 'platform.cant'))).toBe(
272
+ true,
273
+ );
274
+ });
275
+
276
+ it('bundle contains exactly 12 CANT protocol files', () => {
277
+ const protocolFiles = EXPECTED_PROTOCOLS.filter((f) =>
278
+ existsSync(join(skillRoot, 'bundled', 'protocols', f)),
279
+ );
280
+ expect(protocolFiles).toHaveLength(12);
281
+ });
282
+ });
283
+ });
@@ -0,0 +1,40 @@
1
+ # ct-master-tac Bundle Contents
2
+
3
+ > @task T430 @epic T382 @umbrella T377
4
+ > Source: `packages/skills/skills/ct-master-tac/bundled/`
5
+
6
+ This directory holds the canonical bundle assets shipped with the `ct-master-tac` plugin.
7
+
8
+ ## protocols/
9
+
10
+ Copies of the 12 CANT protocol files from
11
+ `packages/core/src/validation/protocols/cant/`.
12
+
13
+ Each file defines a protocol primitive in the RCASD-IVTR+C lifecycle:
14
+
15
+ | File | ID | RCASD Stage |
16
+ |------|----|-------------|
17
+ | `research.cant` | RSCH | R — Research |
18
+ | `consensus.cant` | CONS | C — Consensus |
19
+ | `architecture-decision.cant` | ADR | A — Architecture Decision |
20
+ | `specification.cant` | SPEC | S — Specification |
21
+ | `decomposition.cant` | DCMP | D — Decomposition |
22
+ | `implementation.cant` | IMPL | I — Implementation |
23
+ | `validation.cant` | VALID | V — Validation |
24
+ | `testing.cant` | TEST | T — Testing |
25
+ | `contribution.cant` | CONT | cross-cutting |
26
+ | `release.cant` | REL | R — Release |
27
+ | `artifact-publish.cant` | ART | release sub-protocol |
28
+ | `provenance.cant` | PROV | release sub-protocol |
29
+
30
+ ## teams/
31
+
32
+ | File | Description |
33
+ |------|-------------|
34
+ | `platform.cant` | Canonical 3-tier CleoOS platform team seed |
35
+
36
+ ## Maintenance
37
+
38
+ When protocol files change in `packages/core/src/validation/protocols/cant/`,
39
+ re-copy them here and bump the version in `ct-master-tac/manifest.json` and
40
+ `ct-master-tac/SKILL.md`.
@@ -0,0 +1,90 @@
1
+ ---
2
+ kind: protocol
3
+ version: 1.0.0
4
+ id: ADR
5
+ title: "Architecture Decision Record Protocol"
6
+ status: active
7
+ type: conditional
8
+ audience: "llm-agent, orchestrator"
9
+ tags: "adr, architecture, decisions"
10
+ skillRef: ct-adr-recorder
11
+ lastUpdated: 2026-04-08
12
+ enforcement: advisory
13
+ stage: "architecture-decision"
14
+ consult-when: "Recording a formal architecture decision after consensus reaches PROVEN verdict; superseding an existing ADR; any task carrying --protocol adr flag"
15
+ input:
16
+ consensus_manifest_id: "string — ID of the originating consensus manifest (required)"
17
+ decision_title: "string — short title for the ADR"
18
+ options_evaluated: "string[] — options that were considered"
19
+ output:
20
+ adr_id: "string — canonical ADR identifier (ADR-NNN)"
21
+ status: "proposed | accepted | superseded"
22
+ stored_at: "string — path to .cleo/adrs/<id>.md and decisions table row"
23
+ ---
24
+
25
+ # Architecture Decision Record (ADR) Protocol
26
+ #
27
+ # Provenance: @task T4798 (ADR-006 Implementation), @task T428 (gap patch)
28
+ # Type: Conditional Protocol
29
+ # Stage: RCADSD - A (ADR)
30
+ # Max Active: 3 protocols (including base)
31
+ #
32
+ # Trigger Conditions
33
+ #
34
+ # This protocol activates when the task involves:
35
+ # Decision Recording: "decision", "adr", "architecture decision"
36
+ # Stage Transition: "after consensus", "begin adr"
37
+ # Formalization: "lock in decision", "formalize choice", "decide"
38
+ # Architectural Shift: "pivot", "new architecture", "supersede"
39
+ # Record Creation: "create adr", "write adr", "record decision"
40
+ #
41
+ # Explicit Override: --protocol adr flag on task creation.
42
+ #
43
+ # Requirements (RFC 2119)
44
+ #
45
+ # MUST:
46
+ # ADR-001: MUST be generated from an accepted Consensus report verdict
47
+ # ADR-002: MUST include a consensus_manifest_id linking to its originating consensus
48
+ # ADR-003: MUST require explicit HITL approval to transition from proposed to accepted
49
+ # ADR-004: MUST include Context, Options Evaluated, Decision, Rationale, and Consequences sections
50
+ # ADR-005: MUST trigger downstream invalidation if superseded
51
+ # ADR-006: MUST be stored in the canonical decisions SQLite table via Drizzle ORM
52
+ # ADR-007: MUST set agent_type: "decision" in manifest entry
53
+ # ADR-008: MUST block the Specification stage until the ADR status is accepted
54
+ #
55
+ # SHOULD:
56
+ # ADR-010: SHOULD document the exact data structures or schema changes required
57
+ # ADR-011: SHOULD explicitly list which existing ADRs are superseded, with rationale
58
+ # ADR-012: SHOULD flag known technical debt introduced by the decision
59
+ # ADR-013: SHOULD document rejected alternatives with rationale for rejection
60
+ #
61
+ # MAY:
62
+ # ADR-020: MAY include diagrams (Mermaid) illustrating the architectural shift
63
+ # ADR-021: MAY link to external prior art or research documents
64
+ # ADR-022: MAY reference related ADRs that are not superseded but contextually relevant
65
+ #
66
+ # Decision Status Lifecycle:
67
+ # proposed -> accepted -> superseded
68
+ # \-> deprecated
69
+ #
70
+ # HITL Gate:
71
+ # 1. Agent drafts the ADR based on consensus verdict
72
+ # 2. Status is set to proposed
73
+ # 3. Pipeline pauses (HANDOFF_REQUIRED - exit code 65)
74
+ # 4. Human reviews the proposed ADR
75
+ # 5. If approved, status transitions to accepted
76
+ # 6. Only an accepted ADR unlocks the Specification stage
77
+ #
78
+ # Exit Codes:
79
+ # 65: HANDOFF_REQUIRED - ADR drafted as proposed, awaiting HITL acceptance
80
+ # 84: PROVENANCE_REQUIRED - Attempted to create ADR without linked Consensus report
81
+ # 18: CASCADE_FAILED - Downstream work blocked because governing ADR was superseded
82
+ #
83
+ # Anti-Patterns:
84
+ # - Creating ADR without consensus (decisions lack evidence foundation)
85
+ # - Auto-accepting without HITL review (bypasses human oversight gate)
86
+ # - Omitting downstream impact section (future implementers unaware of cascade)
87
+ # - Superseding without updating specs (creates orphaned specifications)
88
+ # - Using ADR to define implementation requirements (that is Specification's role)
89
+ # - Storing ADR only as markdown without SQLite record (loses relational queries)
90
+ # - Skipping rejected alternatives (loses institutional knowledge)