diff --git a/docs/adr/0001-truth-surfaces-b11-delta-appendix-a-reuse-map.md b/docs/adr/0001-truth-surfaces-b11-delta-appendix-a-reuse-map.md new file mode 100644 index 0000000..c81bc0a --- /dev/null +++ b/docs/adr/0001-truth-surfaces-b11-delta-appendix-a-reuse-map.md @@ -0,0 +1,57 @@ +# ADR-0001 Appendix A — Reuse map + schema plan (B¹¹ / Δ / incidents) + +**Date:** 2026-04-14 +**Status:** Proposed (appendix to ADR-0001) + +--- + +## Purpose + +ADR-0001 establishes the decision to add TruthSurface (B¹¹) and DeltaSurface (Δ) and to standardize incident semantics. This appendix makes the decision *actionable* by: + +1) specifying a reuse-first mapping onto existing contracts already present in this repo, and +2) enumerating the minimal net-new schema files + examples required for v0 portability. + +--- + +## Reuse-first mapping + +| Capability we need | Reuse (existing contracts / patterns) | Net-new (v0) | +|---|---|---| +| Signed “truth summary” per plane | Reuse **URN + `type` discriminator + `specVersion`** conventions (e.g., `TelemetryEvent`). Reuse existing evidence references (PolicyDecision/CapabilityToken/RunRecord/ProvenanceRecord) as *refs*, not embedded duplicates. | `schemas/TruthSurface.json` + `examples/truth-surface.sample.json` | +| Typed diff between two truth summaries | Reuse existing “risk + evidence + human approval” posture expressed in `policies/skills/default-policy-pack.rego` as the canonical gate style; DeltaSurface records the gate results, it does not *re-decide* policy. | `schemas/DeltaSurface.json` + `examples/delta-surface.sample.json` | +| Incident semantics (Freeze/Fork/Kill) | Reuse control-plane event structure conventions: `event_id`, `event_name`, `occurred_at`, `actor`, `run`, `refs`, `payload` as in the existing skill execution lifecycle schema and samples. | `schemas/control-plane/incident-events.schema.json` + `examples/control-plane/incident.freeze.sample.json` | +| Frontier / PBAC egress authorization | Reuse `CapabilityToken` as the short-lived signed grant primitive. Treat frontier/network constraints as a profile extension (additive) aligned to the existing governance lifecycle (decision → token). | v0: represent frontier intent + result refs in TruthSurface/DeltaSurface. v1: add an additive `frontier` block to `CapabilityToken.scope` (separate ADR if needed). | + +--- + +## Schema plan (v0) + +New schema files added in this PR branch: + +1) `schemas/TruthSurface.json` +2) `schemas/DeltaSurface.json` +3) `schemas/control-plane/incident-events.schema.json` + +New example payloads added in this PR branch: + +1) `examples/truth-surface.sample.json` +2) `examples/delta-surface.sample.json` +3) `examples/control-plane/incident.freeze.sample.json` + +--- + +## Non-goals for v0 + +- No OpenAPI/AsyncAPI surface changes yet (schemas stabilize first). +- No in-place `CapabilityToken` extension yet (we keep the profile extension as a documented plan until agreed). +- No enforcement logic (belongs in the substrate repo). + +--- + +## Follow-on steps (expected) + +1) Add OpenAPI/AsyncAPI patch entries for TruthSurface/DeltaSurface publishing endpoints + event channels. +2) Add conformance fixtures in workstation-contracts (schema validation + golden examples). +3) Implement substrate emitters/enforcers in SociOS-Linux/SourceOS (services + nftables + incident executor). + diff --git a/docs/adr/0001-truth-surfaces-b11-delta.md b/docs/adr/0001-truth-surfaces-b11-delta.md new file mode 100644 index 0000000..f6c5bd3 --- /dev/null +++ b/docs/adr/0001-truth-surfaces-b11-delta.md @@ -0,0 +1,115 @@ +# ADR-0001 — Truth Surfaces (B¹¹) + Δ-Surfaces + Incident Semantics + +**Date:** 2026-04-14 +**Status:** Proposed + +--- + +## Context + +We need a *portable, machine-verifiable* way to represent “what is true right now” about: + +- the immutable substrate (host integrity and policy posture), +- the controlled user space (governed meaning and intent), +- the agent space (bounded execution and decisions), and +- the witness/replication posture (what was attested externally). + +In practice, the system already carries many of these primitives: + +- The **two-plane contract model** (metadata plane + agent plane) and additive patch strategy (`openapi*.yaml`, `asyncapi*.yaml`). +- A **short-lived signed grant** primitive (`schemas/CapabilityToken.json`) derived from policy decisions. +- A **control-plane event lifecycle** style (e.g., `schemas/control-plane/skill-execution-events.schema.json`) and a default skill policy pack (`policies/skills/default-policy-pack.rego`). +- A concrete *mesh skill* example that already encodes deterministic plans, evidence requirements, and Cairn refs (`examples/control-plane/mesh-skill.checkout-validate.yaml`). + +What is missing is a canonical “truth object” that can be: + +1) generated deterministically, +2) signed and Merkle-addressed, +3) compared across time and planes (Δ), and +4) gated/promoted with explicit thresholds and evidence requirements. + +We also need incident semantics that are explicit and replayable (Freeze → Fork → Kill) rather than implicit operational folklore. + +## Decision + +### 1) Add two new contract types (schema family) to `sourceos-spec` + +We introduce **TruthSurface** (B¹¹) and **DeltaSurface** (Δ) as first-class contract objects, published alongside the existing schema families. + +- **TruthSurface (B¹¹)**: a signed, Merkle-addressed summary for a given plane (`sealed/system`, `controlled/user`, `open/agent`, `witness/twin`). +- **DeltaSurface (Δ)**: a signed diff between two TruthSurfaces with: + - semantic drift metrics, + - runtime drift metrics, + - governance deltas, + - a promotion recommendation + gate results. + +These new types must compose cleanly with existing primitives (TelemetryEvent, ExecutionDecision, PolicyDecision/CapabilityToken, ProvenanceRecord) rather than replacing them. + +### 2) Represent “PBAC tickets” as a CapabilityToken profile, not a new token class + +Off-box / frontier egress authorization is expressed as a **CapabilityToken** profile extension: + +- add network scope constraints (e.g., `frontier_hops`, `targets`, `egress_class`) as structured fields, +- keep the existing governance flow (evaluate → decision → issue token), +- ensure tokens remain short-lived and auditable. + +This prevents parallel token taxonomies. + +### 3) Standardize incident semantics as contract-level events + +We define incident semantics as a small set of event types aligned with the existing control-plane event lifecycle style: + +- `incident.freeze` +- `incident.fork` +- `incident.kill` + +Each event MUST carry: +- actor context (human/agent/service), +- run/trace linkage (when applicable), +- refs to evidence bundles and pre/post Cairn anchors, +- status progression compatible with existing control-plane conventions. + +### 4) Promotion gates are contract-level, evidence-first + +Promotion of a surface (or a claim derived from it) requires explicit gate checks: + +- evidence bundle completeness (required evidence list satisfied), +- risk threshold checks, +- approval rules (e.g., human approval required for certain classes), +- semantic coherence thresholds, +- runtime integrity thresholds. + +We explicitly reuse the posture already present in `policies/skills/default-policy-pack.rego` (risk gating, human approval requirement, evidence requirement checking) as the canonical style baseline. + +### 5) Keep enforcement out of this repository + +`sourceos-spec` defines **what** a surface/token/event is. +Enforcement remains the responsibility of the substrate and runtime implementations (e.g., `SociOS-Linux/SourceOS`). + +## Alternatives considered + +| Alternative | Reason not chosen | +|-------------|------------------| +| Put truth surfaces directly in the substrate repo only | Breaks the “canonical contract registry” role of this repo; makes portability and interoperability harder. | +| Create a new standalone “truth-surface spec” repo | Fragments the spec; duplicates identity/versioning discipline; increases coordination overhead. | +| Use only existing TelemetryEvent/ExecutionDecision structures | Those are necessary components but not sufficient as a signed, Merkle-addressed *summary surface* with promotion gating and Δ comparison. | + +## Consequences + +Positive: +- A single canonical contract for truth, drift, and gating across planes. +- Enables conformance fixtures and independent validators (e.g., workstation lanes). +- Allows implementations to evolve while remaining interoperable (schemas, OpenAPI, AsyncAPI, JSON-LD). + +Negative: +- Adds schema surface area that must be versioned and maintained. +- Requires a clear reuse map to prevent duplication with existing agent-plane primitives. + +## References + +- `ARCHITECTURE.md` — two-plane model and patch-file composition strategy. +- `schemas/CapabilityToken.json` — existing short-lived signed grant primitive. +- `schemas/control-plane/skill-execution-events.schema.json` — lifecycle event conventions. +- `policies/skills/default-policy-pack.rego` — baseline risk/evidence/approval gating style. +- `examples/control-plane/mesh-skill.checkout-validate.yaml` — deterministic plan + evidence requirements + Cairn refs. +- `examples/control-plane/skill.evidence.attached.sample.json` — concrete event sample for evidence attachment. diff --git a/schemas/DeltaSurface.json b/schemas/DeltaSurface.json new file mode 100644 index 0000000..2d1c4f8 --- /dev/null +++ b/schemas/DeltaSurface.json @@ -0,0 +1,105 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/DeltaSurface.json", + "title": "DeltaSurface", + "description": "A signed diff between two TruthSurfaces. Records drift metrics + gate results + recommendation. This is an interoperability artifact and should reference existing evidence/provenance objects, not duplicate them.", + "type": "object", + "additionalProperties": false, + "required": ["id", "type", "specVersion", "fromRef", "toRef", "createdAt", "merkleRoot", "signature", "gate"], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:delta-surface:", + "description": "Stable URN identifier. Pattern: urn:srcos:delta-surface:" + }, + "type": { + "const": "DeltaSurface", + "description": "Discriminator constant — always \"DeltaSurface\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document (e.g., \"2.0.0\")." + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "ISO 8601 timestamp when this delta surface was produced." + }, + "merkleRoot": { + "type": "string", + "minLength": 1, + "description": "Merkle root over referenced artifacts (format is producer-defined; commonly sha256:)." + }, + "signer": { + "type": "string", + "description": "Logical signer identity (key or service name)." + }, + "signature": { + "type": "string", + "minLength": 1, + "description": "Cryptographic signature over the canonicalized delta payload." + }, + + "fromRef": { + "type": "string", + "pattern": "^urn:srcos:truth-surface:", + "description": "URN of the prior TruthSurface." + }, + "toRef": { + "type": "string", + "pattern": "^urn:srcos:truth-surface:", + "description": "URN of the new TruthSurface." + }, + + "metrics": { + "type": "object", + "additionalProperties": false, + "description": "Optional drift metrics. Keep metrics stable and documented to avoid metric sprawl.", + "properties": { + "semantic": { + "type": "object", + "additionalProperties": true, + "description": "Semantic drift summary (topic/anchor/glossary drift)." + }, + "runtime": { + "type": "object", + "additionalProperties": true, + "description": "Runtime drift summary (process/thread/namespace posture changes)." + }, + "governance": { + "type": "object", + "additionalProperties": true, + "description": "Governance drift summary (approvals, obligations, policy pack changes)." + } + } + }, + + "gate": { + "type": "object", + "additionalProperties": false, + "description": "Gate evaluation result block (reuse the posture expressed in the default policy pack).", + "required": ["status"], + "properties": { + "status": { + "type": "string", + "enum": ["permit", "deny", "needs_more_evidence"], + "description": "Overall gate outcome." + }, + "riskScore": { "type": "integer", "minimum": 0 }, + "riskThreshold": { "type": "integer", "minimum": 0 }, + "humanApprovalRequired": { "type": "boolean" }, + "humanApproved": { "type": "boolean" }, + "evidenceRequired": { "type": "array", "items": { "type": "string" } }, + "evidencePresent": { "type": "array", "items": { "type": "string" } }, + "evidenceMissing": { "type": "array", "items": { "type": "string" } }, + "reasons": { "type": "array", "items": { "type": "string" } } + } + }, + + "refs": { + "type": "object", + "additionalProperties": true, + "description": "Pointers to evidence bundles, policy decisions, and Cairn anchors relevant to this delta." + } + } +} diff --git a/schemas/TruthSurface.json b/schemas/TruthSurface.json new file mode 100644 index 0000000..dcf232e --- /dev/null +++ b/schemas/TruthSurface.json @@ -0,0 +1,111 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/TruthSurface.json", + "title": "TruthSurface", + "description": "A signed, Merkle-addressed truth summary emitted by a plane (system/user/agent/witness). This is an interoperability artifact: it references existing governance/provenance objects, it does not replace them.", + "type": "object", + "additionalProperties": false, + "required": ["id", "type", "specVersion", "plane", "createdAt", "merkleRoot", "signature"], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:truth-surface:", + "description": "Stable URN identifier. Pattern: urn:srcos:truth-surface:" + }, + "type": { + "const": "TruthSurface", + "description": "Discriminator constant — always \"TruthSurface\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document (e.g., \"2.0.0\")." + }, + "plane": { + "type": "string", + "enum": ["system.sealed", "user.controlled", "agent.open", "witness.twin"], + "description": "Which plane emitted this surface." + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "ISO 8601 timestamp when this surface was produced." + }, + "merkleRoot": { + "type": "string", + "minLength": 1, + "description": "Merkle root over referenced artifacts (format is producer-defined; commonly sha256:)." + }, + "signer": { + "type": "string", + "description": "Logical signer identity (key or service name)." + }, + "signature": { + "type": "string", + "minLength": 1, + "description": "Cryptographic signature over the canonicalized surface payload." + }, + + "refs": { + "type": "object", + "additionalProperties": false, + "description": "Pointers to existing governance/provenance objects and evidence bundles.", + "properties": { + "policyDecisionRefs": { + "type": "array", + "items": { "type": "string", "pattern": "^urn:srcos:decision:" } + }, + "capabilityTokenIds": { + "type": "array", + "items": { "type": "string" } + }, + "runRecordRefs": { + "type": "array", + "items": { "type": "string", "pattern": "^urn:srcos:run:" } + }, + "provenanceRefs": { + "type": "array", + "items": { "type": "string", "pattern": "^urn:srcos:prov:" } + }, + "telemetryRefs": { + "type": "array", + "items": { "type": "string", "pattern": "^urn:srcos:telemetry:" } + }, + "evidenceBundleRefs": { + "type": "array", + "items": { "type": "string" } + }, + "cairnBeforeRef": { "type": "string" }, + "cairnAfterRef": { "type": "string" } + } + }, + + "evidence": { + "type": "object", + "additionalProperties": false, + "description": "Evidence completeness panel. Producers should keep this summary aligned with the policy pack expectations.", + "properties": { + "required": { "type": "array", "items": { "type": "string" } }, + "present": { "type": "array", "items": { "type": "string" } }, + "missing": { "type": "array", "items": { "type": "string" } } + } + }, + + "semantics": { + "type": "object", + "additionalProperties": true, + "description": "Governed meaning summary: anchors/topics/glossary bindings. Shape may evolve; keep stable keys where possible." + }, + + "runtime": { + "type": "object", + "additionalProperties": true, + "description": "Runtime truth summary (process/thread/namespace/capability posture). Shape may evolve; keep stable keys where possible." + }, + + "governance": { + "type": "object", + "additionalProperties": true, + "description": "Governance posture summary (approvals, risk score, obligations satisfied, policy pack digest)." + } + } +}