Skip to main content

agent-coroner

Artifact contracts, silent-failure detection, and LLM autopsy reports for unattended AI agents.

Your cron-scheduled agent ran fine — exit code 0 — but the weekly report it was supposed to write never appeared. Nothing alerted you. That's a silent failure, and it's the failure mode of unattended agents. agent-coroner watches the artifacts your jobs promise to produce, notifies you when a promise is broken, and (optionally) dispatches a read-only Claude "coroner" to write a postmortem explaining why.

How it works

  1. Contracts — declare what each job must produce (contracts.yaml)
  2. Checker — a fast, deterministic, LLM-free check: file exists, fresh enough, big enough, passes your verify command. Run it from cron / Task Scheduler.
  3. Autopsy — only when a contract is violated, claude -p is launched read-only (Read,Grep,Glob) to diagnose the logs and write a 4-section postmortem (facts / hypotheses / verification steps / prevention). If the autopsy itself fails, the violation notification still goes out — detection never depends on the LLM.

No self-healing by design: the coroner examines the scene, it never touches it.

Install

uv tool install agent-coroner   # or: pip install agent-coroner

Requires the claude CLI on PATH only for autopsies; check/status/unread work without it.

Quick start

contracts.yaml:

jobs:
  weekly-report:
    schedule: "FRI 08:30"
    grace_minutes: 60
    artifacts:
      - path: "reports/weekly-*.md"
        max_age_hours: 192
        min_bytes: 500
    logs: "run.log"

Run it before the artifact exists (or after it's gone stale) and the checker reports a missing violation with a non-zero exit code:

$ coroner check --config contracts.yaml --no-autopsy
[coroner] 1 violation detected
- weekly-report / reports/weekly-*.md: missing (no file matches 'reports/weekly-*.md' under <contracts-dir>)
[coroner] 1 violation detected
- weekly-report / reports/weekly-*.md: missing (no file matches 'reports/weekly-*.md' under <contracts-dir>)
$ echo $?
1

(The message appears twice here because no notify command is configured: the checker prints its own progress line, then falls back to printing the same message a second time as the "notification". Set notify — see below — to route it somewhere else instead of stdout twice.)

Once reports/weekly-*.md exists, is fresh, and clears min_bytes, the same command prints weekly-report: ok and exits 0.

Register coroner check on a schedule:

schtasks /create /tn "coroner-check" /tr "coroner check --config C:\path\to\contracts.yaml" /sc daily /st 09:00
*/15 * * * * coroner check --config /path/to/contracts.yaml >> /var/log/coroner.log 2>&1

Contract reference

  • lang — top-level, "en" (default) or "ja" — language of autopsy postmortem section headers. Any other value raises a config error at load time.
  • jobs.<name> — one entry per unattended job; the key is the job name used in state, notifications, and postmortem filenames.
  • schedule — free-text metadata only (e.g. "FRI 08:30"), not parsed or enforced by the checker; it exists for humans and for the autopsy prompt's job-definition context.
  • grace_minutes — added to max_age_hours (as minutes) before an artifact counts as stale. Default 0.
  • workdir — directory artifact/log globs are resolved against. Default: the directory containing contracts.yaml.
  • artifacts — list of rules, each checked independently; a job can have any number:
    • path — a glob relative to workdir; the newest matching file (by mtime) is evaluated.
    • max_age_hours — if set, the newest match's age (plus grace_minutes) must not exceed this or the artifact is stale. Omit to skip the freshness check.
    • min_bytes — minimum file size in bytes; below this the artifact is too_small. Default 1.
    • verify — optional shell command run against the newest match; {path} is substituted with the file's full path before the command runs via shell=True in workdir. A non-zero exit is a verify_failed violation. On Windows, quote it — an unquoted {path} containing spaces breaks the command line: use verify: "python check.py \"{path}\"", not verify: "python check.py {path}".
    • Violation types in order of the check: missingstaletoo_smallverify_failed.
  • logs — optional glob for the job's log file; only used to build the autopsy prompt's log-tail evidence, not checked itself.
  • notify — optional shell command run via shell=True when a violation fires. Two substitution tokens, mutually compatible:
    • {message} — the whole notification text flattened to one line: double quotes become single quotes, newlines become "; ". Fragile for anything beyond a simple one-liner.
    • {message_file} — the full, unflattened, multi-line message is written to a temporary UTF-8 text file and this token is replaced with that file's path; the file is deleted after the notify command runs. This is the reliable way to pass a multi-line report through a shell command, e.g. powershell -NoProfile -Command "Get-Content -Raw '{message_file}' | Write-Host".
    • If notify is omitted, the message is printed to stdout instead.

Claude Code plugin

/plugin marketplace add Chikoku-NEKO/agent-coroner
/plugin install agent-coroner@agent-coroner-marketplace
  • /coroner-status — runs coroner status and summarizes which jobs are ok, which have violations, and their recent ok-rate; tells you to uv tool install agent-coroner if the CLI isn't found.
  • /autopsy <job-name> — runs coroner autopsy --job <job-name> on demand and presents the resulting postmortem's four sections, or reports that the job's contract is currently satisfied.
  • A SessionStart hook runs coroner unread at the start of every Claude Code session so unread postmortems (any generated since your last acknowledgment) surface automatically instead of sitting silently in the postmortems directory.

Exit codes / Security notes / License

  • Exit codes: 0 = all contracts satisfied, 1 = one or more violations (or a job's check crashed), 2 = config error (bad/missing contracts.yaml, unknown --job).
  • verify and notify are user-defined shell commands executed with shell=True — only point --config at contract files you trust. A malicious contracts.yaml can run arbitrary commands on your machine.
  • MIT License — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agent_coroner-0.1.0.tar.gz (16.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agent_coroner-0.1.0-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file agent_coroner-0.1.0.tar.gz.

File metadata

  • Download URL: agent_coroner-0.1.0.tar.gz
  • Upload date:
  • Size: 16.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.11

File hashes

Hashes for agent_coroner-0.1.0.tar.gz
Algorithm Hash digest
SHA256 27a744df022833399183bad185039d09424a46a6ccdc900cfcee13b6e48f78c9
MD5 39068a83afa6aa44632f9985351d2b31
BLAKE2b-256 705c59b20301dd229b6f54c4e90e9f377ea088ae00c10de37a3d871b33081c93

See more details on using hashes here.

File details

Details for the file agent_coroner-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: agent_coroner-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.11

File hashes

Hashes for agent_coroner-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b66e2464810696a642fee02c7ecaa2e8331ba952074e4c92ae11dfbf1cb63aea
MD5 033f38868fe7fa076a983c34a3ba1765
BLAKE2b-256 37d25123cb7672673640682f331a01a8a8499fab10ce5db262ec515803dbe9da

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page