AEGIS SPEC · CONTROL PLANE v2.0
Specs as contracts.
Code as ground truth.
Turn legacy systems into executable specifications and keep them aligned as AI agents change the code.
npx aegis-spec install
v2.0.0 · 24 commits ahead of upstream
github.com/Wellbrito29/Aegis · MIT
→ next
← back
F fullscreen
● live
● The problem
AI agents need specs to be safe
Greenfield: write spec, agent executes. Legacy or vibe-coded: no spec → agent has no idea what it cannot break. Drift compounds; refactors stall behind fear of unknown contracts.
WITHOUT AEGIS
vibe-driven evolution
- 10-year-old logic, no documentation
- Implicit business rules nobody can cite
- Agent rewrites a function, breaks an invariant
- Drift between code and Confluence wiki
- "Why did it work yesterday?" loops
- Refactor blocked by fear of unknown contracts
spec = wiki page · drift = silent · review = vibes
WITH AEGIS
spec-as-contract
- Specs extracted from real code · file:line traceable
- Contracts marked 🟢 confirmed · 🟡 inferred · 🔴 gap
- Drift loop catches every diverging edit
- Policy gate blocks signature breaks at the PR
- Knowledge graph shows blast radius before merge
- Agents read specs first, then write
spec = executable · drift = CI gate · review = enforced
02 / 22
● Impact
In numbers
Fork v2.0.0 ships the control plane upstream Reversa never had — graph, policy, drift, audit, bot. All MIT, all in one CLI.
Pipeline stages
4
Discovery → Migration → Build → Control Plane
Languages (Graph L1)
5
JS · TS · Python · Go · Java via tree-sitter
Fork delta vs upstream
+24
commits past 144aee2 (Reversa v1.2.28)
Phase 1 Hooks
Phase 2 Graph L0
Phase 6-9 Graph L1 (JS/TS/PY/Go/Java)
Phase 10 Signature diff
Phase 11 policy-check CLI
Phase 12 Auto Keeper
Phase 13 Audit + bot
Phase 14 CI templates
03 / 22
● Foundation
Three pillars
Specs are the contract. Graph is the ground truth. Keeper is the gate that keeps them aligned. Removing any one collapses the loop.
PILLAR 1
Aegis Spec
Spec authority. Features, contracts, invariants, retroactive ADRs. Generated by Discovery agents, line-traceable to real code.
aegis/specs/sdd/
aegis/specs/adrs/
aegis/specs/openapi/
aegis/specs/user-stories/
Architect · Writer · Detective · Archaeologist · Scout
PILLAR 2
Keeper
Drift gate. Hooks queue every edit, Keeper updates impacted specs in 3 questions and reclassifies confidence.
/aegis-keeper before · pre-edit context
/aegis-keeper after · post-edit sync
keeper-queue.jsonl · event queue
drift.md · 🔴 pending dashboard
Manual · Hooked · Auto · Hybrid
PILLAR 3
Graph
Codebase oracle. L0 universal file imports (regex). L1 symbols & signatures via tree-sitter for 5 languages.
graph build [--level L0|L1]
graph impact <file> · BFS blast radius
graph symbols / callers
graph.json · in-house, MIT, no deps
parsers-l0 · parsers-l1 · extractors · resolve
04 / 22
● Pipeline · 4 stages
From legacy code to guarded code
Stage 1-2 are upstream Reversa heritage (spec generation). Stage 4 is the fork delta — control plane that runs forever after Stage 3 ships.
STAGE 1
Discovery
Legacy code → aegis/ specs.
- Scout
- Archaeologist
- Detective
- Architect
- Writer
- Reviewer
STAGE 2
Migration (optional)
Specs → migration plan + parity tests.
- Paradigm Advisor
- Curator
- Strategist
- Designer
- Inspector
STAGE 3
Build
User's coding agent ships new code.
- Claude Code
- Codex
- Cursor
- Gemini
- Kimi · Opencode · …
STAGE 4 · FORK DELTA
Control plane
New code → guarded against drift, signature break, blast radius.
- Keeper drift loop
- Graph impact
- Policy gate
- Audit log
aegis/runtime/context/
→
graph.json + policy-index.json
→
drift.md + changelog/
→
audit/YYYY-MM-DD.jsonl
05 / 22
● Container view
One CLI, every gate
All modules ship in aegis-spec npm package. No daemon, no service — just a CLI invoked from hooks, the agent, or CI.
flowchart LR
USER["AI Agent
Claude · Codex · Cursor · …"]
HOOK["Engine Hook
PostToolUse · file save"]
CI["CI Job
GitHub · GitLab · CircleCI"]
subgraph CLI ["aegis-spec CLI · bin/aegis.js"]
direction TB
INST["installer/
detect · prompts · manifest"]
AGENTS["agents/ · 30 skills
copied to aegis/skills/"]
GRAPH["graph/
L0 + L1 · 5 languages"]
POLICY["policy/
index · check · adapters"]
AUTO["auto/
classifier · spec-writer"]
AUDIT["audit/
JSONL + redact"]
end
SPECS[("aegis/
specs · runtime · reports")]
USER --> CLI
HOOK --> CLI
CI --> CLI
CLI --> SPECS
GRAPH --> SPECS
POLICY --> SPECS
AUTO --> SPECS
AUDIT --> SPECS
06 / 22
● 30 skills
Agents installed as skills
Each agent ships verbatim into aegis/skills/aegis-*/. The engine activates them via /aegis. Required core + optional specialists + input translators.
Required core
Aegis Spec orchestrator · checkpoints
Scout surface · entrypoints · deps
Archaeologist module-by-module deep dive
Detective rules · state · permissions
Architect C4 · ERD · tech debt
Writer spec generation w/ traceability
Optional specialists
Reviewer spec inconsistencies + gaps
Visor screenshots → UI spec
Data Master DDL · ORM · ERD · triggers
Design System tokens · themes · components
Reconstructor bottom-up rebuild plan
Keeper drift loop + changelog
Migration + translators
Paradigm Advisor stack fit
Curator what survives migration
Strategist sequence + parity
Designer target architecture
Inspector parity tests
N8N Translator visual flow → SDD
07 / 22
● Keeper · local flow
Edit → queue → 3 questions → in-sync
Hooks fire on every save. Keeper asks why · breaking? · context?, then rewrites the impacted spec and reclassifies confidence 🟢🟡🔴.
Local flow
[Edit file] # agent or human
│
└─ engine hook (PostToolUse / save)
├─ aegis/runtime/queue/keeper-queue.jsonl
├─ stub appended to changelog/YYYY-MM-DD.md
└─ impacted spec marked 🔴 pending in drift.md
[/aegis-keeper after] # dev triggers manually or on Stop hook
│
├─ asks 3 Qs: why? breaking? context?
├─ rewrites impacted specs in-place
├─ reclassifies 🟢 confirmed / 🟡 inferred / 🔴 gap
└─ marks specs as 🟢 resolved
[git push] # dev commits both code + updated specs
no LLM mandatory
human intent captured
spec ↔ code stay in lockstep
Three layers · opt-in
1. MANUAL
Run /aegis-keeper after whenever the dev decides.
2. HOOKED
npx aegis-spec add-hooks --engine claude-code
covers cursor · kimi-cli · codex · opencode.
3. ENFORCED
drift-check --severity high in CI — PR fails if drift pending.
08 / 22
● Control plane · CI
CI enforces — never resolves
Keeper never runs automatically in CI: it needs human intent. CI only enforces that drift was resolved locally and the contract was not silently broken.
flowchart TD
PR[PR opened or updated] --> CO[Checkout + restore aegis/runtime/context cache]
CO --> GRAPH["npx aegis-spec graph build --level L1"]
GRAPH --> IDX["npx aegis-spec policy-index build"]
IDX --> DRIFT{"drift-check
--severity high"}
DRIFT -->|exit 1| BLOCK1["BLOCK · spec drift pending
dev must /aegis-keeper after locally"]
DRIFT -->|exit 0| POLICY{"policy-check
signature gate"}
POLICY -->|contract broken| BLOCK2["BLOCK · 🟢 contract violated
protected file or signature diff"]
POLICY -->|clean| IMPACT["aegis graph impact
blast radius posted as PR comment"]
IMPACT --> PASS["Ready for review"]
classDef block fill:#3a0e0e,stroke:#EF4444,color:#fff;
classDef ok fill:#0e3a25,stroke:#00E676,color:#fff;
class BLOCK1,BLOCK2 block
class PASS ok
09 / 22
● Codebase oracle
Graph L0 universal · L1 per-language
L0 = regex import parsers for any text file. L1 = tree-sitter symbol + signature extraction. Output: aegis/runtime/context/graph.json.
Modules · lib/graph/
lib/graph/
├─ builder.js # L0 walker · file imports
├─ builder-l1.js # L1 walker · symbols / calls
├─ incremental.js # dirty-file merge
├─ store.js # atomic JSON write
├─ resolve.js # 4 strategies · TS paths · py · go · java
├─ parsers-l0/ # js · ts · py · go · java · …
├─ parsers-l1/ # tree-sitter per language
├─ extractors/ # symbols · signatures · const exports
└─ queries/ # impact · callers · symbols
CLI
$ aegis graph build --level L1
→ aegis/runtime/context/graph.json
$ aegis graph impact src/api.ts
→ BFS of files touched
$ aegis graph symbols src/api.ts
$ aegis graph callers parseToken
in-house · MIT · no PolyForm
tree-sitter optional dep
~1000 files in <2s
10 / 22
● Contract gate
Policy: file-level + signature diff
Two layers. File-level blocks protected paths. Signature gate detects exported API changes via L1 graph diff. Adapters emit reason in the right format for each AI tool.
lib/policy/
index-builder builds policy-index.json
check APPROVE · WARN · BLOCK per file
diff-detector signature change between commits
overrides 3 sources: config · skill · inline
decisions / reason-builder human-readable verdicts
alternatives suggested safe path
62 / 62 policy tests green · matchGlob mid-path /**/ bug fixed
Adapters · 5 AI tools
lib/policy/adapters/
├─ claude-code.js # JSON hook output
├─ cursor.js # .cursorrules signals
├─ codex.js # text reason
├─ kimi-cli.js # Kimi protocol
└─ opencode.js # Opencode hook fmt
27 adapter tests
deterministic — same diff, same verdict
$ aegis policy-check --base main --head HEAD
→ exit 1 if BLOCK · prints reason · signed block in commit msg
11 / 22
● Phase 12 · Keeper auto
Auto resolution · LLM-classified
Whitelist paths get auto-resolved by Claude (Anthropic SDK). Blacklist stays HITL. Decision tree decides; auto-policy.yaml controls scope. --dry-run skips LLM + writes.
lib/auto/
classifier trivial · review · skip
decision-tree 14 cases covered by tests
spec-writer Anthropic SDK call · prompt-cache
prompt-cache cache 5-min reuse
labels 🟢 auto · 🟡 needs review · 🔴 escalate
policy-schema YAML validator
aegis/config/auto-policy.yaml
auto_resolve: true
model: claude-opus-4-7
whitelist:
- "src/utils/**" # auto-resolve drift here
- "src/**/*.test.js"
blacklist:
- "src/auth/**" # always HITL
- "aegis/specs/adrs/**"
caps:
max_per_run: 10
max_per_day: 50
opt-in
needs ANTHROPIC_API_KEY
JSONL tolerant — bad lines skipped
dry-run by default in CI
12 / 22
● Spec confidence
Every statement is marked
Aegis never pretends. Each claim carries a confidence mark, so reviewers know what is fact, what is inference, what needs a human.
CONFIRMED
Extracted directly from code. Can be cited with file + line.
example
"User cannot login after 3 failed attempts (auth/login.js:84)"
audit trail · ground truth
INFERRED
Deduced from patterns. May be wrong.
example
"Likely intended for SSO integration based on session metadata."
needs validation
GAP
Not determinable from code. Requires human input.
example
"Discount tiers above $10k — value unknown. Open question."
queue in questions.md
13 / 22
● 14 supported
Plug into any coding agent
Installer auto-detects engines present in the environment. Each gets its native entry file. Skills land in aegis/skills/ verbatim.
Claude Code ⭐CLAUDE.md · /aegis
Cursor ⭐.cursorrules · /aegis
Gemini CLIGEMINI.md · /aegis
OpencodeAGENTS.md · aegis
GitHub Copilot.github/copilot-instructions.md
AiderCONVENTIONS.md · aegis
Amazon Q Developer.amazonq/rules/aegis.md
Kimi CLIAGENTS.md · aegis · fork-new
+ hooksclaude · cursor · kimi · codex · opencode
+ git hookspre-commit policy gate
14 / 22
● Surface
CLI commands
Everything is one binary: install, hook, build, gate, audit, migrate. No daemon. No service. Idempotent.
Setup & lifecycle
$ npx aegis-spec install
$ npx aegis-spec status
$ npx aegis-spec update # SHA-256 protected
$ npx aegis-spec add-agent
$ npx aegis-spec add-engine
$ npx aegis-spec add-hooks --engine claude-code
$ npx aegis-spec remove-hooks --engine claude-code
$ npx aegis-spec uninstall # only touches aegis/
Control plane
$ aegis graph build --level L1
$ aegis graph impact src/auth.ts
$ aegis policy-index build
$ aegis policy-check --base main --head HEAD
$ aegis drift-check --severity high
$ aegis keeper-auto # Phase 12 auto loop
$ aegis migrate-reversa # Reversa → Aegis v2
$ aegis migrate-layout # legacy → single-folder
$ aegis export-diagrams
17 command modules · lib/commands/*.js
idempotent
exit-code aware
CI-ready
no daemon
15 / 22
● What gets generated
Everything lives under aegis/
Single folder. Never touches existing project files. Runtime state, specs, reports, architecture, traceability — all addressable, all versioned by the user.
aegis/
├─ config/
│ ├─ state.json # session checkpoints
│ ├─ config.toml # project config
│ ├─ config.user.toml # personal · gitignored
│ ├─ auto-policy.yaml # Keeper auto scope
│ ├─ manifest.yaml
│ └─ files-manifest.json # SHA-256
├─ runtime/
│ ├─ context/
│ │ ├─ surface.json
│ │ ├─ modules.json
│ │ ├─ graph.json
│ │ └─ policy-index.json
│ ├─ queue/keeper-queue.jsonl
│ └─ audit/YYYY-MM-DD.jsonl
├─ skills/ # installed agents
├─ specs/
│ ├─ sdd/ # per-component
│ ├─ user-stories/
│ ├─ adrs/
│ └─ openapi/
├─ reports/
│ ├─ inventory.md
│ ├─ dependencies.md
│ ├─ confidence-report.md
│ ├─ gaps.md
│ ├─ questions.md
│ ├─ drift.md # 🔴 pending dashboard
│ └─ changelog/YYYY-MM-DD.md
├─ architecture/
│ ├─ c4-context.md · c4-containers.md · c4-components.md
│ └─ erd-complete.md
├─ traceability/
│ ├─ spec-impact-matrix.md
│ └─ code-spec-matrix.md
└─ migration/ # optional
16 / 22
● Observability
Audit log + replay queue
Every Keeper decision lands in a daily JSONL. Sensitive fields auto-redacted. Queue tolerates corrupt lines — bad JSON skipped, never blocks the loop.
lib/audit/
audit/
├─ writer.js # append-only JSONL
├─ redact.js # API keys · tokens · emails
└─ schema.md # event shape contract
aegis/runtime/audit/2026-05-14.jsonl
{"ts":"2026-05-14T13:25:00Z","actor":"keeper-auto",
"file":"src/api/auth.ts","verdict":"APPROVE",
"spec_updated":"aegis/specs/sdd/auth.md",
"reason":"signature unchanged · whitelist hit"}
Queue (lib/commands/keeper-auto.js)
JSONL tolerant bad line → skip + warn
whitelist routing auto-resolve path
cap per run/day stops runaway costs
resume safe idempotent re-process
14+ unit tests · keeper-auto queue contract
17 / 22
● Safety
Installer · SHA-256 manifest
Aegis never modifies user code. New files only. update detects user edits via hash and refuses to overwrite customisations. uninstall removes only what Aegis wrote.
lib/installer/
detector finds 14 engines via fs markers
prompts interactive · sensible defaults
orange-prompts dangerous-action UX
manifest SHA-256 per installed file
writer installSkill · installEntryFile
validator input sanity
git-hooks pre-commit policy gate
hooks/ generators per engine
Invariants
- Only writes new files
- Never deletes outside
aegis/
- Detects edited installed files via hash
- Refuses to overwrite user-modified skill
- No API keys requested · stored · transmitted
- Engine intelligence lives in the engine
47 installer tests · manifest · git-hooks · writer · detector
18 / 22
● Quality
Test coverage by module
node --test runner · 47 suites. Static ESM imports throughout. Module-cache stubs for SDK isolation. Real git history used in policy-check e2e.
62
policy tests
match · check · overrides · adapters · index
40
graph tests
store · builder · L1 · incremental · resolver
47
installer tests
manifest · detector · git-hooks · writer
14
auto tests
classifier · decision-tree · spec-writer
9
drift-check
exit codes · severity
9
graph cmd
subcommands + exit codes
e2e
policy-check
real git history
8
matchGlob
incl. mid-path /**/ fix
$ npm test · node --test --test-reporter=spec test/unit/**/*.test.js
19 / 22
● Fork vs upstream
What this fork adds
Upstream sandeco/reversa v1.2.28 = spec generation. Fork = spec + graph + policy + drift + audit + bot + CI templates. Same MIT.
Upstream Reversa
- Discovery agents (Scout · Archaeologist · …)
- Migration agents
- Spec generation pipeline
- Engine entry files
- 5-phase orchestrator
tag base: upstream/main · 144aee2
Fork delta · v2.0.0
- Keeper agent — drift loop after generation
- Graph (in-house, MIT) — L0 + L1, 5 langs
- Policy gate — file + signature diff + adapters
- Auto mode — opt-in LLM resolution
- Audit log + JSONL queue + redaction
- Hook generators — Claude · Cursor · Kimi · Codex · Opencode
- Bot scaffold —
bot/keeper-bot/
- CI templates — GitHub · GitLab · CircleCI
- Kimi CLI engine support
- Single-folder layout ·
aegis/
20 / 22
● Shipped + next
Phases 1 – 14 · all shipped
v2.0.0 closes the control-plane roadmap. Next: deeper language coverage, smarter blast-radius scoring, telemetry-grade audit, bot for self-hosted GitHub/GitLab.
Delivered
P1 Hooks · v1.7.0
P2 Graph L0 · v1.8.0-α1
P3 Storage + queries · v1.8.0-α2
P4 File-level policy · v1.8.0-α3
P5 Keeper ↔ L0 · v1.8.0
P6 Graph L1 JS/TS · v1.9.0-α1
P7 Graph L1 Python · v1.9.0-α2
P8 Graph L1 Go · v1.9.0-α3
P9 Graph L1 Java · v1.9.0-α4
P10 Signature diff · v1.9.0
P11 policy-check CLI · v1.10.0
P12 Auto Keeper · v2.0.0-α1
P13 Audit + bot · v2.0.0-β1
P14 CI templates + docs · v2.0.0
Architectural calls
Build graph in-house instead of GitNexus (PolyForm license + scope mismatch)
tree-sitter is optional dep — L0 always works
Single-folder layout aegis/ replaces split _aegis_sdd/ + _reversa_sdd/
Backlog · v2.1+
keeper-bot for self-hosted GitHub/GitLab · OAuth-app flow
extend parsers-l1/ with tree-sitter-rust · tree-sitter-c-sharp
OpenTelemetry export · grafana dashboard from JSONL
weight impact by call-count + criticality not just BFS depth
static MkDocs page rendering drift.md + graph viz
21 / 22
Aegis Spec
Specs as contracts. Graph as ground truth. Keeper as the gate that keeps them aligned.
npx aegis-spec install
github.com/Wellbrito29/Aegis
wellbrito29.github.io/Aegis
MIT · fork of sandeco/reversa
Home first
End last
F fullscreen
· thanks · questions?
22 / 22