charter

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: MIT

README

Charter

Git-native governance for AI coding agents.

Charter helps teams record important engineering decisions, make them available to coding agents before they change code, and require an explicit acknowledgment when governed code changes. Decisions stay as Markdown files in your repository, reviewed through the same pull requests as everything else.

It is a single Go binary: CLI, MCP server, and CI gate—no hosted service, background daemon, or web application required.

flowchart LR
    H["Human reviewer"] -->|"accepts / rejects"| D["Decision files\n.charter/decisions"]
    A["Coding agent"] -->|"decision_check"| M["Charter MCP\nper-session stdio"]
    M --> D
    Dev["Developer change"] --> C["charter check"]
    D --> C
    C -->|"Governed-By trailer"| PR["Pull request / CI"]

Why Charter?

As repositories adopt AI coding agents, architectural context can be scattered across conversations, tickets, and the memories of individual contributors. Charter makes the durable parts explicit:

  • Teams get a visible, reviewable record of why the system is built the way it is.
  • Developers see applicable constraints before changing a governed area.
  • Agents can search history, check scope, and draft proposals through MCP.
  • Maintainers get a lightweight CI acknowledgment gate without adopting a policy engine or service.

Charter does not replace code review, repository permissions, linters, or security controls. It adds a shared decision record and workflow around them.

Five-minute quickstart

# Install
go install github.com/SkandaPrasad-S/charter/cmd/charter@latest

# Initialize the current repository
charter init

# Draft a decision
charter propose \
  --title "Use PostgreSQL for persistent storage" \
  --context "The service needs transactional writes and relational queries." \
  --decision "Use PostgreSQL for all persistent application data." \
  --scope-path "internal/store/**" \
  --enforcement blocking

# After human review
charter accept 0001 --why "Approved in architecture review"

# Inspect locally, then enforce in CI against a base ref
charter check
charter check --diff origin/main

When a commit changes a blocking scope, acknowledge it in the commit message:

feat: add repository implementation

Governed-By: 0001

How it works

stateDiagram-v2
    [*] --> Proposed: charter propose
    Proposed --> Accepted: human review / charter accept
    Proposed --> Rejected: charter reject --why

    Accepted --> Accepted: charter affirm / reset review date
    Accepted --> Superseded: charter supersede

    note right of Accepted
        review_after may pass while
        status remains accepted.
        Charter reports a stale advisory.
    end note

    Rejected --> [*]: retained as history
    Superseded --> [*]: retained as history
  1. A contributor or agent creates a proposed Decision. It is a draft: it records the suggested choice and rationale, but does not govern code yet.
  2. A human reviews the draft. Review means checking that the problem is real, the decision is clear, alternatives and consequences are understood, and the scope/enforcement level are appropriate for the repository.
  3. The reviewer either accepts it, making it active, or rejects it. A rejected Decision records that the option was considered and declined, including the reason, so a future contributor can learn from that discussion instead of reopening it unknowingly.
  4. Accepted Decisions can match files and diff text through a declared scope. CI requires Governed-By: <id> or Charter: <id> for matching blocking Decisions.
  5. When an accepted Decision needs to change, create and accept a replacement, then supersede the old Decision. Superseding marks the old Decision as no longer active and links it to its replacement; it does not erase it.
  6. Rejected and superseded Decisions are retained as history: they remain committed Markdown records in Git, preserving the context, alternatives, and timeline behind the current architecture.

Use with AI coding agents

Charter runs a small MCP server over stdio. It gives an agent four focused tools:

Tool What it does
decision_check Finds accepted Decisions that govern planned paths or a diff.
decision_search Searches prior non-rejected Decisions.
decision_propose Drafts a new proposed Decision.
decision_list Lists Decisions, optionally by status.

Install supported integrations:

charter install claude
charter install codex

The integration adds MCP configuration and a short managed instruction block. The intended agent workflow is: check first, cite relevant Decision IDs, search before assuming, and propose instead of silently choosing new architecture.

CI gate

sequenceDiagram
    participant Dev as Developer
    participant Git as Git commits
    participant CI as CI runner
    participant Charter as charter check

    Dev->>Git: Commit governed change + Governed-By: 0001
    CI->>Charter: check --diff base-ref
    Charter->>Git: Read changed paths and commit trailers
    Charter->>Charter: Match accepted Decision scopes
    alt blocking match is acknowledged
        Charter-->>CI: Exit 0
    else stale matched Decision
        Charter-->>CI: Exit 1 (advisory)
    else blocking match is uncited
        Charter-->>CI: Exit 2
    else check could not run (bad ref, corrupt store)
        Charter-->>CI: Exit 3
    end

Minimal GitHub Actions example:

name: charter
on: pull_request

jobs:
  governance:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-go@v5
        with:
          go-version-file: go.mod
      - run: go run ./cmd/charter check --diff "${{ github.event.pull_request.base.sha }}"

Documentation

The complete Mintlify documentation is in docs/, with separate task-oriented Guide and exact Reference sections:

Connect this repository to Mintlify; docs.json provides the site navigation and each page is MDX.

Contributing and security

Contributions are welcome. Start with the contribution guide, follow the Code of Conduct, and use the GitHub issue forms for bugs and feature requests. Please report vulnerabilities privately as described in the Security Policy.

Maintainers can follow the release guide for Semantic Versioning, validation, Git tags, and GoReleaser publishing.

Development

go build ./...
go test ./...
go vet ./...

Dependencies are vendored. See the license for terms.

Directories

Path Synopsis
cmd
charter command
Command charter is the governance layer for AI coding agents: a CLI, MCP server, and CI gate over a git-native store of human-approved architectural decisions.
Command charter is the governance layer for AI coding agents: a CLI, MCP server, and CI gate over a git-native store of human-approved architectural decisions.
charter/cmd
Package cmd wires up the charter CLI: init, propose, accept, reject, supersede, affirm, list, show, sync, and check (§9 of the design doc).
Package cmd wires up the charter CLI: init, propose, accept, reject, supersede, affirm, list, show, sync, and check (§9 of the design doc).
internal
bootstrap
Package bootstrap mines a repository for the decisions that are already implicitly in force — in CLAUDE.md/AGENTS.md-style instruction files, in lockfiles and manifests, and in CI/linter config — and turns each finding into a draft proposed decision (§10 of the design doc).
Package bootstrap mines a repository for the decisions that are already implicitly in force — in CLAUDE.md/AGENTS.md-style instruction files, in lockfiles and manifests, and in CI/linter config — and turns each finding into a draft proposed decision (§10 of the design doc).
check
Package check implements Charter's Layer 2 enforcement: a deterministic scope gate that matches changed files against accepted decisions and requires an explicit acknowledgment (§2, §11 of the design doc).
Package check implements Charter's Layer 2 enforcement: a deterministic scope gate that matches changed files against accepted decisions and requires an explicit acknowledgment (§2, §11 of the design doc).
decision
Package decision defines the Decision object: a markdown file with YAML frontmatter that is the single source of truth for a governed choice.
Package decision defines the Decision object: a markdown file with YAML frontmatter that is the single source of truth for a governed choice.
events
Package events is Charter's append-only audit log (design §13).
Package events is Charter's append-only audit log (design §13).
install
Package install wires Charter into a coding agent's tool config: an MCP server registration plus a short managed instruction block in whatever file that tool reads on startup (CLAUDE.md, AGENTS.md, ...).
Package install wires Charter into a coding agent's tool config: an MCP server registration plus a short managed instruction block in whatever file that tool reads on startup (CLAUDE.md, AGENTS.md, ...).
mcp
Package mcp is a minimal, handwritten Model Context Protocol server over stdio — no SDK dependency, by design (§7, §19): four tools is not worth a framework.
Package mcp is a minimal, handwritten Model Context Protocol server over stdio — no SDK dependency, by design (§7, §19): four tools is not worth a framework.
principal
Package principal resolves the identity attached to an action: a human (from git config) or, in future, an agent (from its MCP connection).
Package principal resolves the identity attached to an action: a human (from git config) or, in future, an agent (from its MCP connection).
search
Package search provides decision_search: a query over decision titles and body text.
Package search provides decision_search: a query over decision titles and body text.
store
Package store persists Decisions as files under .charter/decisions/ and provides the operations the CLI and MCP server need on top of them.
Package store persists Decisions as files under .charter/decisions/ and provides the operations the CLI and MCP server need on top of them.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL