Thank you for your interest in contributing to Ouroboros! This guide covers everything you need to get started.
- Quick Setup
- Development Workflow
- Review Boundary Contract
- Ways to Contribute
- Development Environment
- Code Style Guide
- Commit Message Convention
- Release Maintenance
- Project Structure
- Key Patterns
- Documentation Coverage
- CLI Commands → Doc Mapping
- Orchestrator → Doc Mapping
- Capability Graph → Doc Mapping
- Configuration → Doc Mapping
- Evaluation Pipeline → Doc Mapping
- TUI Source → Doc Mapping
- Skills / Plugin → Doc Mapping
- New Command or Flag Checklist
- New Runtime Backend Checklist
- Documentation Issue Severity Rubric
- Documentation Decay Detection
- Contributor Docs
- Code of Conduct
First time? See Getting Started for full install options (Claude Code plugin, pip, or from source).
Dev setup (from source):
git clone https://github.com/Q00/ouroboros && cd ouroboros
uv sync
uv run ouroboros --version # verify
uv run pytest tests/unit/ -q # run tests
uv syncis not the whole loop. The checked-in.mcp.jsonpoints at the published PyPI package, so a clone that you edit is not the code your client runs. Before your first change, read The Development Loop — it covers pointing the tooling at your working tree, where config and state live, and the fastest way to verify each kind of change.
Requirements: Python >= 3.12, uv. LiteLLM-bearing profiles support Python 3.12-3.13.
This repository's .python-version defaults source checkouts to stable Python 3.14 for local development. Core and non-LiteLLM contributor environments support Python 3.12-3.14. LiteLLM-bearing environments, including --all-extras, support Python 3.12-3.13; examples prefer Python 3.13 without making it the minimum.
uv sync --python 3.13 # base dependencies on the preferred current interpreter
uv sync --python 3.13 --all-extras # include optional backends/extras, including LiteLLM
uv run --python 3.13 ouroboros --version
uv run --python 3.13 pytest tests/unit/ -q- Check GitHub Issues for open tasks
- For new features, open an issue first to discuss the approach
- Label your issue with appropriate tags:
bug,enhancement,documentation, etc. - Treat actionable issues as structured work artifacts, not casual notes. See Issue Quality Policy.
git checkout -b feat/your-feature # for new features
git checkout -b fix/your-bugfix # for bug fixes
git checkout -b docs/your-changes # for documentation- Follow the project structure (see Architecture for Contributors)
- Use frozen dataclasses or Pydantic models for data
- Use the
Result[T, E]type instead of exceptions for expected failures - Write tests alongside your code
# Full unit test suite
uv run pytest tests/unit/ -v
# Specific module
uv run pytest tests/unit/evaluation/ -v
# With coverage
uv run pytest tests/unit/ --cov=src/ouroboros --cov-report=term-missingSee Testing Guide for more details.
# Check
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
# Auto-fix
uv run ruff check --fix src/ tests/
uv run ruff format src/ tests/
# Type check
uv run mypy src/ouroboros
# ooo auto product boundary check (Q00/ouroboros#725)
python3 scripts/check-auto-boundary.pyThe last command enforces that the ooo auto core source files do
not introduce domain-specific keywords (github, pull_request,
jira, slack, …). Domain workflows belong in UserLevel plugins,
not in ooo auto. The CI workflow ooo-auto-boundary runs the same
check on every PR.
Coverage is the union of (a) every *.py under src/ouroboros/auto/
and (b) src/ouroboros/cli/commands/auto.py, so any new module added
under the auto package is scanned automatically. Forbidden keywords
are matched as case-insensitive substrings, which catches realistic
identifier forms such as GitHubClient, github_client, JiraIssue,
or SlackNotifier. The script also fails loud if a load-bearing
anchor file (declared in ANCHOR_FILES inside the script) is missing,
so a refactor that renames or removes one of those files cannot
silently strip enforcement coverage — update ANCHOR_FILES in the
same PR.
If a forbidden keyword is genuinely necessary on a line (rare),
append # domain-keyword-allowed: <reason> and include rationale in
the PR description.
main is protected — direct pushes are rejected for everyone, owner included.
Every change lands through a squash-merged PR.
- Write a clear PR description explaining what and why
- Include the structured boundary required by Review Boundary Contract
- Reference the related issue (e.g.,
Closes #123, or a plainRefs #123) — theIssue link presentgate requires it - Ensure all tests pass and linting is clean
- Wait for code review and address feedback
Four checks are required to merge (Ruff Lint, MyPy Type Check,
Test Python 3.12, Bridge TypeScript), and several more fire conditionally
on the paths you touched. Every gate, its local reproduction command, and its
legitimate escape hatch are documented in
CI Gates and Branch Protection.
ouroboros-agent[bot] ties each review verdict to the commit it checked. It
grades your PR against the linked issue's requirements and reproduces the
defects it reports. Confirm the applicable verdict belongs to the current head,
then read
Review Conventions before your first
push — most review rounds are lost to objections you can preempt.
Before creating a release tag, synchronize every version-bearing plugin artifact in the release commit:
python scripts/sync-plugin-version.py --write --version 0.50.7
python scripts/sync-plugin-version.py --require-canonical --version 0.50.7
git diff --checkThe metadata change must be committed before the tag exists, and because main
is protected it can only get there through a PR. Squash-merging mints a new
commit SHA, so create v0.50.7 on the merged main commit — tagging the
pre-merge commit produces a tag that points at a commit main never contained:
git checkout main && git pull origin main --ff-only
git tag -a v0.50.7 -m "Release v0.50.7" && git push origin v0.50.7The tag-triggered release workflow repeats the read-only check and refuses to build when the tag version and tracked metadata differ. It also owns the PyPI publish — never run uv publish locally.
The full sequence, including the release-notes convention, is in CI Gates and Branch Protection.
Review speed depends on whether the PR boundary is explicit. A focused PR gives contributors, review bots, and maintainers the same contract to evaluate. Every PR that changes code, documentation, or operational guidance MUST define the following before implementation and keep it current in the PR description:
| Boundary field | Required declaration |
|---|---|
| User problem | One concrete user problem the PR solves |
| Promised contract | Supported inputs, preconditions, execution conditions, observable behavior, and invariants |
| Implementation boundary | Existing subsystems and components changed, data or security boundaries crossed, and the current owner |
| Non-goals | Unsupported inputs or conditions and related risks intentionally excluded from this PR |
| Evidence | Reproduction steps or tests that prove each promised behavior under the declared conditions |
The declared boundary narrows implementation scope; it MUST NOT waive an existing public or repository contract, an approved issue or RFC requirement, or a maintainer decision. If a proposed non-goal conflicts with one of those baseline obligations, the contributor MUST ask the maintainer to approve a scope change or revisit the RFC before implementation.
Do not begin from an unsupported solution assumption and then absorb every lifecycle, rollback, concurrency, or authority concern that follows from it. If implementation reveals a new subsystem or ownership boundary, stop and let a maintainer decide whether the PR expands, splits, or returns to RFC discussion.
- Contributor: declares the contract and boundary, keeps the implementation inside them, and does not silently widen either while addressing review feedback.
- Review bot or reviewer: blocks only direct contract violations and immediate user-data or security risks. A valid risk outside the declared boundary becomes a follow-up only when it has a named owner.
- Maintainer: decides whether a proposed subsystem, ownership change, or scope expansion belongs in the current PR, a follow-up PR, or a revised RFC.
Every finding MUST answer these questions with evidence:
- Does the finding reproduce under the inputs and execution conditions promised by the PR?
- Does the finding violate the contract promised by the PR?
- Would resolving it require a new subsystem or a new ownership boundary?
- Can the original user problem be solved without the subsystem introduced by the PR?
- If the scope is split, does an immediate user-data or security risk remain?
Apply outcomes in this order:
| Evidence | Review outcome |
|---|---|
| Questions 1 and 2 are yes | Changes Requested. The finding is reproducible inside the promised boundary and breaks the PR contract. |
| Question 5 is yes, but resolving the direct risk does not require a new subsystem or owner | Changes Requested. Immediate user-data and security risks introduced by the PR are blockers. |
| Questions 3 and 5 are yes | Stop the PR and revisit the RFC with a maintainer. The safe fix requires scope or ownership that the current PR cannot decide. |
| Questions 3 and 4 are yes, and question 5 is no | Owned follow-up. Create or link a follow-up issue or PR with a named owner; it is not a blocker once the current contract is satisfied. |
| The finding does not reproduce inside the declared conditions, or question 2 is no | Not a blocker. Record it only as an owned follow-up when it is independently valid and actionable. |
Severity alone does not decide whether a review comment blocks a PR. Boundary, contract impact, and immediate risk do.
flowchart LR
A[Small user problem] --> B[Unsupported solution assumption]
B --> C[New lifecycle ownership]
C --> D[Rollback requirement]
C --> E[Concurrency requirement]
C --> F[Filesystem authority requirement]
D --> G[PR scope expands]
E --> G
F --> G
G --> H[New review blockers repeat]
flowchart LR
A[Small user problem] --> B[Declare inputs, conditions, and contract]
B --> C[Declare subsystem, ownership, and non-goals]
C --> D[Implement the smallest contract-satisfying change]
D --> E[Prove behavior under declared conditions]
E --> F{Five-question review}
F -->|Q1 + Q2| G[Changes Requested]
F -->|Q3 + Q4 and not Q5| H[Owned follow-up]
F -->|Q3 + Q5| I[Stop and revisit RFC]
Found a bug? Please open an issue with:
- Clear title: Summarize the bug
- Impact: Explain what is blocked or broken
- Description: Steps to reproduce, expected vs actual behavior
- Acceptance criteria: State what will be true once fixed
- Environment: Python version, OS,
uv run ouroboros --version - Logs: Relevant error messages or stack traces
See the Issue Quality Policy for the full bug issue standard.
## Summary
[What is broken]
## Impact
[Why this matters]
## Steps to Reproduce
1. Run `ooo interview "test"`
2. Enter X when prompted
3. Observe error
## Expected Behavior
[What should happen]
## Actual Behavior
[What happens instead]
## Acceptance Criteria for Fix
- [ ] [Condition that proves the bug is fixed]
## Environment
- Python: 3.12+
- Ouroboros: v0.9.0
- OS: macOS 15.2
## Logs
```
[paste error output]
```Have an idea? Open an issue only when it is structured enough to act on.
Feature issues should be written in a PRD-lite format with:
- Problem: What problem exists today?
- Why now: Why is this worth doing now?
- User / persona: Who is affected?
- Current vs desired behavior: What changes?
- Constraints and non-goals: What boundaries matter?
- Acceptance criteria: What would make this done?
If the idea is still fuzzy, use GitHub Discussions or Discord first, then turn it into a structured issue.
See the Issue Quality Policy for the full feature issue standard.
When submitting a PR:
- Boundary declared: State the user problem, promised contract, implementation boundary, non-goals, and evidence required by Review Boundary Contract
- Small, focused changes: One logical change per PR
- Tests included: New observable behavior needs contract-level tests
- Docs updated: Update relevant documentation
- Clean history: Squash commits before submitting if needed
Help improve docs by:
- Fixing typos and unclear explanations
- Adding examples to existing features
- Translating documentation (if you speak multiple languages)
- Creating tutorials or guides
When reporting or fixing a documentation problem, apply the Documentation Issue Severity Rubric: use the existing documentation label and add a **Severity:** critical/high/medium/low line so maintainers can triage and prioritise correctly.
Review open PRs using the five-question review rubric:
- Request changes only for contract violations or immediate user-data or security risks
- Move valid out-of-boundary risks to an owned follow-up instead of expanding the PR
- Escalate new subsystem or ownership requirements to a maintainer when they also carry immediate risk
- Suggest non-blocking improvements without presenting them as merge requirements
# Copy environment template
cp .env.example .env
# Edit .env with your API keys
# Required: ANTHROPIC_API_KEY or OPENAI_API_KEY# Unit tests (fast, no network)
uv run pytest tests/unit/ -v
# Integration tests (requires MCP server)
uv run pytest tests/integration/ -v
# E2E tests (full system)
uv run pytest tests/e2e/ -v
# Skip slow tests for fast iteration
uv run pytest tests/ --ignore=tests/unit/mcp --ignore=tests/integration/mcp --ignore=tests/e2e# TUI tests
uv run pytest tests/ --ignore=tests/unit/mcp --ignore=tests/integration/mcp --ignore=tests/e2e -k "tui or tree"
# Evaluation pipeline
uv run pytest tests/unit/evaluation/ -v
# Orchestrator
uv run pytest tests/unit/orchestrator/ -v# Install pre-commit hooks
uv run pre-commit install
# Hooks run automatically on git commit
# Manual run:
uv run pre-commit run --all-files- Line length: 100 characters
- Quotes: Double quotes for strings
- Indentation: 4 spaces (no tabs)
- Tool: Ruff (auto-formats on save)
# Format code
uv run ruff format src/ tests/- Tool: mypy (Python 3.12 target)
- Missing imports: Ignored (
ignore_missing_imports = true) - See
pyproject.toml [tool.mypy]for the full configuration
# Type check
uv run mypy src/ouroborosRuff enforces:
- Pycodestyle (E, W)
- Pyflakes (F)
- isort (I)
- flake8-bugbear (B)
- flake8-comprehensions (C4)
- pyupgrade (UP)
- flake8-unused-arguments (ARG)
- flake8-simplify (SIM)
# Lint
uv run ruff check src/ tests/- Minimum supported: Python 3.12
- Test matrix: Python 3.12, 3.13, and 3.14 for core/non-LiteLLM profiles; Python 3.12 and 3.13 for LiteLLM-bearing profiles
- Source-checkout default:
.python-versionselects stable Python 3.14 for local development - Use
uv sync --python 3.13 --all-extrasbeforeuv run --python 3.13 ...for current LiteLLM-bearing contributor environments. Python 3.12 remains supported for lower-bound validation. - Use modern Python features (type unions
|, match statements, etc.)
We follow a simplified semantic commit format:
<type>(<scope>): <subject>
[optional body]
| Type | When to Use |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation changes |
chore |
Build, tooling, dependency updates |
refactor |
Code refactoring (no behavior change) |
test |
Test changes |
perf |
Performance improvements |
Common scopes: cli, tui, evaluation, orchestrator, mcp, plugin, core
# Feature
git commit -m "feat(evaluation): add consensus trigger for seed drift > 0.3"
# Bug fix
git commit -m "fix(tui): resolve crash when AC tree is empty"
# Docs
git commit -m "docs: update CLI reference with new flags"
# Refactor
git commit -m "refactor(orchestrator): extract parallel execution to separate module"For complex changes, add a body explaining the why:
git commit -m "feat(evaluation): add stage 3 consensus trigger
This enables multi-model voting when:
- Seed is modified during execution
- Ontology evolves significantly
- Drift score exceeds 0.3
Closes #42"src/ouroboros/
core/ # Foundation: Result type, Seed, errors, context
bigbang/ # Phase 0: Interview and seed generation
routing/ # Phase 1: PAL Router (model tier selection)
execution/ # Phase 2: Double Diamond execution
resilience/ # Phase 3: Stagnation detection, lateral thinking
evaluation/ # Phase 4: Three-stage evaluation pipeline
secondary/ # Phase 5: TODO registry
orchestrator/ # Runtime abstraction and orchestration
providers/ # LLM provider adapters (LiteLLM)
persistence/ # Event sourcing, checkpoints
tui/ # Terminal UI (Textual)
cli/ # CLI commands (Typer)
mcp/ # Model Context Protocol server/client
config/ # Configuration management
tests/
unit/ # Fast, isolated tests (no network, no DB)
integration/ # Tests with real dependencies
e2e/ # End-to-end CLI tests
fixtures/ # Shared test data
.claude-plugin/ # Plugin definitions (skills, agents, hooks)
agents/ # Custom agent prompts
skills/ # Plugin skill definitions
hooks/ # Plugin hooks
Detailed explanations: Key Patterns
from ouroboros.core.types import Result
def validate_score(score: float) -> Result[float, ValidationError]:
if 0.0 <= score <= 1.0:
return Result.ok(score)
return Result.err(ValidationError(f"Score {score} out of range"))
# Consume
result = validate_score(0.85)
if result.is_ok:
process(result.value)
else:
log_error(result.error.message)from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class CheckResult:
check_type: CheckType
passed: bool
message: str# Events are immutable and append-only
event = create_stage1_completed_event(execution_id="exec_123", ...)
await event_store.append(event)from typing import Protocol
@runtime_checkable
class ExecutionStrategy(Protocol):
def get_tools(self) -> list[str]: ...This section defines which documentation files must be updated when a specific source file or code path changes. Reviewers should verify that all relevant doc files are updated before merging any PR that touches the listed source paths.
The authoritative implementation directories are:
| Directory | What it controls |
|---|---|
src/ouroboros/cli/commands/ |
All user-facing CLI commands and flags |
src/ouroboros/orchestrator/ |
Orchestrator runtime, session management, parallel execution |
src/ouroboros/config/ |
Configuration schema and defaults |
Any change to a file under src/ouroboros/cli/commands/ requires reviewing and updating the corresponding documentation:
Flags covered: --resume, --state-dir, --orchestrator, --runtime, --llm-backend, --debug
Must update:
docs/cli-reference.md—initcommand section (flags, examples)docs/getting-started.md— interview workflow descriptiondocs/getting-started.md— introductoryooo init/ouroboros initexamplesdocs/getting-started.md— onboarding flow
Also check:
docs/runtime-guides/claude-code.mdanddocs/runtime-guides/codex.md— if--orchestratoror--runtimebehavior changes
Flags covered: --orchestrator/--no-orchestrator, --resume, --mcp-config, --mcp-tool-prefix, --dry-run, --debug, --sequential, --runtime, --no-qa
Must update:
docs/cli-reference.md—runcommand section (flags, examples, defaults)docs/getting-started.md— execution workflow descriptiondocs/getting-started.md—ooo run/ouroboros runexamples
Also check:
docs/runtime-guides/claude-code.mdanddocs/runtime-guides/codex.md— if--runtimesemantics changedocs/runtime-capability-matrix.md— if a runtime backend is added or removed
Subcommands: show, backend, init, set, validate
config subcommands are implemented command surfaces. Keep their behavior aligned with the authoritative docs/cli-reference.md config section.
Must update:
docs/cli-reference.md—configcommand sectiondocs/getting-started.md— configuration management section
Implemented subcommands: auto, run
Placeholder subcommands on main: executions, execution, health
Note: Only the placeholder subcommands listed above should be marked
[Placeholder — not yet implemented]in docs until real persistence or health-check behavior is wired in. Do not mark implementedstatussubcommands as placeholders.
Must update:
docs/cli-reference.md—statuscommand section
Must update:
docs/cli-reference.md—mcpcommand sectiondocs/api/mcp.md— MCP server/client configuration
Must update:
docs/cli-reference.md—setupcommand sectiondocs/getting-started.md— setup step in onboarding
Must update:
docs/cli-reference.md—tuicommand sectiondocs/guides/tui-usage.md— TUI usage guide
Must update:
docs/cli-reference.md—cancelcommand section
Changes under src/ouroboros/orchestrator/ affect runtime behavior documentation:
| Source file | Must update |
|---|---|
runtime_factory.py |
docs/runtime-capability-matrix.md, docs/runtime-guides/claude-code.md, docs/runtime-guides/codex.md — if a backend is added, removed, or changes its NotImplementedError status |
adapter.py (ClaudeAgentAdapter) |
docs/runtime-guides/claude-code.md — permission modes, session flow |
codex_cli_runtime.py (CodexCliRuntime) |
docs/runtime-guides/codex.md — permission modes, --runtime codex behavior |
opencode_runtime.py (OpenCodeRuntime) |
docs/runtime-capability-matrix.md, docs/runtime-guides/opencode.md — permission modes, --runtime opencode behavior |
runner.py (OrchestratorRunner) |
docs/architecture.md — orchestration lifecycle; docs/getting-started.md — session ID output, resume flow |
parallel_executor.py |
docs/cli-reference.md — --sequential flag behavior; docs/architecture.md — parallel execution strategy |
coordinator.py (LevelCoordinator) |
docs/architecture.md — inter-level conflict resolution and coordinator review gate |
session.py |
docs/cli-reference.md — session ID format, resume semantics |
workflow_state.py |
docs/architecture.md — AC state machine, ActivityType values; docs/guides/tui-usage.md — if activity display changes |
dependency_analyzer.py |
docs/architecture.md — dependency level computation description |
execution_strategy.py |
docs/architecture.md — execution strategy types (code, research, analysis); docs/guides/seed-authoring.md if strategy selection is user-facing |
mcp_config.py / mcp_tools.py |
docs/api/mcp.md — MCP config YAML schema |
command_dispatcher.py |
docs/architecture.md — command dispatch model |
level_context.py |
docs/architecture.md — level context description |
Runtime availability rule: If create_agent_runtime() raises NotImplementedError for a backend, that backend must not appear in docs as a working option. Runtime backend availability is registry-owned; when runtime_backend_choices() or setup support changes, update the runtime capability matrix, setup docs, and per-runtime guide/gap documentation together.
Changes that add, remove, rename, or reinterpret a skill execution capability must keep the capability graph and generated runtime instructions in sync.
| Source path | Must update |
|---|---|
skills/*/SKILL.md |
docs/runtime-guides/skill-capability-guides.md if required_capabilities changes or the skill depends on a new abstract runtime action |
src/ouroboros/backends/capabilities.py |
docs/runtime-guides/skill-capability-guides.md; renderer/package snapshot tests for Codex, Hermes, Claude, and setup-owned runtime artifacts |
src/ouroboros/runtime_instruction_artifacts.py |
docs/runtime-guides/skill-capability-guides.md; docs/cli-reference.md setup section if install paths or managed surfaces change |
Packaged guide snapshots such as .claude-plugin/SKILL_CAPABILITY_GUIDE.md |
Update when render_backend_skill_capability_guide(<backend>) output changes |
Before submitting a capability graph PR, run the checklist in
docs/runtime-guides/skill-capability-guides.md.
Changes under src/ouroboros/config/ affect configuration reference documentation:
| Source class | Config key path | Must update |
|---|---|---|
OrchestratorConfig |
orchestrator.* |
docs/cli-reference.md — --runtime flag; README.md config snippet |
LLMConfig |
llm.* |
docs/architecture.md, docs/api/core.md — model defaults |
EconomicsConfig / TierConfig |
economics.* |
docs/architecture.md — tier descriptions |
ClarificationConfig |
clarification.* |
docs/guides/seed-authoring.md — ambiguity threshold |
ExecutionConfig |
execution.* |
docs/architecture.md — iteration limits |
ResilienceConfig |
resilience.* |
docs/architecture.md — stagnation/lateral thinking |
EvaluationConfig |
evaluation.* |
docs/architecture.md — three-stage evaluation |
ConsensusConfig |
consensus.* |
docs/architecture.md — Stage 3 consensus |
DriftConfig |
drift.* |
docs/architecture.md — drift monitoring thresholds |
PersistenceConfig |
persistence.* |
docs/getting-started.md — database path |
When a new config key is added to any model class, check README.md and docs/getting-started.md for any sample config.yaml snippets that may need updating.
config/loader.py: If the config file search path, environment variable names (e.g., OUROBOROS_CONFIG), or YAML loading logic change, update:
docs/getting-started.md— config file location instructionsdocs/config-reference.md— environment variable overrides sectionREADME.md— any config bootstrap snippet
Changes under src/ouroboros/evaluation/ affect:
| Source file | Must update |
|---|---|
pipeline.py |
docs/architecture.md — Stage descriptions (Stage 1 Mechanical, Stage 2 Semantic, Stage 3 Consensus); docs/guides/evaluation-pipeline.md |
trigger.py |
docs/architecture.md — consensus trigger thresholds; docs/guides/evaluation-pipeline.md — when Stage 3 is invoked |
mechanical.py |
docs/guides/evaluation-pipeline.md — Stage 1 check list |
models.py |
docs/api/core.md — evaluation result types |
artifact_collector.py |
docs/architecture.md — artifact collection description |
Changes under src/ouroboros/tui/ that alter the visible interface or user interactions affect:
| Source path | Must update |
|---|---|
screens/dashboard_v3.py |
docs/guides/tui-usage.md — dashboard layout, key bindings |
widgets/ac_tree.py |
docs/guides/tui-usage.md — AC tree display; docs/architecture.md if AC state rendering changes |
widgets/drift_meter.py |
docs/guides/tui-usage.md — drift meter description |
widgets/phase_progress.py |
docs/guides/tui-usage.md — phase progress bar description |
screens/lineage_selector.py / lineage_detail.py |
docs/guides/tui-usage.md — lineage navigation section |
Any new screen added to screens/ |
docs/guides/tui-usage.md — add a new section; docs/cli-reference.md if a new key binding or tui sub-command is introduced |
Note: TUI key bindings visible in
screens/*.py(BINDINGS = [...]) are user-facing and must be listed indocs/guides/tui-usage.md.
Changes under skills/ (YAML skill definitions used by Claude and Codex) or src/ouroboros/plugin/ affect:
| Source path | Must update |
|---|---|
skills/codex.md |
docs/runtime-guides/codex.md — if skill instructions change |
skills/*.yaml, skills/*/SKILL.md, or src/ouroboros/agents/*.md |
docs/ guide that describes the affected skill/agent behaviour; docs/runtime-guides/skill-capability-guides.md if required capabilities change |
src/ouroboros/plugin/skills/executor.py |
docs/architecture.md — skill execution model |
src/ouroboros/plugin/agents/registry.py |
docs/architecture.md — agent registry; docs/runtime-capability-matrix.md if supported agents change per runtime |
Note:
skills/YAML files are a user-visible configuration surface. Any new skill must be listed in the relevant runtime guide before the PR is merged.
When adding a new CLI command or flag, use this checklist before submitting a PR:
-
docs/cli-reference.mdupdated with the new command/flag, its type, default, and at least one example -
docs/getting-started.mdupdated if the flag changes workflow behavior -
docs/getting-started.mdreviewed — update if a common flow is affected -
README.mdreviewed — update the quick-start snippet if the new command changes day-1 usage - If the feature is a placeholder/stub: docs must include
> **Note**: This feature is not yet implemented.
When adding support for a new runtime backend (e.g., new entry in AgentRuntimeBackend enum):
-
docs/runtime-capability-matrix.md— add a new row -
docs/runtime-guides/— create a new guide file<runtime>.md -
docs/cli-reference.md— add the backend name to--runtimeoption description -
docs/getting-started.md— update prerequisites section - Remove any
[Not yet available]orNotImplementedErrormarkers once fully shipped
When a reviewer or contributor identifies a documentation problem, classify it by severity for urgency and triage. Apply the Review Boundary Contract first: severity does not independently decide whether a PR comment blocks.
| Severity | Issue marker | Definition | User Impact | Merge Policy |
|---|---|---|---|---|
| Critical | documentation label + **Severity:** critical in the issue/PR body |
The documented information is factually wrong: a command, flag, path, or option described in the docs does not exist or behaves differently than described. | User follows the docs and fails — the command errors, the path is missing, or the flag is rejected. | Changes Requested when it reproduces under the PR's declared conditions and violates its contract, or when it creates immediate user-data/security risk. Otherwise use an owned follow-up. |
| High | documentation label + **Severity:** high in the issue/PR body |
The documentation is misleading: information is technically present but framed in a way that causes confusion, omits a required step, or implies an unimplemented capability. | User follows the docs and proceeds incorrectly — they finish the step but reach a wrong state or have false expectations. | Apply the boundary and contract test. Do not block by severity alone; link a named owner for valid out-of-boundary follow-up. |
| Medium | documentation label + **Severity:** medium in the issue/PR body |
The documentation has inconsistent style or terminology or an ambiguity that does not make the documented path incorrect. | User is mildly confused by inconsistency but can still succeed. | Non-blocking. Can merge; assign an owner when follow-up is needed. |
| Low | documentation label + **Severity:** low in the issue/PR body |
The documentation has a minor cosmetic gap or an edge case missing where another safe documented path exists. | User experiences minor friction at most; no incorrect outcome. | Non-blocking. Address opportunistically. |
| Example | Severity | Why |
|---|---|---|
docs/cli-reference.md lists --foo flag that does not exist in the source |
Critical | User runs the command and gets "no such option" |
docs/getting-started.md omits uv sync before uv run ouroboros |
Critical | User's first command fails with ModuleNotFoundError |
opencode listed as a working --runtime value without [Not yet available] |
High | User configures --runtime opencode and gets a confusing NotImplementedError |
OUROBOROS_AGENT_RUNTIME written as OUROBOROS_RUNTIME_BACKEND in one file |
High | User sets the wrong env var and the setting silently has no effect |
Docs recommend export OUROBOROS_MAX_PARALLEL=2 but the variable does not exist |
High | User sets the variable; parallelism is not actually limited (false expectation) |
A major config section (economics:, evaluation:) entirely absent from docs |
High | User who needs non-default configuration for that section has no documentation to follow; they omit a required step |
claude-code vs claude_code used interchangeably across different docs files |
Medium | Minor confusion; both forms resolve correctly in the CLI |
| Section headings use Title Case in some files and Sentence case in others | Medium | Style inconsistency; no functional impact |
A minor config section (drift: thresholds) absent from docs; defaults are safe |
Medium | User can operate with defaults; gap only matters for advanced tuning |
An alternative invocation (ouroboros tui bare vs ouroboros tui monitor) absent |
Low | User can use the documented form; no incorrect outcome |
- When reviewing a docs-affecting PR, scan each changed file against the Documentation Decay Detection checks below and classify any finding using the table above.
- When filing a GitHub issue for a documentation problem, add the existing
documentationlabel and include a body line such as**Severity:** critical,**Severity:** high,**Severity:** medium, or**Severity:** low. - When writing a PR description that fixes a documentation problem, state the severity in the PR summary (e.g., "Fixes documentation severity: critical —
--resumeflag was listed with wrong default"). - Apply the Review Boundary Contract before severity: direct contract violations and immediate user-data/security risks require changes; valid risks outside the boundary require a linked follow-up with a named owner; new subsystem or ownership plus immediate risk requires maintainer/RFC escalation.
- Track open documentation findings in GitHub issues with the
documentationlabel; do not rely on a separate register file unless one is introduced and kept current.
Current open documentation issues are tracked with the
documentationlabel.
To catch doc drift during development, reviewers should check:
- Flag parity: Run
ouroboros <cmd> --helpand compare every flag todocs/cli-reference.md. Any mismatch is a documentation bug. - Placeholder honesty: If a command's implementation body is
# Placeholder implementation, the corresponding doc entry must say[Placeholder — not yet implemented]. - Runtime parity:
claude,codex, andopencodeare all fully-implemented backends. Any doc that lists a backend as available must have a corresponding runtime guide indocs/runtime-guides/. - Config key drift: After any change to
src/ouroboros/config/models.py, grep for the changed key name acrossdocs/to find stale references. - TUI key bindings: If
screens/*.pyBINDINGSarrays change, verifydocs/guides/tui-usage.mdreflects the new keys. - Skills registry drift: If a new
skills/*.yamlfile is added, check thatdocs/runtime-guides/codex.mdor the relevant guide mentions it. - Orchestrator new file: If a new
.pyfile is added tosrc/ouroboros/orchestrator/, add it to the Orchestrator → Doc Mapping table above before the PR is merged.
# Quick doc-drift scan: compare CLI help output with cli-reference.md
uv run ouroboros init --help
uv run ouroboros run workflow --help
uv run ouroboros config --help
uv run ouroboros status --help
# Find stale config key references
grep -r "opencode_permission_mode\|runtime_backend\|codex_cli_path" docs/
# Find any 'opencode' reference in docs that lacks the [Not yet available] marker
grep -rn "opencode" docs/ | grep -v "Not yet available" | grep -v "semantic-link-rot" | grep -v "cli-audit"
# Check TUI key bindings are documented
grep -rn "BINDINGS" src/ouroboros/tui/screens/ | grep -v "__pycache__"
# List skill YAML files to cross-check against runtime guides
ls skills/*.yaml 2>/dev/null || echo "No skill YAML files found"- Architecture Overview - How the system fits together
- Testing Guide - How to write and run tests
- The Development Loop - Run your own code: local MCP, config, state, per-change verification
- Review Conventions - What the review bot demands, and how to preempt a round
- Key Patterns - Core patterns with code examples
- CI Gates and Branch Protection - What CI enforces, how to reproduce it locally, and how releases land
- GitHub Issues: Report bugs or request features
- GitHub Discussions: Ask questions or share ideas
- Security Reports: See SECURITY.md before reporting vulnerabilities
- Community Conduct: See CODE_OF_CONDUCT.md
The canonical community rules live in CODE_OF_CONDUCT.md.
We pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
Positive behavior includes:
- Being respectful and inclusive
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Unacceptable behavior includes:
- Harassment, trolling, or derogatory comments
- Personal or political attacks
- Public or private harassment
- Publishing private information without permission
- Any other conduct which could reasonably be considered inappropriate
Project maintainers may remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct.
Contact: For any questions or concerns, please open a GitHub issue with the conduct label.
By contributing to Ouroboros, you agree that your contributions will be licensed under the MIT License.