Skip to main content

ChronoAgent 0.5.0 — a safety layer for AI coding agents

ChronoAgent sits between an AI coding agent and your machine. It does four things:

  1. Stops dangerous commands before they run. This includes the scripts a command starts (python cleanup.py, npm test, make clean, x.bat), not only the command text.
  2. Takes a savepoint before every command that can change files (and whenever you ask), so a bad change to your project files can be rolled back, and the rollback itself can be undone.
  3. Keeps a signed, tamper-evident audit log of everything that was scanned, blocked, run, restored or approved.
  4. Guards the agent's own shell and edit tools (Claude Code hook), not only the commands it chooses to send to Chrono.

It is a dependency-free Python package (3.8+) with a CLI (chrono), an MCP server for AI clients, and a Python SDK. The fleet gateway pilot is described in FLEET.md.

Read "What Chrono cannot do" below before you rely on it. It is a guardrail for cooperating tools on one machine. It is not a sandbox, an antivirus or a backup.

Install / upgrade in Windows CMD

Download the ZIP. Without extracting it, in its download folder:

python -m pip install --user --upgrade chrono-agent-0.5.0.zip
python -m chrono_agent --version

Expected: chrono-agent 0.5.0. If chrono is not on PATH, every example also works as python -m chrono_agent .... Python 3.8 or newer is required. This release has not been published to PyPI (see PUBLISHING.md).

Upgrading from 0.4.x keeps your .chrono folders. Old audit records keep verifying, and new records are signed from the first action after the upgrade (see Audit trail).

Quick start with an AI agent (Claude Code, Claude Desktop, Cursor)

In your project folder:

chrono init
chrono guard install
chrono policy pin
  • chrono init starts tracking the folder and takes the first savepoint.
  • chrono guard install adds a PreToolUse hook to .claude/settings.json. From then on, every Bash/PowerShell command and every file edit the agent makes goes through Chrono first. The command runs a self-test and tells you if the hook works with your Python. Restart the client afterwards.
  • chrono policy pin (optional, after you write a chrono-policy.yaml) locks the policy. If anyone edits it later, every command is refused until a person reviews the change and pins again.

For clients that use MCP, add Chrono as a server (examples/mcp-config.json):

{ "mcpServers": { "chrono": { "command": "python", "args": ["-m", "chrono_agent", "mcp"] } } }

The MCP server exposes chrono_scan, chrono_run, chrono_snapshot, chrono_status, chrono_log, chrono_rollback and chrono_audit_verify. chrono_run is the enforced path: blocked commands never start.

To make chrono_run the only way the agent can run commands, deny the client's own shell tools:

chrono guard install --deny-raw-shell

Command reference (one command at a time)

chrono init
chrono snapshot -m "before agent"
chrono run python agent.py
chrono status
chrono diff
chrono log
chrono rollback
chrono branch feature
chrono checkout main
chrono merge feature
chrono scan "rm -rf /"
chrono guard install
chrono guard status
chrono guard uninstall
chrono policy
chrono policy pin
chrono prune --keep-auto 200 --dry-run
chrono audit
chrono audit --verify
chrono audit --keys
chrono audit --rotate-key
chrono audit --reset-witness
chrono audit --csv --out audit-report.csv
chrono audit --push https://audit.example.com/ingest --verify-remote
chrono team add sara --role developer
chrono git install-hook
chrono db add appdb --engine sqlite --path app.db
chrono db snapshot appdb
chrono db restore appdb
chrono dashboard --out report.html
chrono mcp
chrono --help

Try these in a disposable test project first. init is idempotent. Default rollback restores the current branch HEAD; choose an ID from log to go further back. Every rollback first saves a rescue savepoint of unsaved changes and prints undo this rollback: chrono rollback ID.

The guard hook (closes the "other shell" gap)

An MCP server only sees what the agent sends to it. An agent that also has the client's own Bash or PowerShell tool could run anything around Chrono. chrono guard install closes that gap for Claude Code and compatible clients. The client runs python -m chrono_agent guard hook before each tool call and passes the call as JSON:

Chrono decision What the client does
block (risk 70+, or a policy block rule) refuses the call (exit code 2) and shows the reason to the agent; nothing runs
approve (policy approval band) asks the person at the keyboard (permissionDecision: ask)
allow takes a savepoint first (not for read-only commands), then follows the client's normal permission rules; the guard never auto-approves

File edits (Write, Edit, MultiEdit, NotebookEdit) are refused when they target Chrono's own control files: .chrono/, chrono-policy.yaml, .claude/settings*.json and the Chrono home with its keys. Any error inside the guard blocks the call (fail closed). The hook settings are control data: a rollback never removes or reverts them.

--scope user installs into ~/.claude/settings.json instead, so dangerous commands are refused in every folder, not just Chrono projects. chrono guard status shows what is installed and runs the self-test again; do that after every Python or Chrono upgrade.

What the scanner reads

Every command is matched against 100+ rules: recursive and forced deletes in shells and languages, disk and partition wipes, shadow-copy/backup/recovery wiping, firewall and Defender tampering, autostart registry keys and scheduled tasks, secret exfiltration, reverse shells, encoded payloads, database wipes, git history rewrites, cloud and Kubernetes deletes, and more. It looks through common text obfuscation (quote splitting, backslashes, zero-width characters, $IFS, brace expansion).

New in 0.5.0: on every enforcing path (chrono_run, the guard, chrono run, chrono scan) it also reads what the command will run, in the project folder:

  • script files: python x.py, python -m pkg.mod, node x.js, deno run, bun run, ruby, perl, php, bash x.sh, ./x.sh, x.bat, cmd /c x.cmd, powershell -File x.ps1, and the scripts those batch/shell files start;
  • package scripts: npm test, npm run build (including pre/post scripts), npm install / yarn (the project's own preinstall/install/postinstall/prepare), yarn X, pnpm X;
  • make targets: make, make clean, and the targets they depend on.

Inside files only clear findings count (score 60+), and comment lines are skipped. Files over 1 MB, more than 16 scripts per command, or nesting deeper than 4 levels are refused rather than half-checked. Without the project folder (assess(cmd) in the SDK) nothing is read, as before.

Savepoints, rollback and what they cover

chrono_run and the guard take an automatic savepoint before each command that could change files. Read-only commands (dir, ls, type, git status, git log, python --version, pip list, chrono status and similar) skip it, because they cannot change anything. Set CHRONO_SAVEPOINTS=always to take one anyway. On Windows a program with the same name in the project folder (for example a where.bat) is never treated as read-only.

A rollback restores the tracked files in the project folder, and nothing else. It does not undo:

  • system changes: registry, services, scheduled tasks, shadow copies, boot settings, firewall/Defender settings, installed software;
  • files outside the project folder, or in ignored folders (.git, node_modules, .venv, venv, __pycache__, .idea, .vscode);
  • network calls, messages, payments, cloud resources;
  • databases you did not register with chrono db add (and registered ones only back to their last chrono db snapshot).

For those, the scanner's block is the only protection, which is why Chrono blocks them. Every chrono_run and chrono_rollback reply states this scope in its covers field, so an agent cannot mistake the time machine for a whole-system restore.

Old automatic savepoints can be pruned: chrono prune --keep-auto 200 or --older-than 30 (days), with --dry-run first. Manual snapshots, commits, merges and branch heads are never pruned. History stays linked and unused file versions are removed. A retention: section in the policy applies the same limits automatically after each chrono_run.

Audit trail

Every state change, scan, block, approval, guard decision and policy change is appended to .chrono/audit.jsonl: who, when, from which host and folder, which snapshot, the risk score and the outcome.

Since 0.5.0 the log is signed by default. Each record carries an HMAC-SHA256 made with a key stored outside the project, in %USERPROFILE%\.chrono-agent\keys (or $CHRONO_HOME/keys), created on first use. Someone who can only write the project folder can no longer rebuild a valid-looking chain after editing it. After each record Chrono also updates an external witness (the newest record's number and digest, in the same home folder). Cutting off the newest records, or replacing the whole log, is therefore detected too, and the next write does not hide it.

chrono audit --verify            " chain, signatures, witness and snapshot anchors
chrono audit --keys              " key id and key-store location (never the key itself)
chrono audit --rotate-key        " new key; older records keep verifying
chrono audit --reset-witness     " after you restored .chrono from a backup on purpose (recorded)
  • Back up .chrono-agent\keys. A log whose key is lost can no longer be verified.
  • CHRONO_AUDIT_KEY=<secret> uses a key you manage yourself (a vault, a CI secret) instead of the key store.
  • CHRONO_AUDIT_REQUIRE_KEY=1 is strict mode: unsigned records fail verification and unsigned writing is refused.
  • CHRONO_AUDIT_UNSIGNED=1 switches signing off (the 0.4 behaviour). Use it only for testing.
  • Records from 0.4 stay valid as an older-format prefix. A signed log that later contains an unsigned record fails, because that is what a downgrade attack looks like.
  • CHRONO_MODEL / CHRONO_AGENT label every record with the model and client. They are self-reported labels, not proof of identity.

Policy file (chrono-policy.yaml)

A starting point is in examples/chrono-policy.yaml. It covers thresholds (block, approve), custom rules, an exact-command allow: list (backslashes allowed since 0.5.0, for example reg add HKCU\Software\MyCompany\MyApp /v * /d * /f), named approvers, roles, the gates: mcp.rollback: approve human gate, and retention. chrono policy validates the file. A broken policy blocks every enforced command until it is fixed (fail closed).

  • chrono policy pin stores the file's fingerprint (signed) in the Chrono home. After that, any edit blocks every command on the enforcing paths until a person runs chrono policy pin again.
  • Every change Chrono notices is written to the audit log as policy.changed.
  • The policy is control data: snapshots ignore it, so a rollback never deletes or reverts it.

Run / rescue behaviour (chrono run)

Programs run with exact argument boundaries, without a shell by default (chrono run -- python "my agent.py"). A successful run saves a post-command snapshot before printing COMMIT. On failure: r rolls back, d shows the diff (the program is not rerun), t retries, k keeps changes uncommitted, and end of input rolls back. Shell mode needs one quoted string: chrono run --shell "echo hello". --force bypasses the scanner, not OS permissions. It needs the run.force role if the policy sets one, and the scanner refuses chrono run --force when an agent tries it through the guard or chrono_run.

Python SDK

from chrono_agent import Transaction

with Transaction(".", "trusted agent") as tx:
    # first set of edits
    tx.savepoint("models")
    # more edits; tx.rollback_to("models") keeps the first set
# an exception restores BEGIN; a clean exit saves COMMIT

What Chrono cannot do (read this)

  • It is not a sandbox. A program that is allowed to run can do anything your account can do. The scanner reads command text and the scripts a command starts. It cannot follow variables (a=rm; $a -rf /), decode arbitrary payloads, see inside compiled programs (.exe, .pyc) or modules a script imports, or know what a remote server does. For hostile code, run agents with least privilege in a container or VM.
  • Enforcement covers the paths that go through Chrono: MCP chrono_run, the guard hook, chrono run. An agent with an unguarded shell, an IDE extension that runs its own commands, or a person at a terminal are not covered.
  • Rollback covers project files only (see Savepoints, rollback and what they cover). Keep independent backups.
  • Local trust boundary: keys, witnesses and pins live in the Chrono home of the same OS account. Anyone who can read that folder can forge records, and anyone who can write it can move the witness or pin. Use CHRONO_AUDIT_KEY from a vault and chrono audit --push to a store the agent cannot reach when that matters.
  • Approvals and roles are named, not authenticated. A process with its own unguarded shell can run chrono approvals approve. The guard refuses that command from the agent, but only the guard path is covered.
  • Symlinks and special files are not tracked. Empty directories, ACLs, timestamps and alternate streams are not preserved. Very large files are held in memory during snapshot and restore.
  • Power loss or kill -9 in the middle of a restore can leave a partial restore. .chrono is not an independent backup.
  • The fleet gateway's own event chain (FLEET.md) is still plain SHA-256. It is a pilot.

Tests

In the extracted package folder:

python -m unittest discover -s tests -v
python benchmarks\scanner_benchmark.py
python benchmarks\redteam.py

Tests use temporary projects and a temporary Chrono home, never your real project or keys. Results and the test environment are in VERIFICATION.md. What changed since the 0.4.1rc2 audit is in docs/REMEDIATION.md, and the threat model is in SECURITY.md.

Metadata

Release files for chrono-agent 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chrono-agent 0.5.0
File Size Uploaded Provenance Actions
chrono_agent-0.5.0.tar.gz 115.4 kB Without provenance Details for chrono_agent-0.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for chrono-agent 0.5.0
File Interpreter ABI Platform Actions
chrono_agent-0.5.0-py3-none-any.whl Python 3 none any Details for chrono_agent-0.5.0-py3-none-any.whl

Total release size: 206.8 kB

Release files / chrono_agent-0.5.0.tar.gz

Download URL chrono_agent-0.5.0.tar.gz
Size 115.4 kB
Tags Source
SHA-256 checksum
How to use checksums
e772bd06a7b761c8d1314695b08423c76dfe3dad09e88e47368fea37cd30295c
BLAKE2b-256 checksum
How to use checksums
31882742695988449ecb9c69e1a778cf4ee01c912572b20f6188fad92c6e3b3e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / chrono_agent-0.5.0-py3-none-any.whl

Download URL chrono_agent-0.5.0-py3-none-any.whl
Size 91.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
19a039b84e2ee20cba41a990ee0a45c614834fd657217b2622178a872f2fcff5
BLAKE2b-256 checksum
How to use checksums
695e5e6bfe8ad741a2086a852c2198edcdabef56601073788b663f80f79eb73b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Security for chrono-agent 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page