Skip to main content

Covener

Spec-driven development for AI agent teams.
Governance for regulated domains and large projects: traceable, auditable, human-approved.

CI PyPI Python License: MIT

pip install covener && covener init

Covener is a repository layout, a deterministic checker and a set of agent definitions that turn Claude Code, Cursor or any tool that reads AGENTS.md into a development team you can govern.

  • Specifications, bugs and tasks are files with a status. What the product is, where it deviates, and what has to be done never mix and never grow.
  • Sprints hold the work: one work log per item with a checklist, the agents' summaries, decisions and reviews, and your feedback. Closed sprints are archived; nothing is stored twice.
  • Approval is a rule in a file. An item is done only when a human wrote Approved: Yes in its work log. covener status --strict fails CI when that rule, or any consistency rule, is broken.
  • Knowledge is evidence. Regulations, contracts and procedures in knowledge/ become a page-anchored corpus with a citation graph and an optional semantic graph; agents cite file#page-N, reviewers verify, and status flags dangling references.
  • Nothing runs a server, calls a model or needs the package once initialised. Two commands for the method, one for knowledge, one to expose both as MCP tools.

Why Covener

Spec-driven development tools stop at the spec. spec-kit generates a pile of Markdown per feature and numbers features so that two developers branching on the same day collide. Kiro writes requirements, design and tasks, then treats them as launch documents that drift as soon as code changes. BMAD answers the problem with a dozen personas and the process overhead that comes with them. OpenSpec tracks changes well, but a spec is still just text an agent can declare done. None of them keeps the decisions made while building, none makes human approval something a machine can verify, and none can tell you which article of which regulation a requirement comes from.

Covener does all three. Every decision, review and human comment is written next to the item it belongs to, so a new session starts from the record instead of from zero. An item is done only when a person wrote Approved: Yes, and covener status --strict fails CI otherwise, which makes the approval something an auditor can rely on rather than a line in a prompt. Requirements that come from regulations cite their evidence page by page, backed by a citation graph built without a model, so nothing about a law can be hallucinated. It does this with two files per item, five roles with hard boundaries, sprints that never collide across a team, and a layout you can explain in a minute.

How it works

cd my-project
covener init          # links the agents into Claude Code and Cursor; never overwrites your files

Then talk to the team in your IDE:

I want customers to connect their Stripe account and receive payments.

Step Role What happens in the repository
1 product Reads specs/vision.md and the existing specs, reports the impact, drafts specs/stripe-connect.md with acceptance criteria and, when a regulation applies, references: to the evidence. You set status: approved.
2 planner Opens sprints/payments-onboarding/ with the spec (and open bugs first) and writes the checklist in the work log.
3 engineer, qa, reviewer Implement, test against the criteria, review architecture, security and compliance. Each writes its entry in the work log.
4 planner Sets the sprint to review and tells you what to evaluate.
5 you Approved: No with what to change, or Approved: Yes.
6 planner Reworks until you approve, marks the spec done, archives the sprint.
covener status        # backlog, sprints, inconsistencies, what to do next

Repository layout

specs/vision.md                     product intent
specs/<id>.md                       what the product is: one living file per spec (draft -> approved -> done)
bugs/<id>.md                        what is wrong (open -> done)
tasks/<id>.md                       work that changes neither: migrations, refactors, upgrades (open -> done)
sprints/<name>/sprint.md            owner, status, specs, bugs and tasks in scope (active -> review -> closed)
sprints/<name>/<kind>s/<id>.md      the item's work log: checklist, summary, decisions, QA, review, feedback
sprints/archive/YYYY-MM-DD-<name>/  closed sprints
knowledge/                          optional: domain documents, their Markdown, INDEX.md, CITATIONS.md
agents/<name>.md                    one file per agent; .claude/agents and .cursor/agents link here
AGENTS.md                           a small block every coding agent reads (CLAUDE.md imports it)
.covener/config.yaml                role to agent mapping and tools; nothing else

Domain folders are fine: specs/payments/stripe-connect.md has the id payments/stripe-connect.

Which folder? If in a year someone must read it to know what the product is, it is a spec. If it describes something that is wrong today, it is a bug. If they only need to know it was done, it is a task. Specs are living documents: to extend, change or remove a requirement, edit the spec, it goes back to draft, approve it again, and a sprint carries the change. Its history is the sprints that touched it.

No backlog file. The backlog is every open bug, approved spec and open task that is not in an open sprint: bugs first, then everything by two optional front matter fields, priority and epic. Reprioritising is a one-line change in one file, so a team never fights over a list.

The work log

sprints/<name>/specs/<id>.md (or bugs/<id>.md, tasks/<id>.md) is a chronological log. Agents add entries; you add one.

# stripe-connect

## Checklist
- [x] onboarding endpoint
- [x] token refresh
- [ ] operator docs

## Summary
Implemented in payments/onboarding.py; 6 tests in tests/test_onboarding.py.

## Decisions
- 2026-09-12 Store the Stripe account id, not the token; tokens are fetched on demand.

## QA
Verdict: pass
- AC1 test_onboarding_starts, AC2 test_reconnect_expired, AC3 manual check on staging.

## Review
Verdict: pass with notes
- medium: retry on 429 missing in payments/client.py:41; add backoff.

## Feedback
Approved: No
Also handle a revoked authorization, not only an expired one.

## Rework
Added revocation handling and a test.

## Feedback
Approved: Yes

The last entry is the state: awaiting feedback, changes requested or approved (the checklist does not count). covener status derives everything from this file.

covener status

Covener

Product
  Vision: OK

Specs
  Total: 4
  Draft: 1
  Approved: 2
  Done: 1

Bugs
  Total: 2
  Open: 2
  Done: 0

Tasks
  Total: 1
  Open: 1
  Done: 0

Backlog
  Items: 3
  [bugs]
    - wrong-currency (priority 1)
  [platform]
    - task migrate-postgres (priority 1)
  [payments]
    - spec refunds (priority 2)

Sprints
  payments-onboarding (review, alvaro): approved 1/2
    - spec stripe-connect: awaiting feedback, checklist 5/6
    - bug expired-tokens: approved, checklist 2/2

Done
  - spec reporting-api (2026-09-10-reporting-v1 2026-09-10)

Governance
  Pending human review: 1
  Pending spec approval: 1
  Errors: 0
  Warnings: 0

Next
  * Review and approve specs/ideas.md (draft)
  * Give feedback on spec stripe-connect in sprints/payments-onboarding/specs/stripe-connect.md

--json for machines, --verbose for warnings, --strict to fail CI on errors. No model is involved; it only reads files.

Errors are the rules that protect your authority and the repository's consistency: an item done without your Approved: Yes; a sprint closed with unapproved work; an item in two open sprints; a draft spec, a done item or an unknown id in an open sprint; an open sprint in the archive; invalid statuses or unparsable files; a missing vision; a configured agent without a definition. Closed sprints are history: only the approval rule applies to them, so a spec that later changes never breaks CI. A second open sprint for the same owner is a warning, not an error: that is what a hotfix looks like.

Working in a team

One sprint, one owner, one branch, one pull request. Git isolates parallel work; Covener makes the rules checkable.

  • Name sprints by what they deliver (payments-onboarding), never by number: sequential numbers collide the moment two people branch.
  • The owner is a field in sprint.md. One open sprint per owner is the norm; an item is in at most one open sprint. covener status flags both after a merge.
  • Specs, bugs and tasks are one file each, so two people rarely touch the same one. Approval is in the file.
  • History is the archive of closed sprints plus status: done in the item. Archive after the pull request merges. Everything is committed; nothing is personal or ignored.

Bugs, tasks and hotfixes

A bug is a deviation from the product. A fix is the change that corrects it. A hotfix is a fix that cannot wait. A task is work that leaves no requirement behind. The words stay apart; the flow stays the same.

Situation Flow
Trivial fix (one place, no design decision) "Fix this." The engineer fixes it with a test and tells you. No file, no sprint.
Bug worth tracking "This is the problem." Product registers bugs/<id>.md (symptom, reproduction, cause if known, expected behaviour), open from the start: a bug is reported, not approved. It waits at the top of the backlog for the next sprint; an active sprint's scope does not change.
Hotfix Same, but the planner opens a one-bug sprint now (sprints/hotfix-<slug>/) and the cycle runs in an hour: regression test, fix, QA, review, your Approved: Yes, archive.
Technical work "Migrate to Postgres." The planner registers tasks/<id>.md (goal, why, scope, done-when, risk and rollback), open from the start. Same cycle; QA verifies the done-when and that no spec regressed. If the work leaves a durable requirement ("data lives in Postgres"), it is a spec instead.

Bugs and tasks never touch a spec. If a bug reveals the spec was wrong, or a task changes what the product promises, that is a separate change to the spec.

Project Knowledge

Regulated products depend on documents nobody reads twice: laws, contracts, procedures, internal standards. Covener makes them a first-class input with evidence, so an agent never writes "the regulation says" from memory.

pip install "covener[oracle]"        # "covener[knowledge]" for the deterministic layer only
cp ~/regulations/*.pdf knowledge/
covener knowledge build              # incremental: only new or changed documents are processed

Deterministic layer, no model, no network. Every source becomes Markdown with ## Page N headings next to it; knowledge/INDEX.md lists the corpus; knowledge/CITATIONS.md is the graph of explicit cross-references between documents, resolved to the documents in the corpus. Patterns cover EU regulations and directives and Spanish-language public law today; adding a jurisdiction is one regular expression. Nothing in this layer can be hallucinated.

Knowledge Oracle, optional. A graph of entities and relationships plus vector retrieval over the same Markdown, built with a frontier model and stored as local files (LightRAG: NetworkX graph, nano-vectordb, no server). One tool, search_knowledge, returns answer, relations and evidence with knowledge/<file>.md#page-N references. Without evidence it says so instead of guessing.

covener knowledge ask "What must happen when a customer asks us to delete their data?"
Personal data must be erased without undue delay when the data subject withdraws consent or the
data is no longer necessary [gdpr.md#page-43]; the controller must inform recipients of the erasure
[gdpr.md#page-44].

Evidence
  - knowledge/gdpr.md#page-43: Article 17 ... the controller shall have the obligation to erase ...
  - knowledge/gdpr.md#page-44: Article 19 ... communicate any rectification or erasure ...
Relations
  - gdpr -> data-retention-policy (citation)
  - data-retention-policy -> gdpr (citation)

How the team uses it. Product asks the Oracle before drafting a governed spec and cites the evidence in references:. Engineer reads the cited pages before implementing. Reviewer opens every citation, checks the implementation against the wording, and asks the Oracle whether an uncited document contradicts the spec: a contradiction is a fail. covener status warns when a reference points to a file that does not exist.

# specs/data-erasure.md
references: [knowledge/gdpr.md#page-43, knowledge/data-retention-policy.md#page-2]

Models: claude-sonnet-5 for extraction and answers, voyage-4-large for retrieval, both multilingual; the Oracle answers in the language of the question. Override with COVENER_LLM_MODEL and COVENER_EMBED_MODEL (voyage-law-2 is tuned for legal text). Keys (ANTHROPIC_API_KEY, VOYAGE_API_KEY) live in the environment, never in the repository. Indexing costs cents to a few dollars per hundred documents. The graph lives in .covener/knowledge/ (ignored by git, rebuildable); the Markdown and both index files are committed and reviewable.

Tools: CLI and MCP

The same implementation has two doors: the CLI for people and CI, and a local MCP server for the model. AGENTS.md tells the agents when to use which.

Level For Registered in Covener
CLI people, CI installed covener init, status, knowledge build, knowledge ask, serve
Instructions the model, at session start AGENTS.md, agents/*.md when to use each tool or command
MCP tools the model, any time .mcp.json, .cursor/mcp.json, written by init status, search_knowledge, list_knowledge_sources
Chat commands you, as shortcuts .claude/commands, .cursor/commands roadmap
pip install "covener[mcp]"     # included in covener[oracle]
covener init                   # registers the server; re-run after installing the extra

Claude Code reads .mcp.json (project scope, committed) and asks you to accept the server once. Cursor reads .cursor/mcp.json; enable it under Settings, MCP. Codex, Windsurf and others: point their MCP config at covener serve (stdio). The server exposes nothing that changes the repository.

The agents

Five roles with explicit boundaries, one Markdown file each in agents/, in the front matter format Claude Code and Cursor read natively. init links .claude/agents and .cursor/agents to that folder, so there is exactly one copy of each agent and editing it is editing the file.

Role Owns Never
product vision, impact analysis, specs, bug intake, evidence in references: code, approving its own specs
planner tasks, sprint scope, briefs, feedback requests, closing and archiving code, writing ## Feedback, marking done without approval
engineer implementation, fixes (regression test first), tasks, infrastructure editing specs, expanding scope
qa tests from acceptance criteria, acceptance verification, regressions changing application code
reviewer architecture, security, quality, compliance against citations; also on pull requests editing anything

The prompts follow current Anthropic and OpenAI guidance for frontier coding models: clear objective, just-in-time reads, explicit outputs, explicit human gates, no permission-seeking for work already requested. The model is a property of the agent (model: claude-sonnet-5 or inherit); defaults are a fast model for QA, a balanced one for the engineer, a strong one for the rest.

Extending the team. Roles are the contract; agents are files. Rename or disable a role in .covener/config.yaml; add an agent by adding a file (a frontend-engineer.md next to engineer.md is visible to every tool through the links). For stack-specific know-how, prefer skills over more roles: Claude Code and Cursor load a skill only when the task needs it, so one engineer with frontend, backend and infra skills stays cheaper and more consistent than three engineers with three prompts. Keep agents/ for boundaries and skills/ for expertise.

# .covener/config.yaml
agents:
  reviewer: security-reviewer   # agents/security-reviewer.md
  qa: off
tools: [claude, cursor]

Install

pip install covener            # or: uv tool install covener / pipx install covener
covener init                   # --tools claude,cursor  --dry-run  --install-agents
covener status                 # --json  --verbose  --strict
covener knowledge build        # --no-graph  --dry-run        (covener[knowledge] or [oracle])
covener knowledge ask "..."    # --json
covener serve                  # MCP over stdio               (covener[mcp])

Python 3.10+. One runtime dependency (PyYAML). No network. -C <dir> works on every command.

Existing files are safe. An existing AGENTS.md keeps its content and gets the Covener block between <!-- covener:start --> and <!-- covener:end -->; an existing CLAUDE.md gets an @AGENTS.md import; existing .claude/agents/ or .cursor/agents/ directories keep their files and get per-agent links; a legacy .cursorrules is reported.

Windows. Links become directory junctions when symlinks are not permitted. Clone with git config core.symlinks true, or run covener init after cloning to repair the links.

CI.

- run: pip install covener && covener status --strict

What Covener does not do

No project-management UI. No orchestration engine. No MCP requirement. No autonomous deployment. No user stories, requirement layers or profiles. Updating the package never touches your files. The repository works without the package installed.

FAQ

Do I need MCP, hooks or a server? No. The repository provides the context. covener serve is optional and runs locally over stdio, for IDEs that prefer tools to shell commands.

Can I use my own agents or skills? Yes. Drop a file in agents/; it is visible to every tool through the links. Rename or disable roles in .covener/config.yaml. Put stack-specific expertise in skills rather than in more roles.

What if I uninstall the package? Everything keeps working. The method is in the files; covener status is only a checker.

Does it work with Codex, Copilot or Windsurf? They read AGENTS.md, so the instructions and the layout work. Agent files are linked for Claude Code and Cursor today; other adapters are a few lines each.

Why not just a good CLAUDE.md? A CLAUDE.md tells an agent how to behave. It does not keep decisions between sessions, does not separate what must be true from what happened, cannot stop an agent from calling something done, and cannot cite a regulation with a page number. Covener adds exactly those four things.

Roadmap

  • Codex and Windsurf link adapters; skills/ linked like agents/.
  • /covener chat commands for approving and requesting changes from the conversation.
  • A reviewer GitHub Action that posts the ## Review entry on pull requests.
  • Knowledge Oracle: DOCX and HTML sources, more citation jurisdictions, compliance reports per spec.

Contributing

Issues and pull requests are welcome; see CONTRIBUTING.md.

pip install -e ".[dev]" && pytest && ruff check . && mypy

Standards used: AGENTS.md, Claude Code subagents and CLAUDE.md imports, Cursor subagents and rules; conventions from OpenSpec, spec-kit and Kiro; LightRAG and Voyage AI for the Oracle.

License

MIT. Built by @ajmorenodelarosa.

Release files for covener 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for covener 0.1.0
File Size Uploaded
covener-0.1.0.tar.gz 59.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for covener 0.1.0
File Interpreter ABI Platform
covener-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 125.0 kB

Release files / covener-0.1.0.tar.gz

Download URL covener-0.1.0.tar.gz
Size 59.5 kB
Tags Source
SHA-256 checksum
How to use checksums
370e0e1b76a7a09f1349f94bbd3b0bcb3e965deeee947cc0b57795cd4253b920
BLAKE2b-256 checksum
How to use checksums
3c9c6edbb9b64817895e5d6a746edce5d11a4cbd54fcee211f5f640cc49853a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

Release files / covener-0.1.0-py3-none-any.whl

Download URL covener-0.1.0-py3-none-any.whl
Size 65.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7429c33117587afeef7cabe482075d413f478a9d028ab705c8fb519dcdc7faf4
BLAKE2b-256 checksum
How to use checksums
15d0796663fece73a16a6932215cee083f827ea3ffb05c53c01e296cb952a232
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

Release history Release notifications | RSS feed

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page