diff --git a/.sourceos/manifest.json b/.sourceos/manifest.json new file mode 100644 index 0000000..e198920 --- /dev/null +++ b/.sourceos/manifest.json @@ -0,0 +1,30 @@ +{ + "repo": "SourceOS-Linux/sourceos-spec", + "domain": "spec", + "specVersion": "0.1.0", + "ownedSchemas": [ + "SourceOSRepoManifest", + "SyncEngineManifest", + "SourceChannelEnvelope", + "SourceGraphWrite", + "AgentCapabilityLease", + "AuditEvent" + ], + "syncEngines": [], + "sourceChannels": [], + "policyClasses": [ + "critical" + ], + "auditEvents": [ + "spec.schema.added", + "spec.contract.updated" + ], + "dangerousSurfaces": [ + "spec.schema.breaking_change", + "spec.policy_contract.update" + ], + "authorityRepos": [ + "SourceOS-Linux/sourceos-spec" + ], + "notes": "Canonical SourceOS/SociOS contract authority for the local-first agentic graph foundation." +} diff --git a/README.md b/README.md index 44c42cd..d3b1824 100644 --- a/README.md +++ b/README.md @@ -46,12 +46,39 @@ sourceos-spec/ │ └── fog-vocabulary.jsonld # Additive fog vocabulary seed │ └── docs/ + ├── architecture/ # Architecture specs and system models + ├── security/ # Threat models and security requirements + ├── specs/ # Contract-level specs outside schema files + ├── integration/ # Cross-repository estate integration maps ├── adr/ # Architecture Decision Records └── contract-additions/ # Discoverability notes for additive families ``` --- +## Agentic graph foundation + +The local-first agentic graph foundation extends the existing contract layer so SourceOS and SociOS components share one governed model for workspace state, sync, agents, memory, policy, terminals, browsers, relays, and audit. + +Start here: + +- [Local-First Agentic Graph Architecture](docs/architecture/local-first-agentic-graph.md) +- [Agentic Sync Threat Model](docs/security/agentic-sync-threat-model.md) +- [Sync Engine Registry Specification](docs/specs/sync-engine-registry.md) +- [SourceChannel Bridge Contract](docs/specs/sourcechannel.md) +- [Estate Integration Repo Map](docs/integration/repo-map.md) + +New machine-readable contracts: + +- `schemas/SourceOSRepoManifest.json` +- `schemas/SyncEngineManifest.json` +- `schemas/SourceChannelEnvelope.json` +- `schemas/SourceGraphWrite.json` +- `schemas/AgentCapabilityLease.json` +- `schemas/AuditEvent.json` + +--- + ## Schema families The schemas are organised into domain-oriented families that map to the SourceOS / SociOS contract surface: @@ -68,6 +95,7 @@ The schemas are organised into domain-oriented families that map to the SourceOS | + | **Agent Plane** | `AgentSession`, `ExecutionDecision`, `ExecutionSurface`, `SkillManifest`, `MemoryEntry`, `SessionReceipt`, `SessionReview`, `TelemetryEvent`, `FrustrationSignal` | | + | **Release / Experiments** | `ExperimentFlag`, `RolloutPolicy`, `ReleaseReceipt` | | + | **Fog Layer** | `Topic`, `TopicEnvelope`, `ReplicationPolicy`, `ContentRef`, `Offer`, `WorkOrder`, `UsageReceipt`, `SettlementEvent` | +| + | **Agentic Graph Foundation** | `SourceOSRepoManifest`, `SyncEngineManifest`, `SourceChannelEnvelope`, `SourceGraphWrite`, `AgentCapabilityLease`, `AuditEvent` | --- diff --git a/docs/architecture/local-first-agentic-graph.md b/docs/architecture/local-first-agentic-graph.md new file mode 100644 index 0000000..4d56a48 --- /dev/null +++ b/docs/architecture/local-first-agentic-graph.md @@ -0,0 +1,177 @@ +# Local-First Agentic Graph Architecture + +Status: draft +Spec family: SourceOS/SociOS contract layer +Primary owners: SourceOS core, Policy Fabric, Agent Registry, Memory Mesh, Prophet Workspace + +## Purpose + +SourceOS and the SociOS agent plane require a governed, encrypted, local-first, agent-aware graph substrate. The goal is not ordinary settings sync. The goal is to let the trusted computing environment move across devices, workspaces, repos, agents, terminals, browsers, relays, and organizations without losing local authority. + +## Design thesis + +SourceOS should sync the whole trusted computing environment as a governed local-first graph. + +This means: + +- Developer and workspace environment state is product surface. +- Sync is decomposed by engine, not implemented as one opaque blob replicator. +- Agent settings are execution policy, not ordinary configuration. +- Memory is governed graph state, not automatic durable truth. +- Relays transport signed/encrypted objects; relays are not authority. +- Secrets are never ordinary graph values. +- Every privileged bridge must be origin-bound, scope-bound, signed, auditable, revocable, and policy checked. + +## Core layers + +### SourceIdentity + +Owns user, device, workspace, organization, repo, agent, relay, and model/provider identities. It issues signing keys, device records, scoped tokens, workspace keys, organization policy authority keys, and agent identity references. + +Agents never own root identity. Agents request scoped capabilities from SourceIdentity and SourcePolicy. + +### SourceGraph + +The canonical typed graph substrate. SourceGraph stores nodes and edges for users, devices, repos, workspaces, agents, tools, memories, policies, terminal sessions, browser sessions, models, relays, artifacts, tasks, and audit events. + +Every node and edge carries an ID, schema version, owner, author, origin device, workspace scope, policy domain, encryption scope, timestamp, causal metadata, signature, and audit pointer. + +### SourceStore + +The local durable state layer. It must work offline, support encrypted collections, tombstones, local indexes, schema migration, sync cursors, and policy-aware read/write APIs. + +### SourceSync + +The engine registry, scheduler, and relay protocol. SourceSync includes SyncSupervisor, SyncEngineRegistry, per-domain SyncEngine implementations, SyncTrackers, SyncMirrors, SourceRelay transport, and a Conflict Workbench. + +### SourcePolicy + +The policy evaluation and enforcement layer. It evaluates device policy, user policy, workspace policy, repo policy, enterprise policy, agent policy, model policy, network/firewall policy, and compliance policy. + +Precedence rule: stronger safety, enterprise, repo, and local policy wins. Remote policy cannot silently weaken a local or enterprise restriction. + +### SourceChannel + +The secure bridge between UI, web, terminal, browser, MCP, local daemons, and agent runtimes. SourceChannel requests are origin-bound, profile-bound, workspace-bound, capability-bound, signed, auditable, revocable, replay-protected, and human-readable. + +No surface is trusted merely because it runs on localhost. + +### SourceAudit + +Append-only operational memory. SourceAudit records graph writes, sync decisions, policy decisions, agent grants, tool execution, memory proposal/promotion/revocation, shell profile changes, browser bridge calls, model route changes, remote commands, and conflict resolution. + +Sherlock and Holmes consume SourceAudit to explain why a state transition happened. + +## Canonical graph objects + +- User +- Device +- Organization +- Workspace +- Repo +- Agent +- Tool +- CapabilityLease +- PolicyBundle +- PolicyDecision +- MemoryObject +- TerminalSession +- ShellProfile +- BrowserSession +- ModelProvider +- SecretRef +- RelayPeer +- Artifact +- Task +- AuditEvent + +## Canonical sync engines + +- sourceos.sync.clients +- sourceos.sync.workspace +- sourceos.sync.shell +- sourceos.sync.agent-registry +- sourceos.sync.policy-fabric +- sourceos.sync.memory-mesh +- sourceos.sync.browser +- sourceos.sync.secrets +- sourceos.sync.audit +- sourceos.sync.models +- sourceos.sync.extensions + +## Merge strategy classes + +- crdt: low-risk collaborative state such as presence and cursors +- graph_merge: workspace graph, tasks, artifact references +- append_only: audit and provenance records +- manual_review: memory conflicts, shell profile changes, workspace destructive changes +- strongest_policy_wins: security and enterprise policy +- signed_authority_required: policy bundles, agent trust grants, org controls +- never_merge: raw secrets, private keys, device keys, credential material +- quarantine: unknown schemas, unsigned agent instructions, unexpected remote writes + +## Required state machine + +Canonical states: + +- disabled +- local_only +- not_configured +- missing_identity +- missing_device_key +- missing_workspace_key +- network_down +- network_untrusted +- relay_unreachable +- auth_pending +- policy_blocked +- engine_disabled +- engine_dirty +- engine_syncing +- engine_current +- conflict_detected +- review_required +- quarantined +- degraded +- healthy + +Canonical reason codes: + +- no_user_profile +- no_org_profile +- policy_denied +- signature_invalid +- schema_unknown +- migration_required +- secret_redacted +- remote_policy_weaker +- remote_policy_newer +- local_policy_stronger +- capability_expired +- agent_untrusted +- relay_untrusted +- workspace_scope_mismatch +- profile_boundary_violation +- manual_review_required + +## Product integration + +- Prophet Workspace is the cockpit for graph state, sync health, policy explanations, memory review, agent capabilities, conflicts, and audit timelines. +- Policy Fabric is the policy authority. +- Agent Registry owns signed manifests, trust tiers, and capability leases. +- Memory Mesh owns proposed, scoped, approved, promoted, synced, expired, and revoked memory states. +- Mesh Rush transports signed and encrypted graph objects without becoming authority. +- TurtleTerm and sourceos-shell own terminal and shell surfaces but request privileges through SourceChannel and Policy Fabric. +- BearBrowser owns browser/workspace state and must enforce personal, workspace, and enterprise profile boundaries. +- Sherlock/Holmes explain decisions, diff graph state, inspect quarantine, and surface suspicious mutations. + +## Acceptance criteria + +1. Every implementation repo declares its SourceOS ownership through `.sourceos/manifest.json`. +2. Every sync engine has a manifest, schema version, merge rule, policy class, encryption scope, and audit model. +3. Every agent capability is represented as a scoped, expiring, revocable lease. +4. Memory has a proposal/review/promote lifecycle and cannot silently globalize. +5. Shell profile changes and executable sync objects require policy review. +6. Secrets sync only as references or vault-backed leases. +7. SourceChannel mediates all privileged UI/web/local/agent bridges. +8. Sherlock can explain accepted, rejected, merged, quarantined, and downgraded graph writes. diff --git a/docs/integration/repo-map.md b/docs/integration/repo-map.md new file mode 100644 index 0000000..e5af92d --- /dev/null +++ b/docs/integration/repo-map.md @@ -0,0 +1,315 @@ +# SourceOS Agentic Graph Estate Integration Map + +Status: draft +Scope: GitHub estate integration for SourceOS local-first agentic graph foundation. + +## Control repo + +### SourceOS-Linux/sourceos-spec + +Role: canonical architecture and contract source. + +Owns: + +- Local-first agentic graph architecture +- Sync engine registry +- SourceGraph record model +- SourceChannel contract +- Agentic sync threat model +- Repo manifest contract +- Acceptance criteria + +## Shared tooling + +### SourceOS-Linux/sourceos-devtools + +Role: validator and operator tooling. + +Owns: + +- JSON Schema validation CLI +- sourceos contract validate +- sourceos repo scan +- sourceos graph doctor +- sourceos sync doctor +- sourceos policy explain +- estate inventory scanner + +## SourceOS runtime and product surface + +### SourceOS-Linux/sourceos-shell + +Role: shell execution and shell sync. + +Owns: + +- sourceos.sync.shell implementation +- shell profile sync +- command template policy +- environment redaction +- audit events for shell profile changes + +### SourceOS-Linux/TurtleTerm + +Role: terminal product surface. + +Owns: + +- terminal UI integration +- pane/session state +- workspace-bound terminal context +- Neovim integration surface +- SourceChannel client integration + +### SourceOS-Linux/agent-term + +Role: terminal-native agent ChatOps. + +Owns: + +- Matrix-oriented agent interaction +- slash topic routing +- workspace-context-bound agent sessions +- audit events for chat-driven agent commands + +### SourceOS-Linux/agent-machine + +Role: local agent runtime. + +Owns: + +- local agent execution +- capability lease enforcement +- model/provider runtime selection +- local-only mode +- enterprise firewall profile support + +### SourceOS-Linux/openclaw + +Role: coding-agent compatibility and execution primitives. + +Owns: + +- coding-agent runtime compatibility +- local code-agent execution primitives +- policy-aware tool use integration + +### SourceOS-Linux/BearBrowser + +Role: browser/workspace bridge. + +Owns: + +- sourceos.sync.browser +- workspace-bound browser sessions +- tab/bookmark/session policy +- origin-bound SourceChannel bridge +- extension metadata policy + +### SourceOS-Linux/sourceos-boot + +Role: bootstrapping and early system integration. + +Owns: + +- device initialization hooks +- early profile bootstrap contracts +- boot-time policy loading contract + +### SourceOS-Linux/sourceos-model-carry + +Role: model transport and local/remote model profile integration. + +Owns: + +- sourceos.sync.models participation +- local model availability metadata +- model/provider routing fixtures + +## Socioprophet control plane + +### SocioProphet/agent-registry + +Role: governed agent registry. + +Owns: + +- sourceos.sync.agent-registry +- signed agent manifests +- agent identity records +- agent trust tiers +- capability leases +- tool grants +- model compatibility metadata + +### SocioProphet/policy-fabric + +Role: policy authority. + +Owns: + +- sourceos.sync.policy-fabric +- policy precedence +- signed policy bundles +- explainable policy decisions +- allow/deny/review/quarantine decisions +- firewall and network profile policy + +### SocioProphet/guardrail-fabric + +Role: enforcement and safety guardrail layer. + +Owns: + +- guardrail constraints +- safety floors +- unsafe operation gating +- runtime enforcement support for policy-fabric + +### SocioProphet/memory-mesh + +Role: governed memory graph. + +Owns: + +- sourceos.sync.memory-mesh +- memory object lifecycle +- memory provenance +- proposal/review/promotion workflow +- memory quarantine +- memory retention and revocation + +### SocioProphet/prophet-workspace + +Role: primary workspace cockpit. + +Owns: + +- workspace graph UI +- sync health panel +- policy explanation panel +- memory review UI +- agent capability panel +- conflict workbench +- audit timeline + +### SocioProphet/sourceos-workspace + +Role: SourceOS workspace facade or bridge. + +Owns: + +- workspace bridge contracts +- SourceOS-specific workspace abstractions +- integration with prophet-workspace where required + +### SocioProphet/sociosphere + +Role: workspace/controller topology. + +Owns: + +- user/org/workspace/repo/agent topology +- controller relationships +- workspace graph composition + +### SocioProphet/meshrush + +Role: peer/relay transport. + +Owns: + +- SourceRelay transport +- peer discovery +- encrypted object transport +- offline queueing +- enterprise relay profiles +- local LAN and homelab sync modes + +### SocioProphet/sherlock + +Role: observability and investigation. + +Owns: + +- audit ingestion +- graph diff explanation +- suspicious mutation inspection +- policy and sync explanation surfaces + +### SocioProphet/sherlock-search + +Role: search over graph, audit, policy, and memory state. + +Owns: + +- audit/event index +- graph object index +- policy decision search +- memory provenance search + +### SocioProphet/google_workspace_mcp + +Role: Google Workspace bridge. + +Owns: + +- workspace connector integration +- SourceChannel-compatible MCP behavior +- policy-aware external document access + +## Legacy OS and desktop integration sources + +These repos are initial inventory and harvesting targets, not immediate rewrite targets. + +- SociOS-Linux/os +- SociOS-Linux/accounts +- SociOS-Linux/settings-daemon +- SociOS-Linux/default-settings +- SociOS-Linux/files +- SociOS-Linux/desktop +- SociOS-Linux/switchboard +- SociOS-Linux/gnome-online-accounts + +## Required `.sourceos/manifest.json` + +Each primary implementation repo must add a manifest: + +```json +{ + "$schema": "https://sourceos-linux.github.io/sourceos-spec/schemas/SourceOSRepoManifest.json", + "repo": "owner/name", + "domain": "workspace|agent|policy|memory|shell|browser|os|transport|observability|tooling|spec", + "ownedSchemas": [], + "syncEngines": [], + "sourceChannels": [], + "policyClasses": [], + "auditEvents": [], + "dangerousSurfaces": [] +} +``` + +## M1 required repo manifests + +- SourceOS-Linux/sourceos-spec +- SourceOS-Linux/sourceos-devtools +- SourceOS-Linux/sourceos-shell +- SourceOS-Linux/TurtleTerm +- SourceOS-Linux/agent-term +- SourceOS-Linux/agent-machine +- SourceOS-Linux/BearBrowser +- SocioProphet/agent-registry +- SocioProphet/policy-fabric +- SocioProphet/memory-mesh +- SocioProphet/prophet-workspace +- SocioProphet/sociosphere +- SocioProphet/meshrush +- SocioProphet/sherlock + +## M1 acceptance criteria + +1. All M1 repos declare `.sourceos/manifest.json`. +2. sourceos-devtools can scan manifests and report compliant, partial, missing, or invalid. +3. Each manifest declares sync engines, policy classes, audit events, dangerous surfaces, and owned schemas where applicable. +4. Runtime repos do not merge high-risk sync objects without policy class and audit event definitions. +5. Policy, agent, memory, shell, browser, and transport repos reference this repo as their contract authority. diff --git a/docs/security/agentic-sync-threat-model.md b/docs/security/agentic-sync-threat-model.md new file mode 100644 index 0000000..9f885c6 --- /dev/null +++ b/docs/security/agentic-sync-threat-model.md @@ -0,0 +1,236 @@ +# Agentic Sync Threat Model + +Status: draft +Scope: SourceOS local-first graph, sync engines, SourceChannel, agent registry, memory mesh, policy fabric, shell, browser, terminal, and workspace surfaces. + +## Security thesis + +In an agentic operating environment, synced configuration can become execution control. A remote graph write that changes an agent instruction, shell profile, model route, tool grant, memory object, MCP endpoint, extension state, browser bridge, or policy bundle can directly alter what the system does. + +Therefore, agentic sync is a control-plane security boundary, not convenience replication. + +## Primary assets + +- User identity and device identity +- Workspace graph state +- Agent manifests and capability leases +- Policy bundles and policy decisions +- Memory objects and memory provenance +- Shell profiles, aliases, environment templates, and command templates +- Browser workspace sessions and extension metadata +- Model/provider routing preferences +- Secret references and vault leases +- Audit events and provenance records +- Relay peer identities +- SourceChannel bridge envelopes + +## Threat actors + +- Malicious remote relay +- Compromised user device +- Compromised enterprise profile +- Malicious browser extension +- Malicious workspace web app +- Malicious or confused agent +- Poisoned memory source +- Malicious repo dependency +- Malicious MCP server +- Network attacker +- Insider with partial repo or policy access +- Stale device replaying old graph writes + +## Threats and controls + +### Remote graph poisoning + +Threat: an attacker submits graph objects that alter agent, memory, policy, shell, browser, or model state. + +Controls: + +- Require signatures on graph writes. +- Validate schema version and collection ownership. +- Quarantine unknown schemas and unsigned writes. +- Enforce per-engine policy classes. +- Require manual review for dangerous merge classes. +- Emit audit events for accepted, rejected, and quarantined writes. + +### Agent capability escalation + +Threat: an agent gains tool, model, memory, shell, network, or MCP access through synced configuration. + +Controls: + +- Represent every privilege as an expiring capability lease. +- Bind leases to agent ID, workspace ID, tool scope, policy bundle hash, and grantor. +- Deny leases without a valid policy decision and audit pointer. +- Revoke leases through SourcePolicy and Agent Registry. +- Never trust agent self-declared capabilities without registry validation. + +### Memory injection + +Threat: remote or agent-generated memory silently changes long-term behavior. + +Controls: + +- Use lifecycle states: observed, proposed, scoped, approved, promoted, synced, expired, revoked. +- Require provenance, confidence, sensitivity, retention, mutability, and scope. +- Default agent writes to proposed memory only. +- Require review for global or cross-profile memory promotion. +- Quarantine memory from untrusted agents, browser surfaces, and unknown relays. + +### Shell profile injection + +Threat: synced shell aliases, functions, PATH changes, env templates, or startup scripts execute attacker-controlled commands. + +Controls: + +- Treat shell profile sync as high-risk. +- Block raw shell history sync by default. +- Redact secret-bearing environment state. +- Require policy review for executable shell profile changes. +- Emit SourceAudit events for every profile change. +- Make TurtleTerm and sourceos-shell request changes through SourceChannel. + +### Browser-to-local bridge abuse + +Threat: a web origin, browser extension, or workspace UI controls local agents or shell through a localhost bridge. + +Controls: + +- Use SourceChannel envelopes for every privileged bridge request. +- Bind requests to origin, profile, workspace, capability, nonce, expiry, and policy bundle hash. +- Deny raw localhost trust. +- Require explicit capability grants for browser-to-agent and browser-to-shell paths. +- Audit every accepted and denied bridge call. + +### Policy downgrade + +Threat: remote policy weakens local, enterprise, repo, or safety controls. + +Controls: + +- Stronger policy wins. +- Enterprise restrictions beat personal convenience inside enterprise profiles. +- Local safety floor cannot be weakened remotely. +- Repo policy beats agent preference. +- Unsigned policy bundles are ignored or quarantined. +- Policy downgrade requires signed authority and audit visibility. + +### Secret leakage + +Threat: secrets are synced as ordinary graph state or leaked through command history, environment snapshots, memory, logs, or browser state. + +Controls: + +- Never store raw tokens, private keys, or passwords as SourceGraph values. +- Use SecretRef and vault-backed capability leases. +- Redact secret-bearing environment state. +- Block raw shell history sync by default. +- Mark secret references as never_merge. +- Audit secret lease issuance and revocation. + +### Relay compromise + +Threat: a sync relay observes, mutates, drops, replays, or reorders graph objects. + +Controls: + +- Encrypt payloads by profile, workspace, org, or device scope. +- Sign all graph objects. +- Use nonce, causal metadata, tombstones, and replay protection. +- Treat relay identity as transport metadata, not authority. +- Allow local-only operation when relay trust is insufficient. + +### Model/provider route manipulation + +Threat: synced model routing moves execution from local/private models to remote providers, or from approved providers to unapproved providers. + +Controls: + +- Treat model provider enablement as policy-controlled. +- Bind model route changes to policy decisions. +- Require approval for remote provider enablement in sensitive profiles. +- Audit route changes and provider decisions. +- Support local-only mode and enterprise firewall profiles. + +### Audit tampering + +Threat: attackers erase or rewrite audit records. + +Controls: + +- SourceAudit is append-only. +- Deletion is handled through retention policy, not ordinary mutation. +- Audit records should include hash-linked provenance where supported. +- Sherlock/Holmes must surface gaps, invalid chains, and rejected audit writes. + +## Required security classifications + +Low risk: + +- View layout +- Presence +- Cursors +- Non-executable UI preferences + +Medium risk: + +- Workspace graph references +- Task metadata +- Artifact metadata +- Browser workspace sessions + +High risk: + +- Agent manifests +- Memory objects +- Shell profiles +- Model routing +- Extension enablement +- MCP server definitions + +Critical risk: + +- Policy bundles +- Capability leases +- Secret references +- Device keys +- Org keys +- Cross-device commands +- Wipe or replace commands + +## Required audit events + +- graph.write.accepted +- graph.write.rejected +- graph.write.quarantined +- sync.engine.started +- sync.engine.completed +- sync.conflict.detected +- sync.conflict.resolved +- policy.decision.allow +- policy.decision.deny +- policy.decision.require_review +- agent.lease.granted +- agent.lease.revoked +- agent.execution.started +- agent.execution.denied +- memory.proposed +- memory.promoted +- memory.revoked +- shell.profile.changed +- browser.bridge.accepted +- browser.bridge.denied +- model.route.changed +- secret.lease.issued +- secret.lease.revoked + +## Acceptance criteria + +1. Every high-risk and critical-risk sync object has a policy class, merge rule, and audit event. +2. Every privileged bridge path uses SourceChannel. +3. Every agent privilege is represented as a capability lease. +4. Every memory mutation has provenance and lifecycle state. +5. Every policy decision has an explainable reason code. +6. Every relay-originated write can be traced to identity, signature, policy, and audit. +7. Every unsafe merge path has quarantine or review behavior. diff --git a/docs/specs/sourcechannel.md b/docs/specs/sourcechannel.md new file mode 100644 index 0000000..2532d4b --- /dev/null +++ b/docs/specs/sourcechannel.md @@ -0,0 +1,134 @@ +# SourceChannel Bridge Contract + +Status: draft +Scope: privileged bridge between SourceOS UI, browser, terminal, shell, MCP, agents, local daemons, and enterprise/workspace consoles. + +## Purpose + +SourceChannel is the mandatory bridge contract for privileged communication between product surfaces and local or remote authority-bearing services. + +It exists because browser UIs, workspace UIs, terminal UIs, MCP servers, extensions, and local web apps must not receive ambient authority merely because they run locally or are presented inside a trusted product. + +No surface is trusted because it can reach `localhost`. No web origin controls agents directly. No terminal UI bypasses policy. No MCP server receives secrets or tool access without a scoped capability lease. + +## Required envelope + +```json +{ + "$schema": "https://sourceos-linux.github.io/sourceos-spec/schemas/SourceChannelEnvelope.json", + "channelId": "urn:srcos:channel:example", + "requestId": "urn:srcos:request:example", + "origin": "https://workspace.example", + "surface": "prophet-workspace", + "profileId": "urn:srcos:profile:user", + "workspaceId": "urn:srcos:workspace:example", + "deviceId": "urn:srcos:device:example", + "agentId": "urn:srcos:agent:example", + "capability": "agent.execute.tool", + "scope": { + "repo": "owner/name", + "paths": [], + "tools": [], + "memoryScopes": [] + }, + "policyBundleHash": "sha256:example", + "nonce": "example-nonce", + "issuedAt": "2026-05-04T00:00:00Z", + "expiresAt": "2026-05-04T00:05:00Z", + "reason": "Human-readable reason for this privileged request.", + "auditId": "urn:srcos:audit:example", + "signature": "base64url-signature" +} +``` + +## Surfaces + +- prophet-workspace +- turtleterm +- bearbrowser +- agent-term +- mcp +- daemon +- admin-console + +## Capability classes + +Low-risk: + +- graph.read.metadata +- workspace.view.status +- sync.read.health + +Medium-risk: + +- workspace.update.layout +- browser.update.workspace_session +- memory.propose + +High-risk: + +- agent.execute.tool +- shell.update.profile +- model.route.update +- browser.bridge.agent +- extension.enable + +Critical-risk: + +- policy.bundle.update +- agent.lease.grant +- secret.lease.issue +- device.command.remote +- sync.collection.wipe +- workspace.replace.local + +## Required policy behavior + +1. SourceChannel requests are denied by default. +2. A request must be validated before policy evaluation. +3. Policy evaluation must happen before execution. +4. A valid envelope does not imply permission. +5. A valid policy decision must reference a policy bundle hash and reason code. +6. High-risk and critical-risk requests must emit audit events whether allowed or denied. +7. Critical-risk requests must be signed by an authority recognized for the relevant profile, workspace, org, or device. + +## Replay and expiry + +- Every request requires a nonce. +- Nonces must be single-use within their profile/workspace/device scope. +- Expired requests are denied. +- Replayed requests are denied and audited. +- Stale policyBundleHash values require policy refresh or denial. + +## Required audit events + +- sourcechannel.request.received +- sourcechannel.request.validated +- sourcechannel.request.rejected +- sourcechannel.policy.allow +- sourcechannel.policy.deny +- sourcechannel.policy.require_review +- sourcechannel.execution.started +- sourcechannel.execution.completed +- sourcechannel.execution.failed +- sourcechannel.replay.denied +- sourcechannel.expired.denied + +## Dangerous anti-patterns + +- Trusting localhost as authority +- Letting browser JavaScript call agent runtimes directly +- Letting terminal UI mutate shell startup files without policy review +- Letting MCP servers inherit all local tools +- Letting workspace UI issue persistent memory writes directly +- Letting extension state sync without policy class and audit +- Letting enterprise admin surfaces inspect personal local-first data by default + +## Acceptance criteria + +1. Every privileged surface uses SourceChannel for high-risk and critical-risk operations. +2. Every SourceChannel request has origin, profile, workspace, device, capability, nonce, expiry, policy hash, reason, audit pointer, and signature. +3. Every high-risk and critical-risk operation has a PolicyDecision. +4. Every denied request emits an audit event with reason code. +5. No product surface is trusted solely because it runs locally. +6. No web origin communicates directly with agent, shell, secret, model, or policy services without SourceChannel. diff --git a/docs/specs/sync-engine-registry.md b/docs/specs/sync-engine-registry.md new file mode 100644 index 0000000..9f054ff --- /dev/null +++ b/docs/specs/sync-engine-registry.md @@ -0,0 +1,149 @@ +# Sync Engine Registry Specification + +Status: draft +Scope: SourceOS local-first graph sync engines and implementation repos. + +## Purpose + +The Sync Engine Registry prevents every repository from inventing its own sync model. Each syncable domain must declare a manifest that identifies its collection, schema version, merge rule, policy class, encryption scope, dangerous fields, audit events, and implementation owner. + +A sync engine is not just a transport adapter. It owns domain semantics. + +## Required engine manifest + +```json +{ + "$schema": "https://sourceos-linux.github.io/sourceos-spec/schemas/SyncEngineManifest.json", + "engineId": "sourceos.sync.workspace", + "collection": "workspace", + "schemaVersion": "0.1.0", + "ownerRepo": "SocioProphet/prophet-workspace", + "defaultEnabled": true, + "policyClass": "high", + "encryptionScope": "workspace", + "mergeStrategy": "graph_merge", + "supportsTombstones": true, + "supportsRollback": true, + "supportsExport": true, + "dangerousFields": [], + "auditEvents": [] +} +``` + +## Required fields + +- engineId: stable engine identifier +- collection: canonical SourceGraph collection +- schemaVersion: semantic version of the engine object model +- ownerRepo: repo responsible for implementation and contract evolution +- defaultEnabled: whether engine is enabled by default +- policyClass: low, medium, high, or critical +- encryptionScope: public, profile, workspace, org, device, or vault +- mergeStrategy: crdt, graph_merge, append_only, manual_review, strongest_policy_wins, signed_authority_required, never_merge, or quarantine +- supportsTombstones: whether deletion is represented with tombstones +- supportsRollback: whether local rollback is supported +- supportsExport: whether records are exportable +- dangerousFields: field names requiring review, redaction, or policy gating +- auditEvents: events emitted by the engine + +## Canonical engines + +| Engine | Owner | Collection | Policy | Encryption | Merge | +|---|---|---|---|---|---| +| `sourceos.sync.clients` | SourceOS core | clients | high | profile | signed_authority_required | +| `sourceos.sync.workspace` | `SocioProphet/prophet-workspace`, `SocioProphet/sociosphere` | workspace | high | workspace | graph_merge | +| `sourceos.sync.shell` | `SourceOS-Linux/sourceos-shell`, `SourceOS-Linux/TurtleTerm` | shell | high | profile | manual_review | +| `sourceos.sync.agent-registry` | `SocioProphet/agent-registry` | agents | critical | workspace/org | signed_authority_required | +| `sourceos.sync.policy-fabric` | `SocioProphet/policy-fabric` | policy | critical | org/workspace | strongest_policy_wins | +| `sourceos.sync.memory-mesh` | `SocioProphet/memory-mesh` | memory | high | profile/workspace | manual_review | +| `sourceos.sync.browser` | `SourceOS-Linux/BearBrowser` | browser | high | profile/workspace | manual_review | +| `sourceos.sync.secrets` | SourceOS core, Policy Fabric | secrets | critical | vault | never_merge | +| `sourceos.sync.audit` | SourceAudit, Sherlock/Holmes | audit | critical | profile/workspace/org | append_only | +| `sourceos.sync.models` | `SourceOS-Linux/sourceos-model-carry`, `SourceOS-Linux/agent-machine` | models | high | profile/org | manual_review | +| `sourceos.sync.extensions` | SourceOS core, BearBrowser, TurtleTerm, Prophet Workspace | extensions | high | profile/workspace | manual_review | + +## Merge strategy semantics + +### crdt + +For low-risk collaborative state such as presence, cursors, and layout hints. + +### graph_merge + +For typed graph objects with causal metadata, tombstones, and conflict handling. + +### append_only + +For audit and provenance. Records are never modified in place. + +### manual_review + +For changes that may alter agent behavior, memory, shell execution, browser bridge behavior, or workspace topology. + +### strongest_policy_wins + +For policy. A weaker remote policy cannot override a stronger local, enterprise, repo, or safety policy. + +### signed_authority_required + +For agent trust, org controls, remote commands, and policy-owned state. + +### never_merge + +For secrets, raw keys, credentials, private tokens, and device private material. + +### quarantine + +For unknown schemas, invalid signatures, untrusted relays, unexpected cross-profile writes, and suspected injection attempts. + +## Required engine states + +- disabled +- local_only +- not_configured +- missing_identity +- missing_device_key +- missing_workspace_key +- network_down +- network_untrusted +- relay_unreachable +- auth_pending +- policy_blocked +- engine_disabled +- engine_dirty +- engine_syncing +- engine_current +- conflict_detected +- review_required +- quarantined +- degraded +- healthy + +## Required reason codes + +- no_user_profile +- no_org_profile +- policy_denied +- signature_invalid +- schema_unknown +- migration_required +- secret_redacted +- remote_policy_weaker +- remote_policy_newer +- local_policy_stronger +- capability_expired +- agent_untrusted +- relay_untrusted +- workspace_scope_mismatch +- profile_boundary_violation +- manual_review_required + +## Acceptance criteria + +1. Every sync engine has a manifest. +2. Every engine declares its policy class and merge strategy. +3. Critical engines require signed authority. +4. Secrets use never_merge. +5. Audit uses append_only. +6. Memory, shell, browser, model, and extensions use review-aware strategies. +7. The estate scanner can report missing, invalid, partial, and compliant engine manifests. diff --git a/examples/agent-capability-lease.json b/examples/agent-capability-lease.json new file mode 100644 index 0000000..7825f65 --- /dev/null +++ b/examples/agent-capability-lease.json @@ -0,0 +1,21 @@ +{ + "leaseId": "urn:srcos:lease:demo-reviewer-001", + "agentId": "urn:srcos:agent:demo-reviewer", + "workspaceId": "urn:srcos:workspace:demo", + "grantedBy": "urn:srcos:user:demo-owner", + "capability": "agent.execute.review", + "scope": { + "repo": "SocioProphet/agent-registry", + "tools": [ + "git.read" + ], + "duration": "PT30M" + }, + "issuedAt": "2026-05-05T00:00:00Z", + "expiresAt": "2026-05-05T00:30:00Z", + "policyBundleHash": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "requiresHumanApproval": true, + "revocable": true, + "auditId": "urn:srcos:audit:lease-demo-001", + "signature": "demo-signature" +} diff --git a/examples/audit-event.json b/examples/audit-event.json new file mode 100644 index 0000000..beff12a --- /dev/null +++ b/examples/audit-event.json @@ -0,0 +1,20 @@ +{ + "id": "urn:srcos:audit:demo-policy-allow-001", + "type": "AuditEvent", + "specVersion": "0.1.0", + "eventType": "policy.decision.allow", + "occurredAt": "2026-05-05T00:00:00Z", + "actorId": "urn:srcos:user:demo-owner", + "subjectId": "urn:srcos:agent:demo-reviewer", + "workspaceId": "urn:srcos:workspace:demo", + "deviceId": "urn:srcos:device:macbook-demo", + "policyDomain": "agent", + "outcome": "allow", + "reasonCode": "policy_allowed", + "details": { + "capability": "agent.execute.review", + "repo": "SocioProphet/agent-registry" + }, + "eventHash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "signature": "demo-signature" +} diff --git a/examples/sourcechannel-envelope.json b/examples/sourcechannel-envelope.json new file mode 100644 index 0000000..ada7fb4 --- /dev/null +++ b/examples/sourcechannel-envelope.json @@ -0,0 +1,28 @@ +{ + "channelId": "urn:srcos:channel:prophet-workspace-local", + "requestId": "urn:srcos:request:workspace-agent-lease-001", + "origin": "https://workspace.socioprophet.local", + "surface": "prophet-workspace", + "profileId": "urn:srcos:profile:local-user", + "workspaceId": "urn:srcos:workspace:demo", + "deviceId": "urn:srcos:device:macbook-demo", + "agentId": "urn:srcos:agent:code-reviewer", + "capability": "agent.lease.grant", + "scope": { + "repo": "SocioProphet/agent-registry", + "tools": [ + "git.read", + "github.issue.comment" + ], + "memoryScopes": [ + "workspace:demo" + ] + }, + "policyBundleHash": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "nonce": "demo-nonce-0001", + "issuedAt": "2026-05-05T00:00:00Z", + "expiresAt": "2026-05-05T00:05:00Z", + "reason": "Grant a bounded code-reviewer lease for the demo workspace.", + "auditId": "urn:srcos:audit:sourcechannel-demo-001", + "signature": "base64url-demo-signature" +} diff --git a/examples/sourceos-repo-manifest.json b/examples/sourceos-repo-manifest.json new file mode 100644 index 0000000..e198920 --- /dev/null +++ b/examples/sourceos-repo-manifest.json @@ -0,0 +1,30 @@ +{ + "repo": "SourceOS-Linux/sourceos-spec", + "domain": "spec", + "specVersion": "0.1.0", + "ownedSchemas": [ + "SourceOSRepoManifest", + "SyncEngineManifest", + "SourceChannelEnvelope", + "SourceGraphWrite", + "AgentCapabilityLease", + "AuditEvent" + ], + "syncEngines": [], + "sourceChannels": [], + "policyClasses": [ + "critical" + ], + "auditEvents": [ + "spec.schema.added", + "spec.contract.updated" + ], + "dangerousSurfaces": [ + "spec.schema.breaking_change", + "spec.policy_contract.update" + ], + "authorityRepos": [ + "SourceOS-Linux/sourceos-spec" + ], + "notes": "Canonical SourceOS/SociOS contract authority for the local-first agentic graph foundation." +} diff --git a/examples/sync-engine-manifest.json b/examples/sync-engine-manifest.json new file mode 100644 index 0000000..44b2f06 --- /dev/null +++ b/examples/sync-engine-manifest.json @@ -0,0 +1,35 @@ +{ + "engineId": "sourceos.sync.workspace", + "collection": "workspace", + "schemaVersion": "0.1.0", + "ownerRepo": "SocioProphet/prophet-workspace", + "defaultEnabled": true, + "policyClass": "high", + "encryptionScope": "workspace", + "mergeStrategy": "graph_merge", + "supportsTombstones": true, + "supportsRollback": true, + "supportsExport": true, + "dangerousFields": [ + "automationRules", + "agentBindings", + "policyBindings" + ], + "auditEvents": [ + "sync.engine.started", + "sync.engine.completed", + "sync.conflict.detected", + "workspace.graph.updated" + ], + "stateCodes": [ + "engine_syncing", + "engine_current", + "conflict_detected", + "review_required" + ], + "reasonCodes": [ + "policy_denied", + "workspace_scope_mismatch", + "manual_review_required" + ] +} diff --git a/schemas/AgentCapabilityLease.json b/schemas/AgentCapabilityLease.json new file mode 100644 index 0000000..a06ba58 --- /dev/null +++ b/schemas/AgentCapabilityLease.json @@ -0,0 +1,84 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/AgentCapabilityLease.json", + "title": "AgentCapabilityLease", + "description": "Scoped, expiring, revocable, auditable capability grant for an agent operation.", + "type": "object", + "additionalProperties": false, + "required": [ + "leaseId", + "agentId", + "workspaceId", + "grantedBy", + "capability", + "scope", + "issuedAt", + "expiresAt", + "policyBundleHash", + "requiresHumanApproval", + "revocable", + "auditId", + "signature" + ], + "properties": { + "leaseId": { + "type": "string", + "pattern": "^urn:srcos:lease:" + }, + "agentId": { + "type": "string", + "pattern": "^urn:srcos:agent:" + }, + "workspaceId": { + "type": "string", + "pattern": "^urn:srcos:workspace:" + }, + "grantedBy": { + "type": "string", + "pattern": "^urn:srcos:" + }, + "capability": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + }, + "scope": { + "type": "object", + "additionalProperties": true, + "description": "Bounded lease scope. Typical keys include tools, repos, paths, memoryScopes, models, networkZones, and duration." + }, + "issuedAt": { + "type": "string", + "format": "date-time" + }, + "expiresAt": { + "type": "string", + "format": "date-time" + }, + "policyBundleHash": { + "type": "string", + "pattern": "^sha256:" + }, + "requiresHumanApproval": { + "type": "boolean" + }, + "revocable": { + "const": true + }, + "revokedAt": { + "type": "string", + "format": "date-time" + }, + "revokedBy": { + "type": "string", + "pattern": "^urn:srcos:" + }, + "auditId": { + "type": "string", + "pattern": "^urn:srcos:audit:" + }, + "signature": { + "type": "string", + "minLength": 1 + } + } +} diff --git a/schemas/AuditEvent.json b/schemas/AuditEvent.json new file mode 100644 index 0000000..a8a07ba --- /dev/null +++ b/schemas/AuditEvent.json @@ -0,0 +1,83 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/AuditEvent.json", + "title": "AuditEvent", + "description": "Append-only SourceAudit event for graph writes, sync decisions, policy decisions, agent leases, memory lifecycle, shell/browser bridge calls, relays, and runtime actions.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "eventType", + "occurredAt", + "actorId", + "subjectId", + "policyDomain", + "outcome", + "reasonCode", + "eventHash" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:audit:" + }, + "type": { + "const": "AuditEvent" + }, + "specVersion": { + "type": "string" + }, + "eventType": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + }, + "occurredAt": { + "type": "string", + "format": "date-time" + }, + "actorId": { + "type": "string", + "pattern": "^urn:srcos:" + }, + "subjectId": { + "type": "string", + "pattern": "^urn:srcos:" + }, + "workspaceId": { + "type": "string", + "pattern": "^urn:srcos:workspace:" + }, + "deviceId": { + "type": "string", + "pattern": "^urn:srcos:device:" + }, + "policyDomain": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + }, + "outcome": { + "type": "string", + "enum": ["allow", "deny", "require_review", "quarantine", "error", "informational"] + }, + "reasonCode": { + "type": "string" + }, + "details": { + "type": "object", + "additionalProperties": true + }, + "previousEventHash": { + "type": "string", + "pattern": "^sha256:" + }, + "eventHash": { + "type": "string", + "pattern": "^sha256:" + }, + "signature": { + "type": "string" + } + } +} diff --git a/schemas/SourceChannelEnvelope.json b/schemas/SourceChannelEnvelope.json new file mode 100644 index 0000000..82aa546 --- /dev/null +++ b/schemas/SourceChannelEnvelope.json @@ -0,0 +1,105 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/SourceChannelEnvelope.json", + "title": "SourceChannelEnvelope", + "description": "Origin-bound, profile-bound, workspace-bound, signed, auditable bridge request for privileged SourceOS operations.", + "type": "object", + "additionalProperties": false, + "required": [ + "channelId", + "requestId", + "origin", + "surface", + "profileId", + "deviceId", + "capability", + "scope", + "policyBundleHash", + "nonce", + "issuedAt", + "expiresAt", + "reason", + "auditId", + "signature" + ], + "properties": { + "channelId": { + "type": "string", + "pattern": "^urn:srcos:channel:" + }, + "requestId": { + "type": "string", + "pattern": "^urn:srcos:request:" + }, + "origin": { + "type": "string", + "minLength": 1 + }, + "surface": { + "type": "string", + "enum": [ + "prophet-workspace", + "turtleterm", + "bearbrowser", + "agent-term", + "mcp", + "daemon", + "admin-console", + "other" + ] + }, + "profileId": { + "type": "string", + "pattern": "^urn:srcos:profile:" + }, + "workspaceId": { + "type": "string", + "pattern": "^urn:srcos:workspace:" + }, + "deviceId": { + "type": "string", + "pattern": "^urn:srcos:device:" + }, + "agentId": { + "type": "string", + "pattern": "^urn:srcos:agent:" + }, + "capability": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + }, + "scope": { + "type": "object", + "additionalProperties": true, + "description": "Bounded operation scope. Typical keys include repo, paths, tools, memoryScopes, models, and networkZones." + }, + "policyBundleHash": { + "type": "string", + "pattern": "^sha256:" + }, + "nonce": { + "type": "string", + "minLength": 8 + }, + "issuedAt": { + "type": "string", + "format": "date-time" + }, + "expiresAt": { + "type": "string", + "format": "date-time" + }, + "reason": { + "type": "string", + "minLength": 1 + }, + "auditId": { + "type": "string", + "pattern": "^urn:srcos:audit:" + }, + "signature": { + "type": "string", + "minLength": 1 + } + } +} diff --git a/schemas/SourceGraphWrite.json b/schemas/SourceGraphWrite.json new file mode 100644 index 0000000..31bb7cb --- /dev/null +++ b/schemas/SourceGraphWrite.json @@ -0,0 +1,86 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/SourceGraphWrite.json", + "title": "SourceGraphWrite", + "description": "Signed write envelope for SourceGraph object operations, including policy domain, encryption scope, causal metadata, and audit pointer.", + "type": "object", + "additionalProperties": false, + "required": [ + "objectId", + "collection", + "schemaVersion", + "operation", + "payloadHash", + "authorId", + "deviceId", + "policyDomain", + "encryptionScope", + "causalClock", + "signature", + "auditId" + ], + "properties": { + "objectId": { + "type": "string", + "pattern": "^urn:srcos:" + }, + "collection": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + }, + "schemaVersion": { + "type": "string" + }, + "operation": { + "type": "string", + "enum": ["put", "patch", "delete", "tombstone", "command"] + }, + "payloadHash": { + "type": "string", + "pattern": "^sha256:" + }, + "authorId": { + "type": "string", + "pattern": "^urn:srcos:" + }, + "deviceId": { + "type": "string", + "pattern": "^urn:srcos:device:" + }, + "workspaceId": { + "type": "string", + "pattern": "^urn:srcos:workspace:" + }, + "orgId": { + "type": "string", + "pattern": "^urn:srcos:org:" + }, + "policyDomain": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + }, + "encryptionScope": { + "type": "string", + "enum": ["public", "profile", "workspace", "org", "device", "vault"] + }, + "causalClock": { + "type": "string", + "minLength": 1 + }, + "signature": { + "type": "string", + "minLength": 1 + }, + "auditId": { + "type": "string", + "pattern": "^urn:srcos:audit:" + }, + "reasonCode": { + "type": "string" + }, + "relayId": { + "type": "string", + "pattern": "^urn:srcos:relay:" + } + } +} diff --git a/schemas/SourceOSRepoManifest.json b/schemas/SourceOSRepoManifest.json new file mode 100644 index 0000000..728fc32 --- /dev/null +++ b/schemas/SourceOSRepoManifest.json @@ -0,0 +1,106 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/SourceOSRepoManifest.json", + "title": "SourceOSRepoManifest", + "description": "Repository-level declaration of SourceOS/SociOS contract ownership, sync engines, policy classes, audit events, SourceChannel surfaces, and dangerous surfaces.", + "type": "object", + "additionalProperties": false, + "required": [ + "repo", + "domain", + "specVersion", + "ownedSchemas", + "syncEngines", + "sourceChannels", + "policyClasses", + "auditEvents", + "dangerousSurfaces" + ], + "properties": { + "repo": { + "type": "string", + "pattern": "^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$", + "description": "GitHub repository in owner/name form." + }, + "domain": { + "type": "string", + "enum": [ + "spec", + "tooling", + "workspace", + "agent", + "policy", + "memory", + "shell", + "browser", + "os", + "transport", + "observability", + "model", + "security", + "integration" + ] + }, + "specVersion": { + "type": "string", + "description": "Version of the SourceOSRepoManifest contract used by this repo." + }, + "ownedSchemas": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "syncEngines": { + "type": "array", + "items": { + "$ref": "SyncEngineManifest.json" + } + }, + "sourceChannels": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true, + "description": "Named SourceChannel surfaces or bridge IDs implemented by the repo." + }, + "policyClasses": { + "type": "array", + "items": { + "type": "string", + "enum": ["low", "medium", "high", "critical"] + }, + "uniqueItems": true + }, + "auditEvents": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + }, + "uniqueItems": true + }, + "dangerousSurfaces": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + }, + "uniqueItems": true + }, + "authorityRepos": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$" + }, + "uniqueItems": true, + "description": "Repos this repo depends on as contract, policy, agent, memory, or runtime authorities." + }, + "notes": { + "type": "string" + } + } +} diff --git a/schemas/SyncEngineManifest.json b/schemas/SyncEngineManifest.json new file mode 100644 index 0000000..f33da45 --- /dev/null +++ b/schemas/SyncEngineManifest.json @@ -0,0 +1,102 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/SyncEngineManifest.json", + "title": "SyncEngineManifest", + "description": "Contract declaration for a SourceOS local-first sync engine, including owner, policy class, encryption scope, merge strategy, dangerous fields, and audit events.", + "type": "object", + "additionalProperties": false, + "required": [ + "engineId", + "collection", + "schemaVersion", + "ownerRepo", + "defaultEnabled", + "policyClass", + "encryptionScope", + "mergeStrategy", + "supportsTombstones", + "supportsRollback", + "supportsExport", + "dangerousFields", + "auditEvents" + ], + "properties": { + "engineId": { + "type": "string", + "pattern": "^sourceos\\.sync\\.[a-z0-9_.-]+$" + }, + "collection": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + }, + "schemaVersion": { + "type": "string" + }, + "ownerRepo": { + "type": "string", + "pattern": "^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$" + }, + "defaultEnabled": { + "type": "boolean" + }, + "policyClass": { + "type": "string", + "enum": ["low", "medium", "high", "critical"] + }, + "encryptionScope": { + "type": "string", + "enum": ["public", "profile", "workspace", "org", "device", "vault"] + }, + "mergeStrategy": { + "type": "string", + "enum": [ + "crdt", + "graph_merge", + "append_only", + "manual_review", + "strongest_policy_wins", + "signed_authority_required", + "never_merge", + "quarantine" + ] + }, + "supportsTombstones": { + "type": "boolean" + }, + "supportsRollback": { + "type": "boolean" + }, + "supportsExport": { + "type": "boolean" + }, + "dangerousFields": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "auditEvents": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + }, + "uniqueItems": true + }, + "stateCodes": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "reasonCodes": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } +}