centinela

module
v0.57.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: MIT

README

Centinela

Centinela

Plan → code → tests → validate → docs — enforced.

validate latest release go version license go report card stars

A harness-governance layer for AI coding agents. Centinela sits on top of Claude Code and OpenCode and makes your team's engineering discipline — plan → code → tests → validate → docs — enforced rather than requested. Every feature passes through guardrails, mechanical verification, and injected context automatically, so an agent's output looks like it came from a disciplined human team.

30-second tour
go install github.com/samuelnp/centinela@latest

centinela init                    # wire Claude/OpenCode hooks + scaffold docs/
centinela start my-feature        # required before any file write — opens "plan" step
# write docs/plans/my-feature.md + specs/my-feature.feature, then:
centinela complete my-feature     # advances plan → code (blocked if artifacts missing)
# … implement … advance through tests → validate → docs
centinela validate                # runs G1 file-size, i18n, your test/lint commands

If an agent tries to write source code while the workflow is in the plan step, the prewrite hook blocks the write and tells the agent what's missing.


Demo

Centinela governing a Claude Code session

A simulated Claude Code session: the PreToolUse hook blocks the ungoverned write, the agent starts the workflow, every file write is tagged with the active step, and the gates verify before anything ships — enforced, not requested.

Recorded with vhs. To regenerate: vhs assets/demo.tape (the session script lives in assets/demo.sh).


Why Centinela

AI coding agents are fast but undisciplined. Left to their own devices they skip planning, write tests as an afterthought, and ship without validation. Centinela fixes this by:

  • Blocking file writes in the wrong workflow step via agent integrations
  • Requiring artifacts before a step can advance — no plan file means no code, no tests means no validate
  • Running gate checks automatically at the validate step (file size limits, i18n completeness, your test suite)
  • Injecting context into every agent session so the model always knows which feature is active and which step it is on

The result: every feature ships with a written plan, a Gherkin spec, three test layers, and a passing gate suite — regardless of whether a human or an AI agent wrote it.

Centinela is harness engineering for AI agents: it owns the verification, context, and environment control that decide whether shipped code is trustworthy — and delegates the agent loop itself to Claude Code / OpenCode. → Concepts


How Centinela Works

Bootstrap once, then every feature runs through five enforced steps inside its own git worktree, driven by specialist subagents and guarded by agent hooks, ending in a validated merge back to main.

flowchart TB
    subgraph BOOT["🏗️ Bootstrap · once per project"]
        direction LR
        INIT["centinela init<br/>wires Claude + OpenCode hooks<br/>scaffolds docs/ + centinela.toml"]
        PROJ["PROJECT.md<br/>archetype + stack"]
        ROAD["ROADMAP.md + .workflow/roadmap.json<br/>phased feature plan"]
        INIT --> PROJ --> ROAD
    end

    ROAD --> START["centinela start &lt;feature&gt;<br/>required before any file write"]
    START --> WT["git worktree add<br/>.worktrees/&lt;feature&gt; · branch &lt;feature&gt;<br/>state: .workflow/&lt;feature&gt;.json"]
    WT --> PLAN

    subgraph FLOW["🔒 Five-step workflow · enforced order · runs inside the feature worktree"]
        direction TB

        subgraph PLAN["1 · plan"]
            direction LR
            PL["planner<br/>reasoning · opus-4-7<br/>strategy + spec lenses"]
            PL --> PLANART["docs/features/&lt;f&gt;.md<br/>docs/plans/&lt;f&gt;.md<br/>specs/&lt;f&gt;.feature"]
        end

        subgraph CODE["2 · code"]
            direction LR
            SE["senior-engineer<br/>reasoning · opus-4-7"] -. user-facing only .-> UX["ux-ui-specialist<br/>balanced · sonnet-4-6<br/>mobileFirst"]
            SE --> CODEART["implementation files"]
        end

        subgraph TESTS["3 · tests"]
            direction LR
            QA["qa-senior<br/>balanced · sonnet-4-6"] --> ECT["edge-case-tester<br/>fast · haiku-4-5"]
            ECT --> TESTART["tests/unit · tests/integration<br/>tests/acceptance<br/>.workflow/&lt;f&gt;-edge-cases.md"]
        end

        subgraph VAL["4 · validate"]
            direction LR
            VS["validation-specialist<br/>fast · haiku-4-5"] --> GATES["Gates<br/>G1 file-size · G11 i18n<br/>G2/G3/G5/G6/G7/G8 review<br/>+ centinela.toml commands"]
            GATES --> GK["gatekeeper report<br/>.workflow/&lt;f&gt;-gatekeeper.md"]
            GK --> PRD["production-readiness<br/>when gate enabled"]
        end

        subgraph DOCSTEP["5 · docs"]
            direction LR
            DS["documentation-specialist<br/>fast · haiku-4-5"] --> DOCART["docs/guides/ · README.md updates<br/>+ changelog + specialist evidence"]
        end

        PLAN -->|complete| CODE -->|complete| TESTS -->|complete| VAL -->|complete| DOCSTEP
    end

    DOCSTEP --> MERGE["centinela merge &lt;feature&gt;"]
    MERGE --> CONF{"spec conflicts?"}
    CONF -- yes --> BLOCK["blocked —<br/>resolve conflicting specs"]
    CONF -- no --> MV{"merge + validate clean?"}
    MV -- yes --> DONE["merge into main<br/>remove .worktrees/&lt;feature&gt;"]
    MV -- no --> STEWARD["merge-steward<br/>reasoning · opus-4-7<br/>writes evidence →<br/>centinela merge --continue"]
    STEWARD --> MV

    subgraph HOOKS["⚙️ Agent hooks · enforce all of the above automatically"]
        direction LR
        PRE["PreToolUse<br/>block writes that don't<br/>match the current step"]
        POST["PostToolUse<br/>append status tag<br/>↳ feature · step · X/5"]
        UPS["UserPromptSubmit<br/>inject workflow context,<br/>plan-advisor questions,<br/>required evidence"]
    end
    HOOKS -. guards .-> FLOW

    classDef agent fill:#1f6feb22,stroke:#1f6feb,color:#adbac7;
    classDef artifact fill:#23863622,stroke:#238636,color:#adbac7;
    classDef gate fill:#9e6a0322,stroke:#d29922,color:#adbac7;
    classDef cmd fill:#8957e522,stroke:#8957e5,color:#adbac7;
    class BT,FS,SE,UX,QA,ECT,VS,DS,STEWARD agent;
    class PLANART,CODEART,TESTART,DOCART,GK artifact;
    class GATES,PRD gate;
    class INIT,START,WT,MERGE,DONE cmd;

Legend — 🟦 subagents (tier · model) · 🟩 required artifacts · 🟨 quality gates · 🟪 centinela commands. Model tiers shown are the built-in defaults; override any role via [orchestration.models] in centinela.toml. Each step only advances when centinela complete finds its required artifacts, and the hooks block any file write that doesn't belong to the current step.

A full walkthrough lives in Workflow & Hooks.


Install

Prerequisites: Go 1.21+

go install github.com/samuelnp/centinela@latest

Or grab a pre-built binary from Releases, or on macOS/Linux:

curl -fsSL https://raw.githubusercontent.com/samuelnp/centinela/main/scripts/install.sh | sh

Verify with centinela --help.

macOS/Linux: go install places the binary in ~/go/bin. Ensure that directory is on your PATH:

export PATH="$HOME/go/bin:$PATH"  # add to ~/.zshrc or ~/.bashrc

Quickstart

Run once in your project root:

centinela init

This scaffolds CLAUDE.md, PROJECT.md.template, centinela.toml, and docs/, and wires the Claude/OpenCode hooks. Safe to re-run — existing files are never overwritten. Then:

  1. Fill in PROJECT.md — rename the template and complete it, or let your agent interview you and write it. This sets your architecture archetype and stack.
  2. Configure centinela.toml — add your lint/test commands and pick your gates. Copy a ready-made setup from the Configuration guide.
  3. Build your first feature — centinela start <feature>, then advance through the five steps.

→ Full setup, roadmap bootstrap, and a worked example: Getting Started.


Documentation

Guide What it covers
Getting Started Full setup: init, PROJECT.md, roadmap bootstrap, your first feature, migrate
Configuration Guide Copy-paste centinela.toml recipes by use case (solo, team+CI, local models, regulated, fleet)
Configuration Reference Every centinela.toml key — type, default, allowed values
Workflow & Hooks The enforced five-step workflow and the agent hooks behind it
Quality Gates Built-in and opt-in gates, diff-aware mode, claim verification
MCP Governance Consume governance from any MCP-speaking harness
Concepts Harness engineering — why Centinela exists, and when not to use it
Architecture Archetypes Hexagonal, Rails-native, N-Tier, ECS, Modular
Contributing Develop Centinela on Centinela; build from source

For a complete agent-collaboration example, see HOWTO.md.


License

MIT

Directories

Path Synopsis
cmd
centinela command
internal
acceptance
Package acceptance classifies validate commands as acceptance executions and parses runner reports for scenarios that did not actually assert.
Package acceptance classifies validate commands as acceptance executions and parses runner reports for scenarios that did not actually assert.
analyze
Package analyze produces a deterministic, read-only inventory of a codebase (languages, manifests, locales, package layout, dependency graph) with no LLM call.
Package analyze produces a deterministic, read-only inventory of a codebase (languages, manifests, locales, package layout, dependency graph) with no LLM call.
brownmap
Package brownmap is an aggregator that turns the read-only analyze Inventory into a DRAFT roadmap for a brownfield repo: it regenerates the in-process reconstruct.Reconstruction and partitions capability into a Baseline phase (already-built surfaces, never re-planned) plus net-new gap phase(s) seeded from reconstruct "# TODO: confirm" targets and repeatable --goal strings.
Package brownmap is an aggregator that turns the read-only analyze Inventory into a DRAFT roadmap for a brownfield repo: it regenerates the in-process reconstruct.Reconstruction and partitions capability into a Baseline phase (already-built surfaces, never re-planned) plus net-new gap phase(s) seeded from reconstruct "# TODO: confirm" targets and repeatable --goal strings.
calibration
Package calibration computes read-only per-model governance-friction analysis over the telemetry event log and recommends a tighter, looser, or unchanged enforcement profile per driver model.
Package calibration computes read-only per-model governance-friction analysis over the telemetry event log and recommends a tighter, looser, or unchanged enforcement profile per driver model.
cost
Package cost is a read-only cost-governance analytics aggregator over the telemetry log plus the host-harness transcript.
Package cost is a read-only cost-governance analytics aggregator over the telemetry log plus the host-harness transcript.
delivery
Package delivery is a read-only aggregator that composes the two delivery artifacts for `centinela deliver --via pr` — the Markdown PR body and a single Keep-a-Changelog line — out of the evidence Centinela already holds.
Package delivery is a read-only aggregator that composes the two delivery artifacts for `centinela deliver --via pr` — the Markdown PR body and a single Keep-a-Changelog line — out of the evidence Centinela already holds.
docsctx
Package docsctx assembles the curated feature-scale inputs the documentation specialist reads in the docs step: feature brief, plan, spec scenarios, and the optional changelog draft.
Package docsctx assembles the curated feature-scale inputs the documentation specialist reads in the docs step: feature brief, plan, spec scenarios, and the optional changelog draft.
docstring
Package docstring is a leaf that reports exported identifiers declared without a doc comment.
Package docstring is a leaf that reports exported identifiers declared without a doc comment.
doctor
Package doctor diagnoses (and, where safe, repairs) Centinela project-health problems: hook wiring, roadmap drift, abandoned worktrees, stale .workflow state, orphaned evidence, config drift, and binary version skew.
Package doctor diagnoses (and, where safe, repairs) Centinela project-health problems: hook wiring, roadmap drift, abandoned worktrees, stale .workflow state, orphaned evidence, config drift, and binary version skew.
evidence
Package evidence provides typed CLI authoring + validation for the per-role .workflow/<feature>-<role>.json artifacts described in docs/architecture/evidence-contract.md.
Package evidence provides typed CLI authoring + validation for the per-role .workflow/<feature>-<role>.json artifacts described in docs/architecture/evidence-contract.md.
filelock
Package filelock is an advisory cross-process file lock: the one primitive two different domains need to serialize a read-modify-write of a shared file.
Package filelock is an advisory cross-process file lock: the one primitive two different domains need to serialize a read-modify-write of a shared file.
gatereport
Package gatereport parses the validate-step verifier report, `.workflow/<feature>-gatekeeper.md`.
Package gatereport parses the validate-step verifier report, `.workflow/<feature>-gatekeeper.md`.
gitdiff
Package gitdiff resolves the set of files changed on the current branch relative to a configurable base ref.
Package gitdiff resolves the set of files changed on the current branch relative to a configurable base ref.
githooks
Package githooks installs and removes the centinela pre-commit hook via a marker-delimited splice into hooksDir/pre-commit, never clobbering user content.
Package githooks installs and removes the centinela pre-commit hook via a marker-delimited splice into hooksDir/pre-commit, never clobbering user content.
gitutil
Package gitutil is a tiny leaf wrapper around `git` and the GitHub CLI that answers the questions `centinela deliver`/`complete` ask before offering a delivery path: does the repo have an `origin` remote, is `gh` available, and which delivery options does the {origin × worktree} matrix permit.
Package gitutil is a tiny leaf wrapper around `git` and the GitHub CLI that answers the questions `centinela deliver`/`complete` ask before offering a delivery path: does the repo have an `origin` remote, is `gh` available, and which delivery options does the {origin × worktree} matrix permit.
golist
Package golist is a tiny leaf wrapper around the `go list` toolchain that loads a module's package import graph and module path.
Package golist is a tiny leaf wrapper around the `go list` toolchain that loads a module's package import graph and module path.
importgraph
Package importgraph is a leaf that loads a project's intra-project import graph for the G2 gate across languages.
Package importgraph is a leaf that loads a project's intra-project import graph for the G2 gate across languages.
insights
Package insights computes read-only governance analytics over the telemetry event log.
Package insights computes read-only governance analytics over the telemetry event log.
mcp
Package mcp exposes Centinela's governance as a versioned MCP server.
Package mcp exposes Centinela's governance as a versioned MCP server.
memory
Package memory implements the governed project-memory ledger: capturing typed facts from step artifacts and recalling the relevant slice at plan time.
Package memory implements the governed project-memory ledger: capturing typed facts from step artifacts and recalling the relevant slice at plan time.
reconstruct
Package reconstruct is an aggregator that consumes the read-only internal/analyze Inventory contract to deterministically reconstruct a behavioral spec corpus: one specs/<slug>.feature Gherkin skeleton plus one docs/features/<slug>.md brief stub per significant module/surface, with honest "# TODO: confirm" gaps.
Package reconstruct is an aggregator that consumes the read-only internal/analyze Inventory contract to deterministically reconstruct a behavioral spec corpus: one specs/<slug>.feature Gherkin skeleton plus one docs/features/<slug>.md brief stub per significant module/surface, with honest "# TODO: confirm" gaps.
roadmapcheckpoint
Package roadmapcheckpoint owns the emit/suppress/stale decision for the post-roadmap-definition checkpoint directive.
Package roadmapcheckpoint owns the emit/suppress/stale decision for the post-roadmap-definition checkpoint directive.
roadmapstate
Package roadmapstate owns THE definition of what "roadmap state" is: the governance bookkeeping files a roadmap mutation rewrites, as opposed to the product the repository ships.
Package roadmapstate owns THE definition of what "roadmap state" is: the governance bookkeeping files a roadmap mutation rewrites, as opposed to the product the repository ships.
selfupdate
Package selfupdate implements `centinela update`: it resolves the latest GitHub release, downloads the host-platform asset, verifies it against the release SHA256SUMS, and atomically replaces the running binary.
Package selfupdate implements `centinela update`: it resolves the latest GitHub release, downloads the host-platform asset, verifies it against the release SHA256SUMS, and atomically replaces the running binary.
synthesize
Package synthesize is an aggregator that consumes the read-only internal/analyze Inventory contract to infer a project's best-fit architecture archetype and synthesize a draft PROJECT.md.
Package synthesize is an aggregator that consumes the read-only internal/analyze Inventory contract to infer a project's best-fit architecture archetype and synthesize a draft PROJECT.md.
teamdashboard
Package teamdashboard computes a read-only, multi-feature team-status board from in-memory inputs the caller reads off disk.
Package teamdashboard computes a read-only, multi-feature team-status board from in-memory inputs the caller reads off disk.
telemetry
Package telemetry is the governance event log: a non-blocking, append-only JSONL recorder (one Event per line) plus a lenient reader.
Package telemetry is the governance event log: a non-blocking, append-only JSONL recorder (one Event per line) plus a lenient reader.
treestate
Package treestate captures the exact tree state a verdict certified.
Package treestate captures the exact tree state a verdict certified.
ui
verdict
Package verdict aggregates gates, verify, evidence, and workflow provenance into a deterministic, machine-readable JSON packet.
Package verdict aggregates gates, verify, evidence, and workflow provenance into a deterministic, machine-readable JSON packet.
verify
Package verify independently re-derives ground truth for the claims an evidence file makes and reports divergence.
Package verify independently re-derives ground truth for the claims an evidence file makes and reports divergence.
worktreepath
Package worktreepath is the `.worktrees/<feature>` path vocabulary: the directory name and the cwd -> feature scan, nothing else.
Package worktreepath is the `.worktrees/<feature>` path vocabulary: the directory name and the cwd -> feature scan, nothing else.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL