Skip to main content

Deterministic tmux relay/dedup daemons for AI-agent fleet monitoring

Project description

chitra

chitra is a set of systemd-supervised daemons that deterministically deliver text into tmux-hosted AI-agent sessions, record what happened, and watch their state. Its core dispatch, ledger, rate-limit, and routing paths are Python control loops, not an LLM deciding what to send or where to send it.

It was built to manage large parallel sessions with LLM coding agents, allowing the user to do more while chitra handles delivery and state tracking, applies optional LLM-backed judgment gates, and gates external harnesses such as Claude and Codex against clearly defined goals.

Scope

chitra delivers messages to LLM-driven sessions in tmux and observes their state. Delivery, queueing, routing, rate limiting, ledger writes, and state tracking are deterministic; routing is config lookup, not content judgment.

LLM judgment is layered on deliberately for specific gates: goal nudging, completion-claim review, and interview functionality. Chitra also dispatches to and gates external coding-agent harnesses such as Claude via claude-code and Codex; those agents do the content work, while chitra records, routes, reviews, and releases according to its own ledgers and policies.

Quickstart

pip install chitra-monitor  # or: pip install git+https://github.com/ReticleWorks/chitra.git@<tag>

Replace <tag> with a released version from the tags page, or drop @<tag> to install from the default branch.

Requires Python 3.12+ and tmux on the host. See Install for local development setup, Configuration for environment variables, and Delivering into a tmux pane for what chitra actually does to a pane.

Why "chitra"

The name is a short form of Chitragupta, a figure from Hindu tradition described as the divine registrar and keeper of a complete, accurate ledger of deeds — one who records, verifies what is recorded, and reports to the decision-maker, but does not act on that decision-maker's behalf. That remains this package's contract: it observes, verifies against frozen goals and cited artifacts, gates release, and relays without doing an agent session's work for it. The name is used respectfully as a functional reference, not as religious imagery.

BrowserStack's chitragupta-node and chitragupta-rails are open-source SDKs that use the same name for structured JSON (JavaScript Object Notation) logging — attaching metadata to log lines rather than relaying or signing them. Different tool, same naming logic: the name attaches to something that records and structures what happened, not something that decides what should happen.

What's in this repo

chitra installs twelve command-line entrypoints backed by a set of small, single-purpose modules. dispatchd and triaged are the always-on daemons; the rest are periodic or ad-hoc tools.

Delivery

  • chitra.dispatch / chitra.dispatchd — drain a JSON order queue and deliver each message into a tmux session via bracketed paste, confirming delivery by grepping the session's own transcript. One writer per session (LaneLock); idempotent and crash-safe (see Delivery guarantees).
  • chitra.ledger — an append-only, HMAC-signed log of every delivered message.

Monitoring

  • chitra.watchd — emits tmux pane-change and turn-end events and runs a completion audit on each finished turn.
  • chitra.triaged / chitra.sweepd — deduplicated state-change events and a compact fleet-state feed for downstream monitors.
  • chitra.draft_scanner — flags unsubmitted drafts left sitting in a tmux input box.

PR review

  • chitra.pr_review / chitra.pr_reviewd (chitra-pr-review) — deterministic blast-radius/diff-size pre-checks plus an isolated multi-reviewer security pass over one pull request's diff, logged to a signed ledger and reported as a plain PR comment. Never merges, approves, requests changes, or fails a required check by default; see the pr_reviewd module docstring and PRReviewPolicy.block_on_findings. Stock trigger: .github/workflows/pr-security-review.yml.

Goals and completion

  • chitra.goals — a per-lane goal store with a write-once enrolled done-condition, guarded by flock.
  • chitra.goal_enforcement / chitra.completion_gate / chitra.close_gate — review a session's completion claim against its frozen goal and cited evidence; spend, credentials, and irreversible actions stay operator-gated.

Rate limiting

  • chitra.usage / chitra.rate_limit_guard / chitra.account_registry — read account usage and pause/resume lanes on provider limits or host load pressure, over a durable, crash-safe transaction. See docs/pause-recovery.md.

Rendering

  • chitra.board / chitra.convlog — a terminal roster of goals and open asks, and an append-only operator-brief conversation log.

Delivering into a tmux pane

Delivery into a live tmux session follows one path:

  1. tmux display-message -p -t <target> '#{pane_in_mode}' — if 1, the pane is in copy-mode (which silently swallows input); run tmux send-keys -X cancel and wait briefly.
  2. printf '%s' "$text" | tmux load-buffer -b <name> -
  3. tmux paste-buffer -p -b <name> -t <target> — the -p flag is mandatory; without it, newlines act as Enter keypresses and the message can self-submit early.
  4. tmux send-keys -t <target> Enter
  5. Confirm delivery by grepping the target session's transcript for the delivered text. "Looks sent" is not evidence.

For a remote target, each command is the same, ssh-wrapped to run on the actual target host. Checking the local tmux server's state, or grepping local transcripts, when the target is remote reports on the wrong host.

Delivery guarantees

  • Single writer. dispatchd holds a LaneLock per session id across each delivery, so two writers can't race to paste into the same session and corrupt its next turn.
  • Idempotent. Once a result file exists for an order, it is never redispatched, even across a restart. A crash between paste and result is reconciled with a send-nonce marker plus the same transcript-grep check, not a blind second paste.
  • Authenticated. Every successful delivery appends an HMAC-SHA256-signed record to an append-only JSONL ledger; a reader with the signing key can prove a given message was delivered. This is a trusted-host model — anyone who can write to the ledger file can rewrite it — so treat "not in the ledger" as a strong signal, not tamper-proof evidence. See chitra.ledger.verify_delivery.

Running the daemons

dispatchd and triaged run continuously. chitra-rate-limit-guard is a one-shot CLI meant to run on a timer. Example systemd units, with placeholder paths and service user, live under packaging/systemd/:

sudo cp packaging/systemd/chitra-rate-limit-guard.service.example /etc/systemd/system/chitra-rate-limit-guard.service
sudo cp packaging/systemd/chitra-rate-limit-guard.timer.example /etc/systemd/system/chitra-rate-limit-guard.timer
sudoedit /etc/systemd/system/chitra-rate-limit-guard.service   # fill in placeholders
sudo systemctl daemon-reload
sudo systemctl enable --now chitra-rate-limit-guard.timer

Configuration

Each entrypoint is configured with CLI flags (--help on any command lists them) and a small set of environment variables. The most common:

Env var Default Notes
CHITRA_STATE_DIR /var/lib/chitra Base directory for the queue, ledger, and ledger key
REMOTE_DISPATCH_HOSTS (empty) Comma-separated allowlist of hosts dispatch may target over ssh
CHITRA_CLAUDE_PROJECTS ~/.claude/projects Root searched for transcript-grep delivery verification
CHITRA_ROUTING_CONFIG (unset) Optional task_type → routing-hint config; see docs/routing.yaml.example
CHITRA_POLICY_CONFIG (unset) Optional completion-gate and dispatch policy; see docs/policy.yaml.example

The full set — ssh options, triage log paths, transcript globs — is documented per-command via --help.

Routing. A caller can tag a DispatchOrder with an opaque task_type. If a routing config is set, dispatchd maps that to a routing_hint (a model/harness preference the caller's system uses); an explicit routing_hint always wins, and chitra carries the hint through to the ledger but never acts on it.

Install

Requires Python 3.12+ and tmux (chitra shells out to the tmux binary; there is no Python tmux dependency).

pip install chitra-monitor  # or: pip install git+https://github.com/ReticleWorks/chitra.git@<tag>

Not yet on PyPI — see docs/DESIGN.md for the packaging rationale.

For local development:

git clone https://github.com/ReticleWorks/chitra.git
cd chitra
pip install -e '.[test]'
pytest

Getting help

Questions and bug reports: open an issue. See CONTRIBUTING.md before opening a nontrivial PR; security reports go through SECURITY.md.

Authors

Trey (Reticle Works) with Claude and Codex.

License

MIT © 2026 Reticle Works. See LICENSE for the full text.

Project details


Download files

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

Source Distribution

chitra_monitor-0.8.2.7.tar.gz (289.3 kB view details)

Uploaded Source

Built Distribution

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

chitra_monitor-0.8.2.7-py3-none-any.whl (203.5 kB view details)

Uploaded Python 3

File details

Details for the file chitra_monitor-0.8.2.7.tar.gz.

File metadata

  • Download URL: chitra_monitor-0.8.2.7.tar.gz
  • Upload date:
  • Size: 289.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for chitra_monitor-0.8.2.7.tar.gz
Algorithm Hash digest
SHA256 5a79a4dfc5f598464d7e0bac0f55ca1d8e1d1006533ca03034a4935bd0866541
MD5 d234dcde36f015f9a5eded634430717e
BLAKE2b-256 89a253fd58fde59f8c0742bdfa2cdc3766036e7b40e1e14ea52cdf8650e93f9c

See more details on using hashes here.

File details

Details for the file chitra_monitor-0.8.2.7-py3-none-any.whl.

File metadata

File hashes

Hashes for chitra_monitor-0.8.2.7-py3-none-any.whl
Algorithm Hash digest
SHA256 8eaaf23f5daa9ca84c69354f5656c8e9dbb058300499d5a8c7ec69af4a5450d8
MD5 352d6d70159f0b3d4e619fa28f58e026
BLAKE2b-256 93e77a730aacee09c96feaac0485e7fcbfea445d20a79d0158cbb049a3de4c95

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