// how it works LIVE

How It Works

Models propose. Code decides. Every write passes a gate.

How AgentOS works, and why I trust what it produces. Every assistant starts with the same picture of who I am and what I am working on, so no session starts from zero. The real work runs as supervised jobs with strict budgets, and a checker written in ordinary code rejects anything unfinished before it is allowed to change anything real.

How AgentOS works, and why its output can be trusted. Every assistant reads the same context portfolio through a local MCP server, so no session starts from zero, and the same shared memory and skills deploy to all three AI clients. The real agent work runs as budgeted jobs on a task-graph runtime inside that gateway, where a verifier written in code rather than AI rejects anything incomplete, and only verified work is allowed to change anything real. Git backs up every layer; each is independently useful, and stacked together they make every session context-aware by default.

one shared memory across assistants agents do real work on a budget code checks every result a verified review of every project costs cents
10 portfolio files 03 ai clients 04 executable workflows $0.33 verified portfolio audit (usd)
layer_1_context_portfolio [01]

Context Portfolio

Ten structured markdown files in context-portfolio/. Each file covers one dimension of how I work. They are machine-readable, dense, and written to be useful to an AI without ceremony. Edits are reflected immediately: the MCP server reads from disk on every request.

identity.md

Who I am, my role, stack, principles, and how to work with me.

role-and-responsibilities.md

Core responsibilities, weekly cadence, key decisions owned, and reporting structure.

current-projects.md

Five active projects with status, stack, and cross-project relationships.

communication-style.md

Writing style, formatting preferences, what to avoid, and audience-specific patterns.

decision-log.md

How decisions are made, recent decisions, and currently open decisions.

domain-knowledge.md

Areas of expertise, key terminology, frameworks, and what is actively being learned.

goals-and-priorities.md

Current goals, longer-term goals, tradeoff thinking, and what success looks like.

preferences-and-constraints.md

Hard constraints, strong preferences, things disliked, and AI output preferences.

team-and-relationships.md

Key relationships, working styles, and organisational context.

tools-and-systems.md

Full tooling inventory across Salesforce, AI, VSCode, frontend, and project management.

Portfolio files are also readable via an interview agent (context-portfolio-interviewer/) that can review and update each file through a structured conversation, keeping them accurate as circumstances change.
layer_2_mcp_server [02]

MCP Server

A Node.js (ESM) server using the official @modelcontextprotocol/sdk. Binds to 127.0.0.1:3000 only. Runs under pm2 and auto-starts on Windows login via Task Scheduler. All three AI clients connect to the same server instance.

01
MCP Transport

StreamableHTTP (stateless) transport on POST /mcp, guarded by a bearer token generated on first run and compared with a timing-safe check. Every portfolio file is exposed as a portfolio://<name> resource. Files read from disk on every request, so edits are live without a restart. No session management required with stateless transport.

02
Status and Telemetry Endpoints

GET /status returns server metadata, uptime, restart count, and a rolling request log. POST endpoints receive events from client hooks:

/skill-log: records skill/command invocations with model and token usage
/tool-log: records MCP tool calls with duration and token data
/command-log: receives Cursor slash command events (hooks.json) and Codex command events (logging block injected at sync)
/agent-log: tracks agent invocations with per-agent token stats
/portfolio-read: accepts external portfolio-read events from non-resource clients
/memory-synced: records the timestamp of the last memory sync
/set-project: tags subsequent entries with the active workspace name
03
Persistence

All-time counters (invocations, tokens, restarts, uptime) are persisted to persist.json on a 60-second interval and on graceful shutdown. Session counters reset on restart; all-time counters accumulate across restarts. persist.json is gitignored so telemetry data does not pollute the repo.

04
Token Normalisation

A normalisation pipeline converts token usage across providers (camelCase and snake_case field names) into a consistent internal format. Per-model aggregation tracks session and all-time totals separately for any model ID a client reports, from the Claude family through the OpenRouter-hosted models the runtime routes to.

canonical_vs_runtime [03]

Canonical vs Runtime

The git repository is the single source of truth. The runtime directories (~/.claude/, ~/.codex/, ~/.cursor/) are derived state: they can always be recreated from the repo by running the relevant client's sync.ps1.

Canonical (git repo)
clients/claude/CLAUDE.md: behavioural contract
clients/shared/memory/: global memory files
clients/shared/skills/: 16 shared commands
clients/claude/settings.json: hooks + permissions
clients/codex/config-fragment.toml: Codex MCP block
clients/cursor/mcp-config.json: Cursor MCP config
Runtime (local machine)
~/.claude/CLAUDE.md: deployed by sync.ps1
~/.claude/memory/: deployed from shared/memory/
~/.claude/commands/: deployed from shared/skills/
~/.codex/config.toml: config fragment injected
~/.cursor/mcp.json: deployed by sync.ps1
~/.cursor/skills/: shared skills deployed
layer_3_shared_memory_and_skills [04]

Shared Memory and Skills

clients/shared/ is the single location for memory and skills that apply to all three clients. Each client's sync.ps1 sources from here, so a change to a shared command or memory file propagates to Claude, Codex, and Cursor on the next sync.

clients/
shared/
├── memory/
│  ├── global.md ──▶ identity, role, stack
│  ├── conventions.md ──▶ Salesforce, git, code standards
│  └── projects/ ──▶ per-project context files
└── skills/ ──▶ 16 shared slash commands
claude/ ──▶ CLAUDE.md, settings.json, commands/, sync.ps1
codex/ ──▶ config-fragment.toml, sync.ps1
cursor/ ──▶ mcp-config.json, hooks.json, sync.ps1
Shared skills are templated. {{LIGHTWEIGHT_MODEL}} and {{CLIENT_NAME}} placeholders expand per client at sync time, so a single skill file targets the right lightweight model and client name on Claude, Codex, and Cursor without divergent copies.
bootstrap_sequence [05]

Bootstrap Sequence

The system restores to a new machine by cloning the repo and running one script. bootstrap.ps1 sets AGENTOSROOT, validates prerequisites, installs dependencies, starts the gateway under pm2 with its pinned environment contract, deploys every client config, and builds and installs the dashboard extension. It is idempotent, so re-running it brings a machine back into sync.

Step Action What it does
1 Clone, then run bootstrap.ps1 One command from a PowerShell terminal. Every step below runs automatically and is safe to re-run.
2 Prerequisites and environment Validates Node.js 20+, pm2, and the Claude CLI, sets the AGENTOSROOT environment variable, and installs the gateway's dependencies.
3 Gateway and clients Starts the gateway under pm2 via ecosystem.config.cjs (pinned port 3000, workspace root, and least-privilege filesystem roots), then deploys CLAUDE.md, memory, commands, and settings to Claude, Codex, and Cursor. MCP registration ships as config in mcp-servers.json, so there is no manual register step.
4 Adapt, then verify settings.json paths expand per machine at deploy time; if the wider layout differs, bootstrap prints the exact gateway-config edit-set to update. The dashboard Setup Wizard then confirms the gateway is online and every step is green.
why_the_runtime_exists [01][06]

Scale and trust

AgentOS started with a single automated loop that could do a job from start to finish without me watching. The next problem was scale and trust: run that kind of work across every project at once, and stop believing an AI's output just because it arrived.

The linear pipeline proved one loop could run unattended. The next problem was scale and trust: run agent work across every project at once, and stop believing model output just because it arrived.

The runtime answers both. A graph engine wraps the proven pipeline as one node type and fans it out over the portfolio with bounded concurrency and a budget circuit breaker. Then a verification layer, written in code rather than prompted into a model, decides what is accepted downstream.

The design rule is constant across every layer: the graph structure, sequencing, and safety enforcement are deterministic. Only the inside of a node is allowed to be creative.

No model output is ever applied without passing deterministic validation gates. A model can propose a fix; it cannot reach the file.
What it adds
01Task-graph engine: fan-out, gather, budgets
02Deterministic verifier node (code, not model)
03Advisory challenger (cautions only)
04Replay-only apply engine behind gates
05Model failover routes per stage
06Permanent record of every run
06SQLite run ledger and queue
Status

Live. Multiple workflows run on the graph; real gated fixes have landed in production code. I operate it all from a dashboard inside my editor.

Live. Four executable workflows run on the graph. Portfolio audit runs green with verification across all enrolled projects. Two real gated applies have landed in production code. Operated from the Studio dashboard inside VS Code.

the_graph_engine [07]

One Graph, Many Pipelines

A workflow builds a DAG of nodes. Each fan-out child wraps the full plan/execute/review pipeline for one project. The graph is validated before any node runs, so a malformed graph fails before any model spend. Bounded concurrency and a per-run token budget act as circuit breakers: when the budget trips, in-flight nodes finish, nothing new is scheduled, and the run is marked rather than crashed. A failed node skips its descendants while independent branches continue.

flowchart TD
    P["Workflow profile
(committed JSON catalogue)"] --> B["Build + validate graph
DAG check, budget breaker"] B --> F["Fan-out: one audit node
per enrolled project"] F --> A1["audit/agentos-dashboard"] F --> A2["audit/salesforce-cicd-blueprint"] F --> A3["audit/salesforce-dev-tools"] A1 --> V1["verify"] A2 --> V2["verify"] A3 --> V3["verify"] V1 -.->|"fail: one bounded re-run
at reduced scope"| A1 V1 --> C1["challenge (opt-in,
advisory only)"] V2 --> G V3 --> G C1 --> G["gather: consolidated report
in declared order"] %% Blueprint tokens as literal hex (Mermaid cannot parse CSS vars or color-mix) classDef code fill:#62d99a1f,stroke:#62d99a,stroke-width:1.5px; classDef model fill:#8b93e81f,stroke:#8b93e8,stroke-width:1.5px; classDef entry fill:#e0be621f,stroke:#e0be62,stroke-width:1.5px; class P entry; class B,F,V1,V2,V3,G code; class A1,A2,A3,C1 model;

Purple nodes run models. Green nodes are deterministic code. The verifier and the gather never call a model; the challenger is model-backed but can only add caution, never change a verdict.

quality_gate [02][08]

The Verifier Is Code, Not a Model

Every result is re-checked by ordinary code before it counts. Did the job actually finish, is the report properly formed, and does every claim it makes match the real file it points at. A job that quietly ran out of budget is treated as a failure, not a pass.

Each audit node feeds a verifier node that re-checks the output deterministically: did the run actually complete and emit final JSON, does the report validate against the schema, and does every finding's anchor text resolve verbatim against the file on disk. A run that silently ran out of budget is a verification failure routed to a bounded re-run at reduced scope, not a clean pass. A clean zero-findings run with completion proof passes honestly.

output

Result exists and has the expected shape

completion

Final findings JSON was actually emitted

schema

Report passes the write-gate validation

anchor

Every finding resolves verbatim on disk

Any claim the AI cannot tie to a real line of the code is rejected before it reaches a report. This one gate killed the worst failure mode: audits that looked clean because the AI never actually finished.

The four failure domains are a locked taxonomy, exported and smoke-tested. A finding the model cannot anchor to a real line of source is rejected before it reaches a report. This one gate killed the runtime's worst failure mode: audits that looked clean because the model never finished.

failover_routes [09]

Failover Routes, Not Single Models

Every pipeline stage resolves to an ordered model route: preferred first, then failovers. A transient provider error (429, 5xx, network) restarts the stage on the next model in the route; a real error (schema, validation, safety gate) is rethrown immediately rather than papered over. Stage telemetry records the chain of attempted models, so a run that survived an outage says so. Routes were born from a real incident: free-tier rate limits blocked the first portfolio run, and the fix was architecture, not retries.

Focused audit mode

A deterministic selector caps each audit at the highest-signal surfaces (entry points first, tests last, deduplicated by file) and injects a hard finalisation instruction naming the exact turn by which findings JSON must be emitted. Ending a run without JSON is a failure, not a pass.

Per-stage model choice

Five-layer precedence per stage: UI override, project, pipeline, workspace, stage default. Each layer can name a single model or a full route. Planning and review lean on reasoning models; execution leans on tool-reliable ones; every stage is swappable without touching the engine.

the_write_path [10]

Apply Is a Replay, Never an Improvisation

The runtime never writes source during an audit. A fix is applied later, by replaying a saved, verifier-passed report through a deterministic apply engine. Dry-run is the default; a real write requires an explicit flag and then survives a chain of gates enforced in code. Anchor matching is CRLF-aware (content is compared LF-normalised and written back in the file's native line endings), because the first real apply candidate was blocked by exactly that mismatch.

flowchart TD
    R["Saved audit report
(verifier-passed findings)"] --> RP["Replay:
--apply-from-code-report"] RP --> D{"Mode?"} D -->|"default"| PV["Dry-run preview
no write possible"] D -->|"--apply-write"| G1{"Inside FS_ROOTS allow-list?"} G1 -->|"no"| X["Rejected: no write"] G1 -->|"yes"| G2{"Working tree clean?"} G2 -->|"no"| X G2 -->|"yes"| G3{"Anchor matches source?
(CRLF-aware)
"} G3 -->|"no"| X G3 -->|"yes"| W["Apply the fix"] W --> G4{"Declared build gate passes?"} G4 -->|"no"| RV["Revert, native EOLs preserved"] G4 -->|"yes"| L["Append-only apply ledger"] %% Blueprint tokens as literal hex (Mermaid cannot parse CSS vars or color-mix) classDef entry fill:#e0be621f,stroke:#e0be62,stroke-width:1.5px; classDef gate fill:#e0be621f,stroke:#e0be62,stroke-width:1.5px; classDef code fill:#62d99a1f,stroke:#62d99a,stroke-width:1.5px; classDef fail fill:#e697521f,stroke:#e69752,stroke-width:1.5px; class R entry; class D,G1,G2,G3,G4 gate; class RP,PV,W,L code; class X,RV fail;
The gates are mandatory

A target with no declared build gate yields a gate error for every unit and no tree mutation. Apply cannot be combined with the graph or pipeline paths: one report, one target, one gated write path. Every apply is recorded in an append-only ledger.

Approval spine

For any future queued apply, an approval boundary already exists: grants bind to the exact apply fingerprint, are issued out of band via a CLI (grant, list, revoke), and fail closed. Approval grants no authority by itself, and queued apply remains impossible by design until it is deliberately switched on.

workflow_profiles [11]

Four Workflows on One Engine

Workflows are catalogued in a committed JSON registry with a hardened contract: profiles are descriptive metadata, an executable profile must map to a real workflow defined in code, and no JSON field can grant apply or execution authority. The registry is validated before any model call; a field that even looks like an authority grant throws at load. Project enrolment lives in a second committed registry, so adding a project to the portfolio is a reviewed git change.

Model-backed
code-audit

The reference workflow: fan-out code audit over the enrolled targets with optional verify and challenge stages. The only workflow with an (always gated) apply story.

Model-backed
website-audit

The proposal-first sibling: fans the website content audit out over the enrolled projects and consolidates. Read-only with no apply path; it writes nothing to the website.

Deterministic detector
documentation-drift

No model at all: inspects a bounded set of doc surfaces and reports candidate drift against known project state. Proof the graph layer carries more than audits.

Deterministic detector
changelog-coverage

Evidence source is git history: commits that landed after the newest changelog entry are reported as candidate coverage gaps. Detection only; drafting prose stays a planned, separate profile.

platform_spine [12]

Durable, Local, Honest About It

Underneath the runtime sits a local platform layer: a SQLite run ledger and queue (better-sqlite3, WAL) dual-written alongside the canonical JSONL telemetry, behind an async interface that could later point at a hosted database without touching callers. Store reads are opt-in with strict JSONL fallback. Queue payloads are secret-free by construction; the worker injects credentials at drain time. Orphaned store rows are retained and reported, never fabricated into fake history.

run telemetry
├── runs.jsonl / graph-runs.jsonl ── canonical, append-only
└── SQLite ledger + queue ── dual-written, WAL, opt-in reads
gateway (pm2, bearer-authed, loopback only)
├── run-control API: workflows, runs, live node events (SSE)
├── read-only: run history, queue status, profiles, projects
└── pinned non-secret env contract ── secrets never in config
proof_not_promises [03][13]

Validated Live

01
Portfolio audit, verified, for cents

The first portfolio-scale focused-plus-verify run came back green across all enrolled projects: every audit passed the deterministic verifier, for about US$0.33 in total model spend. Repeat paid runs confirmed the result was repeatable, not lucky.

02
Real applies, gated end to end

Two real fixes found by the audit have been applied through the full replay path (dry-run, gates, write, build gate, ledger) and committed: a dead write removed and a dead field removed. Small on purpose: the point was proving the write path, not the diff.

03
The failure modes are tested, not assumed

The failure modes are exercised by an automated test suite that costs nothing to run: the ways a run can go wrong are tested deliberately, not discovered later. The rules the system must obey are written down and locked.

An offline smoke suite runs with zero token spend: DAG validation, budget trips, verifier mechanics, failover routes, CRLF apply matching, approval fail-closed behaviour, and the report parser against malformed model output. Runtime contracts are written down and locked in RUNTIME-CONTRACTS.md.

04
Reliability incidents became architecture

Free-tier rate limits became failover routes. A silently incomplete audit became the completion failure domain. A loose anchor became the verbatim anchor gate. A line-ending mismatch became a smarter, ending-aware apply. Each hardening traces to a named, recorded incident.

Free-tier rate limits became failover routes. A silently incomplete audit became the completion failure domain. A loose anchor became the verbatim anchor gate. A line-ending mismatch became CRLF-aware apply. Each hardening traces to a named, recorded incident.

See it operated

The runtime is driven from Studio, a hub inside the VS Code dashboard: discover workflows, price a run before launching it, and watch the graph execute live.

View the dashboard →
inside_a_node [04][14]

From demo to infrastructure

A single successful agent run proves nothing. It proves the task can work once, not that it works reliably. The gap between a demo that worked yesterday and infrastructure you trust to run unattended is the whole problem.

This runtime closes that gap. It separates the parts that must be reliable (connecting tools, validating calls, retrying transient failures, applying writes) from the part that is allowed to be creative (the model deciding what to do). The reliable parts are code. The creative part is sandboxed behind a gate it cannot reach around.

The result is a loop that can be measured, hardened, and reused. Build one loop properly and the next one is a prompt and a config entry, not a rewrite.

The model is the least trusted component in the system. Every tool call it makes is parsed and schema-checked before it reaches a tool. Every write it proposes is applied by code, not by the model.
What it is
01Plan / execute / review pipeline
02Bounded self-correction loop
03Model plans, code applies
04Reliability harness, not one green run
05Provider-agnostic by construction
Status

Live. Two loops in production (Website Update and Content Audit), on a shared pipeline, safety gate, and repeatability harness. The same pipeline is now the node type inside every graph workflow on the runtime.

the_node_pipeline [15]

One Pipeline, Every Loop

Three stages and an optional correction loop. One MCP connection is opened once and shared across every stage. The pipeline holds no transport or model detail itself, so every loop on the site runs on this same engine.

Stage 01
Plan

The planner model reads the tool catalogue and the task, then writes a short numbered plan. It executes nothing. Planning and doing are deliberately separate stages.

Stage 02
Execute

The executor runs the agent loop, calling MCP tools to carry out the plan and adapting when a step turns out wrong. Turn-budgeted, so it cannot run forever.

Stage 03
Review

The reviewer checks the result against the original request. It approves, or rejects with a structured reason, what is missing, and a suggested fix.

On rejection, the executor runs again with the reviewer's feedback, up to a set correction budget. The verdict is parsed into structured fields before it goes back, so the executor receives actionable feedback, not raw prose.

task
└── plan (DeepSeek V4 Flash) ── reads tool catalogue, writes a plan, runs nothing
└── execute (Qwen3 Coder) ── agent loop: model ⇄ MCP tools, turn-budgeted
└── review (DeepSeek V4 Flash) ── APPROVED / REJECTED + reason, missing, suggestion
└── correct ── on REJECTED, re-execute with feedback, up to N times
model_routing [05][16]

Built for the Token Scarcity Era

AgentOS is built for a world where autonomous loops have to be sustainable. A single task can involve planning, execution, review, correction, audit, and summarisation, each step consuming tokens. Running every stage through a premium frontier model turns experimentation into an operating cost problem.

Planning + Review
DeepSeek

Used where reasoning quality matters most: planning the approach, reviewing outputs, and deciding whether a result should be accepted or corrected.

Synthesis + Audit
Kimi

Used where breadth matters: reading many files, synthesising evidence, and producing richer website audit proposals from long-context project history.

Execution + Tools
Qwen

Used for tool-heavy execution: inspecting files, calling the system's tools, and generating structured edit lists that ordinary code can validate.

Used for tool-heavy execution: inspecting files, calling MCP tools, and generating structured change-sets that deterministic code can validate.

OpenRouter sits behind this routing layer as the model gateway. The architecture is not “use the strongest model everywhere”; it is “use the cheapest capable model for each stage, keep repeatable work in code, and spend intelligence where it matters”.

model routing
├── plan (DeepSeek) ── reasoning-heavy planning, no tools executed
├── execute (Qwen) ── tool-heavy execution and structured edit lists
├── execute (Qwen) ── tool-heavy MCP execution and structured change-sets
├── audit (Kimi) ── long-context synthesis and narrative proposals
└── apply (code) ── deterministic validation, replacement, and structural inserts
loop_reliability [17]

Built to Be Reliable

01
The model is never trusted

Every tool call is parsed and checked against the tool's JSON schema before it reaches the MCP server. The reasoning blocks the open-weight models prepend are stripped first. An invalid call never touches a tool.

02
Two failure classes, handled separately

Transient provider failures (429, 5xx, network) are retried with exponential backoff, invisible to the model. Invalid tool calls are sent back to the model with the schema so it can self-correct, budgeted per tool per run.

03
A repeatability harness, not a single green run

The harness runs the same task many times and reports success rate, average attempts, turns, duration, and token cost. Reliability becomes a number you can watch move between changes, not a vibe. One green run proves capability; this measures whether it holds.

04
Provider-agnostic by construction

The loop holds no transport or model detail. Four role profiles map to OpenRouter models: planner on DeepSeek V4 Flash, tools on Qwen3 Coder, agentic on Kimi K2.5, cheap on the free Qwen tier. Swapping a provider or adding a second agent means touching the edges, not the loop.

05
Offline test coverage

A smoke-test block exercises the write gate, scope allowlist, coverage checks, change-set parsing, and the deterministic apply without hitting a model or the network. The safety-critical paths are tested in isolation.

what_runs_on_the_pipeline [06][18]

What Runs on the Pipeline

The engine's first job is keeping this website up to date on its own, and the bigger workflows reuse the same machinery underneath. Adding a new job is quick because the safety checks are already built. The list grows; the engine does not change.

Two loops run directly on the pipeline, and the graph workflows (code audit, website audit, and the deterministic detectors) wrap it as their node type. Each new loop is a prompt and a config entry on top of the same pipeline, gate, and harness. This list grows; the engine does not change.

First jobLoop 01
Website Update

The pipeline's first real job is the site you are reading. It keeps the Showcase Website current from each project's source repo, and it is the template every future loop follows.

How it works

The model reads the project's release notes and documentation, then returns a checked list of proposed edits: what is stale, what is current, and why. When changes are applied, code performs each edit exactly and re-reads the file to confirm it took. The model plans. Code applies. A clean run reaches a fixed point: apply, then re-run, and nothing changes.

The model reads the project's CHANGELOG, README, and shipped version, then returns a validated JSON change-set: what is stale, what is current, and why. In apply mode, code performs each edit with an exact-snippet replace and re-reads the file to confirm it took. The model plans. Code applies. A clean run reaches a fixed point: apply, then re-run, and nothing changes.

The safety gate

Writes are allowed only inside the website directory, only through exact-snippet replace (never full-file rewrites), only on elements inside the chosen scope, and only up to a per-run cap. No-op edits are skipped. Git operations are blocked. Dry-run intercepts every write, so a preview can never touch a file. The gate is enforced in code, not by asking the model nicely.

introspective_engineering [19]

A System That Audits Its Own Code and Website Content

AgentOS does not just build software. It runs a content-audit loop that automatically evaluates whether the showcase website communicates the project's achievements, and when it falls short, proposes concrete improvements grounded in git evidence. The loop produces a synthesis layer with fields like whatFeelsUnderstated, whatIsMostImpressiveNow, and recommendedHeroShift, each backed by citations to commits and changelog entries. The model proposes; the evidence decides.

SchemaVersion 4
Deterministic Decision Engine

Code, not the model, computes nextBestActionScore using explicit penalties: effort (low 0, medium 4, high 8) and risk (low 0, medium 3, high 6). A +3 grounding bonus rewards fully evidenced proposals. Impact is weighted by stated confidence so ungrounded hype sinks regardless of self-rating.

Grounding Split
Evidence vs Speculation

A structural synthesisGrounding coverage ratio reports how many factual claims cite evidence. Readers can tell demonstrated fact from positioning suggestion at a glance. New sections must pass a three-criteria justification gate (clearCapabilityGap, cannotBeMergedIntoExisting, addsDifferentiation) or be flagged as under-justified.

Loop 02
Content Audit

While the Website Update loop keeps the site current, the Content Audit loop asks a harder question: is the site as impressive as the work? It reads git history and CHANGELOG since the last sync, compares the evidence to the live site, and produces a three-layer report: synthesis (what changed, why it matters, how to reposition), findings (stale copy, missing concepts), and proposals (website-ready copy with placement anchors). Every proposal cites evidence; every write is safety-gated.