Date: 2026-03-13 Purpose: Concrete roles, communication standards, quality gates, and file conventions for Claude/Codex cooperation in the BELFEM codebase. Status: Official extension of AGENTS.md and CLAUDE.md. This file is the authoritative protocol.
If guidance conflicts across collaboration docs, apply this order:
Claude Code — Primary AI (broad exploration)
Codex — Secondary AI (precision audit)
Collaboration artifacts are organized by their reader, and lifetime follows audience:
An artifact is ephemeral iff no human ever needs to return to it. The boundary between the two tiers is a distillation step, not a copy: at thread/session close the signal is lifted from the AI-only scratch into the durable AI+human record (the devlog, and ./todo/ progress files as applicable) before the scratch is swept. That distillation is precisely what makes aggressive GC of the AI-only tier safe.
Format follows audience. AI-only files stay machine-parseable — keep the # AI, ## Audit, and Confidence: markers so the receiving model can orient — but need no human-prose polish. AI+human files are curated and distilled for a human reader.
The AI-to-AI exchange is a set of sharded, ephemeral, per-task files under ./tmp/ai_exchange/: one file per topic, ./tmp/ai_exchange/<slug>.md, where <slug> is a short lowercase_underscore topic tag (e.g. periodic_thin_cut). One topic per file. Either AI may create, read, or append to the file for the current task at any time.
"The blackboard" is a spoken synonym for this channel (adopted 2026-08-20, after the published term it maps to — see METHODOLOGY.md). An instruction like "see blackboard" or "put it on the blackboard" means the current task's ./tmp/ai_exchange/<slug>.md file. The directory name stays ai_exchange; only the vocabulary gained the alias. One deliberate deviation from the published pattern: during blind jury rounds the blackboard property is suspended — auditors must not read each other's postings until reconciliation.
These files are AI-only scratch: machine-parseable, disposable, and never committed (./tmp/ai_exchange/ is git-ignored). The durable record of any conclusion lives in the devlog (§6), not here. Do not archive them — they are swept, not retained (see §10).
For work scoped to ./nonfree/ or to porting code from ./tmp/manta/ into ./nonfree/, do not create, read, or append the AI-only exchange at all — suppress the AI-only tier entirely. The shared exchange is routed through external AI vendors and is therefore a vendor-bound leak surface; nonfree work is Christian's proprietary project and must not cross it. Keep coordination in chat and record session outcomes only in the local human-readable record (./nonfree/devlog/).
Copy this format exactly for every entry:
Rules:
AIs are typically trained to sound confident. In this project, we do the opposite: communicate uncertainty honestly so the partner AI and the user can assess claims independently.
| Tier | Meaning | Action for receiving AI |
|---|---|---|
| high | Strong evidence, verified in code and/or literature | Spot-check is sufficient |
| medium (~N%) | Likely correct but not fully verified; add approximate % when helpful | Verify before acting on it |
| low | Educated guess, needs investigation | Treat as hypothesis, investigate independently |
Why this matters: When Claude says "I'm ~70% sure the bug is here," Codex can focus its audit energy on verifying that specific claim rather than re-scanning everything. When Codex finds a C++ standard violation, it should say whether it's guaranteed UB or merely implementation-defined.
Before signing off on a Claude finding, Codex addresses only the relevant items from this checklist. Items that don't apply to the change under review should be marked "N/A" — there is no requirement to comment on all 8 for a localized fix.
When a deviation from doc/coding_philosophy.md is found, Codex flags it with a confidence level and proposes the corrected pattern.
| # | Item | What to check |
|---|---|---|
| 1 | Naming conventions | a/t/m/g prefixes in framework code; mathematical-kernel exception for standard notation |
| 2 | Container selection | Cell<T> for arrays, Vector<T>/Matrix<T> for linear algebra only, DynamicBitset, ShiftRegister |
| 3 | Memory management | Manual malloc/free on hot paths, ownership via Cell<T*> (non-owning) vs Cell<T> (owning), alignment |
| 4 | Error handling | BELFEM_ASSERT for debug-only checks, BELFEM_ERROR for always-active runtime errors, release-build behavior |
| 5 | MPI patterns | 64 KB chunking, data() safety on empty Cell, alignment, distributed operation correctness |
| 6 | Thread safety / OpenMP | BELFEM is MPI-first and deliberately not thread-safe internally. Flag any accidental internal thread assumptions or hybrid-model hazards. OpenMP is possible but requires external synchronization (#pragma omp critical) |
| 7 | Performance-first rules | No hidden allocations in loops, zero-abstraction penalty, preallocate buffers |
| 8 | Literature compliance | When applicable: did Claude follow the routing tables? Do citations match the implementation? (Use CLAUDE.md citation format) |
Literature routing is mandatory when the task involves:
Literature routing is not required for:
When literature is used:
At the end of every meaningful session, create a devlog summary in ./devlog/ and update ./devlog/README.md with a one-line entry linking the new file.
The devlog is the durable AI+human distillation of the ephemeral exchange (§2). The per-task ./tmp/ai_exchange/<slug>.md files are AI-only scratch and are swept. At thread/session close, lift the conclusion — what was confirmed, refuted, or left open, with file:line evidence and confidence — into the devlog (and into the relevant ./todo/ progress file when there is one) before the exchange file becomes GC-eligible. If it is not in the devlog or a ./todo/ file, treat it as lost once the scratch is swept.
Distinction from ./todo/: Devlogs record what was changed and why (backward-looking). Task files in ./todo/ document what needs to be done (forward-looking). Both are AI+human, durable, and tracked in-repo — in contrast to the AI-only exchange.
Todo-file prose (standing rule, revised 2026-08-20): ./todo/ files get no Codex prose sweep. The earlier rule required one on every draft or substantial edit; it is withdrawn as not worth its cost. ./todo/ files are working artifacts for the AI-plus-human team, not documentation a user reads, and the sweep spends vendor budget to smooth prose whose density is more useful than its polish. This changes nothing about technical audits of a todo file's content, which are unaffected and still expected where the plan warrants one. The prose sweep is now reserved for user-facing documentation — see CLAUDE.md §"Prose Gets a Language Sweep" for the scope and the exclusions.
Todo-file checkboxes (standing rule): whenever a ./todo/ file lists steps, always give each step a GitHub checkbox (- [ ]). Keep the boxes live:
See todo/closed/periodic_thin_cut_continuity_fix.md for the reference style (checked, unchecked, and struck-through steps), and todo/plan_template.md for the current skeleton.
For work scoped to ./nonfree/ or to porting code from ./tmp/manta/ into ./nonfree/, write session devlogs to ./nonfree/devlog/ instead of ./devlog/. Do not update ./devlog/README.md for nonfree-only sessions. If ./nonfree/devlog/ has its own README or index, update that local index; otherwise the dated devlog file is sufficient.
dlYYYYMMDD_topic.md
Examples:
**Date:** is the only field every entry carries, and an entry without it is a defect. Fill the rest where they apply, and add one of your own where the session needs it — the fields below are the ones that recur, not a schema.
Three points where the practiced form differs from the older one, and why:
Brief description of findings and outcomes.
Four things the table encodes, each of which cost something to learn:
scripts/cross_review.sh --jury and --relay refuse to run unless all four variables are set, and name this table when they do. --quick pins the cheap row itself and forces it onto the auditors, so the unattended post-commit hook cannot be retuned by whatever shell happened to commit.
.claude/scripts/ask_copilot.sh is not part of the regular jury. The two seats are Codex and Grok, and a round that runs both is the standard. Copilot exists as a substitute for a seat that is temporarily unavailable — a vendor outage, or a usage limit that will not clear inside the session. It is low priority: no depth row is defined for it, and no effort is spent tuning it.
When a seat is filled by the reserve, say so in the exchange entry and in the devlog. A round with a substitute seat is still a two-voice round, but the vendor diversity it was bought for is weaker, and that belongs in the record. Reporting the outage to Christian is unchanged — the reserve does not make an outage silent.
A good audit prompt is specific:
"Audit `src/homology/cl_CutProcessor.cpp:420-426`: does positive-only `tCase` admission correctly implement single-imposition for all interior shared faces, or can two adjacent elements both get positive cases for the same face? Reference the self-cancel block at lines 476-486."
A poor prompt is vague:
"Check if the cut logic is correct."
| Path | Audience | Purpose | Lifetime |
|---|---|---|---|
| ./tmp/ai_exchange/<slug>.md | AI-only | Live, per-task AI-to-AI exchange (sharded by topic) | Ephemeral; safe to delete anytime — recommended sweep of files older than 14 days |
| ./todo/ai_exchange.md (legacy) | AI+human | Pre-2026-06-18 single-file exchange — historical record only, not written anymore | Persistent (frozen) |
| ./todo/ai_exchange_archive_*.md | AI+human | Archived legacy exchange threads | Persistent |
| ./todo/*.md (other) | AI+human | Task planning and implementation plans | Persistent |
| ./devlog/dlYYYYMMDD_topic.md | AI+human | Session summaries — the durable distillation of the exchange | Persistent |
| ./devlog/campaigns/<name>.md | AI+human | Current-state page per ACTIVE campaign (§11) | Persistent, rewritten in place |
| ./todo/debt_register.md | AI+human | Live open-item register with the blocking-1.0 lens (§11); its preamble is the operating manual for both files | Persistent, one table |
| ./todo/debt_register_closed.md | AI+human | Archive of retired (struck) register rows, same columns | Persistent, append-on-strike |
| ./nonfree/devlog/dlYYYYMMDD_topic.md | AI+human | Session summaries for nonfree-only work | Persistent |
| ./doc/ai_collaboration_protocol.md | AI+human | This file — the authoritative protocol | Persistent |
A finding or change is reviewed when a static audit is complete. It is verified only when an executable gate has passed. Devlogs, todo trackers, and exchange entries must not write "verified" for syntax-only or read-only work — write "reviewed", or name the actual gate that ran.
Strongest first:
Lower levels support, never replace, higher ones. Reviewer agreement is the weakest tier: three concurring audits do not lift a claim past level 5. Physics and design questions are adjudicated by Christian against the literature regardless of level (see the cross-review rules).
A new audit round on the same subject requires at least one of:
Otherwise the next step is the executable gate, not another review.
devlog/campaigns/<name>.md (one page per ACTIVE campaign: current accepted design, branch, last passing reproducer, open P0/P1, superseded approaches, links) and todo/debt_register.md (the live rows, one table: ID | area | severity | status | reproducer | blocking-1.0?, with todo/debt_register_closed.md carrying the retired rows in the same columns) are the compression layer over the append-only devlog. A session that resolves or creates an open item updates the campaign page and the register in the same session; the dated devlog entry links to them and does not restate their content. The register's own preamble governs how a row is read, when it may be struck, and what counts as closure evidence — read it before editing a row.