Thank you for contributing! This document is the single entry point for the workflow; the ecosystem-wide standards it follows live in the team knowledge rooms (source of truth when this file and reality disagree).
- Branches:
developis the integration branch;mainis the release branch (tags only). All work happens as branch → PR → squash-merge intodevelop. No direct pushes, no force pushes. - Branch names (CI-enforced):
feat/*,fix/*,docs/*,chore/*,perf/*,security/*,refactor/*,test/*,build/*,ci/— notefeat/, notfeature/. - Commits: Conventional Commits (
feat:,fix:,docs:,chore:,refactor:,test:). The PR title becomes the squash commit message. - Pre-commit:
cargo fmt→cargo clippy --workspace --all-targets -- -D warnings→cargo test --workspace. CI enforces the same set. - Code review: every PR gets a Cora review (below) plus maintainer review before merge. CI must be green.
- Use the issue templates (bug report, feature request).
- Issue-first: larger changes (new features, architecture, new subsystems) start as an issue for discussion before any PR. One PR = one logical change; split accordingly.
- Epics live in docs/epics.md, each with a tracking issue on GitHub. Check the acceptance criteria in the issue when done, in the same PR.
- One logical change per PR; large change-sets (~40+ files) can time out the Cora Review job (30-minute limit) — split into ~15–20-file PRs.
- Body sections, in order: What / Why / Changes / Testing. A PR without them fails the PR Description check.
- Base every PR on
develop. PRs intomainare only accepted fromdeveloporchore/release-*(release flow).
Never merge on schedule or assumption:
gh pr checks <N>— all checks pass.- The Cora review verdict must be real: the review result lands as an issue comment — it must say "✅ No issues found" or list concrete findings. "Review could not complete" / LLM error = blocker → re-run until a real verdict (or consciously accept with documented justification).
- Code-scanning alerts on the PR head — investigate each one.
- Validate every finding against the code: real → fix with a regression test; false positive → dismiss with evidence.
- CI auto-fix loop: max 3 attempts, then stop and escalate.
- Squash-merge, delete the branch, sync
develop.
Cora (cora CLI) is the standard review gate for this repo, wired in at
three levels:
- Pre-commit hook —
cora review --stagedruns on every commit (installed via git template;cora hook uninstallper-repo to remove).- Exit
0→ clean, commit proceeds. - Exit
2→ blocking issues (major/critical). Fix them;--no-verifyskips fmt/clippy too, so prefer fixing. Known FP categories are encoded in.cora.yamlrules. - Exit
1→ cora itself errored (no key, config). Non-blocking; commit proceeds.
- Exit
- Manual scan — run
cora scanlocally after significant changes (new module, security-adjacent code). Scan is full-codebase; usecora review(diff-based) for large changes. - CI check —
Cora Reviewjob (.github/workflows/cora-review.yml) reviews every PR viacodecoradev/cora-review-action@v1and reports SARIF security findings. A red Cora Review check means findings must be triaged before merge.
Review behavior is configured in .cora.yaml (focus areas, tole-specific
rules that encode intentional patterns — env-resolved credentials,
argv-validated subprocess tools, wire-only redaction — plus ignore rules for
known FP categories).
Exit-code reference:
| Code | Meaning | Action |
|---|---|---|
| 0 | No issues | Commit proceeds |
| 2 | Blocking issues (major/critical) | Fix before commit |
| 1 | Cora error (no key, config error) | Non-blocking, commit proceeds |
Known issue (2026-09-18): cora 0.13.0 no longer reads the legacy
~/.cora/auth.toml / ~/.cora/config.yaml. Until re-provisioned with
cora auth login, exports are required: CORA_API_KEY, CORA_BASE_URL,
CORA_MODEL.
All repository artifacts are written in English: commit messages, PR titles/bodies, issues, code comments, and documentation files. Keep chat discussions in whatever language you prefer — files must be English.
Running live agent missions against a stale binary produces misleading results (the model truthfully reports tools that no longer exist, or old behavior that was already fixed). Before any live validation or mission run:
- Always build and invoke the repo checkout binary, not a PATH-resolved
one:
cargo build --release -p tole-cli && ./target/release/tole .... Bothtole-coreandtole-cliare published to crates.io, but the registry copy lags your checkout. tole serve --transport mcpworks on a plain build since #168 —mcp-httpis a defaulttole-clifeature; no extra flags needed.- If a
~/.cargo/bin/toleshim is installed, re-sync it after every version bump:cp target/release/tole ~/.cargo/bin/tole— verify withtole --versionmatching the workspace version inCargo.toml.
Before claiming a build is ready to release, run the provider doctor at the full tier with the repo checkout binary:
cargo build --release -p tole-cli && ./target/release/tole doctor --tier fullIt must exit 0 (chat, streaming and a real tool-call loop all green); the
result is recorded in the coverage ledger (tole doctor --summary).
- The core crate (
tole-core) must stay platform-agnostic: no stdin/stdout, no CLI assumptions. Host interaction goes through traits (Storage,Provider,Tool,Approver). - Session storage is append-only (JSONL, one file per session). Never mutate or delete entries; corrections are new entries.
- Every non-ReadOnly tool must go through an
Approver. There is no bypass path.Destructiveis structurally unregistrable without an interactive approver and never allowlistable — do not weaken the three enforcement layers (registry /AllowlistApprover/ host prompt). - MCP tools are always
Risk::Write. Server-supplied metadata is never trusted for risk classification. - Adding code is a last resort — first check whether configuration or an existing mechanism solves the problem.
Contributions are licensed to the project under the MIT license (inbound = outbound). No additional agreement is required.