@cleocode/skills 2026.5.83 → 2026.5.86

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.
Files changed (55) hide show
  1. package/package.json +1 -1
  2. package/skills/_shared/__tests__/lifecycle-protocol-reconcile.test.ts +112 -0
  3. package/skills/_shared/__tests__/loom-adr-links.test.ts +163 -0
  4. package/skills/_shared/__tests__/loom-stage-coverage.test.ts +167 -0
  5. package/skills/ct-adr-recorder/SKILL.md +92 -0
  6. package/skills/ct-adr-recorder/__tests__/skill-adr-recorder.test.ts +65 -0
  7. package/skills/ct-consensus-voter/SKILL.md +14 -0
  8. package/skills/ct-contribution/SKILL.md +80 -0
  9. package/skills/ct-docs-lookup/SKILL.md +116 -1
  10. package/skills/ct-docs-lookup/references/ctx7-workflow.md +198 -0
  11. package/skills/ct-docs-lookup/references/library-id-resolution.md +217 -0
  12. package/skills/ct-docs-lookup/references/version-specific-docs.md +220 -0
  13. package/skills/ct-docs-review/SKILL.md +133 -1
  14. package/skills/ct-docs-review/__tests__/skill-docs-review.test.ts +53 -0
  15. package/skills/ct-docs-review/references/inline-comment-patterns.md +268 -0
  16. package/skills/ct-docs-review/references/pr-review-mode.md +270 -0
  17. package/skills/ct-docs-review/references/style-violations.md +341 -0
  18. package/skills/ct-docs-write/SKILL.md +157 -1
  19. package/skills/ct-docs-write/__tests__/skill-docs-write.test.ts +55 -0
  20. package/skills/ct-docs-write/references/audience-targeting.md +305 -0
  21. package/skills/ct-docs-write/references/cleo-style-guide.md +234 -0
  22. package/skills/ct-docs-write/references/markdown-patterns.md +329 -0
  23. package/skills/ct-documentor/SKILL.md +11 -0
  24. package/skills/ct-documentor/references/anti-patterns.md +216 -0
  25. package/skills/ct-documentor/references/chain-orchestration.md +194 -0
  26. package/skills/ct-documentor/references/doc-types-and-templates.md +301 -0
  27. package/skills/ct-documentor/references/style-coordination.md +195 -0
  28. package/skills/ct-epic-architect/SKILL.md +15 -0
  29. package/skills/ct-ivt-looper/SKILL.md +32 -0
  30. package/skills/ct-release-orchestrator/SKILL.md +16 -0
  31. package/skills/ct-research-agent/SKILL.md +24 -0
  32. package/skills/ct-research-agent/references/anti-patterns.md +154 -0
  33. package/skills/ct-research-agent/references/citation-and-evidence.md +140 -0
  34. package/skills/ct-research-agent/references/source-strategy.md +116 -0
  35. package/skills/ct-research-agent/references/triggers-and-routing.md +93 -0
  36. package/skills/ct-skill-validator/SKILL.md +19 -0
  37. package/skills/ct-skill-validator/scripts/check_depth.py +306 -0
  38. package/skills/ct-spec-writer/SKILL.md +86 -1
  39. package/skills/ct-spec-writer/__tests__/skill-spec-writer.test.ts +60 -0
  40. package/skills/ct-spec-writer/references/anti-patterns.md +176 -0
  41. package/skills/ct-spec-writer/references/rfc2119-language.md +138 -0
  42. package/skills/ct-spec-writer/references/spec-templates.md +233 -0
  43. package/skills/ct-spec-writer/references/traceability-matrix.md +145 -0
  44. package/skills/ct-task-executor/SKILL.md +25 -0
  45. package/skills/ct-task-executor/references/acceptance-criteria-mapping.md +163 -0
  46. package/skills/ct-task-executor/references/anti-patterns.md +201 -0
  47. package/skills/ct-task-executor/references/common-failures.md +193 -0
  48. package/skills/ct-task-executor/references/evidence-and-gates.md +179 -0
  49. package/skills/ct-task-executor/references/implementation-patterns.md +160 -0
  50. package/skills/ct-validator/SKILL.md +44 -0
  51. package/skills/ct-validator/references/anti-patterns.md +194 -0
  52. package/skills/ct-validator/references/compliance-reports.md +199 -0
  53. package/skills/ct-validator/references/schema-checking.md +191 -0
  54. package/skills/ct-validator/references/validation-modes.md +185 -0
  55. package/skills/manifest.json +82 -16
@@ -0,0 +1,194 @@
1
+ # Anti-Patterns
2
+
3
+ Common failure modes when running validation tasks. These degrade the
4
+ report's usefulness, break downstream consumers, or mask defects. Avoid
5
+ them by following the detection cue and the remediation.
6
+
7
+ ## 1. The Short-Circuit Validator
8
+
9
+ **Symptom.** Validator stops on the first failure and reports only that
10
+ one. The report claims "FAIL" but lists only one issue when there are
11
+ several.
12
+
13
+ **Detection cue.** Issue count is exactly 1 but the underlying tool
14
+ (biome, tsc, jsonschema) has multi-issue output.
15
+
16
+ **Root cause.** Engine was run without `--all-errors` (AJV),
17
+ `--exhaustive`, or equivalent. Or a try/catch wrapped the validation
18
+ and bailed on first throw.
19
+
20
+ **Fix.** Always pass the all-errors flag. For Zod, use `safeParse` and
21
+ collect every issue from `result.error.issues`. For TypeScript, use
22
+ `tsc -b --pretty false` and capture every line.
23
+
24
+ ## 2. The Soft Pass
25
+
26
+ **Symptom.** Report status is `PASS` but the target has known
27
+ unaddressed warnings.
28
+
29
+ **Detection cue.** Findings table contains entries; status is PASS.
30
+
31
+ **Root cause.** Status calculus violation — PASS requires zero
32
+ critical AND ≤2 warnings (per `compliance-reports.md`). Warnings
33
+ above threshold demote to PARTIAL.
34
+
35
+ **Fix.** Apply the status calculus mechanically. PASS only when the
36
+ table is empty (or warnings ≤2). When in doubt, demote.
37
+
38
+ ## 3. The Unreproducible Report
39
+
40
+ **Symptom.** Six weeks later, someone tries to re-validate the same
41
+ target. The report's claims cannot be verified.
42
+
43
+ **Detection cue.** Report has no `## Trace` section or the Trace lists
44
+ no reproducer command.
45
+
46
+ **Root cause.** Reporter forgot to record the command sequence and
47
+ tool versions used.
48
+
49
+ **Fix.** Always include the reproducer. The Trace section is mandatory
50
+ per the canonical scaffold.
51
+
52
+ ```markdown
53
+ ## Trace
54
+
55
+ - Target: packages/cleo/src/release.ts (at 5608f75cd)
56
+ - Tooling: biome@2.4.11, tsc@5.6.0, pnpm@9.x
57
+ - Reproducer:
58
+ pnpm biome check packages/cleo/src/release.ts && \
59
+ pnpm exec tsc -b packages/cleo --pretty false
60
+ ```
61
+
62
+ ## 4. The Mode Confusion
63
+
64
+ **Symptom.** A Document-mode report applies Code-mode rules, or
65
+ vice-versa.
66
+
67
+ **Detection cue.** Findings about TypeScript strictness in a spec
68
+ review; findings about RFC 2119 in a code lint.
69
+
70
+ **Root cause.** Mode was not made explicit at the start; the validator
71
+ defaulted to its strongest familiarity.
72
+
73
+ **Fix.** Declare mode in the report header. The spawn prompt or task
74
+ body MUST set it; if absent, ask the orchestrator to clarify before
75
+ proceeding.
76
+
77
+ ## 5. The Missing Severity
78
+
79
+ **Symptom.** Findings listed but consumer cannot prioritize.
80
+
81
+ **Detection cue.** Findings without `Critical | Warning | Suggestion`
82
+ classification.
83
+
84
+ **Root cause.** Reporter treated all findings as equal.
85
+
86
+ **Fix.** Every finding MUST carry severity. When unclear, apply the
87
+ "blocks ship?" test: yes → Critical; no → Warning; "nice to have" →
88
+ Suggestion.
89
+
90
+ ## 6. The Vague Remediation
91
+
92
+ **Symptom.** Issue says "fix this". Reader does not know how.
93
+
94
+ **Detection cue.** `Fix:` line is missing or contains only "see above"
95
+ / "obvious from context" / "fix the issue".
96
+
97
+ **Root cause.** Reporter ran out of energy by the time they got to
98
+ the fix column.
99
+
100
+ **Fix.** Every finding has a concrete fix step. If the fix requires
101
+ discussion (architectural change), state that — but specifically:
102
+ "file a task to redesign the credential rotation flow; reference
103
+ ADR-XX-NEW once it lands".
104
+
105
+ ## 7. The Phantom Test
106
+
107
+ **Symptom.** Protocol mode report claims REQ-NNN is verified by
108
+ `test/foo.test.ts::case-name`. The test does not exist.
109
+
110
+ **Detection cue.** Reproducer command fails with "no such test".
111
+
112
+ **Root cause.** Reporter copied the spec's traceability matrix without
113
+ re-checking that the named tests still exist (or ever existed).
114
+
115
+ **Fix.** Re-run each verification command from the traceability
116
+ matrix during validation. Flag REQs whose verification fails to
117
+ resolve as Critical findings — the spec drifted from the implementation.
118
+
119
+ ## 8. The Single-File Tunnel
120
+
121
+ **Symptom.** Code-mode validation runs only on the file that was
122
+ explicitly named. Misses related files that share the violation.
123
+
124
+ **Detection cue.** Report has findings in `release.ts` only; the
125
+ same issue exists in 5 sibling files that were not checked.
126
+
127
+ **Root cause.** Reporter took the task literally instead of the
128
+ useful scope.
129
+
130
+ **Fix.** Apply the validation to all related files when feasible —
131
+ "the diff" usually means "all files touched by the task branch", not
132
+ "only the one file the orchestrator mentioned".
133
+
134
+ ## 9. The Stale Schema
135
+
136
+ **Symptom.** Schema-mode validation passes but downstream consumers
137
+ still reject the data.
138
+
139
+ **Detection cue.** Schema version pinned in the report does not match
140
+ the producer's contract.
141
+
142
+ **Root cause.** Schema was updated upstream; validator used a cached
143
+ or pinned older version.
144
+
145
+ **Fix.** Always resolve the schema fresh from the contract source
146
+ (`@cleocode/contracts`). Pin the consumer/producer relationship in
147
+ the schema's `$id` and `version` fields and check both.
148
+
149
+ ## 10. The Disposable Sidecar
150
+
151
+ **Symptom.** JSON sidecar emitted, but it has different findings than
152
+ the markdown report.
153
+
154
+ **Detection cue.** `diff <(md-extract-findings report.md)
155
+ <(jq '.findings' report.json)` shows mismatched data.
156
+
157
+ **Root cause.** Reporter wrote the markdown manually and the JSON
158
+ separately; they drifted.
159
+
160
+ **Fix.** Generate one from the other. Write the structured data first
161
+ (JSON), then render the markdown from it. A `--render-md` flag on the
162
+ report generator enforces this.
163
+
164
+ ## 11. The Unsourced Rule
165
+
166
+ **Symptom.** A finding cites a rule that does not exist in any visible
167
+ standard.
168
+
169
+ **Detection cue.** Rule reference is prose ("naming should be
170
+ consistent") rather than a stable identifier ("AGENTS.md §Package
171
+ Boundary").
172
+
173
+ **Root cause.** Reporter applied a personal preference and labeled
174
+ it as a rule.
175
+
176
+ **Fix.** Every rule citation MUST link to a stable source:
177
+ `AGENTS.md §X`, `ADR-NNN`, `biome.json#rules.style.Y`. If the
178
+ preference is real but unwritten, the report SHOULD propose adding
179
+ it to the standard (file a task) rather than enforcing it silently.
180
+
181
+ ## 12. The Pre-Empty Report
182
+
183
+ **Symptom.** Validator runs against an empty or absent target, reports
184
+ `PASS`.
185
+
186
+ **Detection cue.** Target file is empty or does not exist; report says
187
+ "100% compliance".
188
+
189
+ **Root cause.** Engine returned zero violations because there was
190
+ nothing to violate.
191
+
192
+ **Fix.** Always sanity-check the target exists and has content before
193
+ running validation. Empty/missing target is itself a Critical finding —
194
+ not a clean pass.
@@ -0,0 +1,199 @@
1
+ # Compliance Reports
2
+
3
+ The shape, severity calculus, and downstream consumption of the
4
+ validation report. The report is the validator's product — its format
5
+ is rigid because `ct-ivt-looper`, `ct-release-orchestrator`, and HITL
6
+ gates all parse it.
7
+
8
+ ## Canonical Report Scaffold
9
+
10
+ Every report MUST use this structure. Sections are mandatory; their
11
+ content varies by mode.
12
+
13
+ ```markdown
14
+ # Validation Report: {{VALIDATION_TARGET}}
15
+
16
+ **Mode**: schema | code | document | protocol
17
+ **Date**: {{DATE}}
18
+ **Validator**: ct-validator v2.0.0
19
+
20
+ ---
21
+
22
+ ## Summary
23
+
24
+ - **Status**: PASS | PARTIAL | FAIL
25
+ - **Compliance**: {X}%
26
+ - **Critical Issues**: {N}
27
+ - **Warnings**: {N}
28
+ - **Suggestions**: {N}
29
+
30
+ ## Checklist Results
31
+
32
+ | Check | Status | Details |
33
+ |-------|--------|---------|
34
+ | {CHECK_1} | PASS/FAIL | {Details} |
35
+ | {CHECK_2} | PASS/FAIL | {Details} |
36
+
37
+ ## Issues Found
38
+
39
+ ### Critical
40
+ {List or "None"}
41
+
42
+ ### Warnings
43
+ {List or "None"}
44
+
45
+ ### Suggestions
46
+ {List or "None"}
47
+
48
+ ## Remediation
49
+
50
+ {Required fixes if FAIL/PARTIAL, or "No remediation required" if PASS}
51
+
52
+ ## Trace
53
+
54
+ - Target: {file/spec/diff path}
55
+ - Tooling: {versions of tools run}
56
+ - Reproducer: {one command that re-runs this report}
57
+ ```
58
+
59
+ The Trace section is essential — without a reproducer, the report
60
+ cannot be re-run later to confirm a remediation worked.
61
+
62
+ ## Status Calculus
63
+
64
+ | Mode | PASS | PARTIAL | FAIL |
65
+ |------|------|---------|------|
66
+ | Schema | 0 violations | (n/a) | ≥1 violation |
67
+ | Code | 0 critical, ≤2 warnings | 0 critical, 3+ warnings | ≥1 critical |
68
+ | Document | All required sections present, 0 broken links | 1-2 missing sections | 3+ missing sections OR broken refs |
69
+ | Protocol | 100% REQ compliance | 70-99% compliance | <70% compliance |
70
+
71
+ The status is not a vote — it is a computed function of the findings.
72
+ Two validators running on the same target MUST produce the same
73
+ status.
74
+
75
+ PARTIAL is reserved for cases where the target is shippable WITH
76
+ recorded remediation; FAIL means the target cannot ship as-is.
77
+
78
+ ## Severity Definitions
79
+
80
+ | Severity | Meaning | Examples |
81
+ |----------|---------|----------|
82
+ | Critical | Blocks ship; data corruption, security, AGENTS.md rejection | `any` type, missing required field, broken link in spec |
83
+ | Warning | Should fix soon; degrades quality but does not block | Long body, unused import, missing optional section |
84
+ | Suggestion | Improvement opportunity; no obligation | Extract helper, rename for clarity |
85
+
86
+ Each finding MUST carry a severity. Findings without severity are
87
+ unactionable — the consumer cannot prioritize.
88
+
89
+ ## Per-Finding Format
90
+
91
+ ```markdown
92
+ ### Critical
93
+
94
+ **C-001**: `packages/cleo/src/dispatch.ts:42` uses `any` type.
95
+ - Rule: AGENTS.md Type Safety §1 — "NEVER use `any` type"
96
+ - Fix: Import the relevant type from `@cleocode/contracts` or
97
+ define a narrower union.
98
+ - Verification: `pnpm biome check packages/cleo/src/dispatch.ts`
99
+
100
+ **C-002**: `packages/cleo/src/release.ts:107` catches `err: unknown`.
101
+ - Rule: AGENTS.md Type Safety §5 — "NEVER use `catch (err: unknown)`"
102
+ - Fix: Throw and catch by class from `@cleocode/contracts/errors`.
103
+ - Verification: Replace with `catch (err)` and pattern-match by
104
+ `instanceof`.
105
+
106
+ ### Warnings
107
+
108
+ **W-001**: `packages/cleo/src/dispatch.ts` is 487 lines (warn at 400).
109
+ - Rule: ct-skill-validator audit_body §body-length
110
+ - Fix: Extract sub-handlers into sibling files.
111
+ - Verification: re-run audit_body.py.
112
+
113
+ ### Suggestions
114
+
115
+ **S-001**: `packages/cleo/src/dispatch.ts:120` has a TODO with no task ID.
116
+ - Rule: Internal — TODOs should reference task IDs.
117
+ - Fix: File a task, attach the ID: `// TODO(T9999): ...`.
118
+ ```
119
+
120
+ Each finding gets a stable ID (`C-NNN`, `W-NNN`, `S-NNN`) so subsequent
121
+ reports can reference whether the same issue persists.
122
+
123
+ ## Compliance Percentage
124
+
125
+ For modes that report a percentage:
126
+
127
+ ```text
128
+ compliance = (passed_checks / total_checks) × 100
129
+ ```
130
+
131
+ Round to one decimal. For Protocol mode (REQ compliance), checks are
132
+ the REQs in the spec's traceability matrix. For Schema mode, "checks"
133
+ is the count of constraints evaluated.
134
+
135
+ When the denominator is zero (e.g., a spec with no REQs), the
136
+ percentage is undefined — emit `N/A` and report a Critical finding for
137
+ the empty spec.
138
+
139
+ ## Integration with ct-ivt-looper
140
+
141
+ The IVT loop reads the validator's `status` and `compliance` fields
142
+ to decide whether to continue iterating. The contract:
143
+
144
+ - `status: PASS` → IVT loop converges; release-orchestrator may proceed.
145
+ - `status: PARTIAL` → IVT loop loops once more with the remediation as
146
+ input; if still PARTIAL on iteration 3, escalates to HITL.
147
+ - `status: FAIL` → IVT loop blocks; release-orchestrator MUST not
148
+ proceed; HITL escalation immediate.
149
+
150
+ This contract is the reason status calculus is rigid — fuzzy statuses
151
+ break the loop's termination conditions.
152
+
153
+ ## Integration with Release
154
+
155
+ `ct-release-orchestrator` reads the most recent validation report
156
+ for the epic before allowing ship. The release pipeline (ADR-065)
157
+ contains a gate that asserts `status: PASS` on the implementation
158
+ against the spec. PARTIAL reports trigger a recorded remediation
159
+ plan; FAIL reports block.
160
+
161
+ ## Machine-Readable Sidecar
162
+
163
+ Always emit a JSON sidecar next to the markdown report:
164
+
165
+ ```json
166
+ {
167
+ "target": "packages/cleo/src/release.ts",
168
+ "mode": "code",
169
+ "status": "FAIL",
170
+ "compliance": 88.5,
171
+ "findings": {
172
+ "critical": [
173
+ {"id": "C-001", "file": "...", "line": 42, "rule": "...", "fix": "..."},
174
+ {"id": "C-002", "file": "...", "line": 107, "rule": "...", "fix": "..."}
175
+ ],
176
+ "warnings": [...],
177
+ "suggestions": [...]
178
+ },
179
+ "trace": {
180
+ "tooling": ["biome@2.4.11", "tsc@5.6.0"],
181
+ "reproducer": "pnpm biome check . && pnpm exec tsc -b",
182
+ "timestamp": "2026-05-19T19:35:00Z"
183
+ }
184
+ }
185
+ ```
186
+
187
+ The orchestrator parses this when programmatic decisions are needed;
188
+ the human report (.md) is for review.
189
+
190
+ ## Anti-Patterns
191
+
192
+ | Anti-pattern | Why it fails |
193
+ |--------------|--------------|
194
+ | Vague finding ("file looks weird") | Cannot remediate |
195
+ | Missing severity | Consumer cannot prioritize |
196
+ | No reproducer in trace | Cannot re-validate after fix |
197
+ | PARTIAL with no remediation plan | Status calculus violation |
198
+ | Findings without rule reference | Disputable, not actionable |
199
+ | Markdown only, no JSON sidecar | Breaks orchestrator integration |
@@ -0,0 +1,191 @@
1
+ # Schema Checking
2
+
3
+ Deeper guidance for Schema Validation mode (Mode 1 from
4
+ `validation-modes.md`). Schema checking is the most mechanical of the
5
+ four modes — but only if the inputs are correctly configured. This
6
+ reference covers the configuration pitfalls and tool-selection rules.
7
+
8
+ ## Pick the Right Engine
9
+
10
+ | Engine | Strength | When to use |
11
+ |--------|----------|-------------|
12
+ | AJV (`ajv-cli`) | Fast; draft-07 / 2019-09 / 2020-12 | Generic JSON Schema validation |
13
+ | Zod | Type-safe; integrates with TypeScript | Project-internal data validation |
14
+ | drizzle-orm/zod | Schema → Zod auto-generation | Drizzle ORM consumers |
15
+ | jsonschema (Python) | Cross-language; same draft support | Python-side validation |
16
+ | `cargo schema` / serde | Type-safe; Rust-side | Rust crates |
17
+
18
+ The CLEO repo's primary engine is Zod (via `@cleocode/contracts`) — most
19
+ internal schemas are exported as Zod schemas with optional drizzle
20
+ codegen. Use Zod's `safeParse` to get structured errors.
21
+
22
+ For external contracts (LAFS envelope spec, JSON-RPC requests from
23
+ non-CLEO clients), use AJV or jsonschema for cross-language portability.
24
+
25
+ ## Draft Selection
26
+
27
+ Always state the draft explicitly. Draft-07 and draft-2020-12 have
28
+ incompatible semantics around `$ref`, `if/then/else`, and tuple arrays.
29
+
30
+ | Draft | Best for | Caveats |
31
+ |-------|----------|---------|
32
+ | draft-04 | Legacy | `id` not `$id`; many engines deprecated this |
33
+ | draft-07 | Industry standard | Most engines support fully |
34
+ | draft-2019-09 | New work, conservative | `$defs` replaces `definitions` |
35
+ | draft-2020-12 | New work, full | Some engines lag |
36
+
37
+ CLEO contracts target draft-07 unless the schema needs 2020-12-only
38
+ features (typically `prefixItems` for tuple arrays). Add the explicit
39
+ `"$schema"` field on every published schema:
40
+
41
+ ```json
42
+ {
43
+ "$schema": "http://json-schema.org/draft-07/schema#",
44
+ "title": "TaskEnvelope",
45
+ "type": "object",
46
+ "required": ["success", "meta"],
47
+ ...
48
+ }
49
+ ```
50
+
51
+ ## The Standard Validation Loop
52
+
53
+ ```bash
54
+ # 1. Choose engine; choose draft
55
+ ENGINE=ajv
56
+ DRAFT=draft-07
57
+
58
+ # 2. Resolve schema file (must include $schema or pass --spec)
59
+ SCHEMA=packages/contracts/schemas/envelope.json
60
+
61
+ # 3. Iterate over data files
62
+ for DATA in path/to/*.json; do
63
+ echo "=== $DATA ==="
64
+ npx ajv validate -s "$SCHEMA" -d "$DATA" --spec=$DRAFT --all-errors
65
+ done
66
+
67
+ # 4. Aggregate by file in the report
68
+ ```
69
+
70
+ The `--all-errors` flag (AJV) or `--exhaustive` (Zod's `safeParse` does
71
+ this by default) is essential — the spec ground rule is "report every
72
+ violation", not "stop at the first one".
73
+
74
+ ## Pitfalls
75
+
76
+ ### 1. $ref Resolution Failure
77
+
78
+ **Symptom.** Validator complains "could not resolve $ref" or "unknown
79
+ keyword $ref".
80
+
81
+ **Cause.** Schema references another file by relative path; the engine
82
+ does not know the base directory.
83
+
84
+ **Fix.** Pass `--ref` (AJV) pointing at the referenced files, or inline
85
+ the references with `$defs`. For multi-file schemas, use AJV's
86
+ `addSchema()` API or a bundler step that flattens before validation.
87
+
88
+ ### 2. Implicit Type Coercion
89
+
90
+ **Symptom.** A string `"123"` validates against `{"type": "number"}`.
91
+
92
+ **Cause.** Engine has coercion enabled (`coerceTypes: true` in AJV).
93
+
94
+ **Fix.** Disable coercion for strict validation:
95
+
96
+ ```javascript
97
+ new Ajv({ coerceTypes: false, strict: true, allErrors: true })
98
+ ```
99
+
100
+ CLEO contracts are strict by default — incoming data must already be
101
+ typed correctly.
102
+
103
+ ### 3. Missing required not flagged
104
+
105
+ **Symptom.** A required field is missing; schema says it's required;
106
+ validator passes.
107
+
108
+ **Cause.** The schema's `required` is at the wrong level (nested vs
109
+ top), or the validator is in non-strict mode.
110
+
111
+ **Fix.** Re-check the schema structure. `required` must be a peer of
112
+ `properties` at the same nesting level.
113
+
114
+ ### 4. Additional Properties Silently Allowed
115
+
116
+ **Symptom.** Data has extra fields not in the schema; validator passes.
117
+
118
+ **Cause.** Schema does not specify `additionalProperties: false`.
119
+
120
+ **Fix.** CLEO contracts default to `additionalProperties: false` — extra
121
+ fields indicate either drift in the producer or a malicious payload.
122
+ Override only with an inline justification.
123
+
124
+ ## Reporting Schema Violations
125
+
126
+ Each violation goes in the report as:
127
+
128
+ ```markdown
129
+ ### Violations
130
+
131
+ | Path | Keyword | Actual | Expected | File |
132
+ |------|---------|--------|----------|------|
133
+ | `/data/items/3/id` | required | (absent) | string | manifest-instance.json |
134
+ | `/data/version` | type | "1.2.3" (string) | number | manifest-instance.json |
135
+ | `/meta/timestamp` | format | "today" | date-time | manifest-instance.json |
136
+ | `/error.code` | enum | "E_WUT" | one of [E_NOT_FOUND, E_VALIDATION, ...] | response.json |
137
+ ```
138
+
139
+ The Path column uses JSON Pointer (RFC 6901). The Keyword column names
140
+ the schema constraint violated. Actual + Expected gives the diff
141
+ needed to fix.
142
+
143
+ ## Bulk Schema Validation
144
+
145
+ When validating many instances (e.g., every manifest file in
146
+ `.cleo/agent-outputs/`), produce a summary table first, then drill
147
+ into failures.
148
+
149
+ ```markdown
150
+ ## Summary
151
+
152
+ - **Files validated**: 47
153
+ - **Pass**: 42
154
+ - **Fail**: 5
155
+ - **Compliance**: 89.4%
156
+
157
+ ## Failed Files
158
+
159
+ | File | Violations |
160
+ |------|-----------|
161
+ | `.cleo/agent-outputs/2026-05-19_old.md` | 3 |
162
+ | `.cleo/agent-outputs/2026-05-19_draft.md` | 1 |
163
+ | ... | ... |
164
+
165
+ ## Detail (per-file)
166
+
167
+ ### `.cleo/agent-outputs/2026-05-19_old.md`
168
+
169
+ | Path | Keyword | Actual | Expected |
170
+ |------|---------|--------|----------|
171
+ | ... | ... | ... | ... |
172
+ ```
173
+
174
+ Bulk reports SHOULD be machine-readable. Emit a sibling JSON report
175
+ under the same name when the consumer is automation.
176
+
177
+ ## Self-Test the Schema
178
+
179
+ Before trusting any schema for validation, verify it accepts known-good
180
+ instances and rejects known-bad instances. Maintain a `fixtures/`
181
+ directory next to the schema:
182
+
183
+ ```text
184
+ packages/contracts/schemas/envelope.json
185
+ packages/contracts/schemas/fixtures/envelope-valid.json
186
+ packages/contracts/schemas/fixtures/envelope-missing-success.json
187
+ packages/contracts/schemas/fixtures/envelope-wrong-type.json
188
+ ```
189
+
190
+ A test that exercises all three confirms the schema does what it
191
+ claims. Without fixtures, schema drift goes undetected.