@cleocode/core 2026.4.4 → 2026.4.6
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/dist/discovery.d.ts +69 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1643 -2349
- package/dist/index.js.map +4 -4
- package/dist/init.d.ts +51 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/internal.d.ts +9 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/lifecycle/default-chain.d.ts +8 -2
- package/dist/lifecycle/default-chain.d.ts.map +1 -1
- package/dist/lifecycle/index.d.ts +1 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/stage-guidance.d.ts +140 -0
- package/dist/lifecycle/stage-guidance.d.ts.map +1 -0
- package/dist/orchestration/protocol-validators.d.ts +122 -3
- package/dist/orchestration/protocol-validators.d.ts.map +1 -1
- package/dist/paths.d.ts +91 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/scaffold.d.ts +31 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/skills/dispatch.d.ts +1 -1
- package/dist/skills/skill-paths.d.ts +9 -6
- package/dist/skills/skill-paths.d.ts.map +1 -1
- package/dist/validation/protocols/_shared.d.ts +40 -0
- package/dist/validation/protocols/_shared.d.ts.map +1 -0
- package/dist/validation/protocols/architecture-decision.d.ts +23 -0
- package/dist/validation/protocols/architecture-decision.d.ts.map +1 -0
- package/dist/validation/protocols/artifact-publish.d.ts +22 -0
- package/dist/validation/protocols/artifact-publish.d.ts.map +1 -0
- package/dist/validation/protocols/consensus.d.ts +11 -17
- package/dist/validation/protocols/consensus.d.ts.map +1 -1
- package/dist/validation/protocols/contribution.d.ts +12 -17
- package/dist/validation/protocols/contribution.d.ts.map +1 -1
- package/dist/validation/protocols/decomposition.d.ts +18 -21
- package/dist/validation/protocols/decomposition.d.ts.map +1 -1
- package/dist/validation/protocols/implementation.d.ts +9 -17
- package/dist/validation/protocols/implementation.d.ts.map +1 -1
- package/dist/validation/protocols/provenance.d.ts +23 -0
- package/dist/validation/protocols/provenance.d.ts.map +1 -0
- package/dist/validation/protocols/release.d.ts +25 -0
- package/dist/validation/protocols/release.d.ts.map +1 -0
- package/dist/validation/protocols/research.d.ts +9 -17
- package/dist/validation/protocols/research.d.ts.map +1 -1
- package/dist/validation/protocols/specification.d.ts +7 -17
- package/dist/validation/protocols/specification.d.ts.map +1 -1
- package/dist/validation/protocols/testing.d.ts +22 -0
- package/dist/validation/protocols/testing.d.ts.map +1 -0
- package/dist/validation/protocols/validation.d.ts +22 -0
- package/dist/validation/protocols/validation.d.ts.map +1 -0
- package/package.json +7 -7
- package/src/__tests__/injection-mvi-tiers.test.js +54 -90
- package/src/__tests__/injection-mvi-tiers.test.js.map +1 -1
- package/src/discovery.ts +235 -0
- package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js +3 -1
- package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js.map +1 -1
- package/src/index.ts +16 -0
- package/src/init.ts +196 -0
- package/src/internal.ts +31 -1
- package/src/lifecycle/default-chain.ts +11 -2
- package/src/lifecycle/index.ts +10 -0
- package/src/lifecycle/stage-guidance.ts +282 -0
- package/src/metrics/__tests__/provider-detection.test.js +19 -7
- package/src/metrics/__tests__/provider-detection.test.js.map +1 -1
- package/src/metrics/__tests__/provider-detection.test.ts +19 -7
- package/src/orchestration/__tests__/protocol-validators.test.js +228 -8
- package/src/orchestration/__tests__/protocol-validators.test.js.map +1 -1
- package/src/orchestration/__tests__/protocol-validators.test.ts +259 -7
- package/src/orchestration/protocol-validators.ts +419 -4
- package/src/paths.ts +110 -0
- package/src/scaffold.ts +240 -4
- package/src/skills/dispatch.ts +6 -6
- package/src/skills/skill-paths.ts +27 -23
- package/src/validation/protocols/_shared.ts +88 -0
- package/src/validation/protocols/architecture-decision.ts +52 -0
- package/src/validation/protocols/artifact-publish.ts +49 -0
- package/src/validation/protocols/consensus.ts +44 -74
- package/src/validation/protocols/contribution.ts +28 -65
- package/src/validation/protocols/decomposition.ts +37 -64
- package/src/validation/protocols/implementation.ts +25 -65
- package/src/validation/protocols/protocols-markdown/architecture-decision.md +303 -0
- package/src/validation/protocols/protocols-markdown/artifact-publish.md +600 -0
- package/src/validation/protocols/protocols-markdown/consensus.md +322 -0
- package/src/validation/protocols/protocols-markdown/contribution.md +388 -0
- package/src/validation/protocols/protocols-markdown/decomposition.md +421 -0
- package/src/validation/protocols/protocols-markdown/implementation.md +357 -0
- package/src/validation/protocols/protocols-markdown/provenance.md +613 -0
- package/src/validation/protocols/protocols-markdown/release.md +783 -0
- package/src/validation/protocols/protocols-markdown/research.md +261 -0
- package/src/validation/protocols/protocols-markdown/specification.md +300 -0
- package/src/validation/protocols/protocols-markdown/testing.md +287 -0
- package/src/validation/protocols/protocols-markdown/validation.md +242 -0
- package/src/validation/protocols/provenance.ts +50 -0
- package/src/validation/protocols/release.ts +44 -0
- package/src/validation/protocols/research.ts +25 -87
- package/src/validation/protocols/specification.ts +27 -89
- package/src/validation/protocols/testing.ts +46 -0
- package/src/validation/protocols/validation.ts +46 -0
- package/dist/validation/protocols/release-protocol.d.ts +0 -27
- package/dist/validation/protocols/release-protocol.d.ts.map +0 -1
- package/dist/validation/protocols/testing-protocol.d.ts +0 -27
- package/dist/validation/protocols/testing-protocol.d.ts.map +0 -1
- package/dist/validation/protocols/validation-protocol.d.ts +0 -27
- package/dist/validation/protocols/validation-protocol.d.ts.map +0 -1
- package/schemas/agent-configs.schema.json +0 -120
- package/schemas/agent-registry.schema.json +0 -132
- package/schemas/archive.schema.json +0 -450
- package/schemas/brain-decision.schema.json +0 -69
- package/schemas/brain-learning.schema.json +0 -57
- package/schemas/brain-pattern.schema.json +0 -72
- package/schemas/critical-path.schema.json +0 -246
- package/schemas/deps-cache.schema.json +0 -97
- package/schemas/doctor-output.schema.json +0 -283
- package/schemas/error.schema.json +0 -161
- package/schemas/global-config.schema.json +0 -219
- package/schemas/grade.schema.json +0 -49
- package/schemas/log.schema.json +0 -250
- package/schemas/metrics.schema.json +0 -328
- package/schemas/migrations.schema.json +0 -150
- package/schemas/nexus-registry.schema.json +0 -90
- package/schemas/operation-constitution.schema.json +0 -438
- package/schemas/output.schema.json +0 -164
- package/schemas/projects-registry.schema.json +0 -107
- package/schemas/protocol-frontmatter.schema.json +0 -72
- package/schemas/rcasd-consensus-report.schema.json +0 -10
- package/schemas/rcasd-evidence.schema.json +0 -42
- package/schemas/rcasd-gate-result.schema.json +0 -46
- package/schemas/rcasd-hitl-resolution.schema.json +0 -10
- package/schemas/rcasd-index.schema.json +0 -10
- package/schemas/rcasd-manifest.schema.json +0 -10
- package/schemas/rcasd-research-output.schema.json +0 -10
- package/schemas/rcasd-spec-frontmatter.schema.json +0 -10
- package/schemas/rcasd-stage-transition.schema.json +0 -38
- package/schemas/releases.schema.json +0 -267
- package/schemas/skills-manifest.schema.json +0 -91
- package/schemas/spec-index.schema.json +0 -196
- package/schemas/system-flow-atlas.schema.json +0 -125
- package/src/conduit/__tests__/dual-api-e2e.test.d.ts.map +0 -1
- package/src/conduit/__tests__/dual-api-e2e.test.js +0 -178
- package/src/conduit/__tests__/dual-api-e2e.test.js.map +0 -1
- package/src/conduit/__tests__/dual-api-e2e.test.ts +0 -212
- package/src/validation/protocols/release-protocol.ts +0 -80
- package/src/validation/protocols/testing-protocol.ts +0 -93
- package/src/validation/protocols/validation-protocol.ts +0 -93
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: TEST
|
|
3
|
+
title: Testing Protocol (Project-Agnostic IVT Loop)
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
status: active
|
|
6
|
+
type: base
|
|
7
|
+
audience: [llm-agent, orchestrator]
|
|
8
|
+
tags: [testing, ivt-loop, autonomous, framework-agnostic, compliance]
|
|
9
|
+
skillRef: ct-ivt-looper
|
|
10
|
+
lastUpdated: 2026-04-07
|
|
11
|
+
enforcement: strict
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Testing Protocol — Project-Agnostic IVT Loop
|
|
15
|
+
|
|
16
|
+
**Provenance**: @task T260 (replaces T3155 BATS-locked v1)
|
|
17
|
+
**Version**: 2.0.0
|
|
18
|
+
**Type**: Base Protocol
|
|
19
|
+
**Stage**: IVTR — T (Testing, the closure of the IVT loop)
|
|
20
|
+
**Skill**: `ct-ivt-looper`
|
|
21
|
+
|
|
22
|
+
This protocol defines the **autonomous compliance layer** that runs before any release or pull request. It is intentionally **project-agnostic** — it works in any git worktree regardless of language, framework, or directory layout. The previous v1 of this protocol was hardcoded to BATS (Bash testing) and is fully superseded.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Trigger Conditions
|
|
27
|
+
|
|
28
|
+
This protocol activates when the task involves:
|
|
29
|
+
|
|
30
|
+
| Trigger | Keywords | Context |
|
|
31
|
+
|---------|----------|---------|
|
|
32
|
+
| Loop Closure | "ivt loop", "implement and verify", "ship this task" | Autonomous compliance run |
|
|
33
|
+
| Test Execution | "run tests", "verify", "test this" | Test running across any framework |
|
|
34
|
+
| Coverage | "coverage", "test coverage", "missing tests" | Coverage gap analysis |
|
|
35
|
+
| Spec Compliance | "satisfy spec", "verify against spec", "match the requirements" | Spec-driven verification |
|
|
36
|
+
| Release Gate | "before release", "pre-PR validation", "ship verified" | Last gate before release stage |
|
|
37
|
+
|
|
38
|
+
**Explicit Override**: `--protocol testing` flag on task creation.
|
|
39
|
+
|
|
40
|
+
**Lifecycle Position**: After Validation (V), before Release (R). The Testing stage is the **closure of the Implement → Validate → Test loop**, not a one-shot operation.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Core Principle
|
|
45
|
+
|
|
46
|
+
> **The loop converges on the spec, not on "tests pass". Passing tests that don't cover the spec are a failure.**
|
|
47
|
+
|
|
48
|
+
The Testing stage is autonomous: it iterates Implement → Validate → Test until the implementation satisfies every MUST requirement of the specification. It is **not** a single "run the test suite" operation. Convergence is measured against the spec, not against test count.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Project-Agnostic Mandate
|
|
53
|
+
|
|
54
|
+
This protocol MUST work in any project. It MUST NOT assume:
|
|
55
|
+
|
|
56
|
+
- A specific language (TypeScript, Python, Rust, Go, Ruby, PHP, Bash, …)
|
|
57
|
+
- A specific test framework (vitest, jest, pytest, cargo test, …)
|
|
58
|
+
- A specific directory layout (`tests/`, `__tests__/`, `spec/`, `_test.go`, …)
|
|
59
|
+
- A specific test command (`pnpm test`, `pytest`, `cargo test`, `go test ./...`, …)
|
|
60
|
+
|
|
61
|
+
The implementation skill (`ct-ivt-looper`) MUST detect the framework dynamically from project signals before invoking any test command.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Requirements (RFC 2119)
|
|
66
|
+
|
|
67
|
+
### MUST
|
|
68
|
+
|
|
69
|
+
| Requirement | Description |
|
|
70
|
+
|-------------|-------------|
|
|
71
|
+
| TEST-001 | MUST identify the project's test framework via dynamic detection (config files, lockfile, devDependencies, language toolchain). The framework MUST NOT be hardcoded. |
|
|
72
|
+
| TEST-002 | MUST run the IVT loop with an explicit iteration counter and a hard `MAX_ITERATIONS` cap (default 5). |
|
|
73
|
+
| TEST-003 | MUST trace each MUST requirement from the upstream specification to at least one passing test. |
|
|
74
|
+
| TEST-004 | MUST achieve 100% pass rate before exiting with `ivtLoopConverged: true`. Any failing test blocks convergence. |
|
|
75
|
+
| TEST-005 | MUST exit the loop only when the spec is satisfied (every MUST has a passing test) or `MAX_ITERATIONS` is reached. |
|
|
76
|
+
| TEST-006 | MUST write a test summary to the manifest entry's `key_findings` array — at minimum framework, total run, passed, failed, coverage, iterations. |
|
|
77
|
+
| TEST-007 | MUST set `agent_type: "testing"` in the manifest entry. |
|
|
78
|
+
| TEST-008 | MUST run on a feature branch — never on `main`/`master`. The skill MUST stop and request a feature branch if the worktree is on the trunk. |
|
|
79
|
+
| TEST-009 | MUST escalate non-convergence to HITL via exit code 65 with a manifest entry containing `ivtLoopConverged: false` and `ivtLoopIterations: <n>`. |
|
|
80
|
+
|
|
81
|
+
### SHOULD
|
|
82
|
+
|
|
83
|
+
| Requirement | Description |
|
|
84
|
+
|-------------|-------------|
|
|
85
|
+
| TEST-010 | SHOULD test edge cases and error paths, not just happy paths. |
|
|
86
|
+
| TEST-011 | SHOULD include setup/teardown fixtures appropriate to the detected framework. |
|
|
87
|
+
| TEST-012 | SHOULD use descriptive test names tied to spec requirement codes (e.g., "ADR-003: rejects accepted status without HITL review"). |
|
|
88
|
+
| TEST-013 | SHOULD report a coverage percentage when the framework supports it; warn (non-blocking) if below `coverageThreshold`. |
|
|
89
|
+
| TEST-014 | SHOULD prefer `.cleo/project-context.json#testing.command` when present — that file is CLEO's per-project canonical test command. |
|
|
90
|
+
|
|
91
|
+
### MAY
|
|
92
|
+
|
|
93
|
+
| Requirement | Description |
|
|
94
|
+
|-------------|-------------|
|
|
95
|
+
| TEST-020 | MAY add golden tests for output verification. |
|
|
96
|
+
| TEST-021 | MAY add performance benchmarks. |
|
|
97
|
+
| TEST-022 | MAY add stress / concurrency tests. |
|
|
98
|
+
| TEST-023 | MAY parallelize the IVT loop across independent specs when the agent has worktree isolation. |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## The IVT Loop
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
106
|
+
│ Implement → Validate → Test │
|
|
107
|
+
│ │
|
|
108
|
+
│ 1. Load spec (MUST requirements) │
|
|
109
|
+
│ 2. Apply implementation changes │
|
|
110
|
+
│ 3. Run validation (lint + typecheck + spec-match) │
|
|
111
|
+
│ 4. Detect framework, run tests │
|
|
112
|
+
│ 5. Convergence check: │
|
|
113
|
+
│ - All spec MUSTs have passing tests? │
|
|
114
|
+
│ - Validation clean? Tests 100% pass? │
|
|
115
|
+
│ - YES → record convergence, exit loop │
|
|
116
|
+
│ - NO → analyse failures, increment counter │
|
|
117
|
+
│ 6. If counter >= MAX_ITERATIONS → escalate HITL, exit code 65 │
|
|
118
|
+
│ 7. Else → generate fix, GOTO 2 │
|
|
119
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The loop is **autonomous within MAX_ITERATIONS**. It never spins forever and never exits silently with unmet requirements.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Framework Detection (Project-Agnostic)
|
|
127
|
+
|
|
128
|
+
The skill MUST resolve the test command in this priority order:
|
|
129
|
+
|
|
130
|
+
1. **`.cleo/project-context.json#testing.command`** — CLEO's per-project canonical (highest priority)
|
|
131
|
+
2. **Auto-detection signals** in the worktree:
|
|
132
|
+
|
|
133
|
+
| Signal | Framework | Canonical Command |
|
|
134
|
+
|--------|-----------|-------------------|
|
|
135
|
+
| `vitest.config.*` or `vitest` in package.json devDeps | vitest | `pnpm vitest run` (or `npx vitest run`) |
|
|
136
|
+
| `jest.config.*` or `jest` in package.json devDeps | jest | `npx jest --ci` |
|
|
137
|
+
| `mocha` in package.json devDeps and `.mocharc*` | mocha | `npx mocha` |
|
|
138
|
+
| `pytest.ini` / `pyproject.toml [tool.pytest]` / `conftest.py` | pytest | `pytest -q` |
|
|
139
|
+
| `tests/__init__.py` or `unittest` in stdlib usage | unittest | `python -m unittest discover -q` |
|
|
140
|
+
| `Cargo.toml` | cargo-test | `cargo test --quiet` |
|
|
141
|
+
| `go.mod` | go-test | `go test ./...` |
|
|
142
|
+
| `Gemfile` with `rspec` | rspec | `bundle exec rspec` |
|
|
143
|
+
| `phpunit.xml*` | phpunit | `vendor/bin/phpunit` |
|
|
144
|
+
| `*.bats` files in `tests/` | bats | `bats tests/` |
|
|
145
|
+
| none of the above | other | fall back to project-context.json or HITL ask |
|
|
146
|
+
|
|
147
|
+
3. **Fallback** — if no signal matches, the skill MUST stop and ask the operator to declare the test command in `.cleo/project-context.json`.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Convergence Criteria
|
|
152
|
+
|
|
153
|
+
The loop is converged when **ALL** of these are true:
|
|
154
|
+
|
|
155
|
+
- Every MUST requirement from the upstream specification maps to at least one passing test (TEST-003).
|
|
156
|
+
- The test suite reports `failed: 0`.
|
|
157
|
+
- Lint / format / typecheck reports zero errors.
|
|
158
|
+
- Spec-match validation (validation stage protocol VALID-001) confirms implementation matches the spec.
|
|
159
|
+
- No runtime errors in CI-equivalent local commands.
|
|
160
|
+
|
|
161
|
+
If any of the above is false, the loop continues until `MAX_ITERATIONS` is hit.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Branch Discipline
|
|
166
|
+
|
|
167
|
+
- Detect the current branch via `git branch --show-current`.
|
|
168
|
+
- If the branch is `main`, `master`, `trunk`, `develop`, or matches `release/*` → STOP.
|
|
169
|
+
- Refuse to run the IVT loop on a trunk branch. Request a feature branch from the operator before continuing.
|
|
170
|
+
- The IVT loop modifies code; trunk branches MUST be protected.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Manifest Entry
|
|
175
|
+
|
|
176
|
+
Use `cleo research add` to record the IVT loop result:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
cleo research add \
|
|
180
|
+
--title "Testing IVT loop: <feature>" \
|
|
181
|
+
--file "T####-ivt-report.md" \
|
|
182
|
+
--topics "testing,ivt-loop,<framework>" \
|
|
183
|
+
--findings "framework: <name>,run: N,passed: N,failed: 0,iterations: <n>,converged: true" \
|
|
184
|
+
--status complete \
|
|
185
|
+
--task T#### \
|
|
186
|
+
--agent-type testing
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The orchestrator MUST then call:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
cleo check protocol --protocolType testing \
|
|
193
|
+
--taskId T#### \
|
|
194
|
+
--framework <name> \
|
|
195
|
+
--testsRun N --testsPassed N --testsFailed 0 \
|
|
196
|
+
--ivtLoopConverged true --ivtLoopIterations <n>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
This invokes the canonical pure validator (`validateTestingProtocol` in `packages/core/src/orchestration/protocol-validators.ts`) and is the runtime authority for whether the testing stage is complete.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Integration Points
|
|
204
|
+
|
|
205
|
+
### With Implementation Protocol (the "I" of IVT)
|
|
206
|
+
|
|
207
|
+
The IVT loop wraps `implementation` work — every fix iteration is governed by IMPL-001..007. The loop MUST NOT skip the implementation protocol's own gates.
|
|
208
|
+
|
|
209
|
+
### With Validation Protocol (the "V" of IVT)
|
|
210
|
+
|
|
211
|
+
The validation stage runs **inside** each IVT iteration (step 3), not just before testing. Validation reports feed back into the convergence check.
|
|
212
|
+
|
|
213
|
+
### With Release Protocol
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
Testing (T) ──► Release (R)
|
|
217
|
+
│ │
|
|
218
|
+
│ Converged? │ Requires:
|
|
219
|
+
│ Yes │ - ivtLoopConverged: true
|
|
220
|
+
│ │ - testsFailed: 0
|
|
221
|
+
│ │ - All MUSTs covered
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The release stage MUST refuse to advance if the testing stage's manifest entry has `ivtLoopConverged: false`.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Exit Codes
|
|
229
|
+
|
|
230
|
+
| Code | Constant | Meaning |
|
|
231
|
+
|------|----------|---------|
|
|
232
|
+
| 0 | SUCCESS | Loop converged, manifest recorded |
|
|
233
|
+
| 65 | HANDOFF_REQUIRED | Non-convergence after MAX_ITERATIONS — HITL escalation |
|
|
234
|
+
| 67 | CONCURRENT_SESSION | Generic testing protocol violation (used by orchestration validator) |
|
|
235
|
+
| 80 | LIFECYCLE_GATE_FAILED | A required gate (validation, spec-match, branch discipline) failed |
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## HITL Escalation
|
|
240
|
+
|
|
241
|
+
When the loop fails to converge:
|
|
242
|
+
|
|
243
|
+
1. Write a manifest entry with:
|
|
244
|
+
- `agent_type: "testing"`
|
|
245
|
+
- `key_findings: ["framework: <name>", "iterations: <MAX>", "converged: false", "remaining failures: <list>"]`
|
|
246
|
+
- `actionable: true`
|
|
247
|
+
- `needs_followup: ["HITL review required"]`
|
|
248
|
+
2. Exit with code 65 (`HANDOFF_REQUIRED`).
|
|
249
|
+
3. Surface the unmet spec requirements to the operator with concrete next steps.
|
|
250
|
+
|
|
251
|
+
The operator picks up the loop manually, fixes the blocking failure, and re-launches the IVT loop. The skill MUST NOT silently exit, MUST NOT loosen the spec, and MUST NOT mark the task complete.
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Anti-Patterns
|
|
256
|
+
|
|
257
|
+
| Pattern | Why Avoid |
|
|
258
|
+
|---------|-----------|
|
|
259
|
+
| Hardcoding vitest/jest/pytest | Violates the project-agnostic mandate (TEST-001) |
|
|
260
|
+
| Running tests once and reporting result | Testing is a LOOP, not a one-shot (TEST-005) |
|
|
261
|
+
| Skipping validation between iterations | Validation gates are part of IVT, not a pre-step (TEST-009 wraps both) |
|
|
262
|
+
| Bailing silently on non-convergence | Must escalate to HITL with exit 65 (TEST-009) |
|
|
263
|
+
| Marking task complete with `failed > 0` | TEST-004: 100% pass required for convergence |
|
|
264
|
+
| Modifying main/master branch | TEST-008: branch discipline mandatory |
|
|
265
|
+
| Ignoring spec-requirement traceability | TEST-003: every MUST needs a test |
|
|
266
|
+
| Treating coverage as the convergence metric | Coverage is advisory; spec satisfaction is the gate |
|
|
267
|
+
| Editing test expectations to match broken code | The fix goes in the implementation, not the test |
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Cross-Cutting: Contribution Protocol
|
|
272
|
+
|
|
273
|
+
Multi-agent IVT loops MUST record contributor identity per iteration in the contribution protocol. See `protocols-markdown/contribution.md`.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## References
|
|
278
|
+
|
|
279
|
+
- **Skill**: `packages/skills/skills/ct-ivt-looper/SKILL.md` (project-agnostic loop logic)
|
|
280
|
+
- **Pure validator**: `packages/core/src/orchestration/protocol-validators.ts#validateTestingProtocol`
|
|
281
|
+
- **Wrapper**: `packages/core/src/validation/protocols/testing.ts`
|
|
282
|
+
- **Engine op**: `packages/cleo/src/dispatch/engines/validate-engine.ts#validateProtocolTesting`
|
|
283
|
+
- **Dispatch case**: `packages/cleo/src/dispatch/domains/check.ts` (case `'testing'`)
|
|
284
|
+
- **Per-project test command override**: `.cleo/project-context.json#testing.command`
|
|
285
|
+
- **Implementation protocol** (the "I"): `protocols-markdown/implementation.md`
|
|
286
|
+
- **Validation protocol** (the "V"): `protocols-markdown/validation.md`
|
|
287
|
+
- **Release protocol** (downstream gate): `protocols-markdown/release.md`
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: VALID
|
|
3
|
+
title: Validation Protocol
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
status: active
|
|
6
|
+
type: base
|
|
7
|
+
audience: [llm-agent, orchestrator]
|
|
8
|
+
tags: [validation, quality, compliance]
|
|
9
|
+
skillRef: ct-validator
|
|
10
|
+
lastUpdated: 2026-02-24
|
|
11
|
+
enforcement: strict
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Validation Protocol
|
|
15
|
+
|
|
16
|
+
**Provenance**: @task T3155, @epic T3147
|
|
17
|
+
**Version**: 1.0.1
|
|
18
|
+
**Type**: Conditional Protocol
|
|
19
|
+
**Stage**: IVTR - V (Validation)
|
|
20
|
+
**Max Active**: 3 protocols (including base)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Trigger Conditions
|
|
25
|
+
|
|
26
|
+
This protocol activates when the task involves:
|
|
27
|
+
|
|
28
|
+
| Trigger | Keywords | Context |
|
|
29
|
+
|---------|----------|---------|
|
|
30
|
+
| Verification | "validate", "verify", "check", "audit" | Correctness checking |
|
|
31
|
+
| Quality | "quality", "qa", "review" | Quality assurance |
|
|
32
|
+
| Compliance | "compliance", "conform", "standard" | Standards adherence |
|
|
33
|
+
| Smoke Test | "smoke", "sanity", "basic test" | Initial verification |
|
|
34
|
+
|
|
35
|
+
**Explicit Override**: `--protocol validation` flag on task creation.
|
|
36
|
+
|
|
37
|
+
**Lifecycle Position**: After Implementation (I), before Testing (T)
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Requirements (RFC 2119)
|
|
42
|
+
|
|
43
|
+
### MUST
|
|
44
|
+
|
|
45
|
+
| Requirement | Description |
|
|
46
|
+
|-------------|-------------|
|
|
47
|
+
| VALID-001 | MUST verify implementation matches specification |
|
|
48
|
+
| VALID-002 | MUST run existing test suite and report results |
|
|
49
|
+
| VALID-003 | MUST check protocol compliance via `lib/protocol-validation.sh` |
|
|
50
|
+
| VALID-004 | MUST document pass/fail status for each validation check |
|
|
51
|
+
| VALID-005 | MUST write validation summary to manifest |
|
|
52
|
+
| VALID-006 | MUST set `agent_type: "validation"` in manifest |
|
|
53
|
+
| VALID-007 | MUST block progression if critical validations fail |
|
|
54
|
+
|
|
55
|
+
### SHOULD
|
|
56
|
+
|
|
57
|
+
| Requirement | Description |
|
|
58
|
+
|-------------|-------------|
|
|
59
|
+
| VALID-010 | SHOULD verify edge cases identified in specification |
|
|
60
|
+
| VALID-011 | SHOULD check for regressions in related functionality |
|
|
61
|
+
| VALID-012 | SHOULD validate error handling paths |
|
|
62
|
+
| VALID-013 | SHOULD measure against acceptance criteria |
|
|
63
|
+
|
|
64
|
+
### MAY
|
|
65
|
+
|
|
66
|
+
| Requirement | Description |
|
|
67
|
+
|-------------|-------------|
|
|
68
|
+
| VALID-020 | MAY perform performance validation |
|
|
69
|
+
| VALID-021 | MAY verify security constraints |
|
|
70
|
+
| VALID-022 | MAY suggest additional test cases |
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Validation Checklist
|
|
75
|
+
|
|
76
|
+
### Code Validation
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# 1. Syntax check
|
|
80
|
+
bash -n scripts/*.sh lib/*.sh
|
|
81
|
+
|
|
82
|
+
# 2. Protocol compliance
|
|
83
|
+
source lib/protocol-validation.sh
|
|
84
|
+
validate_implementation_protocol "$TASK_ID"
|
|
85
|
+
|
|
86
|
+
# 3. Run existing tests
|
|
87
|
+
bats tests/unit/*.bats
|
|
88
|
+
bats tests/integration/*.bats
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Specification Compliance
|
|
92
|
+
|
|
93
|
+
| Check | Command | Pass Criteria |
|
|
94
|
+
|-------|---------|---------------|
|
|
95
|
+
| Spec exists | `ls docs/specs/*.md` | File present |
|
|
96
|
+
| RFC 2119 keywords | `grep -E "MUST|SHOULD|MAY"` | Keywords present |
|
|
97
|
+
| Implementation matches | Manual review | All MUST satisfied |
|
|
98
|
+
|
|
99
|
+
### Exit Code Validation
|
|
100
|
+
|
|
101
|
+
| Exit Code | Meaning | Action |
|
|
102
|
+
|-----------|---------|--------|
|
|
103
|
+
| 0 | All validations pass | Proceed to Testing |
|
|
104
|
+
| 62 | Specification mismatch | Fix implementation |
|
|
105
|
+
| 64 | Implementation protocol violation | Fix provenance |
|
|
106
|
+
| 67 | Generic protocol violation | Review and fix |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Output Format
|
|
111
|
+
|
|
112
|
+
### Validation Report
|
|
113
|
+
|
|
114
|
+
```markdown
|
|
115
|
+
# Validation Report: T####
|
|
116
|
+
|
|
117
|
+
**Date**: YYYY-MM-DD
|
|
118
|
+
**Validator**: agent-id
|
|
119
|
+
**Task**: T####
|
|
120
|
+
**Epic**: T####
|
|
121
|
+
|
|
122
|
+
## Summary
|
|
123
|
+
|
|
124
|
+
- **Status**: PASS | FAIL | PARTIAL
|
|
125
|
+
- **Checks Passed**: X/Y
|
|
126
|
+
- **Critical Issues**: N
|
|
127
|
+
|
|
128
|
+
## Detailed Results
|
|
129
|
+
|
|
130
|
+
| Check | Result | Notes |
|
|
131
|
+
|-------|--------|-------|
|
|
132
|
+
| Syntax | PASS | No errors |
|
|
133
|
+
| Tests | PASS | 48/48 pass |
|
|
134
|
+
| Protocol | PASS | Compliance 95% |
|
|
135
|
+
|
|
136
|
+
## Issues Found
|
|
137
|
+
|
|
138
|
+
1. [Issue description]
|
|
139
|
+
2. [Issue description]
|
|
140
|
+
|
|
141
|
+
## Recommendations
|
|
142
|
+
|
|
143
|
+
1. [Action item]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Manifest Entry
|
|
147
|
+
|
|
148
|
+
@skills/_shared/manifest-operations.md
|
|
149
|
+
|
|
150
|
+
Use `cleo research add` to create the manifest entry:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
cleo research add \
|
|
154
|
+
--title "Validation: [Feature Name]" \
|
|
155
|
+
--file "T####-validation-report.md" \
|
|
156
|
+
--topics "validation,qa" \
|
|
157
|
+
--findings "RESULT: X/Y checks passed,ISSUES: N found,STATUS: PASS|FAIL" \
|
|
158
|
+
--status complete \
|
|
159
|
+
--task T#### \
|
|
160
|
+
--actionable \
|
|
161
|
+
--agent-type validation
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Integration Points
|
|
167
|
+
|
|
168
|
+
### With Implementation Protocol
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
Implementation (I) ──► Validation (V)
|
|
172
|
+
│
|
|
173
|
+
├── Run tests
|
|
174
|
+
├── Check compliance
|
|
175
|
+
└── Verify spec match
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### With Testing Protocol
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
Validation (V) ──► Testing (T)
|
|
182
|
+
│ │
|
|
183
|
+
│ ├── Write new tests
|
|
184
|
+
│ └── Full coverage
|
|
185
|
+
│
|
|
186
|
+
└── Identifies gaps for Testing to fill
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### With lib/protocol-validation.sh
|
|
190
|
+
|
|
191
|
+
The validation protocol uses these functions:
|
|
192
|
+
|
|
193
|
+
| Function | Purpose | Exit Code |
|
|
194
|
+
|----------|---------|-----------|
|
|
195
|
+
| `validate_implementation_protocol()` | Check IMPL-* compliance | 64 |
|
|
196
|
+
| `validate_specification_protocol()` | Check SPEC-* compliance | 62 |
|
|
197
|
+
| `validate_protocol()` | Generic protocol check | 67 |
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Enforcement
|
|
202
|
+
|
|
203
|
+
### Via lib/protocol-validation.sh
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
source lib/protocol-validation.sh
|
|
207
|
+
|
|
208
|
+
# Validate a specific protocol
|
|
209
|
+
validate_implementation_protocol "$TASK_ID" "$MANIFEST_ENTRY" "true"
|
|
210
|
+
|
|
211
|
+
# Generic validation
|
|
212
|
+
validate_protocol "implementation" "$TASK_ID" "$DATA"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Exit Codes
|
|
216
|
+
|
|
217
|
+
| Code | Constant | Description |
|
|
218
|
+
|------|----------|-------------|
|
|
219
|
+
| 62 | EXIT_PROTOCOL_SPECIFICATION | Spec validation failed |
|
|
220
|
+
| 64 | EXIT_PROTOCOL_IMPLEMENTATION | Implementation validation failed |
|
|
221
|
+
| 67 | EXIT_PROTOCOL_GENERIC | Generic validation failed |
|
|
222
|
+
| 68 | EXIT_VALIDATION_INCOMPLETE | Validation not finished |
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Cross-Cutting: Contribution Protocol
|
|
227
|
+
|
|
228
|
+
When validation involves multi-agent work:
|
|
229
|
+
|
|
230
|
+
1. **Record validator identity** in manifest
|
|
231
|
+
2. **Attribute findings** to validating agent
|
|
232
|
+
3. **Track validation consensus** if multiple validators
|
|
233
|
+
|
|
234
|
+
See: `src/protocols/contribution.md` for attribution requirements.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## References
|
|
239
|
+
|
|
240
|
+
- **Specification**: `docs/specs/PROTOCOL-ENFORCEMENT-SPEC.md` *(ARCHIVED — modernization tracked in T5492)*
|
|
241
|
+
- **Implementation**: `lib/protocol-validation.sh`
|
|
242
|
+
- **Tests**: `tests/unit/protocol-validation.bats`
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provenance protocol — thin wrapper delegating to the canonical pure validator.
|
|
3
|
+
*
|
|
4
|
+
* Provenance is a cross-cutting protocol that composes with release via
|
|
5
|
+
* artifact-publish: artifact-publish delegates signing, SBOM generation, and
|
|
6
|
+
* in-toto attestation chain assembly to provenance (see provenance.md Pipeline
|
|
7
|
+
* Integration and release-engine.ts releaseShip()). The CI pipeline already
|
|
8
|
+
* uses `npm publish --provenance` for SLSA L3 keyless attestation via OIDC.
|
|
9
|
+
*
|
|
10
|
+
* @task T260 — create the missing provenance protocol wrapper
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
type ProtocolValidationResult,
|
|
15
|
+
validateProvenanceProtocol,
|
|
16
|
+
} from '../../orchestration/protocol-validators.js';
|
|
17
|
+
import {
|
|
18
|
+
loadManifestEntryByTaskId,
|
|
19
|
+
loadManifestEntryFromFile,
|
|
20
|
+
throwIfStrictFailed,
|
|
21
|
+
} from './_shared.js';
|
|
22
|
+
|
|
23
|
+
interface ProvenanceOpts {
|
|
24
|
+
strict?: boolean;
|
|
25
|
+
hasAttestation?: boolean;
|
|
26
|
+
hasSbom?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Validate provenance protocol for a task. */
|
|
30
|
+
export async function validateProvenanceTask(
|
|
31
|
+
taskId: string,
|
|
32
|
+
opts: ProvenanceOpts,
|
|
33
|
+
): Promise<ProtocolValidationResult> {
|
|
34
|
+
const entry = loadManifestEntryByTaskId(taskId);
|
|
35
|
+
const result = validateProvenanceProtocol(entry, opts);
|
|
36
|
+
throwIfStrictFailed(result, opts, 'provenance', taskId);
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Validate provenance protocol from a manifest file. */
|
|
41
|
+
export async function checkProvenanceManifest(
|
|
42
|
+
manifestFile: string,
|
|
43
|
+
opts: ProvenanceOpts,
|
|
44
|
+
): Promise<ProtocolValidationResult> {
|
|
45
|
+
const entry = loadManifestEntryFromFile(manifestFile);
|
|
46
|
+
const taskId = entry.linked_tasks?.[0] ?? 'UNKNOWN';
|
|
47
|
+
const result = validateProvenanceProtocol(entry, opts);
|
|
48
|
+
throwIfStrictFailed(result, opts, 'provenance', taskId);
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Release protocol — thin wrapper delegating to the canonical pure validator.
|
|
3
|
+
*
|
|
4
|
+
* Renamed from release-protocol.ts in T260. The release protocol orchestrates
|
|
5
|
+
* version bumping, changelog generation, tagging, and pushing. It composes
|
|
6
|
+
* with artifact-publish and provenance at the release stage (see release.md
|
|
7
|
+
* Pipeline Integration + release-engine.ts releaseShip()).
|
|
8
|
+
*
|
|
9
|
+
* @task T4804
|
|
10
|
+
* @task T260 — drop -protocol suffix, delegate to orchestration validator
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
type ProtocolValidationResult,
|
|
15
|
+
validateReleaseProtocol,
|
|
16
|
+
} from '../../orchestration/protocol-validators.js';
|
|
17
|
+
import {
|
|
18
|
+
loadManifestEntryByTaskId,
|
|
19
|
+
loadManifestEntryFromFile,
|
|
20
|
+
throwIfStrictFailed,
|
|
21
|
+
} from './_shared.js';
|
|
22
|
+
|
|
23
|
+
/** Validate release protocol for a task. */
|
|
24
|
+
export async function validateReleaseTask(
|
|
25
|
+
taskId: string,
|
|
26
|
+
opts: { strict?: boolean; version?: string; hasChangelog?: boolean },
|
|
27
|
+
): Promise<ProtocolValidationResult> {
|
|
28
|
+
const entry = loadManifestEntryByTaskId(taskId);
|
|
29
|
+
const result = validateReleaseProtocol(entry, opts);
|
|
30
|
+
throwIfStrictFailed(result, opts, 'release', taskId);
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Validate release protocol from a manifest file. */
|
|
35
|
+
export async function checkReleaseManifest(
|
|
36
|
+
manifestFile: string,
|
|
37
|
+
opts: { strict?: boolean; version?: string; hasChangelog?: boolean },
|
|
38
|
+
): Promise<ProtocolValidationResult> {
|
|
39
|
+
const entry = loadManifestEntryFromFile(manifestFile);
|
|
40
|
+
const taskId = entry.linked_tasks?.[0] ?? 'UNKNOWN';
|
|
41
|
+
const result = validateReleaseProtocol(entry, opts);
|
|
42
|
+
throwIfStrictFailed(result, opts, 'release', taskId);
|
|
43
|
+
return result;
|
|
44
|
+
}
|