Local safety console for autonomous coding agents.
Cortex Sentinel lets you run tools like Codex, Claude Code, Gemini, or scripted agents with a brake pedal, a policy gate, rollback evidence, and a replayable audit trail.
It is the public-facing app in this repo. It is not a hard operating-system sandbox and it does not promise that unsafe software can never touch a file. It is a practical supervision layer for local development: watch the agent, stop risky actions, ask the human before ambiguous actions, and keep evidence of what happened.
- Landing page: docs/index.html
- Showpiece brief: docs/showpiece/cortex-sentinel.md
- Gap analysis and proof contract: GOAL.md
The landing page is intentionally built around the real product story: a local agent asks to act, Sentinel classifies the effect, protected paths are blocked, review actions wait for a human, and trace replay proves the session later.
Coding agents are useful because they can inspect a repo, edit files, run commands, and iterate quickly. That is also why they are risky. A fast agent can delete a file, touch secrets, run a network command, or drift away from the task before a human notices.
Cortex Sentinel is for developers who want the productivity of local coding agents without treating the agent as fully trusted infrastructure.
In college-freshman terms: imagine a student lab where a robot can solder, cut, and test parts. Cortex Sentinel is the lab supervisor. It does not make the tools harmless, but it can pause the robot, enforce rules, ask for permission, write down what happened, and help restore damage in known protected areas.
- Launches a local command or coding agent through
sentinel run. - Watches output for confirmation prompts and risky command text.
- Detects file effects in the workspace.
- Applies deterministic policy before any model judgment.
- Blocks protected files, secret-like paths, external network commands, and production deploy effects.
- Sends ambiguous actions to a local MLX/Gemma auditor when configured.
- Shows pending decisions in a terminal UI with approve, block, pause, kill, and override controls.
- Records JSONL traces with policy decisions, file effects, user actions, rollback events, process lifecycle events, and stable digests.
- Replays traces as JSON or text so the session can be inspected later.
Current evidence from this repo:
- Root test suite has passed with
142 passed. - Nested
mcp-cortexsuite has passed with11 passed. - A fresh independent clone from GitHub passed after the optional MCP-Cortex dependency path was fixed:
140 passed, 2 skipped. - The MLX/Gemma auditor smoke has loaded
mlx-community/gemma-4-12B-it-OptiQ-4bitand returned structuredallow/greenoutput in a Metal-capable local session. - Codex full-screen TUI smoke has been proven through workspace trust, command approval, and harmless output
SENTINEL_CODEX_TUI_OK. - Claude Code startup trust-prompt control has been proven in a disposable workspace.
- Continuous protected-file enforcement is proven with a no-prompt
.envwrite that suspends the runner and rolls back the created protected file.
What is still open:
- Full interactive Claude/Gemini tool-confirmation flows are not yet proven end to end.
- Default readiness leaves the real Gemma auditor external-blocked unless a Metal-capable session opts in.
- MCP-Cortex is trace-oriented in this version. It records decisions; it does not proxy or authorize real MCP traffic.
- Sentinel supervises and reacts. It is not a kernel sandbox, container boundary, or formal security product.
Install into a local Python environment:
pip install -e .If you are using this repo's virtual environment:
venv/bin/python -m pip install -e .Check the local MLX/Gemma environment:
sentinel check-envInspect the current proof matrix:
sentinel readiness --no-run
python scripts/readiness_check.pyRun a simple command under supervision:
sentinel run --config sentinel.yaml -- python -c "print('ready')"Run with a temporary scoped path override:
sentinel run --config sentinel.yaml --allow-path "src/ui/**" -- python agent.pyReplay a saved trace:
sentinel trace replay .sentinel/traces/<session>.jsonl
sentinel trace replay --format text .sentinel/traces/<session>.jsonlFrom the repository root:
python -m pip install -e .This installs the sentinel console script:
sentinel --help
sentinel check-env
sentinel run --config sentinel.yaml -- python agent.py
sentinel run --config sentinel.yaml --allow-path "src/ui/**" -- python agent.py
sentinel readiness --no-run
sentinel trace replay .sentinel/traces/<session>.jsonl
sentinel trace replay --format text .sentinel/traces/<session>.jsonlThe local Gemma auditor uses mlx_lm with:
mlx-community/gemma-4-12B-it-OptiQ-4bit
The repo virtual environment has been verified to contain the needed gemma4_unified -> gemma4 mapping. The real auditor smoke requires macOS Metal access.
Default config file: sentinel.yaml.
workspace_root: .
protected_paths:
- "**/.env"
- "~/.ssh/**"
auto_approve_paths:
- "docs/**"
model_id: "mlx-community/gemma-4-12B-it-OptiQ-4bit"
ignore_dirs:
- ".git"
- "__pycache__"
- ".sentinel"
prompt_patterns:
- "\\?\\s*$"
- "\\[y/n\\]"
trace_dir: ".sentinel/traces"
pty_mode: false
override_ttl_seconds: 900
model_parameters:
max_tokens: 96
temperature: 0.0
risk_thresholds:
read:secret: block
write:secret: block
delete:workspace: confirm
execute:shell: review
network:external: block
deploy:production: block
policy_profile: default
policy_profiles:
locked:
protected_paths:
- "**/.env"
- "~/.ssh/**"
auto_approve_paths:
- "docs/public/**"Policy outcomes:
allow: continue when deterministic policy approves.block: refuse or suspend the risky action.review: ask the auditor, then wait for explicit user approval.confirm: wait for explicit user approval without using the auditor.
Temporary overrides:
sentinel run --allow-path "src/ui/**" -- ...creates a trace-visible allow override for the current session.- Repeating
--allow-pathadds multiple patterns. - Pressing
min the TUI opens a manual override input. - Overrides cannot bypass hard blocks for protected paths, secret-like paths, external network effects, or production deploy effects.
- Overrides expire according to
override_ttl_seconds.
Cortex Sentinel separates deterministic policy from LLM judgment. Protected paths, secret-like paths, external network effects, and production deploy effects are hard policy decisions. They do not rely on the auditor.
Important limitations:
- Continuous enforcement is polling-based. It detects, suspends, and can roll back protected-path effects after they appear; it is not pre-write OS sandboxing.
- Real Claude Code startup trust-prompt control is proven. Real Codex non-interactive model/tool command execution is proven. Real Codex full-screen TUI workspace trust and command approval are proven. Full interactive Claude/Gemini tool-confirmation behavior is not yet proven.
- The PTY runner answers basic terminal queries and starts children with a usable default 24x80 window size. It is still not a complete terminal emulator.
scripts/real_agent_smoke.pyis opt-in and only as safe as the command you pass to it. Use disposable workspaces and avoid secrets.- MCP-Cortex integration is trace-oriented in this app version. It records decisions; it does not proxy or authorize real MCP traffic.
- Do not pass secrets, credentials, PHI, private keys, or unnecessary sensitive data into prompts or traces.
At runtime, Cortex Sentinel sits between the human and the agent process.
- Runner starts the agent. The app launches the command passed to
sentinel run. - Prompt detector watches output. If the agent asks for confirmation, the TUI starts a safety check.
- File observer checks effects. The app compares workspace snapshots to see what files were created, modified, or deleted.
- Policy layer decides first. Hard rules block protected paths, secrets, external network commands, and production deploys.
- Auditor handles ambiguity. For review cases, a local MLX/Gemma auditor must return structured JSON. Free-text
YESis not enough. - Human approves or blocks. Review and confirm outcomes wait for explicit user action.
- Enforcer watches continuously. A background enforcer can detect no-prompt protected writes and suspend the runner.
- Trace store records evidence. Decisions, file effects, user actions, rollback events, and process events are written to local JSONL traces.
Unit and integration tests:
pytest -q
(cd mcp-cortex && python -m pytest -q)Disposable local smokes:
venv/bin/python scripts/sentinel_smoke.py
venv/bin/python scripts/agent_integration_smoke.py
venv/bin/python scripts/enforcement_smoke.py
venv/bin/python scripts/trace_smoke.py
python scripts/e2e_smoke.pyAuditor and real-agent smokes:
venv/bin/python scripts/auditor_smoke.py --dry-run
venv/bin/python scripts/auditor_smoke.py
python scripts/real_agent_smoke.py --dry-run
python scripts/real_agent_smoke.py --probe-installed-agents --timeout 5
python scripts/real_agent_smoke.py --claude-trust-smoke --timeout 8
python scripts/real_agent_smoke.py --codex-exec-smoke --timeout 30
python scripts/real_agent_smoke.py --codex-tui-smoke --timeout 60Readiness and release checks:
sentinel readiness --no-run
python scripts/readiness_check.py
python scripts/release_check.py --skip-wheel
python scripts/release_check.py --wheel-dir /tmp/cortex-sentinel-release-check
git diff --checkscripts/readiness_check.py emits a JSON proof matrix for GOAL.md. By default it runs local disposable smokes and safe non-interactive agent metadata probes, leaves full test suites and remaining real interactive agent commands as manual evidence, and marks the real auditor smoke externally blocked unless --run-real-auditor is provided in a Metal-capable session.
The initial plan was to make the local Gemma auditor and basic agent supervision work. The project grew into a broader local safety console.
Useful drift:
- Added deterministic policy before relying on model judgment.
- Added continuous protected-file enforcement and rollback.
- Added persistent trace storage and trace replay.
- Added package metadata, a
sentinelCLI, and a readiness matrix. - Added a guarded real-agent harness and safe CLI metadata probes.
- Added bounded Claude Code and Codex smokes for real local interaction evidence.
- Added a richer TUI approval flow, approval queue, dedicated panel, and manual override input.
Unresolved drift:
- Real Gemma verification is proven in Metal-capable local runs but remains opt-in in default readiness.
- Full interactive Claude/Gemini tool-confirmation runs are still not complete.
- MCP-Cortex is trace-oriented metadata support, not a full MCP authorization proxy.
Check the environment:
sentinel check-envIf scripts/auditor_smoke.py fails with No Metal device available, rerun it from a local macOS terminal/session that has GPU/Metal access:
venv/bin/python scripts/auditor_smoke.pyIf editable install tries to download dependencies, make sure the environment can reach PyPI or install in an environment where setuptools, PyYAML, and textual are already available.
If no prompts are detected, tune prompt_patterns in sentinel.yaml.
If trace replay reports invalid digests, treat the trace as modified and do not rely on it as audit evidence.
Trace replay includes enforcement rollback metadata when a protected file effect is rolled back. Rollback events record paths, operations, and rollback result names; they do not store protected file contents.
Run a simple command under supervision:
sentinel run --config sentinel.yaml -- python -c "print('ready')"Run a coding agent under supervision only in a disposable workspace until behavior is proven:
sentinel run --config sentinel.yaml -- claude .Run with a temporary scoped override:
sentinel run --config sentinel.yaml --allow-path "docs/drafts/**" -- python agent.pyReplay a trace:
sentinel trace replay .sentinel/traces/session-example.jsonl
sentinel trace replay --format text .sentinel/traces/session-example.jsonlRun the guarded real-agent smoke only with an explicit disposable command:
python scripts/real_agent_smoke.py --dry-run
python scripts/real_agent_smoke.py --probe-installed-agents --timeout 5
python scripts/real_agent_smoke.py --claude-trust-smoke --timeout 8
python scripts/real_agent_smoke.py --codex-exec-smoke --timeout 30
python scripts/real_agent_smoke.py --codex-tui-smoke --timeout 60
python scripts/real_agent_smoke.py --agent-command "claude ." --approval-input n
python scripts/real_agent_smoke.py \
--agent-command "python fixture_agent.py" \
--interaction "Trust workspace.*\\?=>y" \
--interaction "Run safe tool.*\\?=>n" \
--expect-output "answers:y,n"Run the local verification set:
sentinel readiness --no-run
python scripts/readiness_check.py
pytest -q
(cd mcp-cortex && python -m pytest -q)
venv/bin/python scripts/sentinel_smoke.py
venv/bin/python scripts/agent_integration_smoke.py
venv/bin/python scripts/enforcement_smoke.py
venv/bin/python scripts/trace_smoke.py
python scripts/e2e_smoke.py
python scripts/real_agent_smoke.py --dry-run
python scripts/real_agent_smoke.py --probe-installed-agents --timeout 5
python scripts/real_agent_smoke.py --claude-trust-smoke --timeout 8
python scripts/real_agent_smoke.py --codex-exec-smoke --timeout 30
python scripts/real_agent_smoke.py --codex-tui-smoke --timeout 60
git diff --checkRun the release metadata and wheel check:
python scripts/release_check.py --skip-wheel
python scripts/release_check.py --wheel-dir /tmp/cortex-sentinel-release-check