CLAUDE.md — how agents use Bedrock Docs¶
What this repo is¶
Cross-cutting truth for the 8-repo Bedrock system (see README.md).
If you are an agent working in any repo and you need to understand something that
spans repos — the security model, PKI, the wire protocol, the system architecture —
it lives here, not in the individual repo.
MANIFESTO.md is human-owned — never edit it without express permission¶
MANIFESTO.md (this repo's root) is the PETRA product/trust brief and
the load-bearing spec every doc and component must stay aligned to. It is a human-owned
governance artifact:
- An agent MUST NOT edit, reword, restructure, or "reconcile"
MANIFESTO.md— not to fix drift, not to match shipped code, not as part of a larger change — without an explicit, in-session human instruction to change that specific file. A general task ("update the docs", "reconcile to present state", "fix the drift") is not permission to touch MANIFESTO.md. When in doubt, do not touch it. - Agents read MANIFESTO.md and align docs/code to it — the alignment flows one way (MANIFESTO → docs/code), never the reverse. If the code has moved past MANIFESTO, that is a discrepancy to surface to a human, not to silently edit away in the manifesto.
- When a human does authorise a MANIFESTO change, land it as its own reviewed PR; do not bundle it into unrelated work.
This rule overrides the anti-drift/reconciliation guidance below: those apply to the docs pages, never to MANIFESTO.md.
PETRA context¶
PETRA is a battlespace management system providing command, control, and situational awareness across strategic, operational, and tactical echelons. HQ plans and manages the battlespace; edge troops stay synchronised in near-real-time under intermittent connectivity.
Components: Directory (identity/auth/RBAC root of trust), Web (HQ command app), Gateway (NATO/partner interop), Server (Zenoh mesh router), Node (edge device: tracking/video/MAVLink), Android (session-scoped edge client), NiFi (external-feed ingest), Media/Tile Server (out-of-model binary asset servers), common (shared proto/policy/crypto contract).
Trust model: Web, Directory, Gateway, NiFi, and the Media/Tile Servers form the privileged core (full state, HQ-operated, reliable connectivity + physical security). Servers are expendable routers — content-blind, minimal state, compromise = minimal impact. Android and Nodes assume loss/capture and hold only current-session / current-role data; a captured Node also exposes the shared deployment group key in memory until rotation. NiFi and Gateway are write-capable into the core and must authenticate.
Key invariants: Directory is the sole source of identity — all tokens are Directory-signed (Ed25519, protobuf JWT-analogue) with expiry + revocation; a device is an IdentityToken with a
kind:deviceprefix (there is no separate DeviceToken type). Classification uses STANAG-4774 CMBAC labels + clearances, fail-closed. Content is sealed under the deployment group key (AES-256-GCM) while routing metadata is signed-cleartext so content-blind routers can route; verify-before-decode everywhere. Tactical objects (plans, drawings, channels, SitReps, targets) are tombstoned, never hard-deleted — this supports Replay + audit. Plan access control is per-ORBAT and bounded one-up: a unit member sees their own unit's plan, the plan one echelon above, and the subtree below; plans more than one echelon above are commanders-only.
This repo¶
docs — the PETRA documentation site (MkDocs): architecture, protocol, security, and training material. It is the human-readable reference the other modules distil from. Load-bearing constraint: keep it aligned with MANIFESTO.md and the protocol schemas in
common— docs define requirements, they do not implement them, so drift here becomes drift everywhere downstream.
The routing rule (where does a new doc go?)¶
When you write or move a doc, decide its home with one test:
"Would an agent working in a different repo need this?"
- No → it is implementation detail for one repo. Keep it in that repo
(
<repo>/docs/or itsCLAUDE.md). Examples: Android Hilt setup, MDM config, a service's deploy runbook, repo-specific build steps. - Yes, or it is system onboarding → it belongs in this central repo. Write
it here, then delete the duplicate in the source repo and replace it with a
one-line link to the central page. Do not leave two copies — that is how the
current
SECURITY.mddrift happened.
When in doubt, prefer local; promote to central only when a second consumer appears.
Worked example — promoting a doc¶
A security model lived in both android/SECURITY.md and web/SECURITY.md and drifted.
To promote:
- Write the reconciled truth once at
security/model.md(verify against current code — see Anti-drift). - Replace each source file's body with a one-line link to the central page.
- Keep genuinely repo-specific detail local (e.g. the web bridge's impl pointers) and link to it from the central page's "Where to read the code" section.
Result: one page, two links, no copies. (Already done for security, PKI, wire protocol, outbox, and interop standards.)
Finding a repo's entry point¶
Each repo's CLAUDE.md is its agent entry point and should link here for shared concerns
rather than restating them. Start there for repo-specific build/test/convention rules.
Anti-drift¶
- One concept = one page = one repo. No copies.
- A central page that describes code MUST be reconciled against current code when
written — do not copy stale prose. (The stale
android/SECURITY.mddescribes a QUIC transport that the code does not have; reality is Zenoh TLS +verifyAuthEnvelope.) - Describe the present, not the past. Every page states what the code is now,
or what it must become to close a known gap — never what it was. Do not narrate
migrations as history ("previously bound an X.509 serial", "the old QUIC stack is
gone"). State current reality ("identity is token-only;
bound_cert_serialis reserved/removed") and track in-flight work as remaining steps, not as a changelog — e.g.architecture/status-roadmap.md's "In progress / transitional" section lists the steps that remain outstanding. Past tense is fine only for non-code facts: a principal's runtime state ("the user was revoked") or an external standard's older format. - Each repo's
CLAUDE.mdstays the agent entry point for that repo and should link here for shared concerns rather than restating them.
Contributing docs¶
Adding or moving a doc: apply the routing rule above. Write the reconciled truth once
(verify against current code), replace any source-repo duplicate with a one-line link,
and link the new page from README.md and related pages.
Always update the nav in mkdocs.yml when adding, moving, or renaming a page,
and verify with ./build.sh before pushing. The site builds with mkdocs build
--strict (the Cloudflare Pages build command), so a broken link, bad anchor, or a
nav entry pointing at a missing file fails the deploy. Links to files in other
repos must be full GitHub URLs (https://github.com/Bedrock-Defence/<repo>/blob/main/...) —
relative links that escape this repo (../../common/...) break the strict build.