backend/, frontend/) that ship together. A change that touches the product API contract — a product_app.py route, a src/lib/api/*.ts client function — is not done until both sides agree, and both sides’ CI (see Testing and verification) passes.
Branch model
Long-running integration branches (the backend history above
main includes an MVP1 line merged forward periodically) exist during active feature pushes; treat them as temporary, not as a second permanent trunk. Prefer branching from and merging back to main for new work unless you’re explicitly continuing an in-flight integration branch.
Commit style
Commits in both repos follow conventional-commit-style prefixes — observed directly ingit log --oneline:
feat: for new capability, fix: for a bug fix, chore: for non-behavioral maintenance (renames, pinning, dependency/config changes), test: for test-only additions, docs: for documentation-only changes. Write the summary line in the imperative mood, and when a fix is non-obvious, explain the root cause in the body — see caf17a6 (fix: render.yaml used the wrong Blueprint key for the Python runtime) for the level of detail expected: what broke, what the build log showed, and the actual root cause.
Implementation plans executed by an agent commit after every task, one task per commit, in the same conventional-commit style — this is the explicit instruction in docs/superpowers/plans/*.md (“Commit after every task… Conventional-commit style messages as shown”).
The frontend history also shows the standard GitHub revert/reapply pattern for a PR merge that needed to be pulled back and fixed: Merge pull request #1 from causeloop/feat/hitl-remediation-tiers, followed by Revert "Merge pull request #1 ...", followed once the issue was fixed by Reapply "Merge pull request #1 ...". If you need to back out a merged PR, prefer git revert of the merge commit (producing that same auto-generated message) over rewriting shared history.
AGENTS.md: the rules that bind every contributor, human or agent
backend/AGENTS.md is not advisory documentation — it is the safety contract for anyone (person or agent) working in this repository. The rules that matter most:
Choose exactly one mode before starting
Choose exactly one mode before starting
Read
docs/LOCAL_SETUP.md and pick one of product, basic, mvp1, or relational (Research modes, Local product stack) before touching code, and run that mode’s setup doctor (scripts/check_local_setup.py --mode <mode>) before claiming it’s ready.Read the architecture docs before changing MVP1 flow or contracts
Read the architecture docs before changing MVP1 flow or contracts
docs/MVP1_ARCHITECTURE.md before changing MVP1 flow or ownership; docs/MVP1_API_CONTRACT.md before changing frontend/backend payloads for that surface.Never expose secrets
Never expose secrets
Never read, print, log, or commit
.env.local or infra/causeloop.local.env. Use the setup doctor to check whether a required variable exists without ever revealing its value. This applies equally to a human pasting a key into chat and to an agent printing file contents.Live OpenAI calls require explicit, informed user approval
Live OpenAI calls require explicit, informed user approval
Never make a live OpenAI call unless the user has explicitly authorized the data transfer and its cost. The relational banking runner (
workers/run_banking_relational_e2e.py) additionally enforces its own exact authorization string as a second gate — see Research modes.The tracked banking dataset is the only default source
The tracked banking dataset is the only default source
docs/issue-set-2-records.json is the tracked, synthetic 250-record banking input and the default source for both the mvp1 and relational modes. Don’t substitute a personal workbook path (e.g. from ~/Downloads) — the repository must stay runnable from a fresh clone without machine-specific files.Generated artifacts stay local and ignored
Generated artifacts stay local and ignored
Generated reports, workbooks, previews, databases, and downloaded datasets stay under ignored local paths (e.g.
outputs/mvp1/). Never commit them.Don't guess the workbook Node runtime
Don't guess the workbook Node runtime
The relational mode’s reviewed Excel exporter needs
@oai/artifact-tool. Discover the bundled Node executable through the proper workspace-dependency tool and set CAUSELOOP_NODE_PATH — never guess a global module path or install an unreviewed replacement package.Review expectations
There is noCODEOWNERS file or pull request template committed in either repo today, so review routing is a team convention rather than something the tooling enforces — confirm current expectations with your team lead if you’re not sure who should review a given change. What is enforced mechanically, and therefore what a reviewer should expect green before merging:
- Both repos’
product-ci.ymlworkflows (backend: lint, unit tests, Docker image + Neo4j-driver check, Compose config validation, a real product-stack integration run, backup rehearsal; frontend:npm audit,audit:mvp:strict, typecheck,vitest, build, Docker image). See Testing and verification for the full breakdown. - For infrastructure-as-code changes under
deploy/, the backend’sterraformCI job (terraform fmt/validatefor AWS, Bicep param compilation for Azure). - Any change to the product route allowlist (
services/api/product_app.py’sAUTH_OPERATIONS/ONBOARDING_OPERATIONS/TENANT_OPERATIONS/etc.) needs its paired update on the frontend side —scripts/audit-mvp-surface.mjs’s family list — and vice versa, oraudit:mvp:strictand the backend contract test will both fail independently.
Cross-repo contract changes
Because the product API contract is split across two repositories, review a contract-shaped change (new operation, changed payload, new tenant-facing route) against both sides before approving it, not just the repo the PR is opened in:- Backend: is the operation added to (or removed from) the correct allowlist set in
services/api/product_app.py, and doestests/test_product_app_contract.pyreflect it? - Frontend: does
src/lib/api/*.tscall it through the shapescripts/audit-mvp-surface.mjsexpects — akeeportargetfamily, never areplacefamily like/mvp1,/connectors, or/clients? - Does either side’s CI job need a new env var, port, or fixture to exercise it? If so, both
product-ci.ymlfiles may need updating together. - Does a page under
docs-site/reference the old shape? See “When to update this docs site” below.
Where specs and implementation plans live
Non-trivial feature work is designed and planned before code is written, and both artifacts are committed underdocs/superpowers/:
docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md— the design spec: goal, decisions made during brainstorming, and architecture. Seedocs/superpowers/specs/2026-07-19-client-onboarding-design.mdfor the shape (goal, a decisions table, an architecture section).docs/superpowers/plans/YYYY-MM-DD-<topic>-backend.md(or-frontend, etc.) — the task-by-task implementation plan an agent executes, with checkbox tasks, explicit global constraints (tech stack, invariants, “commit after every task”), and a pointer back to its spec.
superpowers:subagent-driven-development or superpowers:executing-plans skill workflow, task by task, each task ending in its own conventional-commit-style commit. If you’re planning work of comparable size — a new API surface, a schema change, a cross-repo contract — write the spec and plan first and commit them under docs/superpowers/ before implementation starts.
When to update this docs site
Update the relevant page underdocs-site/ in the same change (or a fast follow-up in the same PR cycle) whenever you:
- Add, remove, or change a route in
services/api/product_app.py’s allowlist, or change whatscripts/audit-mvp-surface.mjsclassifies askeep/target/replace. - Change an environment variable, default, or port in
infra/docker-compose.product.yml,infra/docker-compose.yml, or theCAUSELOOP_*override list. - Change a command documented here (a
uv run,npm run,docker compose, oralembicinvocation) — including its flags or working directory. - Change deployment topology (Render/Vercel wiring, AWS Terraform, Azure Bicep) in a way that changes how someone reaches a running environment.
docs-site/.authoring/STYLE_GUIDE.md exactly: verify every path, command, port, and endpoint against the actual code before writing it down, cross-link only to pages in its site map, and never invent behavior the code doesn’t have.