sage — Claude Code plugin: hooks, TDD and quality gates
A skills framework that makes the agent frame the task before coding and keeps discipline through hooks. For teams tired of untested edits.
/plugin marketplace add anthropics/claude-plugins-community
/plugin install sage@claude-communityWhat sage does
Sage reshapes how a Claude agent works: clarify first, build second. Its navigator sorts a request across UNDERSTAND → ENVISION → DELIVER → REFLECT, runs a framing round, and points out what is missing before any solutioning. Routing starts with keyword matching; only when nothing matches does a sub-agent classifier pick the phase. You confirm each routing decision.
The load-bearing part is the hooks. They stop a source edit until a test exists, an edit before a spec exists, a hardcoded secret, and a commit before the tests run. The author's point: this is code, not instructions, so an agent cannot switch the check off to get around it. After implementation, five quality gates fire in sequence — spec compliance, constitution compliance, code quality via a separate sub-agent, a hallucination check, and test verification.
Inside are 12 core skills plus installable packs: product/UX, pack-authoring, autoresearch. Project memory and an entity ontology get wired up at init. Mechanical enforcement runs on Claude and opencode; elsewhere you get a prose fallback. The author states plainly that where a rule is only prose, no gain was measured on a frontier model — so count on the hooks, not the advice.
What it helps with
- block a source edit until a test exists
- catch a hardcoded API key before it reaches a commit
- review the spec and plan before implementation starts
- run five quality gates after a feature is built
- carry project context across sessions
Example prompts for the agent
- Map this request across the intent phases and tell me what's missing
- Don't let me touch
src/api.tsuntil there's a test for the new behavior - Run the quality gates on the last implementation
How to install sage
Plugin marketplace
/plugin marketplace add anthropics/claude-plugins-community/plugin install sage@claude-communityStep by step, with commands for each platform: Claude Code plugins: marketplaces, installing, and building your own
Questions about sage
How do I install sage in Claude Code?
Add the marketplace first: /plugin marketplace add anthropics/claude-plugins-community, then install the plugin: /plugin install sage@claude-community.
What does sage do?
It adds a framing round before the agent solves anything, blocking hooks against untested edits and hardcoded secrets, and five quality gates after implementation.
Which platforms get mechanical enforcement?
The hooks run on Claude and opencode. Other platforms fall back to prose without blocking.
Source text
sage-claude-plugin · MIT
# Sage
**An intelligent skills framework for AI agents.**
<p align="center">
<img src="docs/assets/sage-logo-eagle.svg" alt="Sage - An intelligent skills framework for AI agents." width="150" />
</p>
<p align="center">Think clearly. Work thoroughly. Deliver excellence.</p>
Sage is a skills framework that makes AI agents think before they act,
stay focused under complexity, and deliver outcomes you can trust.
Built for product and engineering teams, open to any domain.
**The measured claim:** run a cheap model under Sage and its hook-covered
mistakes — shipping untested code, hardcoding secrets — stay at frontier-clean
levels, because Sage's enforcement is *code*, not instructions, and code
transfers down-model when judgment doesn't. Told to skip the test "just this
once," a bare agent caves **0 for 0 at every tier tested** (Haiku, Sonnet, Opus);
Sage's hook holds. Not asserted — [measured](#what-we-measured), and the claims
we walked back are in the open.
- **Mechanical where it counts** — hooks that block a source edit until a test exists, an edit before a spec exists, a hardcoded secret, and a commit before the tests run; gate scripts with a three-state exit contract. Code, not instructions — and the enforcement is self-protecting: an agent can't switch it off to get around it
- **Think first, build second** — a framing round challenges assumptions before solutioning begins, preventing the most expensive mistake: solving the wrong problem
- **Focus over noise** — three-layer loading pulls in only what the task needs (~1.5–2× a bare agent's input tokens), producing sharper reasoning
- **Runs where you work** — Tier-A mechanical enforcement on Claude Code and opencode, with a graceful prose fallback everywhere else; each platform's tier is *derived* from capabilities that are checked or attested, never claimed
- **Persistent memory built in** — self-learning, project memory, and an entity ontology, wired up at init; the mechanism is measured, the compounding bet is stated honestly
- **Grows with its ecosystem** — 12 focused core skills plus installable packs (product/UX, pack-authoring, autoresearch), extensible with 90K+ community skills from skills.sh
## What we measured
Since v1.2.0, Sage's claims are measured, not asserted: `develop/evals/` runs
adversarial scenarios twice — once in a Sage project, once in a bare one — with
deterministic graders and no LLM judge. The load-bearing result, hardened across
three model tiers (Haiku N=10, Sonnet N=5, Opus N=3):
**1. Mechanical test-first beats model judgment at every tier.** Told "it's just
one number, skip the test," a bare agent ships the untested change **0 for 0** —
at Haiku (0/10), Sonnet (0/5), *and* Opus (0/3). This is not a capability gap
that a better model outgrows; it is an incentive gap, and every model tested
caves to it. Sage's TDD hook blocks the source edit until a test exists, and it
holds at all three tiers. (On Haiku, Sage passes 8/10 — the hook guarantees a
test *exists* before source, not that a weak model writes a *good* one; the two
misses wrote tests that didn't assert the behavior. The discipline holds; test
quality is the model's job.)
**2. The safety floor grows as the model gets cheaper.** Handed a live API key,
a bare agent hardcodes it almost always on Haiku (1/10), sometimes on Sonnet
(3/5), and never on Opus (3/3 clean). The secrets gate's value is largest exactly
where the model is weakest — a genuine floor under cheap models. Run Sage on
Haiku and the hook-covered failure modes stay at frontier-clean levels.
**3. Where a rule is only prose, a capable model ties it — and we say so.** On a
frontier model, refusing the key, distrusting "the tests passed," scope
discipline: the bare agent does all of it on its own, and Sage measures **no
difference**. The phantom-package gate looked dramatic at N=3 (bare 1/3); at N=10
it is 8/10, a minor cheap-model edge — hardening revised our own claim *down*,
which is what hardening is for. Sage's benefit is whatever it has made
mechanical; the prose layers are advice, and advice is rationalizable.
**4. Multi-session work: Sage resumes reliably, and pays for it.** Resuming an
interrupted cycle and honouring a constraint from two contexts ago: **3/3 in both
conditions** — a tie on correctness, at **a few times the cost** (resume ~4×,
noisy; roughly halved from ~9× by the v1.3.5 close-out levers). The edge here is
*determinism*, not correctness — the failure modes are mechanically closed.
The one-line version: **run a cheap model under Sage and the hook-covered
mistakes — untested edits, hardcoded secrets — stay at frontier level, because
hooks transfer down-model and judgment doesn't.** Full numbers, all three tiers,
and the claims we walked back:
[develop/evals/HARDENED-FLOOR-2026-07-17.md](develop/evals/HARDENED-FLOOR-2026-07-17.md).
The honest summary: **Sage's benefit is whatever it has made mechanical.** Costs
are published as sage:bare ratios because ratios transfer across billing models —
on a subscription they arrive as quota and time, not a bill.
> If a rule matters, make it code. If you can't, don't claim it.
Full results, method, corrections, and the bugs the eval found in itself:
**[docs/eval-baseline.md](docs/eval-baseline.md)**.
## Why Sage
### The Navigator
Most AI frameworks skip from request to implementation. Sage's navigator
thinks first — mapping every request to an intent spectrum (UNDERSTAND →
ENVISION → DELIVER → REFLECT) and detecting what's missing before work
begins.
It starts with a framing round: surface the pain, challenge the
premises, and arrive at a chosen framing — before any solutioning
happens. Building without research? It tells you what 15 minutes of
discovery would prevent, then lets you decide. Gap detection, not
gatekeeping.
Routing is deterministic first, intelligent second: keywords match
workflows before any LLM judgment. When keywords don't match, a
focused sub-agent classifier picks the right phase. Every routing
decision is confirmed with the user before proceeding. Smart enough
to route accurately. Humble enough to ask when unsure.
### The Quality Chain
AI agents drift silently — skipping steps, hallucinating imports,
building the wrong thing confidently. Sage catches this at every stage:
**Before implementation:**
- Auto-review (sub-agent) verifies spec quality after approval — framing alignment, testable criteria, boundary completeness, edge cases, internal consistency
- Auto-review (sub-agent) verifies plan quality after approval — spec-plan alignment, task decomposition, dependency ordering, coverage gaps
**During implementation:**
- 7 universal coding principles loaded into the build-loop — clarity, error handling, boundary guards, minimal scope, safe APIs, consistency, behavior testing
**After implementation:**
- 5 quality gates sequence automatically — spec compliance, constitution compliance, code quality (independent sub-agent), hallucination check, test verification
- 2 advisory gates activate when applicable — browser check (Lightpanda), design check (frontend files)
- Auto-QA (sub-agent) verifies code against spec — alignment, test coverage, error handling, boundary conditions, integration consistency, coding principles
Six independent sub-agent review points. The agent that writes the code — or
diagnoses the bug — does not review its own work alone.
That holds **only where sub-agent dispatch exists** (a Task tool, or equivalent).
Where it doesn't, the reviews are skipped rather than downgraded. On Claude Code
the skip is now recorded mechanically — a hook writes it to `decisions.md`, and the
cycle cannot be marked complete while its manifest is silent about QA — so a
degraded run is legible after the fact instead of indistinguishable from a clean
one. On a platform without hooks, assume the code was reviewed by the agent that
wrote it, and check `decisions.md` yourself.
### Hybrid Loading
Most frameworks dump every instruction into the context window. Sage loads in
three layers:
- **Eager** — 177 lines (~2.1k tokens) on every turn: routing keywords, the rule
that sends the agent to a skill, and each principle next to the hook that
enforces it. Nothing else.
- **On-demand** — seven system skills fetched only when the conversation matches
their description. A session that never asks about tiers never pays for tiers.
- **Lazy** — capabilities (TDD, coding principles, build-loop) load when a
workflow step needs them.
The eager layer was cut 398 → 177 lines in v1.3.0 with **no behaviour lost**
(test-first still measures 3/3 vs 0/3 with the entire test-first prose deleted —
the hook was doing the work). Net input-token cost vs a bare agent: **~1.6×**,
measured. The 177 is held by a CI budget so it cannot silently grow:
[docs/context-budget.md](docs/context-budget.md).
### Session Resilience
A cycle manifest carries state, context, decisions, and handoff guidance across
context windows. Type `/continue` and Sage resumes where the last session
stopped — from a **generated brief** (`manifest.py resume`): computed cycle
selection, git evidence, decisions in force, and the previous session's notes
labelled *context, not orders*, with a stated authority order (live user >
recorded decisions > manifest prose; evidence beats all). The state fields that
can drift are machine-owned: a hook advances `gate_state` the moment source is
written, and `manifest.py check` fails a manifest that contradicts its tree.
**Measured honestly:** a fresh context resumes an interrupted cycle **3/3** —
and so does a bare agent handed the same files. Sage's edge here is
*determinism* (the failure modes we found — a stale manifest, a dead session's
hedge outranking the live user — are mechanically closed), not correctness. The
cost of the ceremony was ~9× a bare agent; the close-out economy levers
(`gate_review: combined`, batched one-command bookkeeping, inherited-red,
skip-memory, lean test cadence — all config knobs, see `/configure`) have
brought a resume to **a few times** bare's cost, re-measured at every step with
no behaviour lost.
Numbers and the full story: [docs/eval-baseline.md](docs/eval-baseline.md).
### Persistent Memory
<p align="center">
<img src="docs/assets/sage_memory.svg" alt="Sage Memory System — 3 skills, 1 MCP, compounding knowledge." width="600" />
</p>
Sage ships a persistent memory layer — three skills backed by the sage-memory
MCP, wired up automatically by `sage init` (opt out with `--no-memory`):
- **sage-self-learning** captures mistakes as WHEN/CHECK/BECAUSE prevention rules.
- **sage-memory** stores project knowledge as focused prose insights — conventions, decisions, gotchas.
- **sage-ontology** maps entity relationships — touch one module, know the blast radius.
**What's measured, honestly.** The mechanism is proven end-to-end: knowledge
stored in one session is retrieved and applied sessions later, accumulates
across sessions, and survives a fresh checkout — every mechanism check passes,
through the exact stack `sage init` writes. What is *not* yet measured is an
outcome a cheaper channel doesn't match: at every horizon we tested, a bare
agent got the same answers from its own history — the session log, the
committed code (git is a memory system), or the platform's built-in
per-project memory. So memory ships as a **capability with a proven mechanism,
not a measured behavioral edge** — its distinctive bet is knowledge that
crosses *projects* (the one channel none of those alternatives serve), and
that regime is still unmeasured. Numbers and method:
[docs/eval-baseline.md](docs/eval-baseline.md).
## Get Started
### Install
```bash
curl -fsSL https://raw.githubusercontent.com/xoai/sage/main/install.sh | bash
```
Works on macOS and Linux. On Windows, use
[Git Bash](https://git-scm.com/downloads/win) or WSL:
```bash
# Windows — open Git Bash, then:
curl -fsSL https://raw.githubusercontent.com/xoai/sage/main/install.sh | bash
```
All `sage` commands run in bash. On Windows, use Git Bash or WSL
for both installation and daily use.
The installer resolves the latest release tag, downloads its tarball and
`checksums.txt`, and verifies the SHA-256 before unpacking anything. A
mismatch aborts loudly and installs nothing. Pin a specific release with
`SAGE_VERSION=v1.2.0 curl -fsSL … | bash`.
### Path A: New Project (Greenfield)
```bash
sage new my-app # scaffold a new project with Sage
cd my-app
```
Open the project in your IDE, then follow a natural progression:
```
/sage # 1. describe what you want to build
# Sage classifies intent, detects gaps,
# and recommends the right workflow
/research # 2. (optional) user interviews → JTBD →
# opportunity map — understand the problem
# before solutioning
/architect # 3. (optional) system design → ADRs →
# milestone plan — for non-trivial systems
/build # 4. spec → plan → build-loop → quality gates
# auto-review, TDD, coding principles, auto-QA
```
Not every project needs every step. A simple feature can go straight
to `/build`. A complex product benefits from `/research` → `/design`
→ `/architect` → `/build`. Sage tells you what you're skipping and
lets you decide.
### Path B: Existing Project (Brownfield)
```bash
cd your-project
sage init # interactive — detects stack, asks for preset
sage init --preset startup # or pick a preset directly
sage init --prefix # namespace commands as sage:build, sage:fix, etc.
```
Available presets: `base` (default), `startup`, `enterprise`, `opensource`.
Presets add engineering principles on top of the universal base (TDD, no
secrets, explicit deps). Configure later in `.sage/config.yaml`.
**Then teach Sage your codebase:**
```bash
# 1. Set up persistent memory (one-time)
sage setup memory # configures sage-memory MCP server
# 2. Learn your codebase (run inside your IDE)
sage learn # broad scan — architecture, patterns, conventions
sage learn src/billing # deep dive — learn a specific module
```
After install, `sage upgrade` will prompt to upgrade the sage-memory
package when a newer version is available on PyPI, and `sage update`
syncs the latest skill prose into your project automatically — no
manual `sage-memory install-skills` invocations required.
After learning, Sage knows your conventions, architecture, and
landmines. Every future session starts by searching this memory —
no more explaining context from scratch.
**Then work naturally:**
```
/sage # describe your task — Sage reads memory,
# checks for work in progress, and routes
# to the right workflow
/fix # diagnose → scope → fix → verify
# reads prior QA reports and design reviews
/build # spec → plan → build-loop → quality gates
# reads prior research, design specs, ADRs
/autoresearch # autonomous iteration toward a metric
# modify → commit → verify → keep/revert
/continue # resume where you left off — reads the
# cycle manifest for full context handoff
```
### Upgrade
```bash
sage upgrade # moves the framework to the latest release tag
sage update # regenerates platform files, preserves .sage/ state
```
`sage upgrade` checks out the newest `vX.Y.Z` tag and prints the changelog
entries you gained. It no longer tracks `main`: a release tag is the only
thing that has been through the release workflow's checks. On a tarball
install it re-downloads and re-verifies the release's SHA-256 instead, and a
failed upgrade leaves your existing framework untouched.
```bash
sage upgrade --channel main # development channel: unreleased, unverified
```
`sage update` regenerates CLAUDE.md, commands, workflows, and gate
scripts while preserving your project state (decisions, work
artifacts, memory). You may need to restart your IDE to load latest
configs.
### CLI Commands
Run in your terminal:
| Command | What It Does |
|---------|-------------|
| `sage new <n>` | Create a new project with Sage |
| `sage init` | Add Sage to the current directory |
| `sage update` | Regenerate platform files after changes |
| `sage upgrade` | Update Sage to the latest release (`--channel main` for dev) |
| `sage version` | Print the installed framework version |
| `sage learn [path]` | Learn a codebase or module |
| `sage setup memory` | Configure persistent memory (sage-memory MCP) |
| `sage find <query>` | Search skills.sh catalog (90K+ skills) |
| `sage add <source>` | Install skills from owner/repo, URL, or local path |
| `sage add <source> --skill <n>` | Install a specific skill from a repo |
| `sage remove <skill>` | Remove a skill from project |
| `sage skills` | List installed skills |
| `sage update [target]` | Update community skills to latest |
| `sage worktree <slug>` | Create an isolated worktree + branch for a parallel session ([guide](docs/parallel-sessions.md)) |
## How Sage Works
### Routing
<p align="center">
<img src="docs/assets/sage_routing.svg" alt="Sage Routing — 3-layer funnel from keywords to confirmation." width="600" />
</p>
Three layers, deterministic first:
1. **Keywords** (instant) — "build" → `/build`, "fix" → `/fix`, "audit" → `/analyze`. Handles 60-70% of requests with zero LLM judgment.
2. **Sub-agent classifier** (focused) — independent context, single job: classify into UNDERSTAND / ENVISION / DELIVER / REFLECT.
3. **Confirmation** (human decides) — 2-3 options with skill chains visible. The user confirms before anything runs.
### Slash Commands
Use inside your IDE (Claude Code, Antigravity):
| Command | What It Does |
|---------|-------------|
| `/sage` | **Start here.** Routes via keywords → classify → confirm |
| `/build` | Spec → plan → build-loop → quality gates (with auto-review, coding principles, auto-QA). Accepts `--quality-locked`, `--autonomous` |
| `/fix` | Diagnose → scope → fix → verify (reads QA and design-review reports) |
| `/architect` | Elicit → design → milestone plan → phased build (with ADR auto-review). Accepts `--quality-locked`, `--autonomous` |
| `/review` | Independent evaluation. Modes: `--ux` (UX audit/evaluate/heuristics), `--design` (design-system + slop), `--browser` (functional QA, optional Lightpanda) |
| `/learn` | Codebase scan → memory. `--ontology` builds the entity/dependency graph |
| `/reflect` | Review cycle → extract learnings → seed next cycle |
| `/continue` | Resume an active cycle; with none, prints project status |
| `/autoresearch` | Autonomous iteration toward a measurable metric (optional runtime — `sage-autoresearch` pack) |
| `/research`, `/design` | PM/UX workflows — install the `sage-product` pack |
The core command set is 9 (down from 16 in v1.2.0). `/analyze`, `/design-review`,
`/qa`, `/map`, and `/status` folded into modes of `/review`, `/learn`, and
`/continue`; the old names still route for one deprecation cycle. `/research` and
`/design` ship with the [sage-product](https://github.com/xoai/sage-product) pack.
### Workflow Flags
Optional flags change how the workflow operates without changing what it
produces. `--quality-locked` and `--autonomous` apply to `/build` and
`/architect`; `--subagents` and `--parallel` are `/build`'s execution
modes (`/fix` also accepts `--subagents`; a `--parallel` request outside
a graph-derived `/build` cycle is refused loudly, never silently):
| Flag | Effect |
|------|--------|
| `--quality-locked` | At each review checkpoint, loop review/revise until the loop's controller stops it. By default (`review_loop: mode: v2`) the verdict lives in code: findings land in a machine-owned ledger, evidence-free criticals never block (citations must resolve against the spec/constitution to count), a disputed finding cannot vanish — it stops the loop until dispositioned — and every CONTINUE/STOP is computed — measured to converge in ≤3 rounds where the old loop churned to its cap. An advisory stop actually stops (field-derived, 2026-08-16): non-blocking findings can't buy extra rounds, late nits auto-defer to a machine-written `cleanup.md`, and cap/stall count per checkpoint instance. `mode: v1` restores the classic clean-bar loop (pre-flip projects are pinned there by `sage update`); see the `configure` skill's "Review loop" section. |
| `--autonomous` | Skip user-facing elicitation. Agent makes brief/spec/plan decisions by reading memory, codebase patterns, constitution principles, and prior cycles. Every decision cites its source. Unconfident substantive decisions fall back to asking. Use when you want Sage to draft a recommended approach from your project's context. |
| `--subagents` | A fresh implementer subagent per plan task, an independent reviewer per task, a whole-branch review at the end — wired into a machine-scaffolded task ledger the completion guard enforces (a subagent cycle cannot reach `gates-passed` until every task is done AND independently approved). Platform permitting; refusal is loud, never a silent fallback. Mechanics proven (E9/E10); the cost story is deliberately unmeasured — the accounting footer reports counts, not a verdict. |
| `--parallel[=N]` | Dependency-aware parallel implementation lanes on top of `--subagents` (refused loudly without it). The scheduler is code (`lanes.py`), its only input the plan's derived `task_graph:`: a task runs concurrently only if marked `[P]`, its `Depends on:` tasks have merged, and its declared `Files:` are disjoint from every in-flight lane — overlap serializes, a non-`[P]` task runs alone. One worktree + branch per lane, single-writer bookkeeping, dependency-order merges that abort on conflict, full-suite integration proof on merged HEAD per burst. Default 2 lanes, hard cap 4. **No speed or cost claim** — the E-PAR scenarios that would earn one are authored, not yet run. |
```bash
/build --quality-locked # interactive, quality-locked
/build --autonomous "ship dark mode" # autonomous decisions, normal review
/build --autonomous --quality-locked "..." # full autonomy, quality-locked
/architect --autonomous "design billing v2"
```
Flags are independent and combinable. Both have hard iteration caps
and explicit cap-reached prompts — no runaway behavior. Flag state
persists in the cycle manifest, so `/continue` restores them.
#### Project-level defaults
Set defaults in `.sage/config.yaml` so the flags apply automatically
to every `/build`, `/architect`, and `/fix` invocation:
```yaml
quality_locked: true # always loop review until clean
autonomous: false # use interactive elicitation
```
The agent announces active modes and their source at workflow start:
```
Sage → build workflow.
Modes: --quality-locked (from .sage/config.yaml)
Goal: Ship dark mode
```
**Per-run override:** the `--no-quality-locked` and `--no-autonomous`
flags disable a config default for a single run:
```bash
/build --no-quality-locked "quick typo fix" # override config default
```
**Precedence (highest wins):** `--no-X` flag → `--X` flag → config
default → off. Passing both `--X` and `--no-X` is an error.
### Interaction Patterns
Sage communicates clearly at every step:
**Decision points** — numbered options when you need to choose a direction.
**Checkpoints** — `[A] Approve` / `[R] Revise` shortcuts on deliverables.
**Continuations** — `[C] Continue` with a recommended next step.
Free-form input always works. These patterns guide, they don't constrain.
### The Pipeline: UNDERSTAND → ENVISION → DELIVER → REFLECT
<p align="center">
<img src="docs/assets/sage_workflows.svg" alt="Sage Workflows — 9 commands across the UNDERSTAND → ENVISION → DELIVER phases." width="600" />
</p>
Sage organizes work into four phases. Each phase has dedicated
workflows that chain skills automatically:
```
UNDERSTAND ENVISION DELIVER REFLECT
/research /analyze /design /architect /build /fix /reflect
/learn /map /autoresearch
/review /qa
/design-review
```
`/research` chains user-interview → JTBD → opportunity-map.
`/design` chains ux-brief → ux-specify → ux-writing and reads
research findings automatically. `/build` chains spec → plan →
build-loop → quality-gates and reads design specs. `/reflect`
reviews the full cycle, extracts WHEN/CHECK/BECAUSE learnings,
and seeds the next cycle with concrete recommendations.
You can enter at any phase. But the further right you start, the
more you're building on assumptions.
### Enforcement Model
<p align="center">
<img src="docs/assets/sage_enforcement.svg" alt="Sage Enforcement — 5 independent layers." width="600" />
</p>
Agents rationalize. Tell them "MUST write spec" and they'll decide the
conversation IS the spec. Every instruction that requires interpretation
will be reinterpreted.
Sage answers this with five layers — but they are **not equally strong, and the
difference is the whole point.** Layers 1, 2, 3 and 5 are language: they are read
by the same model that is doing the rationalizing, and the eval found them being
rationalized past (Layer 3's `tdd` lost to "it's just one number", 0/3). Layer 4
and the spec-gate hook are **code**: a script's exit status and a blocked tool call
are not open to interpretation, and those held in every run.
Read the layers below with that split in mind. Language persuades; only mechanism
enforces.
**Layer 1 — Always-on rules** in the system prompt. Even if nothing else
loads, the gates prevent the worst violations. Eight rules covering
memory-before-work, spec-first, artifact-only state, checkpoints
(no unilateral deferral), self-check, decisions logging, learning
from corrections, and skills-before-assumptions.
**Layer 2 — Command preambles.** Every slash command has enforcement
rules the agent reads before its first token. Named rationalizations
are blocked: "the design is clear" → NOT a spec file.
**Layer 3 — Capabilities** loaded at the right workflow step. `build-loop`
orchestrates task-by-task execution. `coding-principles` carries 7 universal
quality standards. `tdd` argues for test-first. `systematic-debug` structures root
cause investigation.
> **These are instructions, and instructions get rationalized — the eval caught it.**
> Asked to change one constant under pressure ("it's literally changing one number,
> just do it quickly"), the agent wrote no test in **0 of 3 runs**, with `tdd` loaded
> and the constitution's first principle reading *"Tests before code."* It didn't
> even create a cycle, so every gate Sage owns — all of which fire on a cycle — was
> bypassed by declaring the work small.
>
> **So test-first stopped being a Layer-3 argument and became a Layer-4 gate.** The
> TDD gate (PreToolUse) blocks an edit to a source file when no test has been written
> for it. Re-measured: **3/3, against 0/3 for a bare agent.** The rest of Layer 3 is
> still advocacy — read it as persuasion, not enforcement.
**Layer 4 — Bash gate scripts.** Deterministic. Run BEFORE the agent
reviews. `sage-verify.sh` runs your test suite, `sage-hallucination-check.sh`
verifies imports exist, `sage-spec-check.sh` confirms deliverables match
the plan. The script says tests fail → gate fails, regardless of what
the agent thinks. Each script returns one of three states — `0` pass, `1`
fail, `2` unverifiable — and "unverifiable" is never silently upgraded to a
pass: a project with no test runner stops and asks. The scripts carry their
own regression tests (`develop/validators/gates/`), because a gate that fails
open is worse than no gate at all.
**Layer 5 — Self-learning.** Corrections from past sessions are stored
as WHEN/CHECK/BECAUSE rules and searched before every Standard+ task.
The agent reads its own past failures before repeating them.
Every rule is an **observable condition**, not an action instruction.
"spec.md MUST EXIST on disk" is binary — the agent can't argue a file
into existence. "MUST write spec" is rationalizable — the agent decides
the conversation is the spec. File existence beats language.
**On Claude Code, spec-first is mechanical, not just prose.** A `PreToolUse`
hook (`sage-spec-gate.sh`) blocks edits to source files while a Standard+ cycle
is still pre-spec, and blocks marking a cycle complete before its gates pass.
The agent cannot rationalize past a blocked tool call. It is scoped (fires only
inside a Sage project with an active cycle), escapable (`hard_enforcement:
false`, `tier: tier1`, or editing under `.sage/`), and fails open — a broken
hook never bricks your editor. New projects default it on; projects upgraded
with `sage update` get it installed but **off**, with a notice, so enforcement
never surprises an established workflow.
**Scope Guard (opt-in, unmeasured).** The same mechanical treatment now
exists for declared scope: at plan approval, `manifest.py scope derive`
turns the plan's per-task `Files:`/`Output:` lines into a machine `scope:`
block, and with `scope_gate: standard+` a PreToolUse hook blocks edits
outside it — naming both legal exits (`scope add-collateral --task --reason`,
which records the expansion itself, or amend the plan and `derive
--refresh`). Witness/TDD tests are never scope-blocked. The same
transition also runs `manifest.py graph derive` — the plan's task
structure (`Files:` / `Depends on:` / `[P]`) be...
© xoai · MIT · xoai/sage