# 01 — System Architecture *FPMP v0.1.0 — Draft* ## 1. Overview FPMP defines four layers. Data flows upward; control (corrections, revocations) flows downward through the same log. ``` ┌─────────────────────────────────────────────────────────┐ │ 4. SHARING LAYER capabilities, grants, revocations, │ │ delegated projections │ ├─────────────────────────────────────────────────────────┤ │ 3. DERIVATION LAYER claims, derivation graph, │ │ confidence, corrections/refutations │ ├─────────────────────────────────────────────────────────┤ │ 2. EVIDENCE LAYER ingested artifacts + provenance │ │ (calendar, notes, photos, messages) │ ├─────────────────────────────────────────────────────────┤ │ 1. LOG LAYER signed, append-only operation log; │ │ CRDT-style multi-node sync │ └─────────────────────────────────────────────────────────┘ ``` Everything above the log layer is a **deterministic view materialized from the log**. A node that replays the same log MUST reach the same graph state. This is the core interoperability guarantee. ## 2. Layer 1: Operation Log The unit of truth is the **operation**: a signed, content-addressed, immutable record. ``` Operation { op_id: hash(canonical_bytes) // content address author: device public key user: user root key (or delegation chain to it) lamport: logical clock prev: [op_id, ...] // causal predecessors (DAG) type: EVIDENCE | CLAIM | REFUTE | GRANT | REVOKE | REDACT | INFERENCE_CALL | DEVICE_ADD | DEVICE_REMOVE body: type-specific payload (see Milestone 2 wire spec) sig: signature by author over canonical_bytes } ``` Properties (normative): - **Append-only.** Operations are never mutated or deleted. Corrections are new operations (`REFUTE`); content removal is forward-tombstoning (`REDACT`) — see §6. - **Causal DAG.** `prev` links make the log a Merkle DAG. Sync is set reconciliation over op_ids; ordering ambiguity is resolved by deterministic tie-break (lamport, then op_id), so replay is convergent (a state-based CRDT over an op-based log). - **Self-certifying.** Validity of an op depends only on its signature and its causal ancestry, never on which node you fetched it from. Sync transports are therefore untrusted (see Threat Model). ## 3. Layer 2: Evidence **Evidence** is a raw artifact ingested by an adapter: a calendar event, a note, photo EXIF metadata, a message, a contact card, app telemetry. Evidence ops record: - a content hash of the artifact (the artifact body itself MAY live in an encrypted blob store referenced by hash, keeping the log small); - **source provenance**: adapter id and version, source account, ingestion device, ingestion time, original timestamps; - a sensitivity classification assigned at ingest (revisable by the user via a later op). Evidence is **never shared directly through capabilities** by default. Capabilities expose claims; evidence is the user's private substrate (see 02-trust-model §4). ## 4. Layer 3: Claims and the Derivation Graph A **claim** is a structured statement about the user produced by a **deriver** (rule, heuristic, or model): ``` Claim { subject: user (or an entity in the user's graph) predicate: e.g. "works_at", "weekly_routine", "dietary_preference" object: value confidence: [0,1] + method tag (rule | statistical | model) derived_from: [op_id...] // evidence and/or upstream claims deriver: id + version + (if model) INFERENCE_CALL op_id valid_time: interval the claim asserts about the world } ``` Claims, their inputs, and refutations form the **derivation graph** — a DAG over operations. Three properties matter: 1. **Provenance is structural.** "Why do you believe X?" is answered by walking `derived_from` to evidence leaves. There is no claim without a derivation path. 2. **Corrections cascade.** A `REFUTE` op targeting a claim or an evidence item marks it refuted in the materialized view. Any downstream claim whose support set is invalidated becomes **stale** and MUST be re-derived or withdrawn by the node's derivation engine. Cascade semantics are deterministic: refutation status is part of replay. 3. **Inference is logged.** Every model call that produced a claim is itself an `INFERENCE_CALL` op recording model identity, prompt/input hashes, and output hash — so claims produced by an opaque model still have an auditable boundary, and poisoned inference can be revoked wholesale by refuting the call (see Threat Model §5). ## 5. Layer 4: Capabilities and Sharing A **capability** is a signed grant from the user to a **delegate** (partner, clinic, coach, assistant service, researcher) authorizing read access to a **projection** of the claim graph: ``` Grant { delegate: delegate public key selector: predicate/namespace filter + sensitivity ceiling + optional time bounds + min-confidence floor disclosure: CLAIMS_ONLY (default) | CLAIMS_WITH_DERIVATION_SHAPE expiry: timestamp (mandatory) delegable: false (default; v0 forbids re-delegation) } ``` - The delegate's node receives **only operations matching the selector**, re-encrypted to the delegate's key. It never receives raw evidence unless the user creates an explicit, separate evidence grant. - `CLAIMS_WITH_DERIVATION_SHAPE` reveals that a claim has N supporting items of given types/dates without revealing their content — enough for the delegate to assess reliability without seeing the substrate. - **Revocation** (`REVOKE` op) is mechanical: the user's nodes stop serving new ops to the delegate, rotate the relevant projection keys, and the revocation propagates through sync so honest relays stop forwarding. (What revocation can and cannot guarantee against a *dishonest* delegate who already copied data is treated honestly in Threat Model §4.) ## 6. Redaction in an Append-Only World `REDACT` tombstones an evidence blob: the blob is deleted from blob stores, its key is destroyed, and the log retains only the hash and the redaction op. Claims derived solely from redacted evidence become stale and are withdrawn. The log's history remains verifiable; the content is gone. This is the protocol's answer to "append-only" vs. "right to delete." ## 7. Node Roles | Role | Holds | Trust | |---|---|---| | **Primary node** (phone/laptop) | full log, evidence blobs, derivation engine, keys | fully trusted by user | | **Replica node** (home server) | same as primary | fully trusted | | **Relay** (third-party sync host) | encrypted ops only | untrusted: availability only | | **Delegate node** | projection slice only | semi-trusted: bounded by grant | All roles speak the same wire protocol (Milestone 2). A relay is just a node with no keys. ## 8. The Demo Path (end state) 1. Adapters ingest calendar/notes/photo-metadata → `EVIDENCE` ops. 2. Derivation engine emits `CLAIM` ops with provenance and confidence. 3. User asks "what do you know about me and why?" → CLI walks the graph. 4. User refutes a claim → `REFUTE` op → downstream claims invalidate visibly. 5. User grants a delegate node a narrow selector → delegate syncs only that slice → user revokes → delegate stops receiving updates, audit log proves the whole exchange.