Skip to main content

Who's allowed to do what, and who's accountable, on a team of humans and AI agents: a machine-checkable RACI charter + linter.

Project description

AgenRACI — who's allowed to do what, and who's accountable, on a team of humans and AI agents

CI charter checked PyPI Python License: MIT

When an AI agent does something on your team — ships code, sends a message, spends money — and no human pressed the button, who is accountable? AgenRACI is one plain-language file that answers that up front, for every kind of action: who may do it, who signs off, and who owns the outcome.

For decades, teams have used RACI — a simple chart of who is Responsible, Accountable, Consulted, and Informed for each kind of work. RACI quietly assumes a person starts every task. AI agents break that assumption: they can act on their own, but someone human must still answer for what they do.

AgenRACI brings RACI into the age of AI agents. You write one file — a charter — that lists, for each type of action on your team:

  • who does it (Responsible),
  • who is accountable (exactly one person or role),
  • who must be consulted or kept informed,
  • who has to approve it first, and
  • what happens if the one who should act is unavailable.

A built-in checker reads the charter and flags the gaps before they bite: an action with no one accountable, two people who both think they're in charge, or an approval step that could quietly stall forever.

pip install agenraci
agenraci init                    # writes a commented charter.yaml to edit
agenraci validate charter.yaml   # check it holds together

Cloned the repo instead? Validate a bundled example directly: agenraci validate examples/sprout/charter.yaml.

Prefer to try it without installing? A paste-and-check playground runs the real checker in your browser (nothing uploaded) — see docs/playground/.

New here? Start with the essay: Why AgenRACI — the accountability gap, why classic RACI breaks under agentic AI, and how this fits ISO/IEC 42001 and the EU AI Act.

Already running agents (LangGraph, CrewAI, Claude subagents)? The cookbook From a running agent team to a charter shows what to literally write, mapping graph nodes → roles → accountable owners.

See it catch a gap

A charter where two roles both think they're accountable for shipping code — the checker catches it (rule R1), and the one-line fix passes:

AgenRACI catching a two-accountable conflict, then passing once fixed

$ agenraci validate docs/demo/charter-broken.yaml
✗ R1 single accountable
    - A2_ship_code: has 2 accountable roles (builder, reviewer) — exactly one is required.
FAIL — 1 issue(s) found.

$ agenraci validate docs/demo/charter-fixed.yaml
✓ R1 single accountable
PASS — charter is a valid operating constitution.

Full walkthrough + a recordable GIF script: docs/demo/.

What AgenRACI is (and isn't) yet

Today, AgenRACI helps you write the charter and checks that it holds together. You get:

  • a clear format for the charter file,
  • an automatic checker that catches gaps, conflicts, and approval steps that could deadlock,
  • a worked example and a blank template to start from.

AgenRACI does not run your team — yet. It doesn't (today) intercept actions or enforce approvals at the moment they happen. Tools like LangGraph, CrewAI, and HumanLayer already handle running agents and pausing them for sign-off. AgenRACI sits one level up and answers what they don't: on this specific team, who is allowed to do what, and who breaks a tie. Turning the charter into live, enforced approvals is the next milestone on the roadmap — not a claim about today.

The gap we fill

Today, RACI is mostly applied at the governance level — the boardroom and compliance question of "who answers for the AI system as a whole" (the concern behind standards like ISO/IEC 42001 and the EU AI Act). What's missing is the operating level: a precise, machine-checkable charter for the day-to-day, where the AI agents themselves hold real roles and the rules can be verified by a tool instead of living in a slide deck. That everyday accountability — for the exact moment an agent acts on its own — is what AgenRACI covers.

The core model (three independent questions)

Most "who does what" confusion comes from mixing up three different questions. AgenRACI keeps them separate:

Question What it asks Example
Function What do you do? Orchestrate, Build, Advise, Investigate, Review, Watch
Permission What may you touch? edit_code, merge, deploy, spend, … granted or explicitly denied
Authority Whose call wins in a conflict? Each action's accountable, plus gate escalate_to for timeouts

The proof they're separate: a domain expert can be accountable for a fact, denied the right to touch code, yet able to block a merge on correctness grounds — all at once, none implying the others.

Roles are defined once; members are assigned

You don't rewrite the rules for every agent. Define a small set of roles (orchestrator, engineer, domain expert, researcher, reviewer, monitor) once, then assign humans and agents to them. Adding an agent is a one-line appointment, not a new rulebook.

One accountable per action — no gaps, no turf wars

List the types of action in your project (not individual tasks), and require each to have exactly one accountable role. Nobody accountable = a gap; two people accountable = a turf war. The checker catches both.

Escape hatches so the rules never deadlock

People aren't always online — and neither are agents. So every approval step must say what happens on timeout (block, escalate to someone, or, only for explicitly low-risk actions, proceed), and must have a break_glass emergency path. Any blocked-but-confident actor gets a suggestion_route so their input isn't silently dropped. proceed on timeout is a guarded opt-in — allowed only on an action explicitly marked low-risk — so "low risk" can never become a quiet backdoor for an agent to act unsupervised.

The checker (v0.1)

Rule Checks
R1 single accountable — every action type has exactly one accountable
R2 coverage — no unused permissions; no action uses an undeclared permission
R3 no contradiction — no role both grants and denies the same permission
R4 gate completeness — every approval step has a timeout rule + emergency path; every blocking deny has a suggestion_route
R5 low-risk gating — proceed on timeout only on an action marked low-risk
R6 acyclic authority — gate escalate_to timeouts never form a loop, so a decision can't escalate forever without anyone able to settle it

CLI

agenraci init [path]                             # write a commented starter charter (default: charter.yaml)
agenraci validate <charter.yaml> [more.yaml...]  # parse + check, with a per-rule report
agenraci validate --explain <charter.yaml>       # ...and a plain-language fix under each failure
agenraci validate --format github <charter>      # ...and ::error annotations for GitHub Actions
agenraci schema                                  # print the charter JSON Schema (for editor autocomplete)
agenraci compile --target claude <charter> -o .  # emit .claude/agents/ definitions + a CLAUDE.md snippet
agenraci compile --target github     <charter>   # emit CODEOWNERS + branch-protection checklist + applyable protection.json
agenraci verify  --target github     <charter> --repo OWNER/REPO  # check a live repo enforces the charter (--org ORG sweeps a whole org)
agenraci compile --target humanlayer <charter>   # placeholder in v0.1
agenraci compile --target langgraph  <charter>   # placeholder in v0.1

The claude target makes the charter operative for a Claude Code team: it generates one .claude/agents/<member>.md per agent member — role boundaries, explicit "never do X" denials, who signs off on what — plus a governance snippet for CLAUDE.md. Two people collaborating with their own agents compile the same charter and both sides' agents carry the same rules. (Still honest scope: these are config files the runtime already reads, not runtime interception. This repo's own .claude/agents/ follows exactly this pattern.)

A freshly init'd charter carries a # yaml-language-server: $schema= line, so editors with the YAML language server (e.g. VS Code + the Red Hat YAML extension) give you autocomplete and inline validation as you type.

Keep the charter honest in CI

A charter only protects you if it stays valid as it changes. Two ways to enforce that automatically:

GitHub Action — fail a PR that breaks the charter:

# .github/workflows/charter.yml
on: [push, pull_request]
jobs:
  charter:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: jing-ny/agenraci@v0.1.1
        with:
          charter: charter.yaml      # a path, or a glob like 'governance/*.yaml'

A failing charter shows up as a file-level annotation in the PR's "Files changed" tab (the Action runs validate --format github), not just buried in the run log.

"charter checked" badge — once that workflow is in place, show it off in your README so every reader can see the charter passes:

[![charter checked](https://github.com/<you>/<repo>/actions/workflows/charter.yml/badge.svg)](https://github.com/<you>/<repo>/actions/workflows/charter.yml)

(This repo wears its own: the badge at the top runs AgenRACI's Action on governance/charter.yaml — we govern ourselves with the same check.)

GitHub Action (verify) — check that your repo's branch protection actually matches what the charter declares:

# .github/workflows/charter.yml  (add a second job alongside the validate job)
  verify:
    runs-on: ubuntu-latest
    continue-on-error: true   # see auth caveat below
    steps:
      - uses: actions/checkout@v4
      - uses: jing-ny/agenraci/verify@<ref>
        with:
          charter: charter.yaml          # path to your charter
          repo: ${{ github.repository }} # OWNER/REPO (default)
          branch: main                   # protected branch (default)
          python-version: "3.12"         # Python version (default)

This Action runs agenraci verify --target github against your repo's live branch protection and CODEOWNERS. It exits 1 if the repo drifts from the charter (for example, a required approver was removed from CODEOWNERS), and exits 0 if the branch enforces at least what the charter declares. The charter is a floor: a repo whose protection is stricter than the minimum the charter requires still passes. A gated action whose accountable role has no human member is reported as unenforceable — GitHub code owners must be human — neither pass nor fail.

Exit codes: 0 = clean, 1 = drift, 2 = could-not-check.

Scope reminder. The verify Action is read-only. It never POSTs to GitHub and never intercepts or enforces actions at runtime. It tells you whether drift exists; it does not fix it.

Auth caveat. Reading live branch protection via gh api requires admin permission on the repo. The default GITHUB_TOKEN usually does not have it, so an out-of-the-box run typically exits 2 (could-not-check), not 1 (drift). To get a real drift check, supply an admin-scoped token (for example a PAT stored as a repository secret):

        env:
          GH_TOKEN: ${{ secrets.ADMIN_PAT }}

Without that token, continue-on-error: true prevents a spurious could-not-check exit from turning the build red and being misread as a charter violation. This is exactly what AgenRACI's own dogfood verify job does.

For a step-by-step walkthrough of the full compile → apply → verify loop (with worked examples and exit-code explanations), see Check your repo.

pre-commit hook — catch it before it's even committed:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/jing-ny/agenraci
    rev: v0.1.1
    hooks:
      - id: agenraci-validate        # checks staged charter.yaml / charter.yml files

agenraci validate takes one or more paths, so a single call checks every charter in the repo and exits non-zero if any fails. For a step that another tool or dashboard should parse, add --format json to get one machine-readable object per charter ({charter, project, ok, rules: [...]}) instead of the human report — one JSON object per line when you pass several charters. Add --explain too if JSON consumers should receive each failing rule's plain-language fix as an explanation field on the finding objects.

Code-scanning alerts--format sarif emits a single SARIF 2.1.0 document you can upload so charter failures show up in a repo's Security tab. Add these steps to a job that has agenraci installed (pip install agenraci):

      - run: agenraci validate governance/charter.yaml --format sarif > charter.sarif
        continue-on-error: true            # upload the report even when the charter fails
      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: charter.sarif

(Findings are file-level: the checker points at a target — an action or role name — not a source line, so each alert lands on the charter file.)

Repository layout

agenraci/
├── README.md            # this file
├── SPEC.md              # the three questions, RACI rules, file format, checker rules
├── agenraci/            # the Python package (schema, checker, cli, connectors,
│                        #   and the starter template `agenraci init` writes)
├── governance/          # AgenRACI's own charter — the project governs itself
├── examples/autopilot/    # ★ flagship: an autonomous coding team (1 human + 4 agents)
├── examples/hello-world/  # the smallest meaningful charter (1 human + 1 agent)
├── examples/blog/         # one step up: a gate + separation of powers (1 human + 2 agents)
├── examples/sprout/       # a complete worked example (2 humans + 6 agents)
├── examples/relay/        # an all-agent worked example (5 agents, 0 humans)
└── tests/                 # one test per rule + known-good / known-bad charters

Roadmap

  • v0.1 — write it and check it. The charter format, the checker (R1–R6) with validate --explain plain-language fixes, worked examples (the Autopilot flagship + others), a template, a GitHub Action, and a pre-commit hook.
  • v0.2 — GitHub enforcement loop. ← you are here. agenraci verify --target github checks a live repo's branch protection and CODEOWNERS against the charter and fails CI on drift — offline --settings mode (#60) and live --repo mode via gh api (#61). The companion verify GitHub Action (#62) drops into any workflow in two lines (dogfooded here; live branch-protection reads need admin scope, so the dogfood job uses continue-on-error). agenraci compile --target github (#63) now also emits a directly-applyable classic branch-protection PUT JSON, a ready-to-run gh api command, and a verify round-trip step — closing the compile → apply → verify loop. A step-by-step cookbook (#65) walks the whole loop end-to-end. Still no runtime interception — verify, don't intercept.
  • v0.3 — first runtime connector. A working HumanLayer connector that turns charter gates into real approval pauses, plus a richer authority graph beyond gate escalate_to edges (standing veto relations).
  • v0.4 — LangGraph connector + a small web view that renders the chart so non-engineers can read it.
  • v0.5 — author ergonomics. Inline checker findings in an editor, and a reference mode that explains any rule on demand.

FAQ

Isn't this just RBAC? No. Permission ("what may you touch") is only one of AgenRACI's three axes. Role-based access control answers that one question and stops there. AgenRACI also separates Function (what you do) and Authority (whose call wins in a conflict), and — the part RBAC has no concept of — it centers a single accountable owner for each type of action. RBAC can tell you an agent is allowed to call deploy; it can't tell you who answers for the deploy, who had to sign off first, or what should happen if that approver goes dark. A charter can be denied a permission yet still be accountable for the outcome — those are different axes, and conflating them is exactly the gap AgenRACI exists to close.

Why not just use HumanLayer / LangGraph / CrewAI? Use them — they're solving a different layer. Those frameworks run agents and can pause them to wait for a human sign-off. AgenRACI sits one level up: it's the file that says, for this specific team, who is allowed to do what, who owns each outcome, and who breaks a tie — independent of which runtime you use. The charter is framework-agnostic on purpose. Turning a charter into the live gates those tools enforce (starting with a HumanLayer connector) is on the roadmap; today AgenRACI defines and checks the rules those runtimes would enforce.

Is this vaporware? No. v0.1 writes and checks a charter today: a real file format, an automatic checker with rules R1–R6, worked examples, and a template — all of which you can run from a clone of this repo (pip install -e . then agenraci validate examples/sprout/charter.yaml). What it does not do yet is intercept actions or enforce approvals at runtime; that's stated plainly in What AgenRACI is (and isn't) yet above and tracked on the roadmap, not dressed up as a current capability.

License

MIT — see LICENSE.

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

agenraci-0.2.1.tar.gz (56.2 kB view details)

Uploaded Source

Built Distribution

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

agenraci-0.2.1-py3-none-any.whl (41.8 kB view details)

Uploaded Python 3

File details

Details for the file agenraci-0.2.1.tar.gz.

File metadata

  • Download URL: agenraci-0.2.1.tar.gz
  • Upload date:
  • Size: 56.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for agenraci-0.2.1.tar.gz
Algorithm Hash digest
SHA256 8e20934d03f269ffce1138cc034d19e09a2635fd4be186b0ab986fb773c1fdac
MD5 62134116eb25b2e24140a67537310ddd
BLAKE2b-256 ca45199660c50618dc3436184bca68a8d649569b793bcbc197dd88b867dbf98d

See more details on using hashes here.

Provenance

The following attestation bundles were made for agenraci-0.2.1.tar.gz:

Publisher: publish.yml on jing-ny/agenraci

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agenraci-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: agenraci-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 41.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for agenraci-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8ff6a6d08a51bdd15b5621415e1645472972a18967c5895d228fc8a2d2c20eb7
MD5 2f3a6cf4f9619a53c3bf69503f875508
BLAKE2b-256 e390ed32921f621f922b093e7e367ce98df86677f98ec2ea5b89012f80b42328

See more details on using hashes here.

Provenance

The following attestation bundles were made for agenraci-0.2.1-py3-none-any.whl:

Publisher: publish.yml on jing-ny/agenraci

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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