@cleocode/core 2026.4.14 → 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.
Files changed (56) hide show
  1. package/dist/crypto/credentials.d.ts.map +1 -1
  2. package/dist/hooks/payload-schemas.d.ts +1 -1
  3. package/dist/hooks/payload-schemas.d.ts.map +1 -1
  4. package/dist/index.js +34095 -31432
  5. package/dist/index.js.map +4 -4
  6. package/dist/memory/brain-retrieval.d.ts +4 -0
  7. package/dist/memory/brain-retrieval.d.ts.map +1 -1
  8. package/dist/memory/embedding-local.d.ts +5 -5
  9. package/dist/memory/engine-compat.d.ts +4 -0
  10. package/dist/memory/engine-compat.d.ts.map +1 -1
  11. package/dist/memory/mental-model-injection.d.ts +52 -0
  12. package/dist/memory/mental-model-injection.d.ts.map +1 -0
  13. package/dist/memory/mental-model-queue.d.ts +75 -0
  14. package/dist/memory/mental-model-queue.d.ts.map +1 -0
  15. package/dist/orchestration/index.d.ts +2 -0
  16. package/dist/orchestration/index.d.ts.map +1 -1
  17. package/dist/paths.d.ts +65 -0
  18. package/dist/paths.d.ts.map +1 -1
  19. package/dist/store/brain-accessor.d.ts +2 -0
  20. package/dist/store/brain-accessor.d.ts.map +1 -1
  21. package/dist/store/brain-schema.d.ts +16 -0
  22. package/dist/store/brain-schema.d.ts.map +1 -1
  23. package/dist/store/nexus-validation-schemas.d.ts +1 -1
  24. package/dist/store/nexus-validation-schemas.d.ts.map +1 -1
  25. package/dist/store/validation-schemas.d.ts +1 -1
  26. package/dist/store/validation-schemas.d.ts.map +1 -1
  27. package/migrations/drizzle-brain/20260408000001_t417-agent-field/migration.sql +13 -0
  28. package/migrations/drizzle-brain/20260408000001_t417-agent-field/snapshot.json +28 -0
  29. package/package.json +15 -15
  30. package/src/__tests__/ct-master-tac-install.test.ts +168 -0
  31. package/src/crypto/credentials.ts +28 -0
  32. package/src/hooks/payload-schemas.ts +1 -1
  33. package/src/memory/__tests__/mental-model-wave-8.test.ts +355 -0
  34. package/src/memory/brain-retrieval.ts +55 -29
  35. package/src/memory/embedding-local.ts +5 -5
  36. package/src/memory/engine-compat.ts +24 -2
  37. package/src/memory/mental-model-injection.ts +87 -0
  38. package/src/memory/mental-model-queue.ts +291 -0
  39. package/src/orchestration/index.ts +2 -0
  40. package/src/paths.ts +79 -0
  41. package/src/store/brain-accessor.ts +5 -0
  42. package/src/store/brain-schema.ts +4 -0
  43. package/src/store/nexus-validation-schemas.ts +3 -3
  44. package/src/store/validation-schemas.ts +3 -3
  45. package/src/validation/protocols/cant/architecture-decision.cant +12 -2
  46. package/src/validation/protocols/cant/artifact-publish.cant +11 -1
  47. package/src/validation/protocols/cant/consensus.cant +12 -1
  48. package/src/validation/protocols/cant/contribution.cant +11 -1
  49. package/src/validation/protocols/cant/decomposition.cant +11 -1
  50. package/src/validation/protocols/cant/implementation.cant +11 -1
  51. package/src/validation/protocols/cant/provenance.cant +13 -1
  52. package/src/validation/protocols/cant/release.cant +12 -1
  53. package/src/validation/protocols/cant/research.cant +12 -1
  54. package/src/validation/protocols/cant/specification.cant +11 -1
  55. package/src/validation/protocols/cant/testing.cant +12 -1
  56. package/src/validation/protocols/cant/validation.cant +11 -1
package/src/paths.ts CHANGED
@@ -15,6 +15,7 @@
15
15
  * @task T4458
16
16
  */
17
17
 
18
+ import { AsyncLocalStorage } from 'node:async_hooks';
18
19
  import { existsSync, readFileSync } from 'node:fs';
19
20
  import { homedir } from 'node:os';
20
21
  import { dirname, join, resolve } from 'node:path';
@@ -22,6 +23,76 @@ import { ExitCode } from '@cleocode/contracts';
22
23
  import { CleoError } from './errors.js';
23
24
  import { getPlatformPaths } from './system/platform-paths.js';
24
25
 
26
+ // ============================================================================
27
+ // Worktree Scope (T380/ADR-041 §D3)
28
+ // ============================================================================
29
+
30
+ /**
31
+ * Async context payload set by the spawn adapter when launching a subagent
32
+ * inside a git worktree (ADR-041 §D3).
33
+ *
34
+ * @remarks
35
+ * When `worktreeScope.run(scope, fn)` is active, `getProjectRoot()` returns
36
+ * `scope.worktreeRoot` instead of walking ancestors. All DB path functions
37
+ * that delegate to `getProjectRoot()` therefore direct their I/O to the
38
+ * worktree's `.cleo/` directory, closing the T335 worktree-leak root cause.
39
+ *
40
+ * For processes that were spawned with `CLEO_WORKTREE_ROOT` in their
41
+ * environment (but where AsyncLocalStorage is not in scope), callers should
42
+ * populate the store via:
43
+ * ```ts
44
+ * worktreeScope.run(
45
+ * { worktreeRoot: process.env.CLEO_WORKTREE_ROOT, projectHash: process.env.CLEO_PROJECT_HASH },
46
+ * () => { ... }
47
+ * );
48
+ * ```
49
+ *
50
+ * @task T380
51
+ * @public
52
+ */
53
+ export interface WorktreeScope {
54
+ /**
55
+ * Absolute path to the worktree directory (value of `CLEO_WORKTREE_ROOT`).
56
+ */
57
+ worktreeRoot: string;
58
+ /**
59
+ * Project hash used to scope the worktree under the XDG worktree root
60
+ * (value of `CLEO_PROJECT_HASH`).
61
+ */
62
+ projectHash: string;
63
+ }
64
+
65
+ /**
66
+ * AsyncLocalStorage instance that carries the active {@link WorktreeScope}
67
+ * for the current async execution context.
68
+ *
69
+ * @remarks
70
+ * Set by the spawn adapter (or any caller that wants to redirect CLEO path
71
+ * resolution to a worktree directory) before invoking subagent logic.
72
+ * `getProjectRoot()` checks this store BEFORE the `CLEO_ROOT` env-var and
73
+ * ancestor-walk, so scoped callers transparently receive the worktree root.
74
+ *
75
+ * Callers outside a worktree context receive `undefined` from
76
+ * `worktreeScope.getStore()` and fall through to the existing resolution
77
+ * order unchanged.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * import { worktreeScope } from '@cleocode/core/paths';
82
+ *
83
+ * worktreeScope.run(
84
+ * { worktreeRoot: '/path/to/worktree', projectHash: 'abc123' },
85
+ * async () => {
86
+ * const root = getProjectRoot(); // returns '/path/to/worktree'
87
+ * }
88
+ * );
89
+ * ```
90
+ *
91
+ * @task T380
92
+ * @public
93
+ */
94
+ export const worktreeScope = new AsyncLocalStorage<WorktreeScope>();
95
+
25
96
  /**
26
97
  * Check if a CLEO project is initialized at the given root.
27
98
  * Checks for tasks.db.
@@ -209,6 +280,14 @@ export function getCleoDirAbsolute(cwd?: string): string {
209
280
  * ```
210
281
  */
211
282
  export function getProjectRoot(cwd?: string): string {
283
+ // 0. AsyncLocalStorage worktree scope (T380/ADR-041 §D3) — checked FIRST.
284
+ // When a spawn adapter wraps execution in worktreeScope.run(...), the
285
+ // scoped root wins over all env-var and walk-based resolution.
286
+ const scope = worktreeScope.getStore();
287
+ if (scope !== undefined) {
288
+ return scope.worktreeRoot;
289
+ }
290
+
212
291
  // 1. Honour CLEO_ROOT env var — bypass walk entirely
213
292
  if (process.env['CLEO_ROOT']) {
214
293
  return process.env['CLEO_ROOT'];
@@ -251,6 +251,8 @@ export class BrainDataAccessor {
251
251
  project?: string;
252
252
  sourceType?: (typeof brainSchema.BRAIN_OBSERVATION_SOURCE_TYPES)[number];
253
253
  sourceSessionId?: string;
254
+ /** T417: filter by agent provenance name (Wave 8 mental models). */
255
+ agent?: string;
254
256
  limit?: number;
255
257
  } = {},
256
258
  ): Promise<BrainObservationRow[]> {
@@ -268,6 +270,9 @@ export class BrainDataAccessor {
268
270
  if (params.sourceSessionId) {
269
271
  conditions.push(eq(brainSchema.brainObservations.sourceSessionId, params.sourceSessionId));
270
272
  }
273
+ if (params.agent) {
274
+ conditions.push(eq(brainSchema.brainObservations.agent, params.agent));
275
+ }
271
276
 
272
277
  let query = this.db
273
278
  .select()
@@ -172,6 +172,8 @@ export const brainObservations = sqliteTable(
172
172
  sourceType: text('source_type', { enum: BRAIN_OBSERVATION_SOURCE_TYPES })
173
173
  .notNull()
174
174
  .default('agent'),
175
+ /** T383/T417: agent provenance — identifies the spawned agent that produced this observation. Null for legacy entries. */
176
+ agent: text('agent'), // nullable — null for legacy observations
175
177
  contentHash: text('content_hash'), // SHA-256 prefix for dedup
176
178
  discoveryTokens: integer('discovery_tokens'), // cost to produce this observation
177
179
  createdAt: text('created_at').notNull().default(sql`(datetime('now'))`),
@@ -187,6 +189,8 @@ export const brainObservations = sqliteTable(
187
189
  index('idx_brain_observations_content_hash_created_at').on(table.contentHash, table.createdAt),
188
190
  // T033: type + project compound filter optimization
189
191
  index('idx_brain_observations_type_project').on(table.type, table.project),
192
+ // T417: agent provenance index for memory.find --agent filter
193
+ index('idx_brain_observations_agent').on(table.agent),
190
194
  ],
191
195
  );
192
196
 
@@ -14,11 +14,11 @@
14
14
  */
15
15
 
16
16
  import { createSchemaFactory } from 'drizzle-orm/zod';
17
- import { z } from 'zod/v4';
17
+ import { z } from 'zod';
18
18
 
19
- // Use factory to bind our zod/v4 instance — ensures drizzle-orm/zod uses
19
+ // Use factory to bind our zod instance — ensures drizzle-orm/zod uses
20
20
  // the same z we use everywhere. The type assertion is needed because
21
- // drizzle-orm beta.18's CoerceOptions type doesn't match zod/v4's coerce
21
+ // drizzle-orm beta.18's CoerceOptions type doesn't match zod's coerce
22
22
  // namespace shape (works correctly at runtime).
23
23
  const { createInsertSchema, createSelectSchema } = createSchemaFactory(
24
24
  z as unknown as Parameters<typeof createSchemaFactory>[0],
@@ -13,11 +13,11 @@
13
13
  */
14
14
 
15
15
  import { createSchemaFactory } from 'drizzle-orm/zod';
16
- import { z } from 'zod/v4';
16
+ import { z } from 'zod';
17
17
 
18
- // Use factory to bind our zod/v4 instance — ensures drizzle-orm/zod uses
18
+ // Use factory to bind our zod instance — ensures drizzle-orm/zod uses
19
19
  // the same z we use everywhere. The type assertion is needed because
20
- // drizzle-orm beta.18's CoerceOptions type doesn't match zod/v4's coerce
20
+ // drizzle-orm beta.18's CoerceOptions type doesn't match zod's coerce
21
21
  // namespace shape (works correctly at runtime).
22
22
  const { createInsertSchema, createSelectSchema } = createSchemaFactory(
23
23
  z as unknown as Parameters<typeof createSchemaFactory>[0],
@@ -8,13 +8,23 @@ type: conditional
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "adr, architecture, decisions"
10
10
  skillRef: ct-adr-recorder
11
- lastUpdated: 2026-04-07
11
+ lastUpdated: 2026-04-08
12
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"
13
23
  ---
14
24
 
15
25
  # Architecture Decision Record (ADR) Protocol
16
26
  #
17
- # Provenance: @task T4798 (ADR-006 Implementation)
27
+ # Provenance: @task T4798 (ADR-006 Implementation), @task T428 (gap patch)
18
28
  # Type: Conditional Protocol
19
29
  # Stage: RCADSD - A (ADR)
20
30
  # Max Active: 3 protocols (including base)
@@ -8,12 +8,22 @@ type: cross-cutting
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "artifact, publish, distribution"
10
10
  skillRef: ct-artifact-publisher
11
- lastUpdated: 2026-04-07
11
+ lastUpdated: 2026-04-08
12
12
  enforcement: advisory
13
+ stage: "release"
14
+ consult-when: "Publishing artifacts to any registry (npm, cargo, docker, PyPI, GitHub releases); any task with --protocol artifact-publish; release pipeline artifact phase"
15
+ input:
16
+ artifact_type: "npm-package | python-wheel | python-sdist | go-module | cargo-crate | ruby-gem | docker-image | github-release | generic-tarball"
17
+ version: "string — version string consistent with release config"
18
+ dry_run: "boolean — MUST be true on first invocation"
19
+ output:
20
+ published_artifacts: "object[] — array of {type, name, registry_url, sha256, slsa_level}"
21
+ rollback_manifest: "string | null — path to rollback manifest if partial failure"
13
22
  ---
14
23
 
15
24
  # Artifact Publish Protocol
16
25
  #
26
+ # Provenance: @task T428 (gap patch)
17
27
  # Type: Conditional Protocol
18
28
  # Max Active: 3 protocols (including base)
19
29
  #
@@ -8,8 +8,19 @@ type: conditional
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "consensus, voting, validation"
10
10
  skillRef: ct-consensus-voter
11
- lastUpdated: 2026-04-07
11
+ lastUpdated: 2026-04-08
12
12
  enforcement: strict
13
+ stage: "consensus"
14
+ consult-when: "Reaching a decision that two or more agents must vote on; architecture choices, tool selection, policy decisions; any task carrying agent_type:analysis; phrases like 'reach consensus', 'vote on options', 'resolve the debate'"
15
+ input:
16
+ topic: "string — the question or decision to vote on"
17
+ options: "string[] — candidate options agents vote on"
18
+ agents: "string[] — agent IDs participating in the vote"
19
+ output:
20
+ verdict: "PROVEN | REFUTED | CONTESTED | INSUFFICIENT_EVIDENCE"
21
+ confidence: "number — weighted confidence score 0.0–1.0"
22
+ voting_matrix: "object — per-agent votes with rationale and confidence"
23
+ hitl_required: "boolean — true when threshold not reached"
13
24
  ---
14
25
 
15
26
  # Consensus Protocol
@@ -8,8 +8,18 @@ type: cross-cutting
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "contribution, commit, pr"
10
10
  skillRef: ct-contribution
11
- lastUpdated: 2026-02-24
11
+ lastUpdated: 2026-04-08
12
12
  enforcement: strict
13
+ stage: "cross-cutting"
14
+ consult-when: "Submitting work via git commit or PR; multi-agent consensus contribution; task carries 'contribution protocol', 'submit contribution', or 'consensus workflow'; any cross-cutting attribution recording"
15
+ input:
16
+ task_id: "string — task being contributed"
17
+ commit_message: "string — conventional commit message"
18
+ contributors: "string[] — agent or human contributor IDs"
19
+ output:
20
+ commit_sha: "string — resulting commit SHA"
21
+ pr_url: "string | null — pull request URL if opened"
22
+ attribution_recorded: "boolean — true when contribution row persisted"
13
23
  ---
14
24
 
15
25
  # Contribution Protocol
@@ -8,9 +8,19 @@ type: conditional
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "decomposition, hierarchy, atomicity, planning"
10
10
  skillRef: ct-epic-architect
11
- lastUpdated: 2026-02-24
11
+ lastUpdated: 2026-04-08
12
12
  provenanceTask: T3155
13
13
  enforcement: strict
14
+ stage: "decomposition"
15
+ consult-when: "Breaking a large initiative into atomic tasks; creating epics; planning parallel wave execution; any task with 'decompose', 'break down', 'epic architect', or 'plan tasks'"
16
+ input:
17
+ epic_title: "string — high-level initiative title"
18
+ scope: "string — description of the work to decompose"
19
+ constraints: "string[] — known constraints or exclusions"
20
+ output:
21
+ tasks: "object[] — array of {id, title, size, dependencies, wave} atomic tasks"
22
+ dependency_graph: "object — DAG of task dependencies"
23
+ wave_plan: "object[] — array of {wave, tasks[]} parallel execution waves"
14
24
  ---
15
25
 
16
26
  # Decomposition Protocol
@@ -8,8 +8,18 @@ type: base
8
8
  audience: "llm-agent"
9
9
  tags: "implementation, coding, development"
10
10
  skillRef: ct-task-executor
11
- lastUpdated: 2026-02-24
11
+ lastUpdated: 2026-04-08
12
12
  enforcement: strict
13
+ stage: "implementation"
14
+ consult-when: "Implementing code, fixing bugs, building features, writing programs; any task with 'implement', 'build', 'create', 'fix', 'patch'; IVT loop implementation phase"
15
+ input:
16
+ task_id: "string — task being implemented"
17
+ spec_ref: "string | null — path or ID of the governing specification"
18
+ acceptance_criteria: "string[] — conditions that must be true on completion"
19
+ output:
20
+ files_changed: "string[] — list of modified/created files"
21
+ tests_added: "string[] — new test files or test names"
22
+ manifest_entry: "object — implementation summary for MANIFEST.jsonl"
13
23
  ---
14
24
 
15
25
  # Implementation Protocol
@@ -8,12 +8,24 @@ type: cross-cutting
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "provenance, traceability, lineage"
10
10
  skillRef: ct-provenance-keeper
11
- lastUpdated: 2026-04-07
11
+ lastUpdated: 2026-04-08
12
12
  enforcement: advisory
13
+ stage: "release"
14
+ consult-when: "Generating in-toto attestations, SLSA provenance, or SBOMs; signing artifacts; any task with 'provenance', 'attest', 'sbom', 'cosign', 'checksum', or 'supply chain'; invoked by artifact-publish at signing step"
15
+ input:
16
+ artifact_paths: "string[] — paths to built artifacts requiring provenance"
17
+ source_commit: "string — git SHA of the source commit"
18
+ build_environment: "string — description of build environment"
19
+ output:
20
+ attestation_path: "string — path to in-toto attestation JSON"
21
+ sbom_path: "string | null — path to CycloneDX or SPDX SBOM"
22
+ slsa_level: "1 | 2 | 3 | 4 — achieved SLSA Build Level"
23
+ digests: "object — map of artifact_path to sha256 digest"
13
24
  ---
14
25
 
15
26
  # Provenance Protocol
16
27
  #
28
+ # Provenance: @task T428 (gap patch)
17
29
  # Type: Conditional Protocol
18
30
  # Max Active: 3 protocols (including base)
19
31
  #
@@ -8,8 +8,19 @@ type: conditional
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "release, semver, changelog"
10
10
  skillRef: ct-release-orchestrator
11
- lastUpdated: 2026-04-07
11
+ lastUpdated: 2026-04-08
12
12
  enforcement: strict
13
+ stage: "release"
14
+ consult-when: "Shipping a new version; running 'cleo release ship'; promoting a completed epic to released status; any task with 'release', 'version bump', 'changelog', 'tag', 'publish'"
15
+ input:
16
+ version: "string — CalVer YYYY.MM.patch target version"
17
+ changelog_entries: "string[] — summarized changes since last release"
18
+ artifact_config: "object | null — artifact publish config; null for source-only releases"
19
+ output:
20
+ release_tag: "string — git tag created (e.g. v2026.4.5)"
21
+ changelog_path: "string — path to updated CHANGELOG file"
22
+ artifacts_published: "boolean — true when artifact phase ran"
23
+ release_manifest: "object — release summary for MANIFEST.jsonl"
13
24
  ---
14
25
 
15
26
  # Release Protocol
@@ -8,8 +8,19 @@ type: base
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "research, investigation, evidence"
10
10
  skillRef: ct-research-agent
11
- lastUpdated: 2026-02-24
11
+ lastUpdated: 2026-04-08
12
12
  enforcement: strict
13
+ stage: "research"
14
+ consult-when: "Investigating unknown territory; gathering evidence before a consensus or specification; any task with 'research', 'investigate', 'explore', 'study', 'discover', 'analyze'; tasks that explicitly must NOT modify code"
15
+ input:
16
+ topic: "string — subject of investigation"
17
+ scope: "string — boundaries of the research (what to include/exclude)"
18
+ output_dir: "string — directory for findings (default: .cleo/agent-outputs/)"
19
+ output:
20
+ findings_path: "string — path to the research output markdown file"
21
+ manifest_entry: "object — 3–7 key findings for MANIFEST.jsonl"
22
+ confidence_levels: "object — per-finding confidence 0.0–1.0"
23
+ sources: "string[] — cited URLs or file paths"
13
24
  ---
14
25
 
15
26
  # Research Protocol
@@ -8,8 +8,18 @@ type: conditional
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "specification, requirements, rfc2119"
10
10
  skillRef: ct-spec-writer
11
- lastUpdated: 2026-02-24
11
+ lastUpdated: 2026-04-08
12
12
  enforcement: strict
13
+ stage: "specification"
14
+ consult-when: "Writing technical specifications, API contracts, or requirements documents; any task with 'spec', 'specification', 'requirements', 'rfc'; Specification stage only unlocks after an accepted ADR"
15
+ input:
16
+ adr_id: "string — accepted ADR that governs this specification"
17
+ scope: "string — what the spec covers"
18
+ audience: "llm-agent | human | both — intended readers"
19
+ output:
20
+ spec_path: "string — path to the written specification file"
21
+ requirement_count: "number — total MUST/SHOULD/MAY requirements"
22
+ testable_criteria: "string[] — acceptance criteria derivable from the spec"
13
23
  ---
14
24
 
15
25
  # Specification Protocol
@@ -8,8 +8,19 @@ type: base
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "testing, ivt-loop, autonomous, framework-agnostic, compliance"
10
10
  skillRef: ct-ivt-looper
11
- lastUpdated: 2026-04-07
11
+ lastUpdated: 2026-04-08
12
12
  enforcement: strict
13
+ stage: "testing"
14
+ consult-when: "Running the IVT loop after implementation; verifying acceptance criteria; any task with 'implement and verify', 'run IVT', 'ship this task', 'verify against spec', or implementation tasks with acceptance criteria"
15
+ input:
16
+ task_id: "string — task under test"
17
+ spec_ref: "string | null — specification or acceptance criteria reference"
18
+ worktree: "string — git worktree path for test execution"
19
+ output:
20
+ test_framework: "vitest | jest | mocha | pytest | cargo-test | go-test | rspec | phpunit | bats | other"
21
+ convergence_iterations: "number — IVT loop iterations to convergence"
22
+ test_results: "object — {passed, failed, skipped} counts"
23
+ manifest_entry: "object — convergence metrics for MANIFEST.jsonl"
13
24
  ---
14
25
 
15
26
  # Testing Protocol - Project-Agnostic IVT Loop
@@ -8,8 +8,18 @@ type: base
8
8
  audience: "llm-agent, orchestrator"
9
9
  tags: "validation, quality, compliance"
10
10
  skillRef: ct-validator
11
- lastUpdated: 2026-02-24
11
+ lastUpdated: 2026-04-08
12
12
  enforcement: strict
13
+ stage: "validation"
14
+ consult-when: "Validating compliance against a schema, spec, or standard; running quality checks; any task with 'validate', 'compliance', 'verify', 'audit'; post-implementation quality gate"
15
+ input:
16
+ target: "string — file path, document, or system under validation"
17
+ schema_ref: "string | null — schema or standard reference"
18
+ validation_type: "schema | code-style | protocol | document | custom"
19
+ output:
20
+ passed: "boolean — overall validation result"
21
+ violations: "object[] — array of {rule, severity, location, message}"
22
+ report_path: "string — path to detailed validation report"
13
23
  ---
14
24
 
15
25
  # Validation Protocol