Skip to content

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:device prefix (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 its CLAUDE.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.md drift 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:

  1. Write the reconciled truth once at security/model.md (verify against current code — see Anti-drift).
  2. Replace each source file's body with a one-line link to the central page.
  3. 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.md describes 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_serial is 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.md stays 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.