kryptobaseddev

ct-ivt-looper

"Runs a project-agnostic autonomous Implement-then-Validate-then-Test compliance loop on any git worktree. Detects the project's test framework (vitest, jest, mocha, pytest, unittest, go-test, cargo-test, rspec, phpunit, bats, or other) and iterates until the implementation satisfies its specification, recording convergence metrics to the manifest. Use when given an implementation task that must ship verified: the IVT loop is the autonomous compliance layer enforced before any release or PR. Triggers on phrases like 'implement and verify', 'run the IVT loop', 'ship this task', 'complete implementation with tests', 'verify against spec', or any implementation task with acceptance criteria. Works in any git worktree regardless of language or framework, never hardcoded to one project's tooling."

kryptobaseddev 159 25 Updated 3w ago

Resources

2
GitHub

Install

npx skillscat add kryptobaseddev/cleo/ct-ivt-looper

Install via the SkillsCat registry.

SKILL.md

IVT Looper

Overview

Runs an autonomous Implement-then-Validate-then-Test loop against any git worktree, detects the test framework in use, and iterates until the implementation converges on its specification. This skill is the autonomous compliance layer: no task ships, no release runs, and no PR opens until the loop has recorded a converged result to the manifest.

Core Principle

The loop converges on the spec, not on 'tests pass'. Passing tests that don't cover the spec is a failure.

Immutable Constraints

ID Rule Enforcement
IVT-001 Test framework MUST be detected or declared before the loop starts. validateTestingProtocol rejects entries without a framework; deducts 20 from score.
IVT-002 Loop MUST cap iterations at MAX_ITERATIONS (default 5). Hard counter in the loop; unreachable convergence forces HITL escalation.
IVT-003 Every MUST requirement in the spec MUST map to at least one passing test. Spec-to-test traceability matrix; gaps block convergence.
IVT-004 Final manifest entry MUST record framework, testsRun, testsPassed, testsFailed, ivtLoopConverged, ivtLoopIterations. validateTestingProtocol requires these fields; ivtLoopConverged: false fails validation.
IVT-005 Framework detection MUST NOT be hardcoded to one project's tooling. Detection walks the project tree; no vitest/jest-only code paths.
IVT-006 Loop MUST NOT run on the main branch. Check git branch --show-current; stop if on main/master/trunk.
IVT-007 Non-convergence after MAX_ITERATIONS MUST escalate to HITL (exit code 65). Agent stops, writes manifest with ivtLoopConverged: false, exits.
IVT-008 Final manifest entry MUST set agent_type: "testing". Validator rejects any other value.

The IVT Loop

load_spec(task_id)                         # read acceptance criteria from canon
detect_framework(worktree)                 # see references/frameworks.md
branch_check()                             # abort if on main/master/trunk
iteration = 0

while iteration < MAX_ITERATIONS:          # IVT-002
    iteration += 1

    # ----- I : Implement -----
    apply_patch(current_diff)              # patch generated by the implementer
    ensure_provenance_tags(new_code)       # IMPL-003 tags on new functions

    # ----- V : Validate -----
    lint_result = run_project_linter()
    type_result = run_type_checker()       # tsc / mypy / go vet / rustc
    if lint_result.failed or type_result.failed:
        regenerate_fix_for(lint_result, type_result)
        continue                           # back to top, same iteration count

    # ----- T : Test -----
    test_result = run_framework_tests()    # framework-specific command
    trace = spec_to_test_trace(spec)       # IVT-003: every MUST has a test
    if test_result.all_passed and trace.complete:
        write_manifest(
            framework=framework,
            iterations=iteration,
            converged=True,
            agent_type="testing",
        )
        return CONVERGED                   # exit loop, exit skill with code 0

    # ----- Analyze and regenerate fix -----
    failure = diagnose(test_result, trace)
    current_diff = regenerate_fix_for(failure)

# MAX_ITERATIONS reached without convergence
write_manifest(
    framework=framework,
    iterations=MAX_ITERATIONS,
    converged=False,
    agent_type="testing",
)
escalate_to_hitl()                         # IVT-007: exit code 65

The loop is a single stage from the lifecycle's point of view. Implement, Validate, and Test are not three separate tasks — they are three phases of one autonomous run that either converges or escalates.

Out of Scope (T9675)

ct-ivt-looper operates on the testing LOOM lifecycle stage (stage 8). It performs the dynamic Implement-then-Validate-then-Test loop with framework detection and iterate-until-green convergence semantics.

This skill does NOT:

  • Audit static artifacts for schema/compliance/RFC-2119 keyword usage, ADR-document structure, or JSON Schema conformance. Those belong to ct-validator at the validation stage (stage 7). When the question is "is this document/manifest well-formed?" rather than "does this code converge on its spec?", chain to ct-validator rather than expanding scope here.
  • Promote a green loop to release. Release sequencing belongs to ct-release-orchestrator at stage 9.

Chain handoffs

Direction When Handoff
ct-ivt-looper → ct-validator Loop converged; need to audit the resulting artifacts (e.g. final manifest, spec back-references) against schema/compliance Emit the convergence manifest entry, then dispatch the validation stage
ct-validator → ct-ivt-looper Spec is valid but implementation needs dynamic verification Receive a dispatch from the validation stage; iterate the IVT loop on the worktree

Governance: see ADR-051 (programmatic gate integrity) which defines the evidence atoms (test-run:<json>, tool:test, tool:test-affected where testing.affectedCommand is configured — a full tool:test then only for root-config changes — and ci:<pr> once the PR merged in a project that sets evidence.ciSatisfies) the loop emits and that downstream cleo verify --gate testsPassed re-validates, and ADR-061 (project-agnostic verify tools) which defines the canonical tool-resolution layer.

Framework Detection

Framework detection is project-agnostic: the skill walks the worktree, inspects config files, and selects the correct test command. No language or framework is special-cased above another. The full detection table lives in references/frameworks.md. In summary: detection reads the project manifest (package.json, pyproject.toml, Cargo.toml, go.mod, Gemfile, composer.json, or .cleo/project-context.json#testing.command) and selects one of: vitest, jest, mocha, pytest, unittest, go-test, cargo-test, rspec, phpunit, bats, other.

Convergence Criteria

The loop has converged when all of the following hold:

  • Every MUST requirement in the task's linked specification has at least one passing test (spec-to-test traceability complete).
  • testsFailed == 0, testsRun > 0, and testsPassed == testsRun.
  • Project linter reports zero errors (warnings are allowed).
  • Type checker reports zero errors.
  • CI-equivalent local commands return zero (e.g., pnpm run build, cargo build, go build ./...).
  • No new runtime errors were observed during the test run.

A loop that makes tests pass by deleting assertions, narrowing scope, or mocking the thing under test is not converged — that is a spec violation dressed up as a green run. See references/loop-anatomy.md for worked examples.

Branch Discipline

Before iteration 1, the skill MUST verify the current branch:

branch=$(git branch --show-current)
if [[ "$branch" == "main" || "$branch" == "master" || "$branch" == "trunk" ]]; then
    echo "Refusing to run IVT loop on protected branch: $branch"
    exit 65   # HANDOFF_REQUIRED: ask HITL for a feature branch
fi

The loop is destructive in the sense that it rewrites code on failed iterations. It MUST run on a feature branch or worktree. If the user invoked it on a protected branch, stop and request a feature branch.

Escalation on Non-Convergence

When the loop exhausts MAX_ITERATIONS without converging, the skill MUST:

  1. Write the manifest entry with ivtLoopConverged: false and the iteration count.
  2. Record the last diagnostic output in key_findings.
  3. Exit with code 65 (HANDOFF_REQUIRED).
  4. Leave the worktree in its last state — do not revert.

The human reviewer picks up the worktree, reads the diagnostics, and either raises the iteration cap, rewrites the spec, or manually corrects the implementation before rerunning the skill. The full escalation handoff protocol is in references/escalation.md.

Integration

Record the loop outcome through cleo check protocol:

# Success case: loop converged on iteration 3.
cleo check protocol testing \
  --framework vitest \
  --tests-run 142 \
  --tests-passed 142 \
  --tests-failed 0 \
  --ivt-loop-converged true \
  --ivt-loop-iterations 3

# Failure case: loop exhausted iterations, HITL escalation.
cleo check protocol testing \
  --framework pytest \
  --tests-run 87 \
  --tests-passed 84 \
  --tests-failed 3 \
  --ivt-loop-converged false \
  --ivt-loop-iterations 5

Exit code 0 = loop converged and protocol is valid. Exit code 65 = HANDOFF_REQUIRED (non-convergence).

This skill MUST also chain a validation check against the spec before its own testing check:

cleo check protocol validation \
  --spec-match-confirmed true \
  --test-suite-passed true \
  --protocol-compliance-checked true

Anti-Patterns

Pattern Problem Solution
Hardcoding vitest or jest Violates IVT-005; breaks on any non-JS project Walk the worktree and pick the framework per project
Running the loop on main/master Violates IVT-006; pollutes shared branch Check git branch --show-current and refuse protected branches
No iteration cap Infinite loop on unreachable convergence; context burn Enforce MAX_ITERATIONS (default 5); escalate to HITL on exhaustion
Deleting assertions to force green Tests pass but the spec is not met The skill requires spec-to-test traceability; gaps block convergence
Skipping the validation phase Lint or type errors slip through The loop MUST run lint and type check before the test phase every iteration
Treating testing as "just run the tests" Misses the loop; one-shot runs are not compliant Testing is a loop, not a single call; record ivtLoopIterations
Running the full suite on every iteration Burns CPU/RAM shared with other agents; the cache misses on every edit Iterate on the failing or changed test files; record evidence once at the end: tool:test-affected when testing.affectedCommand is configured, else a targeted test-run:<json> or tool:test; ci:<pr> once the PR merged when the project sets evidence.ciSatisfies
Exiting without writing the manifest Downstream skills cannot see the outcome Always write the manifest entry — converged or not — before exiting
Reverting the worktree on escalation Destroys diagnostic evidence Leave the failed state; the human reviewer needs it

Critical Rules Summary

  1. Detect the test framework from the worktree before iterating; never hardcode.
  2. Cap iterations at MAX_ITERATIONS (default 5); escalate on exhaustion.
  3. Every MUST in the spec MUST map to a passing test before declaring convergence.
  4. Each iteration runs all three phases: Implement, Validate, Test.
  5. Never run on main, master, or trunk — stop and request a feature branch.
  6. Record framework, testsRun, testsPassed, testsFailed, ivtLoopConverged, ivtLoopIterations in the manifest.
  7. On non-convergence, exit 65 and leave the worktree untouched.
  8. Validate every run via cleo check protocol testing.

See also / References

This skill binds to the testing LOOM lifecycle stage. Governing ADRs:

  • ADR-051 — programmatic gate integrity — defines the evidence atoms (test-run:<json>, tool:test, tool:test-affected with testing.affectedCommand, ci:<pr> after merge with evidence.ciSatisfies) that the IVT loop emits and that downstream cleo verify --gate testsPassed re-validates.
  • ADR-061 — project-agnostic verify tools — defines the canonical tool-resolution layer (test, build, lint, typecheck) that the loop walks for framework-agnostic execution.

LOOM coverage matrix: docs/skills/loom-coverage-matrix.md.