A structured codebase template for full and semi-autonomous AI agents and human collaborators.
Kagantic-Base is a GitHub template repository that provides a universal three-file governance
system — AGENTS.md, codebase_rules.md, and index.md — at the root and within every package
and subpackage. It is designed for teams that use AI agents (Claude Code, Codex, Cursor, Windsurf,
or custom API agents) alongside human developers. The template minimizes the token overhead that
agents consume to understand a codebase, enforces clear contracts between humans and agents, and
scales from a single-package project to a large monorepo with nested subpackages. It is entirely
language-agnostic: the root rules contain zero language-specific content, and each package defines
its own language rules independently.
-
Every file has a single, distinct job.
index.mdis a spatial map.codebase_rules.mdis a behavioral contract for code quality.AGENTS.mdis an operational playbook. None of these files should contain content that belongs in one of the others. -
Inheritance is explicit. Package-level governance files declare
## Inherits(what they extend) and## Overrides(what they change from the parent). Local rules always win over root rules, but overrides must be declared with a justification. Silent overrides are a defect. -
Summaries are front-loaded. Every governance file opens with a 2-4 sentence summary block so an agent can decide relevance without reading the full file. This matters at scale: on a 20-package monorepo, an agent that reads summaries before diving into full files saves hundreds of tokens per task.
-
Agents update
index.mdafter every structural change. A stale index is a navigational hazard. Agents must update the relevantindex.mdwhenever they create, delete, rename, or move a file, and flag the update in their output. -
Token efficiency is a first-class concern. Scoped rules, navigation hierarchies, and front-loaded summaries exist to reduce the context an agent must consume. Do not add noise to governance files. Every sentence should earn its place.
Each package — root or otherwise — contains exactly these three governance files:
Tells agents what exists, where it is, and how packages relate. An agent entering an unfamiliar
package reads index.md first. It contains:
- A 2-4 sentence summary of the package.
- An entry points table (primary files and modules with one-line descriptions).
- A subpackages table (links to child
index.mdfiles). - A dependencies section (what this package depends on; what depends on it).
- A
Last Updateddate (maintained by agents after structural changes).
index.md must not contain behavioral rules or coding standards. If you find rules in index.md,
they belong in codebase_rules.md or AGENTS.md.
The single source of truth for how code is written in this package. It covers:
- Language version, formatter, linter, type checking policy.
- Use/Avoid patterns with concrete examples.
- Naming conventions.
- Testing framework, coverage floors, fixture conventions.
- Dependency policy.
The root codebase_rules.md contains zero language-specific rules. All language rules live in
package-level files. This is enforced by convention and CI.
Defines what an agent may do, must do, and must never do within this package. It covers:
- Mode declaration (autonomous / supervised / interactive).
- MAY and MUST NOT scope rules.
- The navigation order agents follow when starting work.
- Named playbooks for common tasks.
- Output contract requirements.
- Escalation triggers.
AGENTS.md must not contain coding standards. If you find style rules in AGENTS.md, they belong
in codebase_rules.md.
/ (root)
├── index.md
├── codebase_rules.md ← language-neutral only
├── AGENTS.md ← defines global defaults and triggers
│
├── example-package-python/
│ ├── index.md
│ ├── codebase_rules.md ← Inherits: /codebase_rules.md | Python rules here
│ └── AGENTS.md ← Inherits: /AGENTS.md | mode: supervised
│
└── example-package-with-subpackages/
├── index.md
├── codebase_rules.md ← Inherits: /codebase_rules.md
├── AGENTS.md ← Inherits: /AGENTS.md | mode: autonomous
└── subpackage-a/
├── index.md
├── codebase_rules.md ← Inherits: ../codebase_rules.md | OVERRIDES line length
└── AGENTS.md ← Inherits: ../AGENTS.md
Conflict resolution rules:
- Local file always wins over the parent.
- Any override must be declared in the
## Overridessection at the top of the overriding file. - The
## Overridessection must name each overridden rule and state a justification. - Global
MUST NOTrules in the rootAGENTS.mdcannot be overridden by any package. - Global escalation triggers cannot be removed by any package.
# <Package Name> — Index
## Summary
[2-4 sentences: what this package does, what problem it solves, what tech stack.]
## Entry Points
| File | Description |
|------|-------------|
| `src/main.ext` | [one-line description] |
## Subpackages
| Subpackage | Description |
|------------|-------------|
| [subpackage-a/](subpackage-a/index.md) | [one-line description] |
## Dependencies
**Depends on:** [list packages this package imports/calls, or "none"]
**Depended on by:** [list packages that import/call this package, or "none"]
## Last Updated
YYYY-MM-DD# Codebase Rules — <Package Name>
> **Summary:** [2-4 sentences summarizing what rules this file adds/changes.]
## Inherits
[path to parent codebase_rules.md, e.g. ../codebase_rules.md or /codebase_rules.md (root)]
## Overrides
[List each rule overridden from the parent. Write "(none)" if nothing is overridden.]
- **Rule:** [rule name from parent] — **Override:** [new rule] — **Justification:** [why]
## Language and Runtime
[Language version, formatter, linter, type hint policy]
## Patterns
### Use
- [concrete pattern to use]
### Avoid
- [concrete pattern to avoid]
## Naming Conventions
[File, class, function, constant, variable naming conventions]
## Testing
[Test framework, coverage floor, fixture conventions, test file placement]
## Dependencies
[How to add/remove deps, allowed/banned libraries]# AGENTS.md — <Package Name>
> **Summary:** [2-4 sentences: what this playbook covers, what it inherits, what it overrides.]
## Inherits
[path to parent AGENTS.md]
## Overrides
[List each rule overridden. Write "(none)" if nothing is overridden.]
## Mode
[autonomous | supervised | interactive]
## Scope
### MAY
- [permitted actions]
### MUST NOT
- [hard prohibitions]
## Navigation Order
1. [file to read first]
2. [file to read second]
...
## Task Patterns
### Adding a new feature
1. [step]
...
## Output Contract
Follows root AGENTS.md output contract. [Any local additions here.]
## Escalation Triggers
Inherits all global triggers. Additional local triggers:
- [local trigger, or "(none)"]The task handoff block is the standard interface for humans to give scoped work to agents. Embed it in a PR description, issue body, or source file header.
<!-- AGENT TASK
scope: <relative path from repo root>
mode: <autonomous | supervised | interactive>
agent: <claude-code | codex | assistants-api | cursor | windsurf | api | any>
goal: <Single sentence describing the desired outcome.>
context: <Background the agent needs that is not in the governance files.>
do_not_touch: <comma-separated files/dirs to leave unchanged, or "none">
must_pass: <tests | lint | typecheck | all | none>
escalate_if: <task-specific escalation conditions, or "none">
-->
Usage example:
<!-- AGENT TASK
scope: example-package-python
mode: supervised
agent: claude-code
goal: Add input validation to the process_items() function so it raises ValueError on empty input.
context: See issue #12. The function currently raises a KeyError, which is confusing to callers.
do_not_touch: requirements.txt
must_pass: all
escalate_if: none
-->
See TASK_HANDOFF.md for the full field reference and additional examples.
After completing any task, an agent must produce output in this exact format:
## Summary
[2-4 sentences: what was done, why, and the outcome.]
## Changes
- `path/to/file.ext` — [created | modified | deleted]: [one-line reason]
## Index Updates
- `path/to/index.md` — [what changed]
- (none)
## Deviations
- `codebase_rules.md` rule violated: [rule name] — [justification]
- (none)
## Escalation Flags
- [anything a human should review before merging]
- (none)Rules:
- Every file touched must appear in
## Changes. Omitting a file is a defect. ## Escalation Flagsmust be present even if the value is(none).- The output contract is required even for escalated (incomplete) tasks.
The following triggers apply everywhere. No package can remove them.
- Task requires modifying more than 2 packages simultaneously.
- A dependency upgrade changes a public API or introduces a breaking change.
- Requirements cannot be resolved from available context (unresolvable ambiguity).
- A
MUST NOTrule would need to be violated to complete the task. - A security-relevant pattern is detected (hardcoded secrets, unsafe deserialization, injection risk).
- Agent confidence in the correct approach is below a reasonable threshold for the task risk level.
When a trigger fires:
- Stop execution immediately.
- Do not make further file changes.
- Produce the output contract up to the escalation point.
- Explain the trigger in detail in
## Escalation Flags.
In any package AGENTS.md, add a ## Escalation Triggers section:
## Escalation Triggers
Inherits all global triggers. Additional local triggers:
- Any change to the public HTTP API schema requires human approval before implementation.
- Database migration files must be reviewed by a human before execution.Local triggers add to the global list. They cannot remove or narrow global triggers.
The governance structure is deliberately designed to minimize the tokens an agent must consume:
-
Front-loaded summaries: Every governance file opens with a 2-4 sentence summary. An agent can read the summary and decide whether to read the full file. On a 20-package repo, skipping irrelevant full files saves thousands of tokens per task.
-
Scoped rules: Language rules live only in the package where they are relevant. A Go agent working in
example-package-gonever needs to read Python rules. -
Navigation hierarchy:
index.mdfiles form a tree. An agent navigates from the root index down to the relevant package, reading only what it needs. It never has to glob the whole repo. -
Named playbooks: Common task patterns in
AGENTS.mdlet agents skip the reasoning step for well-understood tasks (bug fix, add feature, refactor) and go directly to execution. -
Practical tips for keeping governance files lean:
- Do not duplicate rules between root and package files. Inheritance handles it.
- Do not add examples to
codebase_rules.mdunless they prevent a class of recurring mistakes. - Keep
index.mdentry point tables to 10 rows or fewer. Link to sub-indexes for deeper navigation. - Delete stale entries from
index.mdimmediately. Stale entries are noise.
Agent executes without asking for approval. Best for well-scoped tasks in packages with strong CI.
| Aspect | Behavior |
|---|---|
| Planning | Internal only — not presented to human |
| Checkpoints | None (unless escalation fires) |
| File writes | Immediate |
| Ambiguity | Resolved using best judgment; flagged in output |
| Escalation | Always fires; agent stops and flags |
Agent plans, checkpoints, and requests human review at key stages.
| Aspect | Behavior |
|---|---|
| Planning | Presented to human before execution |
| Checkpoints | After each logical stage |
| File writes | After human approval at each stage |
| Ambiguity | Surfaced to human immediately |
| Escalation | Always fires; agent stops and flags |
Agent proposes and explains every change before making it. Human must approve each file write.
| Aspect | Behavior |
|---|---|
| Planning | Presented and revised collaboratively |
| Checkpoints | Before every file write |
| File writes | Only after explicit "yes/proceed/ok" |
| Ambiguity | Treated as a question; discussed with human |
| Escalation | Always fires; agent stops and flags |
When to use each mode:
- Use autonomous for: routine dependency updates, test generation, doc updates, single-package refactors, tasks with clear acceptance criteria and strong CI.
- Use supervised for: cross-package changes, API changes, schema changes, any task where you want a human in the loop at key decision points.
- Use interactive for: exploratory work, learning sessions, IDE-embedded workflows (Cursor, Windsurf), any task where requirements are still evolving.
| Runtime | File System | Shell/Tools | Context | Default Mode |
|---|---|---|---|---|
| Claude Code | Full | Full | Large; multi-file per turn | autonomous (scoped) / supervised (cross-pkg) |
| OpenAI Codex / Responses API | Sandboxed workspace | Limited; verify before use | Stateless per call — re-read governance each session | supervised |
| OpenAI Assistants API | Via file attachments | Code interpreter (sandboxed) | Thread-based + vector store | supervised |
| Cursor | Full IDE | IDE terminal | User-managed; use @file mentions |
interactive |
| Windsurf | Full IDE | IDE terminal | User-managed; use @ mentions |
interactive |
| Custom API agents | Verify at init | Verify at init | No assumption | supervised |
Notes per runtime:
- Claude Code: Respects
AGENTS.mdnatively. Supports multi-file edits in one turn. Useindex.mdnavigation to avoid context bloat on large repos. - Codex / Responses API: Stateless — agents must re-read governance files at the start of every API call session. Pass relevant governance files in the system prompt.
- Assistants API: Upload
index.mdandAGENTS.mdas thread attachments at session start. Index governance files in the vector store for retrieval in long threads. - Cursor: Ask the user to open
index.mdandAGENTS.mdas context before starting. Use Composer mode for multi-file tasks. - Windsurf: Use
@AGENTS.mdand@index.mdmentions at the start of every Cascade session. - Custom API: Verify tool inventory at initialization. Document verified capabilities in a
deployment-specific
AGENTS.mdoverride section.
Multi-agent workflows are supported but disabled by default. To activate:
- Open the root
AGENTS.md. - Find the
## Multi-Agent Rolessection (it is inside an HTML comment block). - Remove the comment tags (
<!--and-->) to activate the section. - Fill in the role definitions for your team's specific workflow.
- Ensure each agent runtime is configured to receive the correct role assignment.
Default roles provided (commented out):
| Role | Responsibility |
|---|---|
| Orchestrator | Decomposes tasks; assigns subtasks to specialists; aggregates outputs |
| Specialist — Code | Implements code changes within an assigned scope |
| Specialist — Test | Writes or updates tests for changes made by the Code specialist |
| Specialist — Review | Reviews all changes; verifies rule compliance; issues PASS/FAIL verdict |
All inter-agent communication flows through the Orchestrator using the standard output contract format. Agents do not communicate directly with each other.
Supporting a new language requires no changes to root files. To add a new language:
-
Create a new package directory:
my-new-package/ -
Copy the three governance files from any existing package as a starting point:
cp example-package-python/index.md my-new-package/index.md cp example-package-python/codebase_rules.md my-new-package/codebase_rules.md cp example-package-python/AGENTS.md my-new-package/AGENTS.md -
Edit
my-new-package/index.md: Update the summary, entry points, and last updated date. -
Edit
my-new-package/codebase_rules.md:- Keep
## Inherits: /codebase_rules.md(root). - Update
## Language and Runtimewith the new language's version, formatter, and linter. - Update
## Patterns,## Naming Conventions,## Testing,## Dependencieswith language-specific rules. - Remove all content from the copied package that is language-specific.
- Keep
-
Edit
my-new-package/AGENTS.md:- Keep
## Inherits: /AGENTS.md(root). - Set the appropriate
## Mode. - Update
## Task Patternsif the language has unusual build or test steps.
- Keep
-
Add your source files and update
my-new-package/index.mdentry points. -
Update the root
index.mdto add the new package to the subpackages table.
That's it. No root files need modification. CI will automatically include the new package in governance validation.
How to bootstrap a new repository from this template:
Click Use this template on GitHub, or clone and re-initialize:
git clone <this-repo-url> my-project
cd my-project
rm -rf .git
git init
git add .
git commit -m "chore: initialize from Kagantic-Base template"index.md: Replace the summary and subpackages table with your project's actual structure. Delete the example packages from the table (you will delete the directories in Step 3).codebase_rules.md: Review the root rules. They are language-neutral and opinionated. Edit to match your team's conventions. Do not add language-specific rules here.AGENTS.md: Set the default mode for your project. Review the runtime compatibility section and adjust if you use runtimes not listed or have custom capability notes.TASK_HANDOFF.md: No changes needed for most projects. Customize examples if desired.
rm -rf example-package-python example-package-rust example-package-typescript \
example-package-go example-package-polyglot example-package-with-subpackagesFor each real package in your project, create a directory with the three governance files. Follow the Adding a New Language guide above.
The governance workflow runs automatically on push and PR to main. If your default branch has
a different name, update .github/workflows/validate-governance.yml:
on:
push:
branches: [your-default-branch]
pull_request:
branches: [your-default-branch]The governance CI checks only for governance file presence. You will want to add separate workflows for:
- Linting and formatting (per language)
- Running tests (per package)
- Security scanning (secret detection, dependency audit)
Add these as separate workflow files in .github/workflows/.
git add .
git commit -m "chore: configure Kagantic-Base for <project name>"
git push -u origin mainThe workflow at .github/workflows/validate-governance.yml:
- Identifies all "governed package" directories (root + all directories with content or an
index.md). - For each governed package, verifies that all files in the
REQUIRED_FILESarray exist. - Collects all failures before exiting, so you see the full list of missing files in one run.
- Exits with code 0 (pass) if all packages are compliant, code 1 (fail) if any are not.
- Prints a clear error message listing every missing file and which package it is missing from.
pushtomainpull_requesttargetingmain
To require an additional governance file in every package:
- Open
.github/workflows/validate-governance.yml. - Find the
REQUIRED_FILESarray (it has a comment above it). - Add the new filename to the array.
REQUIRED_FILES=(
"index.md"
"codebase_rules.md"
"AGENTS.md"
"SECURITY.md" # ← add new required files here
)That's the only change needed. The rest of the workflow adapts automatically.
- Content of governance files (structure, required sections). This is by design — content validation is a human/agent responsibility enforced by the output contract, not by CI.
- Language-specific linting or test results. Add separate workflows for those.
- Whether
index.mdis up to date. Staleness is detected and flagged by agents at runtime.
- A universal three-file governance system that works for any language and any agent runtime.
- A structured task handoff format that minimizes ambiguity.
- Example packages demonstrating governance for Python, Rust, TypeScript, Go, polyglot, and nested subpackages.
- CI enforcement of governance file presence.
- Documentation of agent modes and runtime compatibility.
- A build system, package manager, or monorepo tooling (Nx, Turborepo, Bazel).
- A CI system for running tests, linting, or type-checking (beyond governance validation).
- An agent runtime or framework. This template works with any agent runtime.
- A code generation tool. The template is populated by hand or by an agent following the adoption guide.
- Enforcement of governance file content. Structure is validated by agents, not by CI.
- Secrets management infrastructure. The template documents the policy; you supply the tooling.