diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..6fa2699
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,7 @@
+include LICENSE README.md SECURITY.md
+recursive-include docs *
+recursive-include scripts *
+recursive-include assets *
+recursive-include Sources *
+recursive-include tests *
+global-exclude __pycache__ *.py[cod] .DS_Store
diff --git a/README.md b/README.md
index cb75dbf..4da02c4 100644
--- a/README.md
+++ b/README.md
@@ -158,6 +158,7 @@ Some devices are powerful. Some are private. Some are fragile. Some are approval
```bash
git clone https://github.com/workingclassbuddha/open-compute-protocol.git
cd open-compute-protocol
+python3 -m pip install -e .
python3 scripts/start_ocp_easy.py
```
@@ -199,6 +200,16 @@ If you want the shell-based starter instead of the auto-open launcher:
For a fuller walkthrough, see [docs/QUICKSTART.md](./docs/QUICKSTART.md).
+### Trustworthy Alpha Notes
+
+OCP v0.1.7 is a stabilization pass around packaging, security posture, protocol contract visibility, tests, and demo flow. It is still alpha and should not be treated as production-secure or protocol-stable.
+
+- [Security Model](./docs/SECURITY_MODEL.md)
+- [Operator Authorization](./docs/OPERATOR_AUTH.md)
+- [HTTP API Overview](./docs/OCP_HTTP_API.md)
+- [Two Macs and a Phone Demo](./docs/DEMO_TWO_MACS_AND_PHONE.md)
+- [v0.1 Draft Spec](./docs/spec/OCP_v0.1.md)
+
---
## OCP App
@@ -221,6 +232,26 @@ swift run OCPDesktop
This native Mission Control shell uses the same OCP server, state paths, operator-token phone links, app-status polling, persisted app-history samples, charts, client-derived route topology, guided setup, and default-worker startup behavior as the Python launcher.
+### Native Proof Assistant
+
+The native Mac app now includes a one-click Proof Assistant for the two-device OCP proof. Launch the app, then click **Run Proof Assistant** from the Overview, Setup Doctor, toolbar, or Mesh menu.
+
+
+
+
+
+The assistant runs the no-terminal path end to end:
+
+1. Generates and persists an operator token if needed.
+2. Starts Mesh Mode when the server is not already running in mesh mode.
+3. Waits for `/mesh/app/status` to become reachable.
+4. Copies the tokened phone link once for the run and shows it in the app.
+5. Calls the existing Autonomic Mesh activation flow with proof and repair enabled.
+6. Polls status until setup becomes `strong`, OCP reports a proof issue, or the proof times out with a concrete next fix.
+7. Records one app-history sample at the end so the Mission Control charts reflect the run.
+
+No server routes or schemas are added for this flow. The native assistant only orchestrates the existing `/mesh/app/status`, `/mesh/app/history`, `/mesh/app/history/sample`, and `/mesh/autonomy/activate` endpoints. The individual Start Mesh, Copy Phone Link, Activate Mesh, and Open App controls remain available as secondary controls.
+
Unsigned macOS beta bundle:
```bash
@@ -295,6 +326,7 @@ These are meant to give the project a clearer identity as:
## Tests
```bash
+python3 scripts/check_protocol_conformance.py
python3 -m unittest tests.test_sovereign_mesh
python3 server.py --help
```
diff --git a/Sources/OCPDesktop/App/OCPDesktopApp.swift b/Sources/OCPDesktop/App/OCPDesktopApp.swift
index 4b9df93..161ce0d 100644
--- a/Sources/OCPDesktop/App/OCPDesktopApp.swift
+++ b/Sources/OCPDesktop/App/OCPDesktopApp.swift
@@ -12,6 +12,9 @@ struct OCPDesktopApp: App {
.commands {
CommandGroup(replacing: .newItem) {}
CommandMenu("Mesh") {
+ Button("Run Proof Assistant") { model.runProofAssistant() }
+ .keyboardShortcut("p", modifiers: [.command, .shift])
+ .disabled(model.isProofAssistantRunning)
Button("Activate Mesh") { model.activateMesh() }
.keyboardShortcut("a", modifiers: [.command, .shift])
.disabled(model.isActivating)
diff --git a/Sources/OCPDesktop/Stores/OCPDesktopModel.swift b/Sources/OCPDesktop/Stores/OCPDesktopModel.swift
index 29f01e2..02e3807 100644
--- a/Sources/OCPDesktop/Stores/OCPDesktopModel.swift
+++ b/Sources/OCPDesktop/Stores/OCPDesktopModel.swift
@@ -12,6 +12,8 @@ final class OCPDesktopModel: ObservableObject {
@Published var history = AppStatusHistory.empty
@Published var isRunning = false
@Published var isActivating = false
+ @Published var isProofAssistantRunning = false
+ @Published var proofAssistant = ProofAssistantStatus.idle
let repoRoot: URL
let paths: LaunchPaths
@@ -154,6 +156,14 @@ final class OCPDesktopModel: ObservableObject {
}
}
+ func runProofAssistant() {
+ guard !isProofAssistantRunning else { return }
+ isProofAssistantRunning = true
+ Task {
+ await runProofAssistantFlow()
+ }
+ }
+
func saveConfig() {
let normalized = config.normalized(defaultNodeID: LauncherCore.defaultNodeID())
config = normalized
@@ -181,6 +191,178 @@ final class OCPDesktopModel: ObservableObject {
}
}
+ private func runProofAssistantFlow() async {
+ var copiedPhoneLink = false
+ defer {
+ isProofAssistantRunning = false
+ isActivating = false
+ }
+
+ ensureOperatorToken()
+ proofAssistant = ProofAssistantReducer.initial(mode: currentMode, phoneURL: phoneURL)
+ statusText = proofAssistant.message
+
+ if currentMode != .mesh || !isRunning {
+ startMesh()
+ } else {
+ refreshStaticLinks(mode: .mesh)
+ }
+
+ proofAssistant = ProofAssistantReducer.waitingForServer(phoneURL: phoneURL)
+ statusText = proofAssistant.message
+
+ let firstSnapshot: AppStatusSnapshot
+ do {
+ firstSnapshot = try await waitForReachableServer(timeout: 20)
+ } catch ProofAssistantRunError.startupTimeout {
+ proofAssistant = ProofAssistantReducer.startupTimeout(seconds: 20)
+ statusText = proofAssistant.message
+ await recordHistorySample(preserveStatus: true)
+ return
+ } catch {
+ proofAssistant = ProofAssistantReducer.failure(
+ "Could not reach OCP: \(error.localizedDescription)",
+ detail: "Start Mesh Mode manually or check the configured port, then run the assistant again.",
+ phoneURL: phoneURL
+ )
+ statusText = proofAssistant.message
+ await recordHistorySample(preserveStatus: true)
+ return
+ }
+
+ apply(firstSnapshot)
+ copiedPhoneLink = copyProofAssistantPhoneLinkIfReady()
+ proofAssistant = ProofAssistantReducer.phoneLinkReady(phoneURL: phoneURL, copiedPhoneLink: copiedPhoneLink)
+ statusText = proofAssistant.message
+
+ proofAssistant = ProofAssistantReducer.activating(phoneURL: phoneURL, copiedPhoneLink: copiedPhoneLink)
+ statusText = proofAssistant.message
+ isActivating = true
+
+ do {
+ try await client().activateMesh()
+ } catch {
+ isActivating = false
+ proofAssistant = ProofAssistantReducer.failure(
+ "Activate Mesh failed: \(error.localizedDescription)",
+ detail: nextFix,
+ phoneURL: phoneURL,
+ copiedPhoneLink: copiedPhoneLink
+ )
+ statusText = proofAssistant.message
+ await recordHistorySample(preserveStatus: true)
+ return
+ }
+
+ isActivating = false
+ proofAssistant = ProofAssistantStatus(
+ phase: .pollingProof,
+ title: "Polling proof",
+ message: "Activation completed. The assistant is watching for strong mesh status.",
+ phoneURL: phoneURL,
+ copiedPhoneLink: copiedPhoneLink
+ )
+ statusText = proofAssistant.message
+
+ let finalStatus = await pollProofUntilDone(timeout: 90, copiedPhoneLink: copiedPhoneLink)
+ proofAssistant = finalStatus
+ statusText = finalStatus.message
+ await recordHistorySample(preserveStatus: true)
+ }
+
+ private func waitForReachableServer(timeout: TimeInterval) async throws -> AppStatusSnapshot {
+ let deadline = Date().addingTimeInterval(timeout)
+ var lastError: Error?
+
+ while Date() < deadline {
+ do {
+ let next = try await client().fetchStatus()
+ apply(next)
+ try? await refreshHistory()
+ return next
+ } catch {
+ lastError = error
+ try? await Task.sleep(nanoseconds: 500_000_000)
+ }
+ }
+
+ if lastError != nil {
+ throw ProofAssistantRunError.startupTimeout
+ }
+ throw ProofAssistantRunError.startupTimeout
+ }
+
+ private func pollProofUntilDone(timeout: TimeInterval, copiedPhoneLink: Bool) async -> ProofAssistantStatus {
+ let deadline = Date().addingTimeInterval(timeout)
+ var latestSnapshot = snapshot
+
+ while Date() < deadline {
+ do {
+ let next = try await client().fetchStatus()
+ latestSnapshot = next
+ apply(next)
+ try? await refreshHistory()
+ let reduced = ProofAssistantReducer.status(
+ for: next,
+ mode: currentMode,
+ phoneURL: phoneURL,
+ currentPhase: .pollingProof,
+ copiedPhoneLink: copiedPhoneLink
+ )
+
+ switch reduced.phase {
+ case .completed, .needsAttention, .failed:
+ return reduced
+ default:
+ proofAssistant = reduced.phase == .pollingProof ? reduced : ProofAssistantStatus(
+ phase: .pollingProof,
+ title: "Polling proof",
+ message: reduced.message,
+ detail: reduced.detail.isEmpty ? "Waiting for OCP to report strong status or a concrete fix." : reduced.detail,
+ phoneURL: reduced.phoneURL,
+ copiedPhoneLink: copiedPhoneLink
+ )
+ statusText = proofAssistant.message
+ }
+ } catch {
+ proofAssistant = ProofAssistantStatus(
+ phase: .pollingProof,
+ title: "Polling proof",
+ message: "Status polling is retrying: \(error.localizedDescription)",
+ detail: "The assistant will keep trying until the proof timeout.",
+ phoneURL: phoneURL,
+ copiedPhoneLink: copiedPhoneLink
+ )
+ statusText = proofAssistant.message
+ }
+
+ try? await Task.sleep(nanoseconds: 2_000_000_000)
+ }
+
+ return ProofAssistantReducer.proofTimeout(
+ snapshot: latestSnapshot,
+ phoneURL: phoneURL,
+ copiedPhoneLink: copiedPhoneLink
+ )
+ }
+
+ private func ensureOperatorToken() {
+ guard config.operatorToken.isEmpty else { return }
+ config.operatorToken = Self.generateToken()
+ let normalized = config.normalized(defaultNodeID: LauncherCore.defaultNodeID())
+ config = normalized
+ try? LauncherCore.saveConfig(normalized, to: paths.configPath)
+ }
+
+ private func copyProofAssistantPhoneLinkIfReady() -> Bool {
+ let value = phoneURL.hasPrefix("http") ? phoneURL : appLink(for: .mesh)
+ guard value.hasPrefix("http") else { return false }
+ NSPasteboard.general.clearContents()
+ NSPasteboard.general.setString(value, forType: .string)
+ phoneURL = value
+ return true
+ }
+
private func start(mode: LaunchMode) {
stop()
currentMode = mode
@@ -227,16 +409,17 @@ final class OCPDesktopModel: ObservableObject {
history = try await client().fetchHistory(limit: 240)
}
- private func recordHistorySample() async {
+ private func recordHistorySample(preserveStatus: Bool = false) async {
guard !isSampling else { return }
isSampling = true
+ let previousStatus = statusText
defer { isSampling = false }
do {
_ = try await client().recordHistorySample()
lastSampleAt = Date()
try await refreshHistory()
} catch {
- statusText = "Status is live, but history sampling failed: \(error.localizedDescription)"
+ statusText = preserveStatus ? previousStatus : "Status is live, but history sampling failed: \(error.localizedDescription)"
}
}
@@ -271,3 +454,7 @@ final class OCPDesktopModel: ObservableObject {
"\(UUID().uuidString.lowercased())-\(UUID().uuidString.lowercased())"
}
}
+
+private enum ProofAssistantRunError: Error {
+ case startupTimeout
+}
diff --git a/Sources/OCPDesktop/Views/Components.swift b/Sources/OCPDesktop/Views/Components.swift
index 3d48915..62eef88 100644
--- a/Sources/OCPDesktop/Views/Components.swift
+++ b/Sources/OCPDesktop/Views/Components.swift
@@ -268,6 +268,8 @@ struct CinematicOverviewHero: View {
var meshScore: Int
var phoneURL: String
var isActivating: Bool
+ var proofAssistant: ProofAssistantStatus
+ var isProofAssistantRunning: Bool
var recoveryLabel: String
var recoverySummary: String
var proofLabel: String
@@ -276,6 +278,7 @@ struct CinematicOverviewHero: View {
var primaryPeerSummary: String
var story: [String]
var allowMotion: Bool
+ var runProofAssistant: () -> Void
var startMesh: () -> Void
var activateMesh: () -> Void
var copyPhoneLink: () -> Void
@@ -369,6 +372,7 @@ struct CinematicOverviewHero: View {
.textCase(.uppercase)
}
VStack(alignment: .leading, spacing: 12) {
+ HeroDetailBlock(title: "Assistant", value: proofAssistant.phaseLabel, summary: proofAssistant.message)
HeroDetailBlock(title: "Recovery", value: recoveryLabel, summary: recoverySummary)
HeroDetailBlock(title: "Proof", value: proofLabel, summary: proofSummary)
HeroDetailBlock(title: "Primary Peer", value: primaryPeerLabel, summary: primaryPeerSummary)
@@ -389,12 +393,12 @@ struct CinematicOverviewHero: View {
HeroDeviceScene(allowMotion: allowMotion)
HStack(spacing: 12) {
- Button("Activate Mesh") {
- activateMesh()
+ Button("Run Proof Assistant") {
+ runProofAssistant()
}
.buttonStyle(.borderedProminent)
.controlSize(.large)
- .disabled(isActivating)
+ .disabled(isProofAssistantRunning)
Button("Start Mesh Mode") {
startMesh()
@@ -402,6 +406,13 @@ struct CinematicOverviewHero: View {
.buttonStyle(.bordered)
.controlSize(.large)
+ Button("Activate Mesh") {
+ activateMesh()
+ }
+ .buttonStyle(.bordered)
+ .controlSize(.large)
+ .disabled(isActivating)
+
Button("Copy Phone Link") {
copyPhoneLink()
}
@@ -456,6 +467,154 @@ struct CinematicOverviewHero: View {
}
}
+struct ProofAssistantCard: View {
+ var status: ProofAssistantStatus
+ var phoneURL: String
+ var timeline: [AppStatusSnapshot.TimelineEvent]
+ var isActivating: Bool
+ var runProofAssistant: () -> Void
+ var startMesh: () -> Void
+ var copyPhoneLink: () -> Void
+ var activateMesh: () -> Void
+ var openApp: () -> Void
+
+ var body: some View {
+ MissionCard(tint: tint) {
+ VStack(alignment: .leading, spacing: 16) {
+ HStack(alignment: .firstTextBaseline) {
+ VStack(alignment: .leading, spacing: 5) {
+ Text("Proof Assistant").sectionLabel()
+ Text(status.title)
+ .font(.title3.weight(.bold))
+ }
+ Spacer()
+ StatusPill(text: status.phaseLabel, status: status.statusToken)
+ }
+
+ Text(status.message)
+ .font(.headline)
+ .foregroundStyle(MissionTheme.cream.opacity(0.82))
+ .fixedSize(horizontal: false, vertical: true)
+
+ if !status.detail.isEmpty {
+ Label(status.detail, systemImage: detailIcon)
+ .font(.callout)
+ .foregroundStyle(detailColor)
+ .fixedSize(horizontal: false, vertical: true)
+ }
+
+ VStack(alignment: .leading, spacing: 6) {
+ HStack(spacing: 8) {
+ Image(systemName: status.copiedPhoneLink ? "checkmark.square" : "iphone")
+ .foregroundStyle(status.copiedPhoneLink ? MissionTheme.mint : MissionTheme.signal)
+ Text(status.copiedPhoneLink ? "Phone link copied" : "Phone link")
+ .font(.caption.bold())
+ .foregroundStyle(.secondary)
+ }
+ Text(linkText)
+ .font(.callout.monospaced())
+ .lineLimit(2)
+ .textSelection(.enabled)
+ .foregroundStyle(MissionTheme.cream.opacity(linkText.hasPrefix("http") ? 0.82 : 0.58))
+ }
+ .padding(12)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .background(Color.black.opacity(0.22), in: RoundedRectangle(cornerRadius: 14, style: .continuous))
+
+ HStack(spacing: 10) {
+ Button {
+ runProofAssistant()
+ } label: {
+ Label(status.isRunning ? "Running" : "Run Proof Assistant", systemImage: "checkmark.seal")
+ }
+ .buttonStyle(.borderedProminent)
+ .controlSize(.large)
+ .disabled(status.isRunning)
+
+ Button {
+ startMesh()
+ } label: {
+ Label("Start Mesh", systemImage: "network")
+ }
+ .buttonStyle(.bordered)
+
+ Button {
+ activateMesh()
+ } label: {
+ Label("Activate", systemImage: "bolt.circle")
+ }
+ .buttonStyle(.bordered)
+ .disabled(isActivating)
+
+ Button {
+ copyPhoneLink()
+ } label: {
+ Label("Copy Link", systemImage: "doc.on.doc")
+ }
+ .buttonStyle(.bordered)
+
+ Button {
+ openApp()
+ } label: {
+ Label("Open", systemImage: "safari")
+ }
+ .buttonStyle(.bordered)
+ }
+
+ if !timeline.isEmpty {
+ Divider().opacity(0.36)
+ VStack(alignment: .leading, spacing: 10) {
+ Text("Live Proof Timeline").sectionLabel()
+ TimelineList(events: Array(timeline.prefix(5)))
+ }
+ }
+ }
+ }
+ }
+
+ private var linkText: String {
+ if !status.phoneURL.isEmpty { return status.phoneURL }
+ return phoneURL
+ }
+
+ private var tint: Color {
+ switch status.phase {
+ case .completed:
+ return MissionTheme.mint
+ case .needsAttention:
+ return MissionTheme.copper
+ case .failed:
+ return MissionTheme.ember
+ default:
+ return MissionTheme.signal
+ }
+ }
+
+ private var detailIcon: String {
+ switch status.phase {
+ case .completed:
+ return "checkmark.circle"
+ case .needsAttention, .failed:
+ return "exclamationmark.triangle"
+ default:
+ return "info.circle"
+ }
+ }
+
+ private var detailColor: Color {
+ switch status.phase {
+ case .completed:
+ return MissionTheme.mint
+ case .needsAttention:
+ return MissionTheme.copper
+ case .failed:
+ return MissionTheme.ember
+ default:
+ return .secondary
+ }
+ }
+}
+
struct HeroDetailBlock: View {
var title: String
var value: String
diff --git a/Sources/OCPDesktop/Views/ContentView.swift b/Sources/OCPDesktop/Views/ContentView.swift
index 34fef3f..0804e24 100644
--- a/Sources/OCPDesktop/Views/ContentView.swift
+++ b/Sources/OCPDesktop/Views/ContentView.swift
@@ -34,6 +34,12 @@ struct ContentView: View {
} label: {
Label("Mesh", systemImage: "network")
}
+ Button {
+ model.runProofAssistant()
+ } label: {
+ Label("Proof Assistant", systemImage: "checkmark.seal")
+ }
+ .disabled(model.isProofAssistantRunning)
Button {
model.activateMesh()
} label: {
diff --git a/Sources/OCPDesktop/Views/OverviewView.swift b/Sources/OCPDesktop/Views/OverviewView.swift
index 0d11b21..ebbefd3 100644
--- a/Sources/OCPDesktop/Views/OverviewView.swift
+++ b/Sources/OCPDesktop/Views/OverviewView.swift
@@ -19,6 +19,8 @@ struct OverviewView: View {
meshScore: model.meshScore,
phoneURL: model.phoneURL,
isActivating: model.isActivating,
+ proofAssistant: model.proofAssistant,
+ isProofAssistantRunning: model.isProofAssistantRunning,
recoveryLabel: demo.recoveryLabel,
recoverySummary: demo.recoverySummary,
proofLabel: demo.proofLabel,
@@ -27,12 +29,25 @@ struct OverviewView: View {
primaryPeerSummary: demo.primaryPeerSummary,
story: demo.story,
allowMotion: allowMotion,
+ runProofAssistant: { model.runProofAssistant() },
startMesh: { model.startMesh() },
activateMesh: { model.activateMesh() },
copyPhoneLink: { model.copyPhoneLink() },
openApp: { model.openApp() }
)
+ ProofAssistantCard(
+ status: model.proofAssistant,
+ phoneURL: model.phoneURL,
+ timeline: model.snapshot?.setup?.timeline ?? [],
+ isActivating: model.isActivating,
+ runProofAssistant: { model.runProofAssistant() },
+ startMesh: { model.startMesh() },
+ copyPhoneLink: { model.copyPhoneLink() },
+ activateMesh: { model.activateMesh() },
+ openApp: { model.openApp() }
+ )
+
if showGuide {
CompactSetupGuideCard(
steps: model.setupGuideSteps,
diff --git a/Sources/OCPDesktop/Views/SetupDoctorView.swift b/Sources/OCPDesktop/Views/SetupDoctorView.swift
index 1b04278..c9f1675 100644
--- a/Sources/OCPDesktop/Views/SetupDoctorView.swift
+++ b/Sources/OCPDesktop/Views/SetupDoctorView.swift
@@ -16,6 +16,18 @@ struct SetupDoctorView: View {
DemoStatusStrip(state: demo, roles: model.deviceRoles)
+ ProofAssistantCard(
+ status: model.proofAssistant,
+ phoneURL: model.phoneURL,
+ timeline: model.snapshot?.setup?.timeline ?? [],
+ isActivating: model.isActivating,
+ runProofAssistant: { model.runProofAssistant() },
+ startMesh: { model.startMesh() },
+ copyPhoneLink: { model.copyPhoneLink() },
+ activateMesh: { model.activateMesh() },
+ openApp: { model.openApp() }
+ )
+
SetupGuideCard(
steps: model.setupGuideSteps,
allowMotion: allowMotion,
@@ -46,9 +58,14 @@ struct SetupDoctorView: View {
.foregroundStyle(.secondary)
.textSelection(.enabled)
HStack {
- Button("Activate Mesh") { model.activateMesh() }
+ Button("Run Proof Assistant") { model.runProofAssistant() }
.buttonStyle(.borderedProminent)
+ .disabled(model.isProofAssistantRunning)
+ Button("Activate Mesh") { model.activateMesh() }
+ .buttonStyle(.bordered)
+ .disabled(model.isActivating)
Button("Copy Phone Link") { model.copyPhoneLink() }
+ .buttonStyle(.bordered)
}
}
}
diff --git a/Sources/OCPDesktopCore/ProofAssistant.swift b/Sources/OCPDesktopCore/ProofAssistant.swift
new file mode 100644
index 0000000..0bfb792
--- /dev/null
+++ b/Sources/OCPDesktopCore/ProofAssistant.swift
@@ -0,0 +1,290 @@
+import Foundation
+
+public enum ProofAssistantPhase: String, Codable, Equatable, CaseIterable, Sendable {
+ case idle
+ case startingMesh
+ case waitingForServer
+ case phoneLinkReady
+ case activating
+ case pollingProof
+ case completed
+ case needsAttention
+ case failed
+
+ public var label: String {
+ switch self {
+ case .idle:
+ return "Idle"
+ case .startingMesh:
+ return "Starting Mesh"
+ case .waitingForServer:
+ return "Waiting for Server"
+ case .phoneLinkReady:
+ return "Phone Link Ready"
+ case .activating:
+ return "Activating"
+ case .pollingProof:
+ return "Polling Proof"
+ case .completed:
+ return "Completed"
+ case .needsAttention:
+ return "Needs Attention"
+ case .failed:
+ return "Failed"
+ }
+ }
+
+ public var statusToken: String {
+ switch self {
+ case .idle:
+ return "ready"
+ case .startingMesh, .waitingForServer, .activating, .pollingProof:
+ return "running"
+ case .phoneLinkReady:
+ return "ready"
+ case .completed:
+ return "completed"
+ case .needsAttention:
+ return "needs_attention"
+ case .failed:
+ return "failed"
+ }
+ }
+
+ public var isRunning: Bool {
+ switch self {
+ case .startingMesh, .waitingForServer, .phoneLinkReady, .activating, .pollingProof:
+ return true
+ case .idle, .completed, .needsAttention, .failed:
+ return false
+ }
+ }
+}
+
+public struct ProofAssistantStatus: Equatable, Sendable {
+ public var phase: ProofAssistantPhase
+ public var title: String
+ public var message: String
+ public var detail: String
+ public var phoneURL: String
+ public var copiedPhoneLink: Bool
+
+ public init(
+ phase: ProofAssistantPhase,
+ title: String,
+ message: String,
+ detail: String = "",
+ phoneURL: String = "",
+ copiedPhoneLink: Bool = false
+ ) {
+ self.phase = phase
+ self.title = title
+ self.message = message
+ self.detail = detail
+ self.phoneURL = phoneURL
+ self.copiedPhoneLink = copiedPhoneLink
+ }
+
+ public static let idle = ProofAssistantStatus(
+ phase: .idle,
+ title: "Ready to run proof",
+ message: "Run Proof Assistant to start Mesh Mode, copy the phone link, activate the mesh, and watch for a strong proof."
+ )
+
+ public var isRunning: Bool {
+ phase.isRunning
+ }
+
+ public var canRun: Bool {
+ !phase.isRunning
+ }
+
+ public var phaseLabel: String {
+ phase.label
+ }
+
+ public var statusToken: String {
+ phase.statusToken
+ }
+}
+
+public enum ProofAssistantReducer {
+ public static func initial(mode: LaunchMode, phoneURL: String) -> ProofAssistantStatus {
+ if mode == .mesh {
+ return waitingForServer(phoneURL: phoneURL)
+ }
+ return ProofAssistantStatus(
+ phase: .startingMesh,
+ title: "Starting Mesh Mode",
+ message: "The assistant is preparing this Mac to accept a second device.",
+ phoneURL: clean(phoneURL) ?? ""
+ )
+ }
+
+ public static func waitingForServer(phoneURL: String) -> ProofAssistantStatus {
+ ProofAssistantStatus(
+ phase: .waitingForServer,
+ title: "Waiting for OCP server",
+ message: "Mesh Mode is starting. The assistant will continue as soon as /mesh/app/status responds.",
+ phoneURL: clean(phoneURL) ?? ""
+ )
+ }
+
+ public static func phoneLinkReady(phoneURL: String, copiedPhoneLink: Bool) -> ProofAssistantStatus {
+ ProofAssistantStatus(
+ phase: .phoneLinkReady,
+ title: copiedPhoneLink ? "Phone link copied" : "Phone link ready",
+ message: copiedPhoneLink
+ ? "Open the copied link on the second device. The assistant is ready to activate the mesh."
+ : "Copy this link to the second device, then activate the mesh.",
+ detail: copiedPhoneLink ? "The link was copied once for this run." : "",
+ phoneURL: clean(phoneURL) ?? "",
+ copiedPhoneLink: copiedPhoneLink
+ )
+ }
+
+ public static func activating(phoneURL: String, copiedPhoneLink: Bool) -> ProofAssistantStatus {
+ ProofAssistantStatus(
+ phase: .activating,
+ title: "Activating mesh",
+ message: "OCP is probing routes, repairing what it can, and launching the proof run.",
+ phoneURL: clean(phoneURL) ?? "",
+ copiedPhoneLink: copiedPhoneLink
+ )
+ }
+
+ public static func status(
+ for snapshot: AppStatusSnapshot?,
+ mode: LaunchMode,
+ phoneURL: String,
+ currentPhase: ProofAssistantPhase = .idle,
+ copiedPhoneLink: Bool = false
+ ) -> ProofAssistantStatus {
+ guard let snapshot else {
+ if mode == .mesh {
+ return waitingForServer(phoneURL: phoneURL)
+ }
+ return initial(mode: mode, phoneURL: phoneURL)
+ }
+
+ let setupStatus = normalized(snapshot.setup?.status)
+ let proofStatus = normalized(snapshot.latestProof?.status ?? snapshot.setup?.latestProofStatus)
+ let recoveryState = normalized(snapshot.setup?.recoveryState)
+ let nextFix = clean(snapshot.setup?.nextFix) ?? clean(snapshot.nextActions?.first)
+ let proofSummary = clean(snapshot.latestProof?.summary)
+ let operatorSummary = clean(snapshot.setup?.operatorSummary)
+ let blockingIssue = clean(snapshot.setup?.blockingIssue)
+ let link = bestPhoneURL(snapshot: snapshot, fallback: phoneURL)
+
+ if setupStatus == "strong" {
+ return ProofAssistantStatus(
+ phase: .completed,
+ title: "Proof completed",
+ message: operatorSummary ?? proofSummary ?? "OCP reports a strong two-device proof.",
+ detail: nextFix ?? "Mesh setup is strong.",
+ phoneURL: link,
+ copiedPhoneLink: copiedPhoneLink
+ )
+ }
+
+ if ["needs_attention", "blocked"].contains(setupStatus)
+ || ["needs_attention", "blocked"].contains(recoveryState)
+ || ["failed", "needs_attention", "cancelled"].contains(proofStatus) {
+ return ProofAssistantStatus(
+ phase: .needsAttention,
+ title: "Needs attention",
+ message: nextFix ?? proofSummary ?? "OCP needs one concrete fix before the proof can finish.",
+ detail: blockingIssue ?? proofSummary ?? "Keep the Mac app open and connect the second device with the copied phone link.",
+ phoneURL: link,
+ copiedPhoneLink: copiedPhoneLink
+ )
+ }
+
+ if ["planned", "queued", "running", "accepted"].contains(proofStatus)
+ || ["proving", "activating"].contains(setupStatus)
+ || recoveryState == "repairing" {
+ return ProofAssistantStatus(
+ phase: .pollingProof,
+ title: "Proof running",
+ message: proofSummary ?? operatorSummary ?? nextFix ?? "The assistant is waiting for OCP to complete the whole-mesh proof.",
+ detail: nextFix ?? "This can take a little while after the phone joins.",
+ phoneURL: link,
+ copiedPhoneLink: copiedPhoneLink
+ )
+ }
+
+ if currentPhase == .activating {
+ return activating(phoneURL: link, copiedPhoneLink: copiedPhoneLink)
+ }
+
+ if hasPhoneURL(link) {
+ return phoneLinkReady(phoneURL: link, copiedPhoneLink: copiedPhoneLink)
+ }
+
+ return waitingForServer(phoneURL: link)
+ }
+
+ public static func startupTimeout(seconds: Int) -> ProofAssistantStatus {
+ ProofAssistantStatus(
+ phase: .failed,
+ title: "Server did not start",
+ message: "OCP did not answer /mesh/app/status within \(seconds) seconds.",
+ detail: "Check whether another process owns the configured port, then run Proof Assistant again."
+ )
+ }
+
+ public static func proofTimeout(snapshot: AppStatusSnapshot?, phoneURL: String, copiedPhoneLink: Bool) -> ProofAssistantStatus {
+ if let snapshot {
+ let nextFix = clean(snapshot.setup?.nextFix) ?? clean(snapshot.nextActions?.first)
+ return ProofAssistantStatus(
+ phase: .needsAttention,
+ title: "Proof needs more time",
+ message: nextFix ?? "The proof did not reach strong status before the timeout.",
+ detail: clean(snapshot.setup?.blockingIssue) ?? "Make sure the second device opened the copied phone link and is still reachable.",
+ phoneURL: bestPhoneURL(snapshot: snapshot, fallback: phoneURL),
+ copiedPhoneLink: copiedPhoneLink
+ )
+ }
+
+ return ProofAssistantStatus(
+ phase: .failed,
+ title: "Proof timed out",
+ message: "OCP did not provide proof status before the timeout.",
+ detail: "Run Proof Assistant again after confirming the server is reachable.",
+ phoneURL: clean(phoneURL) ?? "",
+ copiedPhoneLink: copiedPhoneLink
+ )
+ }
+
+ public static func failure(_ message: String, detail: String = "", phoneURL: String = "", copiedPhoneLink: Bool = false) -> ProofAssistantStatus {
+ ProofAssistantStatus(
+ phase: .failed,
+ title: "Proof Assistant failed",
+ message: message,
+ detail: detail,
+ phoneURL: clean(phoneURL) ?? "",
+ copiedPhoneLink: copiedPhoneLink
+ )
+ }
+
+ private static func bestPhoneURL(snapshot: AppStatusSnapshot, fallback: String) -> String {
+ if let fallback = clean(fallback), hasPhoneURL(fallback) {
+ return fallback
+ }
+ return clean(snapshot.setup?.phoneURL) ?? clean(fallback) ?? ""
+ }
+
+ private static func hasPhoneURL(_ value: String) -> Bool {
+ value.hasPrefix("http://") || value.hasPrefix("https://")
+ }
+
+ private static func normalized(_ value: String?) -> String {
+ (clean(value) ?? "").lowercased().replacingOccurrences(of: " ", with: "_")
+ }
+
+ private static func clean(_ value: String?) -> String? {
+ guard let value else { return nil }
+ let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
+ return trimmed.isEmpty ? nil : trimmed
+ }
+}
diff --git a/assets/ocp-proof-assistant.svg b/assets/ocp-proof-assistant.svg
new file mode 100644
index 0000000..88be328
--- /dev/null
+++ b/assets/ocp-proof-assistant.svg
@@ -0,0 +1,137 @@
+
+ OCP Native Proof Assistant
+ A native Mac Proof Assistant flow showing Mesh Mode startup, copied phone link, activation, proof polling, and strong mesh completion.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OCP DESKTOP MISSION CONTROL
+
+
+ NATIVE PROOF ASSISTANT
+ Run the mesh proof
+ Start Mesh Mode, copy the phone link, activate, and watch
+ for strong status without terminal commands.
+
+ Run Proof Assistant
+
+
+ Start Mesh
+
+ Copy Link
+
+
+ PHASE
+ Polling Proof
+
+ 82
+ mesh score
+
+
+ LIVE PROOF TIMELINE
+
+
+ 1
+ Mesh Mode
+ server ready
+
+
+
+ 2
+ Phone Link
+ copied once
+
+
+
+ 3
+ Activate
+ repair enabled
+
+
+
+ 4
+ Strong or Fix
+ final state
+
+
+
+
+
+
+
+ PHONE LINK
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Second device
+ opens copied link
+
+ Token protected
+
+
+
+
+
diff --git a/docs/DEMO_TWO_MACS_AND_PHONE.md b/docs/DEMO_TWO_MACS_AND_PHONE.md
new file mode 100644
index 0000000..47fb428
--- /dev/null
+++ b/docs/DEMO_TWO_MACS_AND_PHONE.md
@@ -0,0 +1,149 @@
+# Two Macs and a Phone: First Sovereign Mesh Proof
+
+This demo is designed for a skeptical user to understand OCP in about 10 minutes. It uses two Macs on the same Wi-Fi network and one phone browser as the operator console.
+
+## Safety First
+
+WARNING: This demo binds OCP to `0.0.0.0` so other devices on the LAN can reach it. For LAN actions, set `OCP_OPERATOR_TOKEN` and use the phone link with a URL fragment token:
+
+```text
+http://HOST_IP:8421/app#ocp_operator_token=YOUR_TOKEN
+```
+
+Do not expose this alpha server to the internet. Do not use real secrets in demo jobs.
+
+## 1. Start Alpha on Machine A
+
+```bash
+OCP_HOST=0.0.0.0 OCP_NODE_ID=alpha-node OCP_DISPLAY_NAME=Alpha python3 scripts/start_ocp_easy.py
+```
+
+Keep the terminal open. Note the printed LAN share URL.
+
+For LAN operator actions, prefer the safer tokened form:
+
+```bash
+OCP_OPERATOR_TOKEN=change-me OCP_HOST=0.0.0.0 OCP_NODE_ID=alpha-node OCP_DISPLAY_NAME=Alpha python3 scripts/start_ocp_easy.py
+```
+
+## 2. Start Beta on Machine B
+
+```bash
+OCP_HOST=0.0.0.0 OCP_PORT=8422 OCP_NODE_ID=beta-node OCP_DISPLAY_NAME=Beta python3 scripts/start_ocp_easy.py
+```
+
+Keep this terminal open too.
+
+For LAN operator actions on Beta too:
+
+```bash
+OCP_OPERATOR_TOKEN=change-me OCP_HOST=0.0.0.0 OCP_PORT=8422 OCP_NODE_ID=beta-node OCP_DISPLAY_NAME=Beta python3 scripts/start_ocp_easy.py
+```
+
+## 3. Open the App on Machine A
+
+Open:
+
+```text
+http://127.0.0.1:8421/app
+```
+
+or use the URL printed by the starter.
+
+## 4. Open the Phone Link
+
+From Machine A, copy the phone link or LAN URL. On the phone, open:
+
+```text
+http://ALPHA_LAN_IP:8421/app#ocp_operator_token=change-me
+```
+
+The fragment after `#` stays in the phone browser and is not sent as part of the HTTP request path.
+
+## 5. Connect Everything
+
+In the app or easy setup view, use `Connect Everything`. OCP should discover or connect the two nodes. If automatic discovery misses, use `Copy My Easy Link` on one machine and paste it into the manual connect box on the other.
+
+## 6. Test Whole Mesh
+
+Use `Test Whole Mesh`. This launches the existing mesh proof flow and should produce operator-readable status about route health and peer cooperation.
+
+## 7. Run on Best Device
+
+If available, use `Run on Best Device`. Full laptop/workstation nodes started with `scripts/start_ocp_easy.py` advertise a default worker, so the scheduler can choose a placement for the demo workload.
+
+## 8. Replicate Proof Artifact
+
+If available, use `Replicate Proof Artifact`. Private proof artifacts require operator-mediated auth today. The app should avoid storing remote operator tokens and should use redacted sync metadata.
+
+## 9. Inspect the Mesh
+
+Open these URLs from a browser or use `curl`:
+
+```text
+http://ALPHA_LAN_IP:8421/mesh/manifest
+http://ALPHA_LAN_IP:8421/mesh/app/status
+http://ALPHA_LAN_IP:8421/mesh/routes/health
+http://ALPHA_LAN_IP:8421/mesh/artifacts
+http://ALPHA_LAN_IP:8421/mesh/scheduler/decisions
+```
+
+For private artifact content, use metadata-only inspection unless you intentionally authorize content access:
+
+```text
+http://ALPHA_LAN_IP:8421/mesh/artifacts/ARTIFACT_ID?include_content=0
+```
+
+## 10. What Happened
+
+You started two local-first OCP nodes, exposed them to the LAN for discovery, used the phone as an operator console, connected peers, tested route health, optionally scheduled work on the best available device, and optionally replicated a proof artifact with explicit operator mediation.
+
+The important boundary: OCP is not pretending the machines are one OS. It is creating a protocol-visible fabric where identity, manifests, routes, work, artifacts, and operator decisions can be inspected.
+
+## Troubleshooting
+
+Cannot find peer:
+
+- Make sure both machines are on the same Wi-Fi.
+- Try `Copy My Easy Link` and paste the URL manually.
+- Check `/mesh/discovery/candidates`.
+
+Firewall issue:
+
+- Allow incoming connections for Python or the OCP app on both Macs.
+- Confirm the port is reachable from the other machine.
+
+Wrong `HOST_IP`:
+
+- Use the LAN URL printed by `scripts/start_ocp_easy.py`.
+- Do not use `127.0.0.1` from the phone, because that points at the phone itself.
+
+Port conflict:
+
+- Use `OCP_PORT=8422` or another free port.
+- Stop any older OCP process before restarting.
+
+Empty deck:
+
+- A fresh node may have no demo activity.
+- Run `python3 scripts/seed_control_demo.py --base-url http://HOST_IP:8421` if you want sample UI data.
+
+No worker available:
+
+- Use `scripts/start_ocp_easy.py` on a full laptop/workstation node.
+- Check `/mesh/app/status` for execution readiness.
+
+Artifact replication denied:
+
+- Private content needs operator authorization or public artifact policy.
+- Use the app action or send explicit `remote_auth` only for trusted demos.
+
+Token missing:
+
+- Set `OCP_OPERATOR_TOKEN` before starting LAN mode.
+- Open the phone app with `#ocp_operator_token=YOUR_TOKEN`.
+
+Browser opened loopback URL from phone:
+
+- Replace `127.0.0.1` with the Mac's LAN IP.
+- Use the printed LAN share URL.
diff --git a/docs/OCP_HTTP_API.md b/docs/OCP_HTTP_API.md
new file mode 100644
index 0000000..db5e84c
--- /dev/null
+++ b/docs/OCP_HTTP_API.md
@@ -0,0 +1,89 @@
+# OCP HTTP API
+
+This is a human-readable overview of the current `/mesh/*` HTTP surface.
+
+`server_contract.py` is the code-owned source of truth for route metadata. It builds the same snapshot served by:
+
+```text
+GET /mesh/contract
+```
+
+Export the contract without starting the server:
+
+```bash
+python3 scripts/export_contract.py --pretty
+python3 scripts/export_contract.py --pretty --output docs/generated/OCP_CONTRACT_v0.1.json
+```
+
+## Route Groups
+
+The current contract contains 94 `/mesh/*` endpoints across these route groups:
+
+| Group | Purpose |
+|---|---|
+| runtime | manifests, contract, app status/history, device profile, discovery, peers, stream, leases, handoff |
+| control | server-sent control stream |
+| missions | jobs, missions, cooperative tasks, continuity, test missions |
+| ops | helpers, workers, approvals, notifications, treaties, secrets, queue, pressure, scheduler decisions |
+| artifacts | artifact list/get, publish, replicate, graph replicate, pin, purge, mirror verification |
+
+The app/status/control pages are outside the `/mesh/*` contract but are part of the same standalone HTTP server:
+
+- `/` and `/app`
+- `/easy`
+- `/control`
+- `/app.webmanifest`
+
+## Auth Modes
+
+OCP currently uses four practical auth modes:
+
+- public/local read: GET routes such as `/mesh/manifest` are readable without operator auth.
+- operator mutation: raw POST mutation routes require loopback by default or a configured operator token.
+- signed peer mutation: selected peer POST handlers accept signed protocol envelopes.
+- private artifact content: content reads require operator authorization unless artifact policy allows public access.
+
+See [Operator Authorization](./OPERATOR_AUTH.md) and [Security Model](./SECURITY_MODEL.md) for details.
+
+## Examples
+
+Read the local manifest:
+
+```bash
+curl http://127.0.0.1:8421/mesh/manifest
+```
+
+Read the live contract:
+
+```bash
+curl http://127.0.0.1:8421/mesh/contract
+```
+
+Connect a peer with an operator token:
+
+```bash
+curl -X POST http://HOST_IP:8421/mesh/peers/connect \
+ -H 'Content-Type: application/json' \
+ -H 'X-OCP-Operator-Token: change-me' \
+ -d '{"base_url":"http://PEER_IP:8422","trust_tier":"trusted"}'
+```
+
+Submit a high-level job example. Exact job shape is still governed by the protocol schema and current runtime support:
+
+```bash
+curl -X POST http://127.0.0.1:8421/mesh/jobs/submit \
+ -H 'Content-Type: application/json' \
+ -d '{"job":{"kind":"demo","command":"echo hello from ocp"}}'
+```
+
+Inspect artifact metadata without content:
+
+```bash
+curl 'http://127.0.0.1:8421/mesh/artifacts/ARTIFACT_ID?include_content=0'
+```
+
+## Stability
+
+OCP v0.1 APIs are alpha. The schema registry is descriptive and only partially enforcing. Response schema coverage may be partial, and future releases should add explicit stability labels per endpoint.
+
+Use the generated contract as an inspection and conformance aid, not as a final compatibility promise for independent implementations yet.
diff --git a/docs/OPERATOR_AUTH.md b/docs/OPERATOR_AUTH.md
new file mode 100644
index 0000000..20b2ab9
--- /dev/null
+++ b/docs/OPERATOR_AUTH.md
@@ -0,0 +1,106 @@
+# Operator Authorization
+
+OCP uses operator authorization to protect raw mesh mutation routes when a node is reachable beyond loopback. This is an alpha control-plane protection, not a production identity system.
+
+## Environment Variables
+
+`OCP_OPERATOR_TOKEN` is the preferred operator token variable.
+
+`OCP_CONTROL_TOKEN` is also accepted for compatibility. If both are set, `OCP_OPERATOR_TOKEN` wins.
+
+If neither token is configured, the server falls back to loopback-only authorization for raw mutation routes.
+
+## Accepted Request Credentials
+
+The server accepts an operator token from the first non-empty value among:
+
+- `X-OCP-Operator-Token: `
+- `X-OCP-Control-Token: `
+- `Authorization: Bearer `
+
+Bearer values are normalized by stripping the `Bearer ` prefix before comparison.
+
+## Loopback Fallback
+
+When no token is configured, raw mesh mutation routes are allowed from loopback clients such as `127.0.0.1`, `::1`, and `localhost`. Non-loopback clients are rejected for those routes.
+
+When a token is configured, loopback clients must also present the token for raw mesh mutation routes. This keeps LAN and local behavior consistent once the operator opts into token mode.
+
+Signed peer POST routes are a separate path and do not use operator-token auth as their primary gate.
+
+## Phone Links
+
+Phone links should carry the operator token in the URL fragment:
+
+```text
+http://HOST_IP:8421/app#ocp_operator_token=YOUR_TOKEN
+```
+
+Fragments are preferable to query strings because browsers do not send fragments to the HTTP server. That keeps the token out of normal server request paths, router logs, reverse-proxy logs, and analytics-style URL capture. The browser app can read the fragment locally and store the token for later OCP POST actions.
+
+Do not put operator tokens in query strings.
+
+## Behavior Table
+
+| Situation | Allowed? | Required credential |
+|---|---:|---|
+| `GET /mesh/manifest` from LAN | yes | none |
+| `POST /mesh/peers/connect` from loopback | yes | none if no token configured; operator token if token configured |
+| `POST /mesh/peers/connect` from LAN | no unless token configured | operator token |
+| signed peer `POST /mesh/handshake` | yes | signed envelope |
+| `GET` private artifact content from LAN | no unless authorized | operator token or public artifact policy |
+
+This table is based on `server_http_handlers.py`: GET routes are generally dispatched without operator auth, raw POST routes require operator auth unless their handler is in the signed peer allowlist, and private artifact content reads require operator auth unless policy allows public access.
+
+## Curl Examples
+
+Local manifest:
+
+```bash
+curl http://127.0.0.1:8421/mesh/manifest
+```
+
+LAN manifest:
+
+```bash
+curl http://HOST_IP:8421/mesh/manifest
+```
+
+Connect a peer with an operator token:
+
+```bash
+curl -X POST http://HOST_IP:8421/mesh/peers/connect \
+ -H 'Content-Type: application/json' \
+ -H 'X-OCP-Operator-Token: change-me' \
+ -d '{"base_url":"http://PEER_IP:8422","trust_tier":"trusted"}'
+```
+
+Use `Authorization: Bearer` instead:
+
+```bash
+curl -X POST http://HOST_IP:8421/mesh/peers/connect \
+ -H 'Content-Type: application/json' \
+ -H 'Authorization: Bearer change-me' \
+ -d '{"base_url":"http://PEER_IP:8422","trust_tier":"trusted"}'
+```
+
+Fetch artifact metadata without content:
+
+```bash
+curl 'http://HOST_IP:8421/mesh/artifacts/ARTIFACT_ID?include_content=0'
+```
+
+Fetch private artifact content with an operator token:
+
+```bash
+curl 'http://HOST_IP:8421/mesh/artifacts/ARTIFACT_ID' \
+ -H 'X-OCP-Operator-Token: change-me'
+```
+
+## Warnings
+
+- Rotate the token if it appears in shell history, screenshots, logs, or shared chat.
+- Do not use a real credential as an OCP operator token.
+- Do not expose the alpha server to the internet.
+- Use high-entropy tokens for LAN tests.
+- Prefer the generated phone link from the app or launcher when possible.
diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md
index 42067c0..697aca0 100644
--- a/docs/QUICKSTART.md
+++ b/docs/QUICKSTART.md
@@ -7,6 +7,7 @@ This is the fastest way to get **The Open Compute Protocol** running locally.
```bash
git clone https://github.com/workingclassbuddha/open-compute-protocol.git
cd open-compute-protocol
+python3 -m pip install -e .
```
## 2. Start one local node
@@ -117,6 +118,8 @@ Bind so another machine on your network can reach it:
OCP_HOST=0.0.0.0 ./scripts/start_ocp.sh
```
+LAN mode exposes the alpha HTTP server to your local network. Read [Security Model](./SECURITY_MODEL.md) and [Operator Authorization](./OPERATOR_AUTH.md) before using LAN mode beyond a trusted demo network.
+
If you want phone/LAN control actions when starting manually, set an operator token and open the app with that token in the URL fragment:
```bash
diff --git a/docs/ROADMAP_v0.1.7.md b/docs/ROADMAP_v0.1.7.md
new file mode 100644
index 0000000..709f286
--- /dev/null
+++ b/docs/ROADMAP_v0.1.7.md
@@ -0,0 +1,86 @@
+# OCP v0.1.7 Trustworthy Alpha Roadmap
+
+No major new concepts. Stabilize packaging, security docs, protocol contract, tests, and demo flow.
+
+## 1. Goal
+
+Make OCP easier to install, safer to understand, easier to test, and more credible as a protocol boundary while preserving the current v0.1.6 Desktop Alpha behavior.
+
+## 2. Non-goals
+
+- no large product features
+- no route removals or public API renames
+- no server replacement
+- no required database beyond SQLite
+- no cloud dependencies or external brokers
+- no production-security claims
+- no claim that OCP v0.1 is stable
+
+## 3. Release Checklist
+
+- packaging metadata exists
+- editable install works
+- operator auth and LAN safety docs exist
+- threat model exists
+- HTTP contract export script exists
+- generated contract JSON is available
+- HTTP API overview points to the code-owned contract
+- test subsystem directories exist for future focused tests
+- two-machine plus phone demo is documented
+- README and Quickstart link the new stabilization docs
+
+## 4. Packaging Work
+
+- Add `pyproject.toml` for the current flat Python layout.
+- Keep dependencies empty unless the runtime already requires them.
+- Add `ocp = "server:main"`.
+- Add `ocp-easy = "scripts.start_ocp_easy:main"` because `scripts/start_ocp_easy.py` exposes a clean `main()` function.
+- Add `MANIFEST.in` to include docs, scripts, assets, Swift sources, tests, license, README, and security policy.
+
+## 5. Security/Auth Work
+
+- Document loopback fallback behavior.
+- Document token-mode behavior and accepted headers.
+- Explain why phone links use URL fragments.
+- Warn about LAN binding, operator token leakage, remote artifact auth, executor risk, Docker mounts, and secrets in payloads or environment.
+
+## 6. Protocol/Contract Work
+
+- Keep `server_contract.py` as the code-owned source of truth.
+- Add `scripts/export_contract.py`.
+- Generate `docs/generated/OCP_CONTRACT_v0.1.json`.
+- Keep `scripts/check_protocol_conformance.py` as the conformance smoke check.
+
+## 7. Test-structure Work
+
+- Preserve `tests.test_sovereign_mesh` as the broad regression baseline.
+- Add subsystem directories for future focused tests.
+- Prefer protocol and conformance tests that use `server_contract.py` and `mesh_protocol` schemas.
+
+## 8. Demo Work
+
+- Add a two-Macs-and-phone walkthrough.
+- Use existing `scripts/start_ocp_easy.py` commands.
+- Include LAN operator token guidance.
+- Include troubleshooting for peer discovery, firewall, port, token, worker, deck, and artifact issues.
+
+## 9. Known Risks
+
+- The schema registry is descriptive and only partially enforcing.
+- Signed scoped capability grants are schema-defined but not fully enforced yet.
+- Operator-token remote artifact auth is an alpha bridge.
+- Worker execution can run powerful local code.
+- LAN demos depend on local firewall and router behavior.
+- Swift build/test availability depends on local Xcode and SwiftPM setup.
+
+## 10. Definition of Done
+
+- `python3 -m pip install -e .`
+- `python3 scripts/check_protocol_conformance.py`
+- `python3 -m unittest tests.test_sovereign_mesh`
+- `python3 server.py --help`
+- `docs/SECURITY_MODEL.md` exists
+- `docs/OPERATOR_AUTH.md` exists
+- `docs/THREAT_MODEL.md` exists
+- generated contract JSON exists or script exists to generate it
+- two-device demo doc exists
diff --git a/docs/SECURITY_MODEL.md b/docs/SECURITY_MODEL.md
new file mode 100644
index 0000000..629f762
--- /dev/null
+++ b/docs/SECURITY_MODEL.md
@@ -0,0 +1,128 @@
+# OCP Security Model
+
+OCP v0.1.7 is a trustworthy alpha, not a production security boundary. This document explains the current protection model so operators can make safer choices while the protocol and reference implementation mature.
+
+## What OCP Protects
+
+OCP currently focuses on local-first trust for a small mesh of devices you operate or deliberately trust:
+
+- local node identity material under the identity directory
+- peer manifests and signed peer handshakes
+- raw mesh mutation routes from arbitrary LAN clients
+- private artifact content unless policy permits public access
+- redaction of operator-mediated remote artifact tokens from stored metadata and responses
+- basic secret storage and delivery through the local SQLite runtime
+- durable jobs, attempts, artifacts, missions, scheduler decisions, and governance records
+
+## What OCP Does Not Yet Protect
+
+OCP does not yet provide production-grade isolation or enterprise-grade key management:
+
+- no stable security certification or external audit
+- signed scoped capability grants are schema-defined only and not yet enforced as private-content authorization
+- no mature revocation, key rotation, or peer permission matrix
+- no hardened executor sandbox policy across all lanes
+- no network isolation guarantee for Docker or WASM lanes
+- no durable audit export format intended for compliance
+- no guarantee that a malicious trusted peer cannot submit dangerous work if the operator allows it
+
+## Local-First Assumptions
+
+The default server binds to loopback. In that mode, OCP assumes the browser and CLI clients are local to the same machine and controlled by the operator. SQLite is the only required database. No external cloud service, queue, control plane, or broker is required for the standalone alpha flow.
+
+## Loopback Default Safety Model
+
+When no `OCP_OPERATOR_TOKEN` or `OCP_CONTROL_TOKEN` is configured, raw mesh mutation routes are allowed only from loopback clients. This makes the default `127.0.0.1:8421` startup safer for local experimentation.
+
+Loopback is not a substitute for host security. A local process running as the same user can still call OCP routes.
+
+## LAN Exposure Risk
+
+WARNING: Binding OCP to `0.0.0.0` exposes the HTTP server to the local network. Anyone on the LAN who can reach the port may be able to read public/local status routes and attempt operator actions.
+
+When using LAN mode:
+
+- set `OCP_OPERATOR_TOKEN` to a high-entropy value
+- send operator actions through `X-OCP-Operator-Token`, `X-OCP-Control-Token`, or `Authorization: Bearer`
+- avoid untrusted Wi-Fi networks
+- stop the server when the demo is over
+- do not expose the alpha server directly to the internet
+
+## Operator Token Behavior
+
+If `OCP_OPERATOR_TOKEN` or `OCP_CONTROL_TOKEN` is configured, non-signed raw mutation routes require a matching presented token. The server accepts:
+
+- `X-OCP-Operator-Token: `
+- `X-OCP-Control-Token: `
+- `Authorization: Bearer `
+
+WARNING: Operator token leakage gives the holder operator authority over raw mutation routes. Treat the token like a password. Do not paste it into logs, screenshots, shell history you share, or query strings.
+
+## Signed Peer Request Behavior
+
+Some peer POST handlers are allowed as signed peer traffic instead of operator-token traffic:
+
+- `POST /mesh/handshake`
+- `POST /mesh/jobs/submit`
+- `POST /mesh/artifacts/publish`
+- `POST /mesh/agents/handoff`
+
+Those requests are still protocol-alpha surfaces. They rely on signed envelopes and handler-level validation, but peer permissions are not yet a complete capability system.
+
+## Artifact Access Behavior
+
+Artifact metadata is listable through the artifact routes. Artifact content is more sensitive:
+
+- `GET /mesh/artifacts/{artifact_id}?include_content=0` returns metadata without content.
+- `GET /mesh/artifacts/{artifact_id}` includes content by default.
+- Private content from LAN clients requires operator authorization unless artifact policy allows public access.
+
+WARNING: Private artifact replication currently supports explicit operator-token `remote_auth` in the request body. That is an operator-mediated alpha bridge, not the final security model. Capability grants now have an alpha schema and expiry/redaction helper, but grant signatures are not yet enforced by the HTTP artifact content gate.
+
+## Secret Delivery Behavior
+
+OCP has a local secret surface for execution and runtime flows. Secrets should be scoped narrowly and kept out of payloads whenever possible.
+
+WARNING: Secrets passed in JSON payloads, shell commands, environment variables, or job metadata can be exposed through process inspection, logs, history, crash reports, or accidental artifact publication. Prefer explicit secret references and keep demos free of real credentials.
+
+## Execution Risk
+
+OCP can run shell, Python, Docker, and WASM-style workloads through the execution service.
+
+WARNING: Running shell or Python jobs from peers is equivalent to running code chosen by another party on your machine. Only enable worker execution for peers and workloads you trust.
+
+WARNING: Docker jobs can still touch host resources if mounted workspaces, sockets, credentials, or broad paths are exposed. Treat Docker host workspace mounts as sensitive until stricter sandbox policy exists.
+
+WASM is the intended safer direction for portable execution, but the alpha does not yet claim a complete WASM isolation boundary.
+
+## Trust Tiers
+
+Trust tiers are currently policy hints used by peer, helper, scheduler, and operator flows. They help the reference implementation explain posture and choose safer defaults, but they are not yet a complete permissions system.
+
+Current meaning is modest:
+
+- trusted peers may be considered for more cooperation
+- lower-trust peers should be treated as discovery or limited-control participants
+- approval and treaty surfaces can advise operators, but enforcement is still partial
+
+## Known Alpha Limitations
+
+- protocol schemas are descriptive and only partially enforcing
+- response schema coverage is incomplete
+- peer permissions are coarse
+- capability grants are not fully enforced
+- token rotation and revocation are manual
+- Docker/WASM isolation policy is still evolving
+- audit trails are useful for debugging, not compliance
+- LAN demos depend on local firewall and router behavior
+
+## Recommended Safe Defaults
+
+- run local-only with `127.0.0.1` unless you are actively testing LAN mode
+- set `OCP_OPERATOR_TOKEN` before binding to `0.0.0.0`
+- use phone links with URL fragments for token bootstrap
+- avoid real secrets and private data in alpha demos
+- run workers only on machines you control
+- keep artifact content private unless you deliberately publish it
+- prefer metadata-only artifact reads when inspecting from LAN
+- stop the server after demos on shared networks
diff --git a/docs/THREAT_MODEL.md b/docs/THREAT_MODEL.md
new file mode 100644
index 0000000..2b6fb93
--- /dev/null
+++ b/docs/THREAT_MODEL.md
@@ -0,0 +1,98 @@
+# OCP Threat Model
+
+OCP v0.1.7 is an alpha reference implementation for a local-first compute protocol. This threat model is intentionally conservative: it documents what the current code helps with and what remains future work.
+
+## Assets
+
+- node identity keys and peer identity records
+- operator token and phone-link bootstrap token
+- local SQLite runtime state
+- worker queue, attempts, missions, and scheduler decisions
+- artifact metadata and private artifact content
+- secrets and execution environment bindings
+- route health, peer manifests, and discovery records
+- audit-like events and operator approvals
+
+## Actors
+
+- local operator on the same machine
+- phone or browser acting as an operator console
+- trusted peer node on the LAN
+- semi-trusted discovered peer
+- untrusted LAN client
+- malicious local process
+- compromised trusted peer
+- accidental operator error
+
+## Trust Boundaries
+
+- loopback HTTP boundary
+- LAN HTTP boundary when binding to `0.0.0.0`
+- signed peer envelope boundary
+- operator-token boundary
+- SQLite persistence boundary
+- artifact content boundary
+- executor boundary between the OCP server and shell/Python/Docker/WASM jobs
+- browser boundary for phone-token storage
+
+## Entry Points
+
+- `GET /`, `/app`, `/easy`, and `/control`
+- read-oriented `/mesh/*` GET routes
+- raw mutation `/mesh/*` POST routes
+- signed peer POST routes such as `/mesh/handshake`
+- artifact content reads under `/mesh/artifacts/{artifact_id}`
+- worker polling, claiming, and attempt completion
+- secret put/list flows
+- local scripts such as `scripts/start_ocp_easy.py`
+
+## Abuse Cases
+
+- a LAN client attempts to connect peers or mutate device profile without authorization
+- a leaked operator token is used to submit jobs or replicate private artifacts
+- a trusted peer submits shell or Python work that reads local files
+- a Docker job receives a broad host workspace mount
+- a private artifact is fetched from LAN without authorization
+- a token is placed in a query string and captured by logs
+- a stale trusted peer identity is reused after compromise
+- a malicious peer submits a signed envelope for a currently allowed peer route
+- secrets in payloads or environment leak into logs or artifacts
+
+## Mitigations Already Present
+
+- default loopback binding for the standalone server
+- raw mesh mutation routes require loopback unless an operator token is configured
+- operator tokens accepted through dedicated headers or bearer auth
+- tokened phone links use URL fragments instead of query strings
+- selected signed peer POST handlers are separated from raw operator mutations
+- private artifact content requires operator auth unless artifact policy is public
+- artifact replication remote auth is redacted from stored response and sync metadata
+- protocol contract and schema snapshots exist for conformance work
+- SQLite remains local and requires no external broker or control plane
+
+## Mitigations Not Yet Present
+
+- signed scoped capability grant enforcement for private artifact replication
+- complete peer permission matrix
+- key rotation and revocation flows
+- durable audit export suitable for external review
+- executor sandbox policy that is strict by default across shell, Python, Docker, and WASM
+- network isolation policy for Docker/WASM jobs
+- formal separation between demo-trust and real workload-trust tiers
+- comprehensive security-focused conformance tests
+
+## Priority Security Backlog
+
+1. Canonicalize and verify signed scoped capability grants.
+2. Enforce grant audience, subject, expiry, scope, and artifact constraints in the HTTP content gate.
+3. Add key rotation and revocation mechanics.
+4. Clarify peer permissions per route group.
+5. Add durable audit export with token and grant-proof redaction checks.
+6. Define executor sandbox policy and default-deny host mounts.
+7. Add stricter network isolation for Docker/WASM.
+8. Add more security-focused conformance tests.
+9. Keep `remote_auth` operator-token replication only as an explicit fallback.
+
+## Alpha Position
+
+The current implementation is good enough for local development, demos, and protocol-boundary work by careful operators. It should not be treated as production-secure, internet-facing infrastructure.
diff --git a/docs/generated/OCP_CONTRACT_v0.1.json b/docs/generated/OCP_CONTRACT_v0.1.json
new file mode 100644
index 0000000..f210550
--- /dev/null
+++ b/docs/generated/OCP_CONTRACT_v0.1.json
@@ -0,0 +1,4909 @@
+{
+ "conformance": {
+ "fixture_count": 14,
+ "fixtures": [
+ {
+ "id": "signed-envelope-minimal",
+ "purpose": "Canonical minimal signed envelope shape used across POST /mesh routes.",
+ "schema_ref": "SignedEnvelope",
+ "validation": {
+ "issues": [],
+ "schema_ref": "SignedEnvelope",
+ "status": "ok"
+ },
+ "value": {
+ "body": {
+ "artifact": {
+ "descriptor": {
+ "artifact_id": "artifact-fixture",
+ "digest": "f00d"
+ }
+ }
+ },
+ "request": {
+ "implementation": "Sovereign Mesh",
+ "node_id": "fixture-node",
+ "nonce": "fixture-nonce",
+ "protocol_family": "Open Compute Protocol",
+ "protocol_release": "0.1",
+ "protocol_version": "sovereign-mesh/v1",
+ "request_id": "fixture-request",
+ "signature": "fixture-signature",
+ "signature_scheme": "ed25519-sha512-v1",
+ "timestamp": "2026-01-01T00:00:00Z"
+ }
+ }
+ },
+ {
+ "id": "mesh-manifest-minimal",
+ "purpose": "Minimal live-manifest shape advertised by a node.",
+ "schema_ref": "MeshManifest",
+ "validation": {
+ "issues": [],
+ "schema_ref": "MeshManifest",
+ "status": "ok"
+ },
+ "value": {
+ "continuity_capabilities": {
+ "custody_review": true,
+ "mission_continuity": true
+ },
+ "device_profile": {
+ "device_class": "full",
+ "form_factor": "workstation"
+ },
+ "governance_summary": {
+ "active_treaty_ids": [
+ "treaty/fixture-v1"
+ ]
+ },
+ "implementation": {
+ "name": "Sovereign Mesh"
+ },
+ "organism_card": {
+ "continuity_capabilities": {
+ "custody_review": true,
+ "mission_continuity": true
+ },
+ "device_profile": {
+ "device_class": "full",
+ "form_factor": "workstation"
+ },
+ "display_name": "Fixture Node",
+ "endpoint_url": "http://127.0.0.1:8421",
+ "node_id": "fixture-node",
+ "organism_id": "fixture-node",
+ "protocol_version": "sovereign-mesh/v1",
+ "public_key": "fixture-public-key",
+ "treaty_capabilities": {
+ "continuity_validation": true,
+ "treaty_documents": true
+ },
+ "trust_tier": "self"
+ },
+ "protocol": "Open Compute Protocol",
+ "protocol_release": "0.1",
+ "protocol_short_name": "OCP",
+ "protocol_version": "sovereign-mesh/v1",
+ "sync_policy": {
+ "sleep_capable": false
+ },
+ "treaty_capabilities": {
+ "continuity_validation": true,
+ "treaty_documents": true
+ }
+ }
+ },
+ {
+ "id": "job-submission-request",
+ "purpose": "Representative queued Python job submission body.",
+ "schema_ref": "JobSubmissionRequest",
+ "validation": {
+ "issues": [],
+ "schema_ref": "JobSubmissionRequest",
+ "status": "ok"
+ },
+ "value": {
+ "job": {
+ "dispatch_mode": "queued",
+ "kind": "python.inline",
+ "metadata": {
+ "origin": "conformance-fixture"
+ },
+ "payload": {
+ "code": "print('fixture job')"
+ },
+ "policy": {
+ "classification": "trusted",
+ "mode": "batch"
+ },
+ "requirements": {
+ "capabilities": [
+ "python"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "id": "artifact-minimal",
+ "purpose": "Artifact descriptor/result shape returned by /mesh/artifacts endpoints.",
+ "schema_ref": "Artifact",
+ "validation": {
+ "issues": [],
+ "schema_ref": "Artifact",
+ "status": "ok"
+ },
+ "value": {
+ "artifact_kind": "bundle",
+ "created_at": "2026-01-01T00:00:00Z",
+ "descriptor": {
+ "artifact_id": "artifact-fixture",
+ "artifact_kind": "bundle",
+ "digest": "abc123",
+ "media_type": "application/json",
+ "size_bytes": 42
+ },
+ "digest": "abc123",
+ "id": "artifact-fixture",
+ "media_type": "application/json",
+ "metadata": {
+ "job_id": "job-fixture"
+ },
+ "size_bytes": 42
+ }
+ },
+ {
+ "id": "artifact-replicate-request-operator-mediated",
+ "purpose": "Explicit operator-mediated artifact pull request without persisting remote credentials.",
+ "schema_ref": "ArtifactReplicateRequest",
+ "validation": {
+ "issues": [],
+ "schema_ref": "ArtifactReplicateRequest",
+ "status": "ok"
+ },
+ "value": {
+ "artifact_id": "artifact-fixture",
+ "peer_id": "beta-node",
+ "pin": true,
+ "remote_auth": {
+ "token": "fixture-token",
+ "type": "operator_token"
+ }
+ }
+ },
+ {
+ "id": "capability-grant-artifact-read",
+ "purpose": "Alpha signed scoped grant shape for one private artifact read.",
+ "schema_ref": "CapabilityGrant",
+ "validation": {
+ "issues": [],
+ "schema_ref": "CapabilityGrant",
+ "status": "ok"
+ },
+ "value": {
+ "audience_peer_id": "beta-node",
+ "expires_at": "2026-01-01T00:05:00Z",
+ "grant_id": "grant-alpha-private-artifact",
+ "issued_at": "2026-01-01T00:00:00Z",
+ "issuer_peer_id": "beta-node",
+ "nonce": "grant-fixture-nonce",
+ "scope": {
+ "action": "artifact.read",
+ "artifact_id": "artifact-fixture",
+ "digest": "abc123",
+ "max_uses": 1
+ },
+ "signature": "fixture-signature",
+ "signature_scheme": "ed25519-sha512-v1",
+ "subject_peer_id": "alpha-node"
+ }
+ },
+ {
+ "id": "artifact-replicate-request-capability-grant",
+ "purpose": "Private artifact replication request carrying a declared scoped grant instead of a remote operator token.",
+ "schema_ref": "ArtifactReplicateRequest",
+ "validation": {
+ "issues": [],
+ "schema_ref": "ArtifactReplicateRequest",
+ "status": "ok"
+ },
+ "value": {
+ "artifact_id": "artifact-fixture",
+ "peer_id": "beta-node",
+ "pin": true,
+ "remote_auth": {
+ "grant": {
+ "audience_peer_id": "beta-node",
+ "expires_at": "2026-01-01T00:05:00Z",
+ "grant_id": "grant-alpha-private-artifact",
+ "issued_at": "2026-01-01T00:00:00Z",
+ "issuer_peer_id": "beta-node",
+ "nonce": "grant-fixture-nonce",
+ "scope": {
+ "action": "artifact.read",
+ "artifact_id": "artifact-fixture",
+ "digest": "abc123",
+ "max_uses": 1
+ },
+ "signature": "fixture-signature",
+ "signature_scheme": "ed25519-sha512-v1",
+ "subject_peer_id": "alpha-node"
+ },
+ "type": "capability_grant"
+ }
+ }
+ },
+ {
+ "id": "artifact-replicate-response-redacted-auth",
+ "purpose": "Artifact replication response with route proof and redacted remote auth metadata.",
+ "schema_ref": "ArtifactReplicateResponse",
+ "validation": {
+ "issues": [],
+ "schema_ref": "ArtifactReplicateResponse",
+ "status": "ok"
+ },
+ "value": {
+ "artifact": {
+ "artifact_kind": "bundle",
+ "digest": "abc123",
+ "id": "artifact-local",
+ "media_type": "application/json"
+ },
+ "remote_auth": {
+ "redacted": true,
+ "status": "used",
+ "type": "operator_token"
+ },
+ "route_proof": {
+ "best_route": "http://192.168.1.22:8421",
+ "status": "fresh"
+ },
+ "source": {
+ "artifact_id": "artifact-fixture",
+ "digest": "abc123",
+ "peer_id": "beta-node"
+ },
+ "status": "replicated",
+ "verification": {
+ "status": "verified",
+ "verified": true
+ }
+ }
+ },
+ {
+ "id": "continuity-restore-request",
+ "purpose": "Dry-run restore planning request for a continuity vessel.",
+ "schema_ref": "ContinuityRestorePlanRequest",
+ "validation": {
+ "issues": [],
+ "schema_ref": "ContinuityRestorePlanRequest",
+ "status": "ok"
+ },
+ "value": {
+ "artifact_id": "vessel-fixture",
+ "constraints": {
+ "prefer_device_classes": [
+ "relay",
+ "full"
+ ]
+ },
+ "target_peer_id": "trusted-peer"
+ }
+ },
+ {
+ "id": "treaty-audit-request",
+ "purpose": "Treaty validation request for continuity-bound operations.",
+ "schema_ref": "TreatyAuditRequest",
+ "validation": {
+ "issues": [],
+ "schema_ref": "TreatyAuditRequest",
+ "status": "ok"
+ },
+ "value": {
+ "metadata": {
+ "source": "contract-fixture"
+ },
+ "operation": "continuity_restore",
+ "treaty_requirements": [
+ "treaty/fixture-v1"
+ ]
+ }
+ },
+ {
+ "id": "route-health-reachable",
+ "purpose": "A proven HTTP route for a nearby trusted peer.",
+ "schema_ref": "RouteHealth",
+ "validation": {
+ "issues": [],
+ "schema_ref": "RouteHealth",
+ "status": "ok"
+ },
+ "value": {
+ "age_seconds": 0,
+ "best_route": "http://192.168.1.22:8421",
+ "candidates": [
+ {
+ "base_url": "http://192.168.1.22:8421",
+ "checked_at": "2026-01-01T00:00:00Z",
+ "failure_count": 0,
+ "freshness": "fresh",
+ "last_error": "",
+ "last_success_at": "2026-01-01T00:00:00Z",
+ "latency_ms": 12,
+ "next_probe_after": "",
+ "operator_hint": "",
+ "source": "last_reachable",
+ "status": "reachable"
+ }
+ ],
+ "checked_at": "2026-01-01T00:00:00Z",
+ "display_name": "Beta",
+ "failure_count": 0,
+ "freshness": "fresh",
+ "last_error": "",
+ "last_reachable_base_url": "http://192.168.1.22:8421",
+ "last_success_at": "2026-01-01T00:00:00Z",
+ "next_probe_after": "",
+ "operator_hint": "",
+ "operator_summary": "Beta is reachable at http://192.168.1.22:8421.",
+ "peer_id": "beta-node",
+ "status": "reachable"
+ }
+ },
+ {
+ "id": "autonomic-activate-request",
+ "purpose": "Assisted one-button mesh activation request from the phone control surface.",
+ "schema_ref": "AutonomicActivateRequest",
+ "validation": {
+ "issues": [],
+ "schema_ref": "AutonomicActivateRequest",
+ "status": "ok"
+ },
+ "value": {
+ "actor_agent_id": "ocp-mobile-ui",
+ "limit": 24,
+ "max_enlist": 2,
+ "mode": "assisted",
+ "repair": true,
+ "request_id": "autonomic-fixture",
+ "run_proof": true,
+ "scan_timeout": 0.8,
+ "timeout": 3.0
+ }
+ },
+ {
+ "id": "app-status-operator-home",
+ "purpose": "Compact operator-facing status used by the installable OCP app home.",
+ "schema_ref": "AppStatus",
+ "validation": {
+ "issues": [],
+ "schema_ref": "AppStatus",
+ "status": "ok"
+ },
+ "value": {
+ "app_urls": {
+ "app_url": "http://192.168.1.10:8421/app",
+ "base_url": "http://192.168.1.10:8421",
+ "control_url": "http://192.168.1.10:8421/control",
+ "lan_urls": [
+ "http://192.168.1.10:8421/app"
+ ],
+ "phone_url": "http://192.168.1.10:8421/app",
+ "setup_url": "http://192.168.1.10:8421/easy",
+ "share_advice": "",
+ "sharing_mode": "lan"
+ },
+ "approvals": {
+ "items": [],
+ "operator_summary": "No approvals are waiting.",
+ "pending_count": 0
+ },
+ "artifact_sync": {
+ "items": [],
+ "operator_summary": "1 replicated artifact(s) verified.",
+ "replicated_count": 1,
+ "status": "verified",
+ "verified_count": 1
+ },
+ "autonomy": {
+ "mode": "assisted",
+ "operator_summary": "Mesh is strong.",
+ "status": "ok"
+ },
+ "execution_readiness": {
+ "local": {
+ "ready_worker_count": 1,
+ "worker_count": 1
+ },
+ "operator_summary": "Execution is ready.",
+ "status": "ready",
+ "targets": [
+ {
+ "peer_id": "alpha-node",
+ "reasons": [
+ "local worker registered"
+ ],
+ "status": "ready"
+ }
+ ],
+ "worker_capacity": [
+ {
+ "available_slots": 1,
+ "capabilities": [
+ "worker-runtime",
+ "shell"
+ ],
+ "max_concurrent_jobs": 1,
+ "peer_id": "alpha-node",
+ "resources": {
+ "cpu": 1
+ },
+ "status": "active",
+ "worker_id": "alpha-default-worker"
+ }
+ ]
+ },
+ "generated_at": "2026-01-01T00:00:00Z",
+ "latest_proof": {
+ "mission_id": "mission-fixture",
+ "status": "completed",
+ "summary": "Whole Mesh Test Mission is completed.",
+ "title": "Whole Mesh Test Mission"
+ },
+ "mesh_quality": {
+ "healthy_routes": 1,
+ "label": "Mesh strong",
+ "operator_summary": "Mesh is strong.",
+ "peer_count": 1,
+ "route_count": 1,
+ "status": "strong"
+ },
+ "next_actions": [
+ "Mesh is ready."
+ ],
+ "node": {
+ "device_class": "full",
+ "display_name": "Alpha",
+ "form_factor": "laptop",
+ "node_id": "alpha-node",
+ "protocol_release": "0.1",
+ "protocol_version": "sovereign-mesh/v1"
+ },
+ "protocol": {
+ "contract_url": "/mesh/contract",
+ "release": "0.1",
+ "schema_version": "ocp-protocol-schemas/v1alpha1",
+ "version": "sovereign-mesh/v1"
+ },
+ "route_health": {
+ "count": 1,
+ "healthy": 1,
+ "routes": [
+ {
+ "candidates": [],
+ "peer_id": "beta-node",
+ "status": "reachable"
+ }
+ ],
+ "status": "ok"
+ },
+ "setup": {
+ "bind_mode": "lan",
+ "blocker_code": "",
+ "blocking_issue": "",
+ "device_roles": [
+ {
+ "display_name": "Alpha",
+ "peer_id": "alpha-node",
+ "role": "local_command",
+ "status": "ready",
+ "summary": "This Mac is the local command node."
+ },
+ {
+ "display_name": "Beta",
+ "peer_id": "beta-node",
+ "role": "compute",
+ "status": "ready",
+ "summary": "Beta is ready for compute work."
+ }
+ ],
+ "healthy_route_count": 1,
+ "known_peer_count": 1,
+ "label": "Mesh strong",
+ "latest_proof_status": "completed",
+ "next_fix": "No fix needed. The current mesh proof completed.",
+ "operator_summary": "Mesh is strong. Devices have proven routes and the latest proof completed.",
+ "phone_url": "http://192.168.1.10:8421/app",
+ "primary_action": "activate_mesh",
+ "primary_peer": {
+ "display_name": "Beta",
+ "peer_id": "beta-node",
+ "role": "compute",
+ "route": "http://192.168.1.22:8421",
+ "status": "ready",
+ "summary": "Beta is best for compute right now."
+ },
+ "recovery_state": "healthy",
+ "route_count": 1,
+ "status": "strong",
+ "story": [
+ "Mesh is strong.",
+ "Beta is best for compute right now.",
+ "Whole-mesh proof completed."
+ ],
+ "timeline": [
+ {
+ "created_at": "2026-01-01T00:00:00Z",
+ "kind": "proof_completed",
+ "status": "ok",
+ "summary": "Whole-mesh proof completed."
+ }
+ ],
+ "token_status": "configured"
+ },
+ "status": "ok"
+ }
+ },
+ {
+ "id": "contract-snapshot-minimal",
+ "purpose": "Minimal /mesh/contract response shape.",
+ "schema_ref": "ContractSnapshot",
+ "validation": {
+ "issues": [],
+ "schema_ref": "ContractSnapshot",
+ "status": "ok"
+ },
+ "value": {
+ "conformance": {
+ "fixture_count": 0,
+ "fixtures": [],
+ "invalid_fixture_count": 0,
+ "status": "ok"
+ },
+ "contract_version": "ocp-http-contract/v1alpha1",
+ "endpoint_count": 1,
+ "endpoints": [
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_manifest",
+ "id": "get:/mesh/manifest",
+ "method": "GET",
+ "path": "/mesh/manifest",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "MeshManifest",
+ "type": "object"
+ }
+ }
+ ],
+ "groups": {
+ "runtime": {
+ "count": 1,
+ "methods": [
+ "GET"
+ ]
+ }
+ },
+ "protocol_surface": "/mesh/*",
+ "schema_count": 1,
+ "schema_version": "ocp-protocol-schemas/v1alpha1",
+ "schemas": {
+ "MeshManifest": {
+ "type": "object"
+ }
+ },
+ "status": "ok"
+ }
+ }
+ ],
+ "invalid_fixture_count": 0,
+ "schema_version": "ocp-protocol-schemas/v1alpha1",
+ "status": "ok"
+ },
+ "contract_version": "ocp-http-contract/v1alpha1",
+ "endpoint_count": 94,
+ "endpoints": [
+ {
+ "group": "control",
+ "handler": "_handle_control_stream",
+ "id": "get:/mesh/control/stream",
+ "method": "GET",
+ "path": "/mesh/control/stream",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "once": "boolean",
+ "since": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ControlStreamSSE",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_contract",
+ "id": "get:/mesh/contract",
+ "method": "GET",
+ "path": "/mesh/contract",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ContractSnapshot",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_app_status",
+ "id": "get:/mesh/app/status",
+ "method": "GET",
+ "path": "/mesh/app/status",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "AppStatus",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_app_history",
+ "id": "get:/mesh/app/history",
+ "method": "GET",
+ "path": "/mesh/app/history",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "AppStatusHistory",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_manifest",
+ "id": "get:/mesh/manifest",
+ "method": "GET",
+ "path": "/mesh/manifest",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "MeshManifest",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_device_profile",
+ "id": "get:/mesh/device-profile",
+ "method": "GET",
+ "path": "/mesh/device-profile",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "DeviceProfileResponse",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_connectivity_diagnostics",
+ "id": "get:/mesh/connectivity/diagnostics",
+ "method": "GET",
+ "path": "/mesh/connectivity/diagnostics",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_autonomy_status",
+ "id": "get:/mesh/autonomy/status",
+ "method": "GET",
+ "path": "/mesh/autonomy/status",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "AutonomicMeshStatus",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_routes_health",
+ "id": "get:/mesh/routes/health",
+ "method": "GET",
+ "path": "/mesh/routes/health",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "RouteHealthList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_discovery_candidates",
+ "id": "get:/mesh/discovery/candidates",
+ "method": "GET",
+ "path": "/mesh/discovery/candidates",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "status": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "DiscoveryCandidateList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_peers",
+ "id": "get:/mesh/peers",
+ "method": "GET",
+ "path": "/mesh/peers",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "PeerList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_stream",
+ "id": "get:/mesh/stream",
+ "method": "GET",
+ "path": "/mesh/stream",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "since": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "EventStreamSnapshot",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_job_get",
+ "id": "get:/mesh/jobs/{job_id}",
+ "method": "GET",
+ "path": "/mesh/jobs/{job_id}",
+ "request": {
+ "argument_kind": "path",
+ "path": {
+ "job_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Job",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_missions",
+ "id": "get:/mesh/missions",
+ "method": "GET",
+ "path": "/mesh/missions",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "status": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "MissionList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_mission_continuity_get",
+ "id": "get:/mesh/missions/{mission_id}/continuity",
+ "method": "GET",
+ "path": "/mesh/missions/{mission_id}/continuity",
+ "request": {
+ "argument_kind": "path",
+ "path": {
+ "mission_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "MissionContinuitySummary",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_mission_get",
+ "id": "get:/mesh/missions/{mission_id}",
+ "method": "GET",
+ "path": "/mesh/missions/{mission_id}",
+ "request": {
+ "argument_kind": "path",
+ "path": {
+ "mission_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Mission",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_cooperative_tasks",
+ "id": "get:/mesh/cooperative-tasks",
+ "method": "GET",
+ "path": "/mesh/cooperative-tasks",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "state": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "CooperativeTaskList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_cooperative_task_get",
+ "id": "get:/mesh/cooperative-tasks/{task_id}",
+ "method": "GET",
+ "path": "/mesh/cooperative-tasks/{task_id}",
+ "request": {
+ "argument_kind": "path",
+ "path": {
+ "task_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "CooperativeTask",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_pressure",
+ "id": "get:/mesh/pressure",
+ "method": "GET",
+ "path": "/mesh/pressure",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "MeshPressure",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_helpers",
+ "id": "get:/mesh/helpers",
+ "method": "GET",
+ "path": "/mesh/helpers",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "HelperList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_helpers_preferences",
+ "id": "get:/mesh/helpers/preferences",
+ "method": "GET",
+ "path": "/mesh/helpers/preferences",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "peer_id": "string",
+ "workload_class": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_helpers_autonomy",
+ "id": "get:/mesh/helpers/autonomy",
+ "method": "GET",
+ "path": "/mesh/helpers/autonomy",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "AutonomousOffloadEvaluation",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_workers",
+ "id": "get:/mesh/workers",
+ "method": "GET",
+ "path": "/mesh/workers",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "WorkerList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_notifications",
+ "id": "get:/mesh/notifications",
+ "method": "GET",
+ "path": "/mesh/notifications",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "status": "string",
+ "target_agent_id": "string",
+ "target_peer_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "NotificationList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_approvals",
+ "id": "get:/mesh/approvals",
+ "method": "GET",
+ "path": "/mesh/approvals",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "status": "string",
+ "target_agent_id": "string",
+ "target_peer_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ApprovalList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_treaties",
+ "id": "get:/mesh/treaties",
+ "method": "GET",
+ "path": "/mesh/treaties",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "status": "string",
+ "treaty_type": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "TreatyList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_treaty_get",
+ "id": "get:/mesh/treaties/{treaty_id}",
+ "method": "GET",
+ "path": "/mesh/treaties/{treaty_id}",
+ "request": {
+ "argument_kind": "path",
+ "path": {
+ "treaty_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Treaty",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_secrets",
+ "id": "get:/mesh/secrets",
+ "method": "GET",
+ "path": "/mesh/secrets",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "scope": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "SecretList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_queue",
+ "id": "get:/mesh/queue",
+ "method": "GET",
+ "path": "/mesh/queue",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "status": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "QueueMessageList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_queue_events",
+ "id": "get:/mesh/queue/events",
+ "method": "GET",
+ "path": "/mesh/queue/events",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "job_id": "string",
+ "limit": "integer",
+ "queue_message_id": "string",
+ "since": "integer",
+ "since_seq": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "QueueEventList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_queue_metrics",
+ "id": "get:/mesh/queue/metrics",
+ "method": "GET",
+ "path": "/mesh/queue/metrics",
+ "request": {
+ "argument_kind": "none"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "QueueMetrics",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_scheduler_decisions",
+ "id": "get:/mesh/scheduler/decisions",
+ "method": "GET",
+ "path": "/mesh/scheduler/decisions",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "limit": "integer",
+ "status": "string",
+ "target_type": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "SchedulerDecisionList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "artifacts",
+ "handler": "_handle_mesh_artifact_list",
+ "id": "get:/mesh/artifacts",
+ "method": "GET",
+ "path": "/mesh/artifacts",
+ "request": {
+ "argument_kind": "params",
+ "query": {
+ "artifact_kind": "string",
+ "attempt_id": "string",
+ "digest": "string",
+ "job_id": "string",
+ "limit": "integer",
+ "media_type": "string",
+ "owner_peer_id": "string",
+ "parent_artifact_id": "string",
+ "retention_class": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ArtifactList",
+ "type": "object"
+ }
+ },
+ {
+ "group": "artifacts",
+ "handler": "_handle_mesh_artifact_get",
+ "id": "get:/mesh/artifacts/{artifact_id}",
+ "method": "GET",
+ "path": "/mesh/artifacts/{artifact_id}",
+ "request": {
+ "argument_kind": "path_params",
+ "path": {
+ "artifact_id": "string"
+ },
+ "query": {
+ "include_content": "boolean"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Artifact",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_handshake",
+ "id": "post:/mesh/handshake",
+ "method": "POST",
+ "path": "/mesh/handshake",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "manifest": "object",
+ "peer_card": "signed_envelope"
+ },
+ "schema_ref": "SignedEnvelope"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "HandshakeResponse",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_device_profile_update",
+ "id": "post:/mesh/device-profile",
+ "method": "POST",
+ "path": "/mesh/device-profile",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "device_profile": "object"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "DeviceProfileResponse",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_app_history_sample",
+ "id": "post:/mesh/app/history/sample",
+ "method": "POST",
+ "path": "/mesh/app/history/sample",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "source": "string"
+ },
+ "schema_ref": "AppHistorySampleRequest"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "AppHistorySampleResponse",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_autonomy_activate",
+ "id": "post:/mesh/autonomy/activate",
+ "method": "POST",
+ "path": "/mesh/autonomy/activate",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "limit": "integer",
+ "mode": "string",
+ "repair": "boolean",
+ "run_proof": "boolean"
+ },
+ "schema_ref": "AutonomicActivateRequest"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "AutonomicRun",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_routes_probe",
+ "id": "post:/mesh/routes/probe",
+ "method": "POST",
+ "path": "/mesh/routes/probe",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "base_url": "string",
+ "limit": "integer",
+ "peer_id": "string",
+ "timeout": "number"
+ },
+ "schema_ref": "RouteProbeRequest"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "RouteProbeResult",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_discovery_seek",
+ "id": "post:/mesh/discovery/seek",
+ "method": "POST",
+ "path": "/mesh/discovery/seek",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "auto_connect": "boolean",
+ "base_urls": "array",
+ "cidr": "string",
+ "hosts": "array",
+ "limit": "integer",
+ "port": "integer",
+ "trust_tier": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_discovery_scan_local",
+ "id": "post:/mesh/discovery/scan-local",
+ "method": "POST",
+ "path": "/mesh/discovery/scan-local",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "limit": "integer",
+ "port": "integer",
+ "timeout": "number",
+ "trust_tier": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_peers_connect",
+ "id": "post:/mesh/peers/connect",
+ "method": "POST",
+ "path": "/mesh/peers/connect",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "base_url": "string",
+ "peer_id": "string",
+ "trust_tier": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_peers_connect_all",
+ "id": "post:/mesh/peers/connect-all",
+ "method": "POST",
+ "path": "/mesh/peers/connect-all",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "limit": "integer",
+ "refresh_manifest": "boolean",
+ "trust_tier": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_peers_sync",
+ "id": "post:/mesh/peers/sync",
+ "method": "POST",
+ "path": "/mesh/peers/sync",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "limit": "integer",
+ "peer_id": "string",
+ "refresh_manifest": "boolean"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_lease_acquire",
+ "id": "post:/mesh/lease/acquire",
+ "method": "POST",
+ "path": "/mesh/lease/acquire",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "peer_id": "string",
+ "resource": "string",
+ "ttl_seconds": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_lease_heartbeat",
+ "id": "post:/mesh/lease/heartbeat",
+ "method": "POST",
+ "path": "/mesh/lease/heartbeat",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "lease_id": "string",
+ "ttl_seconds": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_lease_release",
+ "id": "post:/mesh/lease/release",
+ "method": "POST",
+ "path": "/mesh/lease/release",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "lease_id": "string",
+ "status": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_worker_heartbeat",
+ "id": "post:/mesh/workers/{worker_id}/heartbeat",
+ "method": "POST",
+ "path": "/mesh/workers/{worker_id}/heartbeat",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "metadata": "object",
+ "resources": "object",
+ "status": "string"
+ },
+ "path": {
+ "worker_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_worker_poll",
+ "id": "post:/mesh/workers/{worker_id}/poll",
+ "method": "POST",
+ "path": "/mesh/workers/{worker_id}/poll",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "limit": "integer"
+ },
+ "path": {
+ "worker_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_worker_claim",
+ "id": "post:/mesh/workers/{worker_id}/claim",
+ "method": "POST",
+ "path": "/mesh/workers/{worker_id}/claim",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "job_id": "string",
+ "ttl_seconds": "integer"
+ },
+ "path": {
+ "worker_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_attempt_heartbeat",
+ "id": "post:/mesh/jobs/attempts/{attempt_id}/heartbeat",
+ "method": "POST",
+ "path": "/mesh/jobs/attempts/{attempt_id}/heartbeat",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "metadata": "object",
+ "ttl_seconds": "integer"
+ },
+ "path": {
+ "attempt_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_attempt_complete",
+ "id": "post:/mesh/jobs/attempts/{attempt_id}/complete",
+ "method": "POST",
+ "path": "/mesh/jobs/attempts/{attempt_id}/complete",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "executor": "string",
+ "metadata": "object",
+ "result": "object"
+ },
+ "path": {
+ "attempt_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_attempt_fail",
+ "id": "post:/mesh/jobs/attempts/{attempt_id}/fail",
+ "method": "POST",
+ "path": "/mesh/jobs/attempts/{attempt_id}/fail",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "error": "string",
+ "metadata": "object",
+ "retryable": "boolean"
+ },
+ "path": {
+ "attempt_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "runtime",
+ "handler": "_handle_mesh_handoff",
+ "id": "post:/mesh/agents/handoff",
+ "method": "POST",
+ "path": "/mesh/agents/handoff",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "handoff": "signed_envelope"
+ },
+ "schema_ref": "SignedEnvelope"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_job_submit",
+ "id": "post:/mesh/jobs/submit",
+ "method": "POST",
+ "path": "/mesh/jobs/submit",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "job": "signed_envelope|object"
+ },
+ "schema_ref": "SignedEnvelope"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_job_schedule",
+ "id": "post:/mesh/jobs/schedule",
+ "method": "POST",
+ "path": "/mesh/jobs/schedule",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "job": "object",
+ "request_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_mission_launch",
+ "id": "post:/mesh/missions/launch",
+ "method": "POST",
+ "path": "/mesh/missions/launch",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "continuity": "object",
+ "intent": "string",
+ "job": "object",
+ "title": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_mission_test_launch",
+ "id": "post:/mesh/missions/test-launch",
+ "method": "POST",
+ "path": "/mesh/missions/test-launch",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "intent": "string",
+ "peer_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_mission_test_mesh_launch",
+ "id": "post:/mesh/missions/test-mesh-launch",
+ "method": "POST",
+ "path": "/mesh/missions/test-mesh-launch",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "include_local": "boolean",
+ "limit": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_continuity_vessel_verify",
+ "id": "post:/mesh/continuity/vessels/verify",
+ "method": "POST",
+ "path": "/mesh/continuity/vessels/verify",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "artifact_id": "string",
+ "include_content": "boolean"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ContinuityVesselVerification",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_continuity_restore_plan",
+ "id": "post:/mesh/continuity/vessels/restore-plan",
+ "method": "POST",
+ "path": "/mesh/continuity/vessels/restore-plan",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "artifact_id": "string",
+ "constraints": "object",
+ "target_peer_id": "string"
+ },
+ "schema_ref": "ContinuityRestorePlanRequest"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ContinuityRestorePlan",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_mission_continuity_export",
+ "id": "post:/mesh/missions/{mission_id}/continuity/export",
+ "method": "POST",
+ "path": "/mesh/missions/{mission_id}/continuity/export",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "dry_run": "boolean",
+ "include_artifacts": "boolean",
+ "metadata": "object"
+ },
+ "path": {
+ "mission_id": "string"
+ },
+ "schema_ref": "ContinuityVesselExportRequest"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ContinuityVesselExport",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_mission_cancel",
+ "id": "post:/mesh/missions/{mission_id}/cancel",
+ "method": "POST",
+ "path": "/mesh/missions/{mission_id}/cancel",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "operator_id": "string",
+ "reason": "string"
+ },
+ "path": {
+ "mission_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_mission_resume_from_checkpoint",
+ "id": "post:/mesh/missions/{mission_id}/resume-from-checkpoint",
+ "method": "POST",
+ "path": "/mesh/missions/{mission_id}/resume-from-checkpoint",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "checkpoint_ref": "object",
+ "metadata": "object",
+ "operator_id": "string"
+ },
+ "path": {
+ "mission_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_mission_resume",
+ "id": "post:/mesh/missions/{mission_id}/resume",
+ "method": "POST",
+ "path": "/mesh/missions/{mission_id}/resume",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "metadata": "object",
+ "operator_id": "string"
+ },
+ "path": {
+ "mission_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_mission_restart",
+ "id": "post:/mesh/missions/{mission_id}/restart",
+ "method": "POST",
+ "path": "/mesh/missions/{mission_id}/restart",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "metadata": "object",
+ "operator_id": "string",
+ "reason": "string"
+ },
+ "path": {
+ "mission_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_job_resume_from_checkpoint",
+ "id": "post:/mesh/jobs/{job_id}/resume-from-checkpoint",
+ "method": "POST",
+ "path": "/mesh/jobs/{job_id}/resume-from-checkpoint",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "checkpoint_ref": "object",
+ "metadata": "object",
+ "operator_id": "string"
+ },
+ "path": {
+ "job_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_job_resume",
+ "id": "post:/mesh/jobs/{job_id}/resume",
+ "method": "POST",
+ "path": "/mesh/jobs/{job_id}/resume",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "metadata": "object",
+ "operator_id": "string"
+ },
+ "path": {
+ "job_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_job_restart",
+ "id": "post:/mesh/jobs/{job_id}/restart",
+ "method": "POST",
+ "path": "/mesh/jobs/{job_id}/restart",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "metadata": "object",
+ "operator_id": "string",
+ "reason": "string"
+ },
+ "path": {
+ "job_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_job_cancel",
+ "id": "post:/mesh/jobs/{job_id}/cancel",
+ "method": "POST",
+ "path": "/mesh/jobs/{job_id}/cancel",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "operator_id": "string",
+ "reason": "string"
+ },
+ "path": {
+ "job_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "missions",
+ "handler": "_handle_mesh_cooperative_task_launch",
+ "id": "post:/mesh/cooperative-tasks/launch",
+ "method": "POST",
+ "path": "/mesh/cooperative-tasks/launch",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "base_job": "object",
+ "name": "string",
+ "shards": "array"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_helpers_plan",
+ "id": "post:/mesh/helpers/plan",
+ "method": "POST",
+ "path": "/mesh/helpers/plan",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "limit": "integer",
+ "workload_class": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_helpers_enlist",
+ "id": "post:/mesh/helpers/enlist",
+ "method": "POST",
+ "path": "/mesh/helpers/enlist",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "peer_id": "string",
+ "reason": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_helpers_drain",
+ "id": "post:/mesh/helpers/drain",
+ "method": "POST",
+ "path": "/mesh/helpers/drain",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "peer_id": "string",
+ "reason": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_helpers_retire",
+ "id": "post:/mesh/helpers/retire",
+ "method": "POST",
+ "path": "/mesh/helpers/retire",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "peer_id": "string",
+ "reason": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_helpers_auto_seek",
+ "id": "post:/mesh/helpers/auto-seek",
+ "method": "POST",
+ "path": "/mesh/helpers/auto-seek",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "limit": "integer",
+ "trust_tier": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_helpers_preferences_set",
+ "id": "post:/mesh/helpers/preferences/set",
+ "method": "POST",
+ "path": "/mesh/helpers/preferences/set",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "peer_id": "string",
+ "preference": "string",
+ "workload_class": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_helpers_autonomy_run",
+ "id": "post:/mesh/helpers/autonomy/run",
+ "method": "POST",
+ "path": "/mesh/helpers/autonomy/run",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "dry_run": "boolean",
+ "reason": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_worker_register",
+ "id": "post:/mesh/workers/register",
+ "method": "POST",
+ "path": "/mesh/workers/register",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "agent_id": "string",
+ "capabilities": "array",
+ "worker_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_notification_publish",
+ "id": "post:/mesh/notifications/publish",
+ "method": "POST",
+ "path": "/mesh/notifications/publish",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "body": "string",
+ "notification_type": "string",
+ "title": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_notification_ack",
+ "id": "post:/mesh/notifications/{notification_id}/ack",
+ "method": "POST",
+ "path": "/mesh/notifications/{notification_id}/ack",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "actor_peer_id": "string",
+ "status": "string"
+ },
+ "path": {
+ "notification_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_approval_request",
+ "id": "post:/mesh/approvals/request",
+ "method": "POST",
+ "path": "/mesh/approvals/request",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "metadata": "object",
+ "summary": "string",
+ "title": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_approval_resolve",
+ "id": "post:/mesh/approvals/{approval_id}/resolve",
+ "method": "POST",
+ "path": "/mesh/approvals/{approval_id}/resolve",
+ "request": {
+ "argument_kind": "path_data",
+ "body": {
+ "decision": "string",
+ "metadata": "object",
+ "operator_peer_id": "string"
+ },
+ "path": {
+ "approval_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_treaty_propose",
+ "id": "post:/mesh/treaties/propose",
+ "method": "POST",
+ "path": "/mesh/treaties/propose",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "summary": "string",
+ "title": "string",
+ "treaty_id": "string",
+ "treaty_type": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_treaty_audit",
+ "id": "post:/mesh/treaties/audit",
+ "method": "POST",
+ "path": "/mesh/treaties/audit",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "metadata": "object",
+ "operation": "string",
+ "treaty_requirements": "array"
+ },
+ "schema_ref": "TreatyAuditRequest"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_secret_put",
+ "id": "post:/mesh/secrets/put",
+ "method": "POST",
+ "path": "/mesh/secrets/put",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "metadata": "object",
+ "name": "string",
+ "scope": "string",
+ "value": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_queue_replay",
+ "id": "post:/mesh/queue/replay",
+ "method": "POST",
+ "path": "/mesh/queue/replay",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "queue_message_id": "string",
+ "reason": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "ops",
+ "handler": "_handle_mesh_queue_ack_deadline",
+ "id": "post:/mesh/queue/ack-deadline",
+ "method": "POST",
+ "path": "/mesh/queue/ack-deadline",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "ack_deadline_seconds": "integer",
+ "queue_message_id": "string",
+ "ttl_seconds": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "Object",
+ "type": "object"
+ }
+ },
+ {
+ "group": "artifacts",
+ "handler": "_handle_mesh_artifact_publish",
+ "id": "post:/mesh/artifacts/publish",
+ "method": "POST",
+ "path": "/mesh/artifacts/publish",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "artifact": "object",
+ "content": "any",
+ "metadata": "object"
+ },
+ "schema_ref": "SignedEnvelope"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ArtifactPublishResponse",
+ "type": "object"
+ }
+ },
+ {
+ "group": "artifacts",
+ "handler": "_handle_mesh_artifact_replicate",
+ "id": "post:/mesh/artifacts/replicate",
+ "method": "POST",
+ "path": "/mesh/artifacts/replicate",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "artifact_id": "string",
+ "base_url": "string",
+ "digest": "string",
+ "peer_id": "string",
+ "pin": "boolean",
+ "remote_auth": "object"
+ },
+ "schema_ref": "ArtifactReplicateRequest"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ArtifactReplicateResponse",
+ "type": "object"
+ }
+ },
+ {
+ "group": "artifacts",
+ "handler": "_handle_mesh_artifact_replicate_graph",
+ "id": "post:/mesh/artifacts/replicate-graph",
+ "method": "POST",
+ "path": "/mesh/artifacts/replicate-graph",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "artifact_id": "string",
+ "base_url": "string",
+ "digest": "string",
+ "peer_id": "string",
+ "pin": "boolean",
+ "remote_auth": "object"
+ },
+ "schema_ref": "ArtifactReplicateRequest"
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ArtifactGraphReplicateResponse",
+ "type": "object"
+ }
+ },
+ {
+ "group": "artifacts",
+ "handler": "_handle_mesh_artifact_pin",
+ "id": "post:/mesh/artifacts/pin",
+ "method": "POST",
+ "path": "/mesh/artifacts/pin",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "artifact_id": "string",
+ "pinned": "boolean",
+ "reason": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ArtifactPinResponse",
+ "type": "object"
+ }
+ },
+ {
+ "group": "artifacts",
+ "handler": "_handle_mesh_artifact_verify_mirror",
+ "id": "post:/mesh/artifacts/verify-mirror",
+ "method": "POST",
+ "path": "/mesh/artifacts/verify-mirror",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "artifact_id": "string",
+ "digest": "string",
+ "peer_id": "string",
+ "source_artifact_id": "string"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ArtifactMirrorVerification",
+ "type": "object"
+ }
+ },
+ {
+ "group": "artifacts",
+ "handler": "_handle_mesh_artifact_purge",
+ "id": "post:/mesh/artifacts/purge",
+ "method": "POST",
+ "path": "/mesh/artifacts/purge",
+ "request": {
+ "argument_kind": "data",
+ "body": {
+ "limit": "integer"
+ }
+ },
+ "response": {
+ "schema_available": true,
+ "schema_ref": "ArtifactPurgeResponse",
+ "type": "object"
+ }
+ }
+ ],
+ "groups": {
+ "artifacts": {
+ "count": 8,
+ "methods": [
+ "GET",
+ "POST"
+ ]
+ },
+ "control": {
+ "count": 1,
+ "methods": [
+ "GET"
+ ]
+ },
+ "missions": {
+ "count": 22,
+ "methods": [
+ "GET",
+ "POST"
+ ]
+ },
+ "ops": {
+ "count": 31,
+ "methods": [
+ "GET",
+ "POST"
+ ]
+ },
+ "runtime": {
+ "count": 32,
+ "methods": [
+ "GET",
+ "POST"
+ ]
+ }
+ },
+ "protocol_surface": "/mesh/*",
+ "schema_count": 75,
+ "schema_version": "ocp-protocol-schemas/v1alpha1",
+ "schemas": {
+ "AppHistorySampleRequest": {
+ "properties": {
+ "source": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "AppHistorySampleResponse": {
+ "properties": {
+ "retention_limit": {
+ "type": "integer"
+ },
+ "sample": {
+ "$ref": "#/schemas/AppStatusSample"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "status",
+ "sample"
+ ],
+ "type": "object"
+ },
+ "AppStatus": {
+ "description": "Operator-facing compact status for the installable OCP app home.",
+ "properties": {
+ "app_urls": {
+ "properties": {
+ "app_url": {
+ "type": "string"
+ },
+ "base_url": {
+ "type": "string"
+ },
+ "control_url": {
+ "type": "string"
+ },
+ "lan_urls": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "phone_url": {
+ "type": "string"
+ },
+ "setup_url": {
+ "type": "string"
+ },
+ "share_advice": {
+ "type": "string"
+ },
+ "sharing_mode": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "approvals": {
+ "type": "object"
+ },
+ "artifact_sync": {
+ "type": "object"
+ },
+ "autonomy": {
+ "type": "object"
+ },
+ "execution_readiness": {
+ "$ref": "#/schemas/ExecutionReadiness"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "latest_proof": {
+ "type": "object"
+ },
+ "mesh_quality": {
+ "properties": {
+ "healthy_routes": {
+ "type": "integer"
+ },
+ "label": {
+ "type": "string"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "peer_count": {
+ "type": "integer"
+ },
+ "route_count": {
+ "type": "integer"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "next_actions": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "node": {
+ "type": "object"
+ },
+ "protocol": {
+ "type": "object"
+ },
+ "route_health": {
+ "$ref": "#/schemas/RouteHealthList"
+ },
+ "setup": {
+ "properties": {
+ "bind_mode": {
+ "type": "string"
+ },
+ "blocker_code": {
+ "type": "string"
+ },
+ "blocking_issue": {
+ "type": "string"
+ },
+ "device_roles": {
+ "items": {
+ "properties": {
+ "display_name": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "role": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "summary": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "healthy_route_count": {
+ "type": "integer"
+ },
+ "known_peer_count": {
+ "type": "integer"
+ },
+ "label": {
+ "type": "string"
+ },
+ "latest_proof_status": {
+ "type": "string"
+ },
+ "next_fix": {
+ "type": "string"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "phone_url": {
+ "type": "string"
+ },
+ "primary_action": {
+ "type": "string"
+ },
+ "primary_peer": {
+ "properties": {
+ "display_name": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "role": {
+ "type": "string"
+ },
+ "route": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "summary": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "recovery_state": {
+ "type": "string"
+ },
+ "route_count": {
+ "type": "integer"
+ },
+ "status": {
+ "type": "string"
+ },
+ "story": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "timeline": {
+ "items": {
+ "$ref": "#/schemas/SetupTimelineEvent"
+ },
+ "type": "array"
+ },
+ "token_status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "status",
+ "node",
+ "app_urls",
+ "mesh_quality",
+ "setup",
+ "next_actions"
+ ],
+ "type": "object"
+ },
+ "AppStatusHistory": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "limit": {
+ "type": "integer"
+ },
+ "samples": {
+ "items": {
+ "$ref": "#/schemas/AppStatusSample"
+ },
+ "type": "array"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "status",
+ "count",
+ "samples"
+ ],
+ "type": "object"
+ },
+ "AppStatusSample": {
+ "description": "Operator/app-facing normalized app status point for local charts.",
+ "properties": {
+ "artifact_verified_count": {
+ "type": "integer"
+ },
+ "execution_ready_targets": {
+ "type": "integer"
+ },
+ "healthy_route_count": {
+ "type": "integer"
+ },
+ "id": {
+ "type": "string"
+ },
+ "known_peer_count": {
+ "type": "integer"
+ },
+ "latest_proof_status": {
+ "type": "string"
+ },
+ "local_ready_workers": {
+ "type": "integer"
+ },
+ "mesh_score": {
+ "type": "integer"
+ },
+ "node_id": {
+ "type": "string"
+ },
+ "payload": {
+ "type": "object"
+ },
+ "pending_approvals": {
+ "type": "integer"
+ },
+ "route_count": {
+ "type": "integer"
+ },
+ "sampled_at": {
+ "type": "string"
+ },
+ "setup_status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "sampled_at",
+ "node_id",
+ "mesh_score"
+ ],
+ "type": "object"
+ },
+ "ApprovalList": {
+ "properties": {
+ "approvals": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "Artifact": {
+ "properties": {
+ "artifact_kind": {
+ "type": "string"
+ },
+ "content": {
+ "type": "any"
+ },
+ "created_at": {
+ "type": "string"
+ },
+ "descriptor": {
+ "$ref": "#/schemas/ArtifactDescriptor"
+ },
+ "digest": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "media_type": {
+ "type": "string"
+ },
+ "metadata": {
+ "type": "object"
+ },
+ "size_bytes": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "id",
+ "digest",
+ "media_type",
+ "artifact_kind"
+ ],
+ "type": "object"
+ },
+ "ArtifactDescriptor": {
+ "properties": {
+ "annotations": {
+ "type": "object"
+ },
+ "artifact_id": {
+ "type": "string"
+ },
+ "artifact_kind": {
+ "type": "string"
+ },
+ "digest": {
+ "type": "string"
+ },
+ "media_type": {
+ "type": "string"
+ },
+ "metadata": {
+ "type": "object"
+ },
+ "role": {
+ "type": "string"
+ },
+ "size_bytes": {
+ "type": "integer"
+ },
+ "uri": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "artifact_id",
+ "digest"
+ ],
+ "type": "object"
+ },
+ "ArtifactGraphReplicateResponse": {
+ "properties": {
+ "artifacts": {
+ "items": {
+ "$ref": "#/schemas/Artifact"
+ },
+ "type": "array"
+ },
+ "governance": {
+ "type": "object"
+ },
+ "graph": {
+ "type": "object"
+ },
+ "remote_auth": {
+ "$ref": "#/schemas/ArtifactReplicationAuth"
+ },
+ "root": {
+ "$ref": "#/schemas/ArtifactReplicateResponse"
+ },
+ "route_proof": {
+ "type": "object"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "status"
+ ],
+ "type": "object"
+ },
+ "ArtifactList": {
+ "properties": {
+ "artifacts": {
+ "items": {
+ "$ref": "#/schemas/Artifact"
+ },
+ "type": "array"
+ },
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "ArtifactMirrorVerification": {
+ "properties": {
+ "artifact": {
+ "$ref": "#/schemas/Artifact"
+ },
+ "artifact_id": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "verification": {
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
+ "ArtifactPinResponse": {
+ "properties": {
+ "artifact": {
+ "$ref": "#/schemas/Artifact"
+ },
+ "artifact_id": {
+ "type": "string"
+ },
+ "pinned": {
+ "type": "boolean"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "ArtifactPublishRequest": {
+ "properties": {
+ "artifact": {
+ "type": "object"
+ },
+ "content": {
+ "type": "any"
+ },
+ "descriptor": {
+ "$ref": "#/schemas/ArtifactDescriptor"
+ },
+ "media_type": {
+ "type": "string"
+ },
+ "metadata": {
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
+ "ArtifactPublishResponse": {
+ "properties": {
+ "artifact": {
+ "$ref": "#/schemas/Artifact"
+ },
+ "descriptor": {
+ "$ref": "#/schemas/ArtifactDescriptor"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "ArtifactPurgeResponse": {
+ "properties": {
+ "artifacts": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "kept": {
+ "type": "integer"
+ },
+ "purged": {
+ "type": "integer"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "ArtifactReplicateRequest": {
+ "properties": {
+ "artifact_id": {
+ "type": "string"
+ },
+ "base_url": {
+ "type": "string"
+ },
+ "digest": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "pin": {
+ "type": "boolean"
+ },
+ "remote_auth": {
+ "$ref": "#/schemas/ArtifactReplicationAuth"
+ }
+ },
+ "type": "object"
+ },
+ "ArtifactReplicateResponse": {
+ "properties": {
+ "artifact": {
+ "$ref": "#/schemas/Artifact"
+ },
+ "governance": {
+ "type": "object"
+ },
+ "remote_auth": {
+ "$ref": "#/schemas/ArtifactReplicationAuth"
+ },
+ "route_proof": {
+ "type": "object"
+ },
+ "source": {
+ "type": "object"
+ },
+ "status": {
+ "type": "string"
+ },
+ "verification": {
+ "type": "object"
+ }
+ },
+ "required": [
+ "status"
+ ],
+ "type": "object"
+ },
+ "ArtifactReplicationAuth": {
+ "description": "Explicit remote-content authorization. Tokens and grant proof material are request-only and must never be persisted or echoed.",
+ "properties": {
+ "grant": {
+ "$ref": "#/schemas/CapabilityGrant"
+ },
+ "grant_id": {
+ "type": "string"
+ },
+ "redacted": {
+ "type": "boolean"
+ },
+ "status": {
+ "type": "string"
+ },
+ "token": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "AutonomicAction": {
+ "properties": {
+ "created_at": {
+ "type": "string"
+ },
+ "details": {
+ "type": "object"
+ },
+ "id": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "summary": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "kind",
+ "status",
+ "summary",
+ "created_at"
+ ],
+ "type": "object"
+ },
+ "AutonomicActivateRequest": {
+ "properties": {
+ "actor_agent_id": {
+ "type": "string"
+ },
+ "limit": {
+ "type": "integer"
+ },
+ "max_enlist": {
+ "type": "integer"
+ },
+ "mode": {
+ "type": "string"
+ },
+ "repair": {
+ "type": "boolean"
+ },
+ "request_id": {
+ "type": "string"
+ },
+ "run_proof": {
+ "type": "boolean"
+ },
+ "scan_timeout": {
+ "type": "number"
+ },
+ "timeout": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "AutonomicMeshStatus": {
+ "properties": {
+ "connectivity": {
+ "type": "object"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "helper_autonomy": {
+ "type": "object"
+ },
+ "last_run": {
+ "type": "object"
+ },
+ "mode": {
+ "type": "string"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "pressure": {
+ "type": "object"
+ },
+ "recommended_actions": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "routes": {
+ "$ref": "#/schemas/RouteHealthList"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "status",
+ "mode",
+ "routes"
+ ],
+ "type": "object"
+ },
+ "AutonomicRun": {
+ "properties": {
+ "actions": {
+ "items": {
+ "$ref": "#/schemas/AutonomicAction"
+ },
+ "type": "array"
+ },
+ "approvals": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "helpers": {
+ "type": "object"
+ },
+ "mode": {
+ "type": "string"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "proof": {
+ "type": "object"
+ },
+ "request_id": {
+ "type": "string"
+ },
+ "result": {
+ "type": "object"
+ },
+ "routes": {
+ "$ref": "#/schemas/RouteHealthList"
+ },
+ "run": {
+ "type": "object"
+ },
+ "status": {
+ "type": "string"
+ },
+ "summary": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "status",
+ "summary",
+ "actions"
+ ],
+ "type": "object"
+ },
+ "AutonomousOffloadEvaluation": {
+ "properties": {
+ "approvals": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "decisions": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "eligible_helpers": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "mode": {
+ "type": "string"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "CapabilityGrant": {
+ "description": "Alpha signed scoped grant shape for future private artifact and route-scoped capabilities.",
+ "properties": {
+ "audience_peer_id": {
+ "type": "string"
+ },
+ "expires_at": {
+ "type": "string"
+ },
+ "grant_id": {
+ "type": "string"
+ },
+ "issued_at": {
+ "type": "string"
+ },
+ "issuer_peer_id": {
+ "type": "string"
+ },
+ "metadata": {
+ "type": "object"
+ },
+ "nonce": {
+ "type": "string"
+ },
+ "scope": {
+ "$ref": "#/schemas/CapabilityGrantScope"
+ },
+ "signature": {
+ "type": "string"
+ },
+ "signature_scheme": {
+ "type": "string"
+ },
+ "subject_peer_id": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "grant_id",
+ "issuer_peer_id",
+ "subject_peer_id",
+ "audience_peer_id",
+ "scope",
+ "issued_at",
+ "expires_at",
+ "signature_scheme",
+ "signature"
+ ],
+ "title": "CapabilityGrant",
+ "type": "object"
+ },
+ "CapabilityGrantScope": {
+ "properties": {
+ "action": {
+ "type": "string"
+ },
+ "artifact_id": {
+ "type": "string"
+ },
+ "constraints": {
+ "type": "object"
+ },
+ "digest": {
+ "type": "string"
+ },
+ "max_uses": {
+ "type": "integer"
+ },
+ "path": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "action"
+ ],
+ "title": "CapabilityGrantScope",
+ "type": "object"
+ },
+ "ConformanceFixture": {
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "purpose": {
+ "type": "string"
+ },
+ "schema_ref": {
+ "type": "string"
+ },
+ "validation": {
+ "type": "object"
+ },
+ "value": {
+ "type": "object"
+ }
+ },
+ "required": [
+ "id",
+ "schema_ref",
+ "value",
+ "validation"
+ ],
+ "type": "object"
+ },
+ "ContinuityRestorePlan": {
+ "properties": {
+ "artifact_readiness": {
+ "type": "object"
+ },
+ "blockers": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "governance": {
+ "type": "object"
+ },
+ "recommended_action": {
+ "type": "string"
+ },
+ "recommended_treaty_device": {
+ "type": "object"
+ },
+ "safe_devices": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "status": {
+ "type": "string"
+ },
+ "warnings": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "ContinuityRestorePlanRequest": {
+ "properties": {
+ "artifact_id": {
+ "type": "string"
+ },
+ "constraints": {
+ "type": "object"
+ },
+ "target_peer_id": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "ContinuityVesselExport": {
+ "properties": {
+ "dry_run": {
+ "type": "boolean"
+ },
+ "governance": {
+ "type": "object"
+ },
+ "mission_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "vessel": {
+ "$ref": "#/schemas/ArtifactDescriptor"
+ },
+ "witness": {
+ "$ref": "#/schemas/ArtifactDescriptor"
+ }
+ },
+ "type": "object"
+ },
+ "ContinuityVesselExportRequest": {
+ "properties": {
+ "dry_run": {
+ "type": "boolean"
+ },
+ "include_artifacts": {
+ "type": "boolean"
+ },
+ "metadata": {
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
+ "ContinuityVesselVerification": {
+ "properties": {
+ "artifact_id": {
+ "type": "string"
+ },
+ "governance": {
+ "type": "object"
+ },
+ "referenced_artifacts": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "status": {
+ "type": "string"
+ },
+ "valid": {
+ "type": "boolean"
+ },
+ "vessel": {
+ "type": "object"
+ },
+ "witnesses": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "ContractSnapshot": {
+ "properties": {
+ "conformance": {
+ "$ref": "#/schemas/ProtocolConformanceSnapshot"
+ },
+ "contract_version": {
+ "type": "string"
+ },
+ "endpoint_count": {
+ "type": "integer"
+ },
+ "endpoints": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "groups": {
+ "type": "object"
+ },
+ "protocol_surface": {
+ "type": "string"
+ },
+ "schema_count": {
+ "type": "integer"
+ },
+ "schema_version": {
+ "type": "string"
+ },
+ "schemas": {
+ "type": "object"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "status",
+ "contract_version",
+ "schema_version",
+ "protocol_surface",
+ "endpoints",
+ "schemas"
+ ],
+ "type": "object"
+ },
+ "ControlStreamSSE": {
+ "description": "Server-sent event stream carrying compact control-deck updates.",
+ "properties": {
+ "data": {
+ "type": "object"
+ },
+ "event": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "CooperativeTask": {
+ "properties": {
+ "child_job_ids": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "created_at": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "metadata": {
+ "type": "object"
+ },
+ "name": {
+ "type": "string"
+ },
+ "request_id": {
+ "type": "string"
+ },
+ "shards": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "state": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "updated_at": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "CooperativeTaskList": {
+ "properties": {
+ "cooperative_tasks": {
+ "items": {
+ "$ref": "#/schemas/CooperativeTask"
+ },
+ "type": "array"
+ },
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "tasks": {
+ "items": {
+ "$ref": "#/schemas/CooperativeTask"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "DeviceProfileResponse": {
+ "properties": {
+ "device_profile": {
+ "type": "object"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "updated": {
+ "type": "boolean"
+ }
+ },
+ "type": "object"
+ },
+ "DiscoveryCandidateList": {
+ "properties": {
+ "candidates": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "EventStreamSnapshot": {
+ "properties": {
+ "cursor": {
+ "type": "any"
+ },
+ "events": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "peers": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "ExecutionReadiness": {
+ "properties": {
+ "local": {
+ "type": "object"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "targets": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "worker_capacity": {
+ "items": {
+ "$ref": "#/schemas/WorkerCapacity"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "HandshakeResponse": {
+ "properties": {
+ "manifest": {
+ "type": "object"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "peer": {
+ "type": "object"
+ },
+ "status": {
+ "type": "string"
+ },
+ "trust_tier": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "HelperList": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "helpers": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "Job": {
+ "properties": {
+ "created_at": {
+ "type": "string"
+ },
+ "dispatch_mode": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string"
+ },
+ "metadata": {
+ "type": "object"
+ },
+ "origin_peer_id": {
+ "type": "string"
+ },
+ "policy": {
+ "type": "object"
+ },
+ "request_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "target_peer_id": {
+ "type": "string"
+ },
+ "updated_at": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "JobSubmission": {
+ "properties": {
+ "artifact_inputs": {
+ "items": {
+ "$ref": "#/schemas/ArtifactDescriptor"
+ },
+ "type": "array"
+ },
+ "continuity": {
+ "type": "object"
+ },
+ "dispatch_mode": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string"
+ },
+ "metadata": {
+ "type": "object"
+ },
+ "payload": {
+ "type": "object"
+ },
+ "policy": {
+ "type": "object"
+ },
+ "requirements": {
+ "type": "object"
+ }
+ },
+ "required": [
+ "kind"
+ ],
+ "type": "object"
+ },
+ "JobSubmissionEnvelope": {
+ "description": "A direct job object or a signed envelope carrying a job submission body.",
+ "one_of": [
+ {
+ "$ref": "#/schemas/JobSubmission"
+ },
+ {
+ "$ref": "#/schemas/SignedEnvelope"
+ }
+ ],
+ "type": "object"
+ },
+ "JobSubmissionRequest": {
+ "description": "Accepted job submission transport shapes for the HTTP surface.",
+ "one_of": [
+ {
+ "$ref": "#/schemas/SignedEnvelope"
+ },
+ {
+ "properties": {
+ "job": {
+ "$ref": "#/schemas/JobSubmission"
+ }
+ },
+ "required": [
+ "job"
+ ],
+ "type": "object"
+ },
+ {
+ "$ref": "#/schemas/JobSubmission"
+ }
+ ],
+ "type": "object"
+ },
+ "MeshManifest": {
+ "properties": {
+ "agent_presence": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "continuity_capabilities": {
+ "type": "object"
+ },
+ "device_profile": {
+ "type": "object"
+ },
+ "governance_summary": {
+ "type": "object"
+ },
+ "implementation": {
+ "type": "object"
+ },
+ "organism_card": {
+ "$ref": "#/schemas/PeerCard"
+ },
+ "protocol": {
+ "type": "string"
+ },
+ "protocol_release": {
+ "type": "string"
+ },
+ "protocol_short_name": {
+ "type": "string"
+ },
+ "protocol_version": {
+ "type": "string"
+ },
+ "queue_metrics": {
+ "type": "object"
+ },
+ "sync_policy": {
+ "type": "object"
+ },
+ "treaty_capabilities": {
+ "type": "object"
+ },
+ "workers": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ }
+ },
+ "required": [
+ "protocol",
+ "protocol_short_name",
+ "protocol_release",
+ "protocol_version",
+ "organism_card"
+ ],
+ "type": "object"
+ },
+ "MeshPressure": {
+ "properties": {
+ "generated_at": {
+ "type": "string"
+ },
+ "helper_recommended": {
+ "type": "boolean"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "pressure": {
+ "type": "object"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "Mission": {
+ "properties": {
+ "continuity": {
+ "type": "object"
+ },
+ "created_at": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "intent": {
+ "type": "string"
+ },
+ "metadata": {
+ "type": "object"
+ },
+ "origin_peer_id": {
+ "type": "string"
+ },
+ "policy": {
+ "type": "object"
+ },
+ "priority": {
+ "type": "string"
+ },
+ "request_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "target_strategy": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "updated_at": {
+ "type": "string"
+ },
+ "workload_class": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "MissionContinuitySummary": {
+ "properties": {
+ "checkpoints": {
+ "items": {
+ "$ref": "#/schemas/ArtifactDescriptor"
+ },
+ "type": "array"
+ },
+ "continuity": {
+ "type": "object"
+ },
+ "governance": {
+ "type": "object"
+ },
+ "latest_checkpoint_ref": {
+ "$ref": "#/schemas/ArtifactDescriptor"
+ },
+ "mission_id": {
+ "type": "string"
+ },
+ "recommended_treaty_device": {
+ "type": "object"
+ },
+ "safe_devices": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "status": {
+ "type": "string"
+ },
+ "treaty_validation": {
+ "type": "object"
+ }
+ },
+ "required": [
+ "mission_id",
+ "continuity"
+ ],
+ "type": "object"
+ },
+ "MissionList": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "missions": {
+ "items": {
+ "$ref": "#/schemas/Mission"
+ },
+ "type": "array"
+ },
+ "peer_id": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "NotificationList": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "notifications": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "peer_id": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "Object": {
+ "description": "Loose object fallback for routes whose detailed response contract has not been promoted yet.",
+ "type": "object"
+ },
+ "PeerAdvisory": {
+ "properties": {
+ "continuity_capabilities": {
+ "type": "object"
+ },
+ "missing_capabilities": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "recommended_action": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "treaty_capabilities": {
+ "type": "object"
+ },
+ "treaty_compatibility": {
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
+ "PeerCard": {
+ "properties": {
+ "capability_cards": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "continuity_capabilities": {
+ "type": "object"
+ },
+ "device_profile": {
+ "type": "object"
+ },
+ "display_name": {
+ "type": "string"
+ },
+ "endpoint_url": {
+ "type": "string"
+ },
+ "governance_summary": {
+ "type": "object"
+ },
+ "habitat_roles": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "node_id": {
+ "type": "string"
+ },
+ "organism_id": {
+ "type": "string"
+ },
+ "protocol_version": {
+ "type": "string"
+ },
+ "public_key": {
+ "type": "string"
+ },
+ "treaty_capabilities": {
+ "type": "object"
+ },
+ "trust_tier": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "organism_id",
+ "node_id",
+ "public_key",
+ "protocol_version"
+ ],
+ "type": "object"
+ },
+ "PeerList": {
+ "properties": {
+ "advisories": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "peers": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "ProtocolConformanceSnapshot": {
+ "properties": {
+ "fixture_count": {
+ "type": "integer"
+ },
+ "fixtures": {
+ "items": {
+ "$ref": "#/schemas/ConformanceFixture"
+ },
+ "type": "array"
+ },
+ "invalid_fixture_count": {
+ "type": "integer"
+ },
+ "schema_version": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "status",
+ "fixture_count",
+ "invalid_fixture_count",
+ "fixtures"
+ ],
+ "type": "object"
+ },
+ "QueueEventList": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "events": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "next_cursor": {
+ "type": "any"
+ },
+ "peer_id": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "QueueMessageList": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "messages": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "queue": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "QueueMetrics": {
+ "properties": {
+ "depth": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "metrics": {
+ "type": "object"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "RouteCandidate": {
+ "properties": {
+ "base_url": {
+ "type": "string"
+ },
+ "checked_at": {
+ "type": "string"
+ },
+ "failure_count": {
+ "type": "integer"
+ },
+ "freshness": {
+ "type": "string"
+ },
+ "last_error": {
+ "type": "string"
+ },
+ "last_success_at": {
+ "type": "string"
+ },
+ "latency_ms": {
+ "type": "any"
+ },
+ "next_probe_after": {
+ "type": "string"
+ },
+ "observed_peer_id": {
+ "type": "string"
+ },
+ "operator_hint": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "base_url",
+ "source",
+ "status"
+ ],
+ "type": "object"
+ },
+ "RouteHealth": {
+ "properties": {
+ "age_seconds": {
+ "type": "any"
+ },
+ "best_route": {
+ "type": "string"
+ },
+ "candidates": {
+ "items": {
+ "$ref": "#/schemas/RouteCandidate"
+ },
+ "type": "array"
+ },
+ "checked_at": {
+ "type": "string"
+ },
+ "display_name": {
+ "type": "string"
+ },
+ "failure_count": {
+ "type": "integer"
+ },
+ "freshness": {
+ "type": "string"
+ },
+ "last_error": {
+ "type": "string"
+ },
+ "last_reachable_base_url": {
+ "type": "string"
+ },
+ "last_success_at": {
+ "type": "string"
+ },
+ "next_probe_after": {
+ "type": "string"
+ },
+ "operator_hint": {
+ "type": "string"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "peer_id",
+ "status",
+ "candidates"
+ ],
+ "type": "object"
+ },
+ "RouteHealthList": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "healthy": {
+ "type": "integer"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "routes": {
+ "items": {
+ "$ref": "#/schemas/RouteHealth"
+ },
+ "type": "array"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "status",
+ "routes"
+ ],
+ "type": "object"
+ },
+ "RouteProbeRequest": {
+ "properties": {
+ "base_url": {
+ "type": "string"
+ },
+ "limit": {
+ "type": "integer"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "timeout": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "RouteProbeResult": {
+ "properties": {
+ "best_route": {
+ "type": "string"
+ },
+ "candidates": {
+ "items": {
+ "$ref": "#/schemas/RouteCandidate"
+ },
+ "type": "array"
+ },
+ "checked": {
+ "type": "integer"
+ },
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "operator_hint": {
+ "type": "string"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "reachable": {
+ "type": "integer"
+ },
+ "results": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "status"
+ ],
+ "type": "object"
+ },
+ "RouteProofFreshness": {
+ "properties": {
+ "best_route": {
+ "type": "string"
+ },
+ "checked_at": {
+ "type": "string"
+ },
+ "freshness": {
+ "type": "string"
+ },
+ "last_success_at": {
+ "type": "string"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "SchedulerDecisionList": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "decisions": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "SecretList": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "secrets": {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "SetupTimelineEvent": {
+ "properties": {
+ "created_at": {
+ "type": "string"
+ },
+ "details": {
+ "type": "object"
+ },
+ "kind": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "summary": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "kind",
+ "status",
+ "summary"
+ ],
+ "type": "object"
+ },
+ "SignedEnvelope": {
+ "properties": {
+ "body": {
+ "type": "object"
+ },
+ "request": {
+ "properties": {
+ "implementation": {
+ "type": "string"
+ },
+ "node_id": {
+ "type": "string"
+ },
+ "nonce": {
+ "type": "string"
+ },
+ "protocol_family": {
+ "type": "string"
+ },
+ "protocol_release": {
+ "type": "string"
+ },
+ "protocol_version": {
+ "type": "string"
+ },
+ "request_id": {
+ "type": "string"
+ },
+ "signature": {
+ "type": "string"
+ },
+ "signature_scheme": {
+ "type": "string"
+ },
+ "timestamp": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "node_id",
+ "timestamp",
+ "nonce",
+ "request_id",
+ "protocol_family",
+ "protocol_release",
+ "protocol_version",
+ "signature_scheme",
+ "signature"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "request",
+ "body"
+ ],
+ "type": "object"
+ },
+ "Treaty": {
+ "properties": {
+ "created_at": {
+ "type": "string"
+ },
+ "document": {
+ "type": "object"
+ },
+ "id": {
+ "type": "string"
+ },
+ "metadata": {
+ "type": "object"
+ },
+ "status": {
+ "type": "string"
+ },
+ "summary": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "treaty_type": {
+ "type": "string"
+ },
+ "updated_at": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "treaty_type",
+ "status",
+ "document"
+ ],
+ "type": "object"
+ },
+ "TreatyAudit": {
+ "properties": {
+ "guidance": {
+ "type": "string"
+ },
+ "metadata": {
+ "type": "object"
+ },
+ "operation": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "validation": {
+ "properties": {
+ "inactive": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "missing": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "required": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "satisfied": {
+ "type": "boolean"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "status",
+ "validation"
+ ],
+ "type": "object"
+ },
+ "TreatyAuditRequest": {
+ "properties": {
+ "metadata": {
+ "type": "object"
+ },
+ "operation": {
+ "type": "string"
+ },
+ "treaty_requirements": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "TreatyList": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "treaties": {
+ "items": {
+ "$ref": "#/schemas/Treaty"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "WorkerCapacity": {
+ "properties": {
+ "available_slots": {
+ "type": "integer"
+ },
+ "capabilities": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "max_concurrent_jobs": {
+ "type": "integer"
+ },
+ "operator_summary": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "resources": {
+ "type": "object"
+ },
+ "status": {
+ "type": "string"
+ },
+ "worker_id": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "WorkerList": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "generated_at": {
+ "type": "string"
+ },
+ "peer_id": {
+ "type": "string"
+ },
+ "workers": {
+ "items": {
+ "$ref": "#/schemas/WorkerCapacity"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "status": "ok"
+}
diff --git a/docs/spec/OCP_CAPABILITY_GRANTS.md b/docs/spec/OCP_CAPABILITY_GRANTS.md
new file mode 100644
index 0000000..87de3d8
--- /dev/null
+++ b/docs/spec/OCP_CAPABILITY_GRANTS.md
@@ -0,0 +1,99 @@
+# OCP Capability Grants Alpha
+
+This document defines the first alpha shape for signed scoped capability grants. It is a protocol-boundary draft, not a complete authorization system.
+
+## Status
+
+Capability grants are currently:
+
+- described in `mesh_protocol` schemas as `CapabilityGrant`
+- included in conformance fixtures
+- accepted as a declared `remote_auth` shape for artifact replication summaries
+- expiry-checked and redacted before being stored or returned
+
+Capability grants are not yet:
+
+- cryptographically verified by the artifact HTTP content gate
+- used as a full replacement for operator-token private artifact pulls
+- backed by durable revocation or key rotation
+- enforced as a complete peer permission system
+
+Operator-token `remote_auth` remains the working fallback for private artifact replication in this alpha.
+
+## Grant Shape
+
+```json
+{
+ "grant_id": "grant-alpha-private-artifact",
+ "issuer_peer_id": "beta-node",
+ "subject_peer_id": "alpha-node",
+ "audience_peer_id": "beta-node",
+ "scope": {
+ "action": "artifact.read",
+ "artifact_id": "artifact-private",
+ "digest": "abc123",
+ "max_uses": 1
+ },
+ "issued_at": "2026-01-01T00:00:00Z",
+ "expires_at": "2026-01-01T00:05:00Z",
+ "nonce": "grant-nonce",
+ "signature_scheme": "ed25519-sha512-v1",
+ "signature": "..."
+}
+```
+
+## Scope
+
+The initial intended scope is private artifact read/replication:
+
+- `action`: `artifact.read`
+- `artifact_id`: optional artifact id constraint
+- `digest`: optional digest constraint
+- `max_uses`: optional replay-budget hint
+- `constraints`: extension object for future restrictions
+
+Future scopes may cover route probing, worker claims, mission restore, or other peer operations.
+
+## Redaction
+
+Grant proof material must not be stored or echoed. Redacted summaries keep only:
+
+- type
+- status
+- grant id
+- issuer, subject, and audience peer ids
+- scope
+- expiry
+- `redacted: true`
+
+They must remove signatures, nonces, tokens, proof payloads, and secrets.
+
+## Validation
+
+Alpha validation checks:
+
+- required fields
+- scope object and action
+- ISO-8601 expiry
+- expiry relative to current time
+
+It does not yet verify signatures. Signature verification is required before grants can authorize private content over HTTP.
+
+## Artifact Replication
+
+Artifact replication now has two documented `remote_auth` paths:
+
+- `operator_token`: working fallback for private remote pulls
+- `capability_grant`: declared alpha grant path with validation and redaction
+
+Until grant enforcement lands, private HTTP artifact content still requires operator authorization or public artifact policy.
+
+## Next Enforcement Steps
+
+1. Canonicalize the grant signing payload.
+2. Verify grant signatures against issuer peer keys.
+3. Check audience and subject against the serving and requesting nodes.
+4. Enforce artifact id and digest constraints in the HTTP content gate.
+5. Add replay/use tracking for `max_uses`.
+6. Add revocation and key rotation.
+7. Keep operator-token remote auth as an explicit fallback during migration.
diff --git a/docs/spec/OCP_v0.1.md b/docs/spec/OCP_v0.1.md
new file mode 100644
index 0000000..6d5111b
--- /dev/null
+++ b/docs/spec/OCP_v0.1.md
@@ -0,0 +1,123 @@
+# Open Compute Protocol v0.1 Draft
+
+## 1. Status
+
+This is a draft boundary document for OCP v0.1. It describes the current Python-first Sovereign Mesh reference implementation and the direction of the protocol. It is not a final standard and does not claim independent implementation compatibility yet.
+
+The current schema registry is descriptive and only partially enforcing; future OCP releases should tighten normative conformance.
+
+## 2. Scope
+
+OCP v0.1 covers local-first mesh identity, peer manifests, signed envelopes, operator authorization, jobs, workers, queue attempts, artifacts, missions, scheduler decisions, device profiles, trust tiers, and conformance inspection.
+
+## 3. Non-goals
+
+- production-grade security certification
+- internet-scale federation
+- cloud control-plane dependency
+- replacement of the current HTTP server
+- required databases beyond SQLite for the reference implementation
+- stable endpoint compatibility guarantees
+
+## 4. Terminology
+
+- Node: a local OCP runtime participant.
+- Peer: another known node.
+- Operator: the human or app controlling raw mesh actions.
+- Worker: an execution participant that can claim and run jobs.
+- Mission: higher-level intent above jobs and cooperative tasks.
+- Artifact: content-addressed output, checkpoint, log, attestation, or bundle.
+- Signed envelope: a protocol message signed by a node identity.
+
+## 5. Node Identity
+
+The reference implementation maintains node identity material under the configured identity directory. Nodes SHOULD use stable identities for trusted mesh demos so peers can recognize them across restarts.
+
+## 6. Peer Manifest
+
+Peers expose manifests through `/mesh/manifest`. A manifest describes node identity, base URL, protocol posture, device profile, and current capability hints. The current HTTP contract treats this as a public/local read surface.
+
+## 7. Signed Envelopes
+
+Signed peer traffic uses `mesh_protocol` envelope helpers. The implementation currently treats these POST handlers as signed peer routes:
+
+- `/mesh/handshake`
+- `/mesh/jobs/submit`
+- `/mesh/artifacts/publish`
+- `/mesh/agents/handoff`
+
+Signed envelopes SHOULD include enough identity, request, and payload data for validation and replay-aware handling. Current enforcement is alpha and route-specific.
+
+## 8. Operator Authorization
+
+Raw mesh mutation routes require operator authorization. If no token is configured, loopback clients MAY use raw mutation routes. If `OCP_OPERATOR_TOKEN` or `OCP_CONTROL_TOKEN` is configured, clients MUST present the matching token in `X-OCP-Operator-Token`, `X-OCP-Control-Token`, or `Authorization: Bearer`.
+
+Phone links SHOULD carry the token in the URL fragment as `#ocp_operator_token=...`.
+
+## 9. Jobs
+
+Jobs describe bounded execution intent. The reference implementation supports submission, scheduling, cancellation, resume, restart, attempts, and checkpoints. Job schemas live in `mesh_protocol` and route metadata lives in `server_contract.py`.
+
+## 10. Workers
+
+Workers register capabilities and resources, poll for work, claim jobs, heartbeat, and report completion or failure. Full laptop/workstation nodes started through the easy launcher may auto-register a default worker for demos.
+
+## 11. Queue and Attempts
+
+The queue records messages and events for durable work progress. Attempts track execution leases, heartbeats, completion, failure, retry posture, and related artifacts.
+
+## 12. Artifacts
+
+Artifacts carry result content, logs, checkpoints, attestations, bundles, lineage, policy, and replication metadata. Private artifact content MUST NOT be served to LAN clients unless operator authorization succeeds or artifact policy allows public access.
+
+Private artifact replication currently MAY use explicit `remote_auth` with an operator token. This is an alpha fallback. OCP v0.1.7 also defines the first `CapabilityGrant` schema and declared `remote_auth: {type: "capability_grant", grant: ...}` path for expiry-checked, redacted grant metadata. Future versions SHOULD enforce signed scoped capability grants for private content authorization.
+
+## 13. Missions
+
+Missions represent durable operator intent above individual jobs and cooperative tasks. The current implementation supports launch, list, inspect, cancel, resume, restart, checkpoint resume, continuity export, and restore planning.
+
+## 14. Scheduler Decisions
+
+Scheduler decisions record why a device or helper was selected. Inputs include device profiles, worker state, route health, trust posture, artifact locality, checkpoint locality, and placement constraints.
+
+## 15. Device Profiles
+
+Device profiles describe node class, form factor, execution tier, power profile, network profile, mobility, and related scheduling hints. Implementations SHOULD treat profiles as hints unless a route or scheduler rule explicitly enforces them.
+
+## 16. Trust Tiers
+
+Trust tiers currently guide scheduling, helper enlistment, discovery, and operator summaries. They are not yet a complete permissions system. Implementations SHOULD avoid treating trust tier labels alone as sufficient authority for dangerous execution.
+
+## 17. Error Handling
+
+The HTTP reference implementation returns JSON error objects for unknown endpoints, operator authorization failures, validation failures, and handler exceptions. Protocol error details are still evolving and should become more consistent in future releases.
+
+## 18. Conformance
+
+`server_contract.py` builds the current HTTP contract snapshot. `mesh_protocol` owns schema definitions and fixtures. `scripts/check_protocol_conformance.py` checks that the snapshot and schema fixtures are internally coherent.
+
+Implementations SHOULD use the contract and schemas as conformance guidance, with the alpha caveat that enforcement is partial.
+
+## 19. Compatibility
+
+The current wire version is `sovereign-mesh/v1`. OCP v0.1 is the first boundary toward independent protocol compatibility, but the reference implementation remains the source of truth for this alpha.
+
+## 20. Known Alpha Gaps
+
+- incomplete response schema coverage
+- descriptive schemas that are only partially enforcing
+- no fully enforced signed scoped capability grants
+- no complete peer permission matrix
+- no mature key rotation or revocation
+- incomplete executor sandbox policy
+- no formal endpoint stability labels
+- security conformance tests need expansion
+
+References:
+
+- `server_contract.py`
+- `mesh_protocol` schemas
+- `scripts/check_protocol_conformance.py`
+- `docs/OCP_STATUS.md`
+- `docs/OCP_MASTER_PLAN.md`
+- `docs/spec/OCP_CAPABILITY_GRANTS.md`
diff --git a/mesh_artifacts/service.py b/mesh_artifacts/service.py
index a25bcc0..c5d2b90 100644
--- a/mesh_artifacts/service.py
+++ b/mesh_artifacts/service.py
@@ -5,6 +5,8 @@
from pathlib import Path
from typing import Any, Optional
+from mesh_protocol.capability_grants import redact_capability_grant, validate_capability_grant
+
class MeshArtifactService:
"""Content-addressed artifact lifecycle helpers for SovereignMesh."""
@@ -459,7 +461,7 @@ def resolve_remote_artifact(
remote_artifact = remote_client.get_artifact(artifact_token, peer_id=self.mesh.node_id, include_content=include_content)
return remote_client, remote_artifact, artifact_token
- def _remote_auth_summary(self, remote_auth: Optional[dict]) -> dict:
+ def _remote_auth_summary(self, remote_auth: Optional[dict], *, now=None) -> dict:
auth = dict(remote_auth or {})
auth_type = str(auth.get("type") or "").strip().lower()
if not auth_type:
@@ -468,7 +470,15 @@ def _remote_auth_summary(self, remote_auth: Optional[dict]) -> dict:
if not str(auth.get("token") or "").strip():
raise self.mesh.MeshPolicyError("remote_auth.operator_token requires a token")
return {"type": "operator_token", "status": "used", "redacted": True}
- if auth_type in {"signed_delegation", "capability_grant"}:
+ if auth_type == "capability_grant":
+ grant = dict(auth.get("grant") or auth)
+ validation = validate_capability_grant(grant, now=now)
+ if validation.get("status") != "ok":
+ issue = next(iter(validation.get("issues") or []), {})
+ detail = issue.get("message") or validation.get("status") or "invalid"
+ raise self.mesh.MeshPolicyError(f"remote_auth.capability_grant {detail}")
+ return redact_capability_grant(grant, status="declared")
+ if auth_type == "signed_delegation":
raise self.mesh.MeshPolicyError("signed artifact delegation is reserved for a future protocol layer")
raise self.mesh.MeshPolicyError(f"unsupported remote_auth type: {auth_type}")
diff --git a/mesh_protocol/capability_grants.py b/mesh_protocol/capability_grants.py
new file mode 100644
index 0000000..fd1cc69
--- /dev/null
+++ b/mesh_protocol/capability_grants.py
@@ -0,0 +1,93 @@
+from __future__ import annotations
+
+from copy import deepcopy
+from datetime import datetime, timezone
+from typing import Any
+
+
+SENSITIVE_GRANT_FIELDS = {"signature", "nonce", "proof", "token", "secret"}
+
+
+def _parse_datetime(value: Any) -> datetime | None:
+ token = str(value or "").strip()
+ if not token:
+ return None
+ if token.endswith("Z"):
+ token = f"{token[:-1]}+00:00"
+ try:
+ parsed = datetime.fromisoformat(token)
+ except ValueError:
+ return None
+ if parsed.tzinfo is None:
+ return parsed.replace(tzinfo=timezone.utc)
+ return parsed.astimezone(timezone.utc)
+
+
+def _issue(path: str, message: str) -> dict[str, str]:
+ return {"path": path, "message": message}
+
+
+def validate_capability_grant(grant: dict[str, Any], *, now: datetime | None = None) -> dict[str, Any]:
+ payload = dict(grant or {})
+ issues: list[dict[str, str]] = []
+ for field in (
+ "grant_id",
+ "issuer_peer_id",
+ "subject_peer_id",
+ "audience_peer_id",
+ "scope",
+ "issued_at",
+ "expires_at",
+ "signature_scheme",
+ "signature",
+ ):
+ value = payload.get(field)
+ if field not in payload or value is None or value == "":
+ issues.append(_issue(f"$.{field}", "required field is missing"))
+
+ scope = payload.get("scope")
+ if not isinstance(scope, dict):
+ issues.append(_issue("$.scope", "scope must be an object"))
+ elif not str(scope.get("action") or "").strip():
+ issues.append(_issue("$.scope.action", "scope action is required"))
+
+ expires_at = _parse_datetime(payload.get("expires_at"))
+ if expires_at is None:
+ issues.append(_issue("$.expires_at", "expires_at must be an ISO-8601 timestamp"))
+ else:
+ comparison_time = (now or datetime.now(timezone.utc)).astimezone(timezone.utc)
+ if expires_at <= comparison_time:
+ issues.append(_issue("$.expires_at", "capability grant is expired"))
+
+ status = "ok"
+ if any(issue["path"] == "$.expires_at" and "expired" in issue["message"] for issue in issues):
+ status = "expired"
+ elif issues:
+ status = "invalid"
+ return {
+ "status": status,
+ "grant_id": str(payload.get("grant_id") or "").strip(),
+ "issuer_peer_id": str(payload.get("issuer_peer_id") or "").strip(),
+ "subject_peer_id": str(payload.get("subject_peer_id") or "").strip(),
+ "audience_peer_id": str(payload.get("audience_peer_id") or "").strip(),
+ "scope": deepcopy(scope) if isinstance(scope, dict) else {},
+ "expires_at": str(payload.get("expires_at") or "").strip(),
+ "issues": issues,
+ }
+
+
+def redact_capability_grant(grant: dict[str, Any], *, status: str = "declared") -> dict[str, Any]:
+ payload = dict(grant or {})
+ scope = payload.get("scope")
+ redacted = {
+ "type": "capability_grant",
+ "status": str(status or "declared").strip(),
+ "redacted": True,
+ "grant_id": str(payload.get("grant_id") or "").strip(),
+ "issuer_peer_id": str(payload.get("issuer_peer_id") or "").strip(),
+ "subject_peer_id": str(payload.get("subject_peer_id") or "").strip(),
+ "audience_peer_id": str(payload.get("audience_peer_id") or "").strip(),
+ "scope": deepcopy(scope) if isinstance(scope, dict) else {},
+ "expires_at": str(payload.get("expires_at") or "").strip(),
+ }
+ return {key: value for key, value in redacted.items() if value not in ("", {}, [])}
diff --git a/mesh_protocol/conformance.py b/mesh_protocol/conformance.py
index 9edc960..ef9bed0 100644
--- a/mesh_protocol/conformance.py
+++ b/mesh_protocol/conformance.py
@@ -121,6 +121,58 @@ def build_protocol_conformance_snapshot() -> dict[str, Any]:
"remote_auth": {"type": "operator_token", "token": "fixture-token"},
},
),
+ _fixture_entry(
+ "capability-grant-artifact-read",
+ schema_ref="CapabilityGrant",
+ purpose="Alpha signed scoped grant shape for one private artifact read.",
+ value={
+ "grant_id": "grant-alpha-private-artifact",
+ "issuer_peer_id": "beta-node",
+ "subject_peer_id": "alpha-node",
+ "audience_peer_id": "beta-node",
+ "scope": {
+ "action": "artifact.read",
+ "artifact_id": "artifact-fixture",
+ "digest": "abc123",
+ "max_uses": 1,
+ },
+ "issued_at": "2026-01-01T00:00:00Z",
+ "expires_at": "2026-01-01T00:05:00Z",
+ "nonce": "grant-fixture-nonce",
+ "signature_scheme": "ed25519-sha512-v1",
+ "signature": "fixture-signature",
+ },
+ ),
+ _fixture_entry(
+ "artifact-replicate-request-capability-grant",
+ schema_ref="ArtifactReplicateRequest",
+ purpose="Private artifact replication request carrying a declared scoped grant instead of a remote operator token.",
+ value={
+ "peer_id": "beta-node",
+ "artifact_id": "artifact-fixture",
+ "pin": True,
+ "remote_auth": {
+ "type": "capability_grant",
+ "grant": {
+ "grant_id": "grant-alpha-private-artifact",
+ "issuer_peer_id": "beta-node",
+ "subject_peer_id": "alpha-node",
+ "audience_peer_id": "beta-node",
+ "scope": {
+ "action": "artifact.read",
+ "artifact_id": "artifact-fixture",
+ "digest": "abc123",
+ "max_uses": 1,
+ },
+ "issued_at": "2026-01-01T00:00:00Z",
+ "expires_at": "2026-01-01T00:05:00Z",
+ "nonce": "grant-fixture-nonce",
+ "signature_scheme": "ed25519-sha512-v1",
+ "signature": "fixture-signature",
+ },
+ },
+ },
+ ),
_fixture_entry(
"artifact-replicate-response-redacted-auth",
schema_ref="ArtifactReplicateResponse",
diff --git a/mesh_protocol/schemas.py b/mesh_protocol/schemas.py
index ef2343d..84feb46 100644
--- a/mesh_protocol/schemas.py
+++ b/mesh_protocol/schemas.py
@@ -161,14 +161,58 @@
},
"ArtifactReplicationAuth": {
"type": "object",
- "description": "Explicit remote-content authorization. Tokens are request-only and must never be persisted or echoed.",
+ "description": "Explicit remote-content authorization. Tokens and grant proof material are request-only and must never be persisted or echoed.",
"properties": {
"type": {"type": "string"},
"token": {"type": "string"},
+ "grant": {"$ref": "#/schemas/CapabilityGrant"},
+ "grant_id": {"type": "string"},
"redacted": {"type": "boolean"},
"status": {"type": "string"},
},
},
+ "CapabilityGrantScope": {
+ "type": "object",
+ "title": "CapabilityGrantScope",
+ "required": ["action"],
+ "properties": {
+ "action": {"type": "string"},
+ "artifact_id": {"type": "string"},
+ "digest": {"type": "string"},
+ "path": {"type": "string"},
+ "max_uses": {"type": "integer"},
+ "constraints": {"type": "object"},
+ },
+ },
+ "CapabilityGrant": {
+ "type": "object",
+ "title": "CapabilityGrant",
+ "description": "Alpha signed scoped grant shape for future private artifact and route-scoped capabilities.",
+ "required": [
+ "grant_id",
+ "issuer_peer_id",
+ "subject_peer_id",
+ "audience_peer_id",
+ "scope",
+ "issued_at",
+ "expires_at",
+ "signature_scheme",
+ "signature",
+ ],
+ "properties": {
+ "grant_id": {"type": "string"},
+ "issuer_peer_id": {"type": "string"},
+ "subject_peer_id": {"type": "string"},
+ "audience_peer_id": {"type": "string"},
+ "scope": {"$ref": "#/schemas/CapabilityGrantScope"},
+ "issued_at": {"type": "string"},
+ "expires_at": {"type": "string"},
+ "nonce": {"type": "string"},
+ "signature_scheme": {"type": "string"},
+ "signature": {"type": "string"},
+ "metadata": {"type": "object"},
+ },
+ },
"ArtifactReplicateRequest": {
"type": "object",
"properties": {
@@ -639,6 +683,300 @@
"generated_at": {"type": "string"},
},
},
+ "Object": {
+ "type": "object",
+ "description": "Loose object fallback for routes whose detailed response contract has not been promoted yet.",
+ },
+ "ControlStreamSSE": {
+ "type": "object",
+ "description": "Server-sent event stream carrying compact control-deck updates.",
+ "properties": {
+ "event": {"type": "string"},
+ "id": {"type": "string"},
+ "data": {"type": "object"},
+ },
+ },
+ "DeviceProfileResponse": {
+ "type": "object",
+ "properties": {
+ "status": {"type": "string"},
+ "peer_id": {"type": "string"},
+ "device_profile": {"type": "object"},
+ "updated": {"type": "boolean"},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "DiscoveryCandidateList": {
+ "type": "object",
+ "properties": {
+ "status": {"type": "string"},
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "candidates": {"type": "array", "items": {"type": "object"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "PeerList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "peers": {"type": "array", "items": {"type": "object"}},
+ "advisories": {"type": "array", "items": {"type": "object"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "EventStreamSnapshot": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "cursor": {"type": "any"},
+ "events": {"type": "array", "items": {"type": "object"}},
+ "peers": {"type": "array", "items": {"type": "object"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "Job": {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string"},
+ "request_id": {"type": "string"},
+ "kind": {"type": "string"},
+ "status": {"type": "string"},
+ "dispatch_mode": {"type": "string"},
+ "target_peer_id": {"type": "string"},
+ "origin_peer_id": {"type": "string"},
+ "policy": {"type": "object"},
+ "metadata": {"type": "object"},
+ "created_at": {"type": "string"},
+ "updated_at": {"type": "string"},
+ },
+ },
+ "Mission": {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string"},
+ "request_id": {"type": "string"},
+ "title": {"type": "string"},
+ "intent": {"type": "string"},
+ "status": {"type": "string"},
+ "priority": {"type": "string"},
+ "workload_class": {"type": "string"},
+ "origin_peer_id": {"type": "string"},
+ "target_strategy": {"type": "string"},
+ "policy": {"type": "object"},
+ "continuity": {"type": "object"},
+ "metadata": {"type": "object"},
+ "created_at": {"type": "string"},
+ "updated_at": {"type": "string"},
+ },
+ },
+ "MissionList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "missions": {"type": "array", "items": {"$ref": "#/schemas/Mission"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "CooperativeTask": {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string"},
+ "request_id": {"type": "string"},
+ "name": {"type": "string"},
+ "state": {"type": "string"},
+ "status": {"type": "string"},
+ "shards": {"type": "array", "items": {"type": "object"}},
+ "child_job_ids": {"type": "array", "items": {"type": "string"}},
+ "metadata": {"type": "object"},
+ "created_at": {"type": "string"},
+ "updated_at": {"type": "string"},
+ },
+ },
+ "CooperativeTaskList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "tasks": {"type": "array", "items": {"$ref": "#/schemas/CooperativeTask"}},
+ "cooperative_tasks": {"type": "array", "items": {"$ref": "#/schemas/CooperativeTask"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "MeshPressure": {
+ "type": "object",
+ "properties": {
+ "status": {"type": "string"},
+ "peer_id": {"type": "string"},
+ "pressure": {"type": "object"},
+ "helper_recommended": {"type": "boolean"},
+ "operator_summary": {"type": "string"},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "HelperList": {
+ "type": "object",
+ "properties": {
+ "status": {"type": "string"},
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "helpers": {"type": "array", "items": {"type": "object"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "AutonomousOffloadEvaluation": {
+ "type": "object",
+ "properties": {
+ "status": {"type": "string"},
+ "mode": {"type": "string"},
+ "decisions": {"type": "array", "items": {"type": "object"}},
+ "eligible_helpers": {"type": "array", "items": {"type": "object"}},
+ "approvals": {"type": "array", "items": {"type": "object"}},
+ "operator_summary": {"type": "string"},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "WorkerList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "workers": {"type": "array", "items": {"$ref": "#/schemas/WorkerCapacity"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "NotificationList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "notifications": {"type": "array", "items": {"type": "object"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "ApprovalList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "approvals": {"type": "array", "items": {"type": "object"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "TreatyList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "treaties": {"type": "array", "items": {"$ref": "#/schemas/Treaty"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "SecretList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "secrets": {"type": "array", "items": {"type": "object"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "QueueMessageList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "messages": {"type": "array", "items": {"type": "object"}},
+ "queue": {"type": "array", "items": {"type": "object"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "QueueEventList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "events": {"type": "array", "items": {"type": "object"}},
+ "next_cursor": {"type": "any"},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "QueueMetrics": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "status": {"type": "string"},
+ "metrics": {"type": "object"},
+ "depth": {"type": "integer"},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "SchedulerDecisionList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "decisions": {"type": "array", "items": {"type": "object"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "ArtifactList": {
+ "type": "object",
+ "properties": {
+ "peer_id": {"type": "string"},
+ "count": {"type": "integer"},
+ "artifacts": {"type": "array", "items": {"$ref": "#/schemas/Artifact"}},
+ "generated_at": {"type": "string"},
+ },
+ },
+ "HandshakeResponse": {
+ "type": "object",
+ "properties": {
+ "status": {"type": "string"},
+ "peer": {"type": "object"},
+ "manifest": {"type": "object"},
+ "trust_tier": {"type": "string"},
+ "operator_summary": {"type": "string"},
+ },
+ },
+ "ArtifactPublishResponse": {
+ "type": "object",
+ "properties": {
+ "status": {"type": "string"},
+ "artifact": {"$ref": "#/schemas/Artifact"},
+ "descriptor": {"$ref": "#/schemas/ArtifactDescriptor"},
+ },
+ },
+ "ArtifactPinResponse": {
+ "type": "object",
+ "properties": {
+ "status": {"type": "string"},
+ "artifact_id": {"type": "string"},
+ "pinned": {"type": "boolean"},
+ "artifact": {"$ref": "#/schemas/Artifact"},
+ },
+ },
+ "ArtifactMirrorVerification": {
+ "type": "object",
+ "properties": {
+ "status": {"type": "string"},
+ "artifact_id": {"type": "string"},
+ "peer_id": {"type": "string"},
+ "verification": {"type": "object"},
+ "artifact": {"$ref": "#/schemas/Artifact"},
+ },
+ },
+ "ArtifactPurgeResponse": {
+ "type": "object",
+ "properties": {
+ "status": {"type": "string"},
+ "purged": {"type": "integer"},
+ "kept": {"type": "integer"},
+ "artifacts": {"type": "array", "items": {"type": "object"}},
+ },
+ },
"PeerAdvisory": {
"type": "object",
"properties": {
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..f909825
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,77 @@
+[build-system]
+requires = ["setuptools>=68"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "open-compute-protocol"
+version = "0.1.7.dev0"
+description = "A sovereign, local-first compute fabric for trusted devices."
+readme = "README.md"
+requires-python = ">=3.11"
+license = "AGPL-3.0-or-later"
+authors = [
+ { name = "Open Compute Protocol contributors" }
+]
+keywords = [
+ "local-first",
+ "mesh",
+ "compute",
+ "protocol",
+ "sovereign",
+]
+classifiers = [
+ "Development Status :: 3 - Alpha",
+ "Environment :: Console",
+ "Intended Audience :: Developers",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.11",
+ "Topic :: Internet :: WWW/HTTP :: HTTP Servers",
+ "Topic :: System :: Distributed Computing",
+]
+dependencies = []
+
+[project.urls]
+Homepage = "https://github.com/workingclassbuddha/open-compute-protocol"
+Repository = "https://github.com/workingclassbuddha/open-compute-protocol"
+Issues = "https://github.com/workingclassbuddha/open-compute-protocol/issues"
+Documentation = "https://github.com/workingclassbuddha/open-compute-protocol/tree/main/docs"
+
+[project.scripts]
+ocp = "server:main"
+ocp-easy = "scripts.start_ocp_easy:main"
+
+[tool.setuptools]
+packages = [
+ "mesh",
+ "mesh_artifacts",
+ "mesh_autonomy",
+ "mesh_execution",
+ "mesh_governance",
+ "mesh_helpers",
+ "mesh_missions",
+ "mesh_protocol",
+ "mesh_scheduler",
+ "mesh_state",
+ "ocp_desktop",
+ "scripts",
+]
+py-modules = [
+ "ocp_startup",
+ "runtime",
+ "server",
+ "server_app",
+ "server_app_history",
+ "server_app_status",
+ "server_artifacts",
+ "server_browser_client",
+ "server_connect",
+ "server_contract",
+ "server_control",
+ "server_control_page",
+ "server_http_handlers",
+ "server_missions",
+ "server_ops",
+ "server_routes",
+ "server_runtime",
+]
+include-package-data = true
diff --git a/scripts/__init__.py b/scripts/__init__.py
new file mode 100644
index 0000000..00cdb07
--- /dev/null
+++ b/scripts/__init__.py
@@ -0,0 +1 @@
+"""Helper scripts exposed for editable-install console entry points."""
diff --git a/scripts/check_protocol_conformance.py b/scripts/check_protocol_conformance.py
index be78520..bce0194 100644
--- a/scripts/check_protocol_conformance.py
+++ b/scripts/check_protocol_conformance.py
@@ -29,6 +29,11 @@ def main() -> int:
for endpoint in snapshot.get("endpoints", [])
if endpoint.get("response", {}).get("schema_ref") and not endpoint["response"].get("schema_available", False)
]
+ generic_response_refs = [
+ endpoint["id"]
+ for endpoint in snapshot.get("endpoints", [])
+ if endpoint.get("response", {}).get("schema_ref") == "Object"
+ ]
errors: list[str] = []
if snapshot.get("status") != "ok":
@@ -46,10 +51,17 @@ def main() -> int:
f"Protocol conformance snapshot: endpoints={snapshot.get('endpoint_count', 0)} "
f"schemas={snapshot.get('schema_count', 0)} "
f"fixtures={conformance.get('fixture_count', 0)} "
- f"unresolved_response_refs={len(unresolved_response_refs)}"
+ f"unresolved_response_refs={len(unresolved_response_refs)} "
+ f"generic_response_refs={len(generic_response_refs)}"
)
print(summary)
+ if generic_response_refs:
+ preview = ", ".join(generic_response_refs[:10])
+ remainder = len(generic_response_refs) - min(len(generic_response_refs), 10)
+ suffix = f" (+{remainder} more)" if remainder > 0 else ""
+ print(f"Response schema coverage still generic: {preview}{suffix}")
+
if unresolved_response_refs:
preview = ", ".join(unresolved_response_refs[:10])
remainder = len(unresolved_response_refs) - min(len(unresolved_response_refs), 10)
diff --git a/scripts/export_contract.py b/scripts/export_contract.py
new file mode 100644
index 0000000..0315680
--- /dev/null
+++ b/scripts/export_contract.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+"""Export the code-owned OCP HTTP contract snapshot as JSON."""
+
+from __future__ import annotations
+
+import argparse
+import json
+import sys
+from pathlib import Path
+from typing import TextIO
+
+ROOT = Path(__file__).resolve().parents[1]
+root_str = str(ROOT)
+if root_str not in sys.path:
+ sys.path.insert(0, root_str)
+
+from server_contract import build_contract_snapshot
+
+
+def build_parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(description="Export the OCP HTTP contract snapshot.")
+ parser.add_argument("--output", default="", help="Optional path to write JSON output.")
+ parser.add_argument("--pretty", action="store_true", help="Pretty-print JSON with stable key order.")
+ return parser
+
+
+def write_snapshot(stream: TextIO, *, pretty: bool) -> None:
+ snapshot = build_contract_snapshot()
+ if pretty:
+ json.dump(snapshot, stream, indent=2, sort_keys=True)
+ else:
+ json.dump(snapshot, stream, separators=(",", ":"), sort_keys=True)
+ stream.write("\n")
+
+
+def main(argv: list[str] | None = None) -> int:
+ parser = build_parser()
+ args = parser.parse_args(argv)
+ try:
+ if args.output:
+ output_path = Path(args.output)
+ output_path.parent.mkdir(parents=True, exist_ok=True)
+ with output_path.open("w", encoding="utf-8") as stream:
+ write_snapshot(stream, pretty=args.pretty)
+ else:
+ write_snapshot(sys.stdout, pretty=args.pretty)
+ except Exception as exc:
+ print(f"ERROR: failed to export contract: {exc}", file=sys.stderr)
+ return 1
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/tests/OCPDesktopCoreTests/LauncherCoreTests.swift b/tests/OCPDesktopCoreTests/LauncherCoreTests.swift
index 4910e47..f7bea99 100644
--- a/tests/OCPDesktopCoreTests/LauncherCoreTests.swift
+++ b/tests/OCPDesktopCoreTests/LauncherCoreTests.swift
@@ -360,3 +360,117 @@ import Foundation
let strongSteps = MissionControlDeriver.setupGuideSteps(snapshot: strong, mode: .mesh, phoneURL: "http://192.168.1.4:8421/app")
#expect(strongSteps.allSatisfy { $0.status == "complete" })
}
+
+@Test func proofAssistantStartsMeshThenSurfacesPhoneLink() throws {
+ let starting = ProofAssistantReducer.initial(mode: .local, phoneURL: "Start Mesh Mode")
+ #expect(starting.phase == .startingMesh)
+
+ let ready = try decodeSnapshot("""
+ {
+ "status": "ok",
+ "setup": {
+ "status": "ready",
+ "phone_url": "http://192.168.1.4:8421/app"
+ }
+ }
+ """)
+
+ let assistant = ProofAssistantReducer.status(
+ for: ready,
+ mode: .mesh,
+ phoneURL: "http://192.168.1.4:8421/app#ocp_operator_token=test",
+ currentPhase: .waitingForServer,
+ copiedPhoneLink: true
+ )
+ #expect(assistant.phase == .phoneLinkReady)
+ #expect(assistant.copiedPhoneLink)
+ #expect(assistant.phoneURL.contains("ocp_operator_token"))
+}
+
+@Test func proofAssistantMovesActivationIntoProofPolling() throws {
+ let proving = try decodeSnapshot("""
+ {
+ "status": "ok",
+ "setup": {
+ "status": "proving",
+ "latest_proof_status": "running",
+ "recovery_state": "repairing",
+ "next_fix": "Keep the second device open while proof runs."
+ },
+ "latest_proof": {"status": "running", "summary": "Whole-mesh proof is in flight."}
+ }
+ """)
+
+ let assistant = ProofAssistantReducer.status(
+ for: proving,
+ mode: .mesh,
+ phoneURL: "http://192.168.1.4:8421/app#ocp_operator_token=test",
+ currentPhase: .activating,
+ copiedPhoneLink: true
+ )
+
+ #expect(assistant.phase == .pollingProof)
+ #expect(assistant.message == "Whole-mesh proof is in flight.")
+}
+
+@Test func proofAssistantCompletesWhenSetupIsStrong() throws {
+ let strong = try decodeSnapshot("""
+ {
+ "status": "ok",
+ "setup": {
+ "status": "strong",
+ "operator_summary": "Mesh is strong.",
+ "latest_proof_status": "completed"
+ },
+ "latest_proof": {"status": "completed"}
+ }
+ """)
+
+ let assistant = ProofAssistantReducer.status(
+ for: strong,
+ mode: .mesh,
+ phoneURL: "http://192.168.1.4:8421/app#ocp_operator_token=test",
+ currentPhase: .pollingProof,
+ copiedPhoneLink: true
+ )
+
+ #expect(assistant.phase == .completed)
+ #expect(assistant.message == "Mesh is strong.")
+}
+
+@Test func proofAssistantNeedsAttentionForFailedProofWithNextFix() throws {
+ let failed = try decodeSnapshot("""
+ {
+ "status": "ok",
+ "setup": {
+ "status": "needs_attention",
+ "latest_proof_status": "failed",
+ "blocking_issue": "No second device responded.",
+ "next_fix": "Open the copied phone link on the second device."
+ },
+ "latest_proof": {"status": "failed", "summary": "Proof failed."}
+ }
+ """)
+
+ let assistant = ProofAssistantReducer.status(
+ for: failed,
+ mode: .mesh,
+ phoneURL: "http://192.168.1.4:8421/app#ocp_operator_token=test",
+ currentPhase: .pollingProof,
+ copiedPhoneLink: true
+ )
+
+ #expect(assistant.phase == .needsAttention)
+ #expect(assistant.message == "Open the copied phone link on the second device.")
+ #expect(assistant.detail == "No second device responded.")
+}
+
+@Test func proofAssistantFailsOnServerStartupTimeout() {
+ let assistant = ProofAssistantReducer.startupTimeout(seconds: 20)
+ #expect(assistant.phase == .failed)
+ #expect(assistant.message.contains("/mesh/app/status"))
+}
+
+private func decodeSnapshot(_ json: String) throws -> AppStatusSnapshot {
+ try JSONDecoder().decode(AppStatusSnapshot.self, from: Data(json.utf8))
+}
diff --git a/tests/README.md b/tests/README.md
new file mode 100644
index 0000000..0f531d6
--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1,18 @@
+# OCP Test Structure
+
+`tests.test_sovereign_mesh` is the current broad regression suite and remains the baseline for the v0.1.7 Trustworthy Alpha pass.
+
+New tests should be added by subsystem as the suite is split up:
+
+- `tests/protocol/` for contract, schema, signed-envelope, and conformance behavior
+- `tests/runtime/` for local SQLite runtime and state behavior
+- `tests/http/` for server route and auth behavior
+- `tests/execution/` for worker execution lanes and result packaging
+- `tests/scheduler/` for placement and decision behavior
+- `tests/artifacts/` for artifact publishing, replication, policy, and retention
+- `tests/missions/` for mission and continuity behavior
+- `tests/app/` for app/status/control API behavior
+- `tests/desktop/` for launcher and desktop integration behavior
+- `tests/integration/` for slower multi-node flows
+
+Integration tests may remain broader and slower. Protocol and conformance tests should prefer `server_contract.py` and `mesh_protocol` schemas over duplicated route metadata.
diff --git a/tests/app/.gitkeep b/tests/app/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/app/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/tests/artifacts/.gitkeep b/tests/artifacts/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/artifacts/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/tests/desktop/.gitkeep b/tests/desktop/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/desktop/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/tests/execution/.gitkeep b/tests/execution/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/execution/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/tests/http/.gitkeep b/tests/http/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/http/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/tests/integration/.gitkeep b/tests/integration/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/integration/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/tests/missions/.gitkeep b/tests/missions/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/missions/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/tests/protocol/.gitkeep b/tests/protocol/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/protocol/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/tests/protocol/test_capability_grants.py b/tests/protocol/test_capability_grants.py
new file mode 100644
index 0000000..f869bcf
--- /dev/null
+++ b/tests/protocol/test_capability_grants.py
@@ -0,0 +1,98 @@
+from __future__ import annotations
+
+import unittest
+from datetime import datetime, timezone
+from types import SimpleNamespace
+
+from mesh_artifacts.service import MeshArtifactService
+from mesh_protocol.conformance import build_protocol_conformance_snapshot
+from mesh_protocol.capability_grants import (
+ redact_capability_grant,
+ validate_capability_grant,
+)
+from mesh_protocol.schemas import get_protocol_schema, validate_protocol_object
+
+
+def fixture_grant(**overrides):
+ grant = {
+ "grant_id": "grant-alpha-private-artifact",
+ "issuer_peer_id": "beta-node",
+ "subject_peer_id": "alpha-node",
+ "audience_peer_id": "beta-node",
+ "scope": {
+ "action": "artifact.read",
+ "artifact_id": "artifact-private",
+ "digest": "abc123",
+ "max_uses": 1,
+ },
+ "issued_at": "2026-01-01T00:00:00Z",
+ "expires_at": "2026-01-01T00:05:00Z",
+ "nonce": "grant-nonce",
+ "signature_scheme": "ed25519-sha512-v1",
+ "signature": "fixture-signature",
+ }
+ grant.update(overrides)
+ return grant
+
+
+class CapabilityGrantProtocolTests(unittest.TestCase):
+ def test_capability_grant_schema_accepts_scoped_artifact_read_grant(self):
+ grant = fixture_grant()
+
+ self.assertIn("CapabilityGrant", get_protocol_schema("CapabilityGrant")["title"])
+ validation = validate_protocol_object("CapabilityGrant", grant)
+
+ self.assertEqual(validation["status"], "ok")
+
+ def test_capability_grant_validation_rejects_expired_grants(self):
+ grant = fixture_grant(expires_at="2026-01-01T00:00:30Z")
+
+ validation = validate_capability_grant(
+ grant,
+ now=datetime(2026, 1, 1, 0, 1, tzinfo=timezone.utc),
+ )
+
+ self.assertEqual(validation["status"], "expired")
+ self.assertIn("expires_at", validation["issues"][0]["path"])
+
+ def test_capability_grant_redaction_keeps_scope_but_removes_signature_material(self):
+ grant = fixture_grant(signature="sensitive-signature", nonce="sensitive-nonce")
+
+ redacted = redact_capability_grant(grant)
+
+ self.assertEqual(redacted["type"], "capability_grant")
+ self.assertEqual(redacted["status"], "declared")
+ self.assertEqual(redacted["grant_id"], "grant-alpha-private-artifact")
+ self.assertEqual(redacted["scope"]["action"], "artifact.read")
+ self.assertTrue(redacted["redacted"])
+ serialized = repr(redacted)
+ self.assertNotIn("sensitive-signature", serialized)
+ self.assertNotIn("sensitive-nonce", serialized)
+
+ def test_artifact_remote_auth_summary_accepts_unexpired_capability_grant(self):
+ mesh = SimpleNamespace()
+ mesh.MeshPolicyError = ValueError
+ service = MeshArtifactService.__new__(MeshArtifactService)
+ service.mesh = mesh
+
+ summary = service._remote_auth_summary(
+ {"type": "capability_grant", "grant": fixture_grant()},
+ now=datetime(2026, 1, 1, 0, 1, tzinfo=timezone.utc),
+ )
+
+ self.assertEqual(summary["type"], "capability_grant")
+ self.assertEqual(summary["status"], "declared")
+ self.assertEqual(summary["grant_id"], "grant-alpha-private-artifact")
+ self.assertTrue(summary["redacted"])
+
+ def test_conformance_snapshot_includes_capability_grant_fixture(self):
+ snapshot = build_protocol_conformance_snapshot()
+ fixture_ids = {fixture["id"] for fixture in snapshot["fixtures"]}
+
+ self.assertIn("capability-grant-artifact-read", fixture_ids)
+ self.assertIn("artifact-replicate-request-capability-grant", fixture_ids)
+ self.assertEqual(snapshot["invalid_fixture_count"], 0)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/tests/runtime/.gitkeep b/tests/runtime/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/runtime/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/tests/scheduler/.gitkeep b/tests/scheduler/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/scheduler/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/tests/test_sovereign_mesh.py b/tests/test_sovereign_mesh.py
index f4086e7..02480f1 100644
--- a/tests/test_sovereign_mesh.py
+++ b/tests/test_sovereign_mesh.py
@@ -6400,7 +6400,19 @@ def test_server_contract_module_exposes_mesh_route_contract(self):
self.assertIn("RouteHealth", snapshot["schemas"])
self.assertIn("AppStatus", snapshot["schemas"])
self.assertIn("AppStatusHistory", snapshot["schemas"])
+ self.assertIn("QueueEventList", snapshot["schemas"])
+ self.assertIn("MissionList", snapshot["schemas"])
+ self.assertIn("WorkerList", snapshot["schemas"])
+ self.assertIn("ArtifactList", snapshot["schemas"])
+ self.assertIn("Object", snapshot["schemas"])
self.assertIn("ProtocolConformanceSnapshot", snapshot["schemas"])
+ unresolved_response_refs = [
+ endpoint["id"]
+ for endpoint in endpoints
+ if endpoint.get("response", {}).get("schema_ref")
+ and not endpoint["response"].get("schema_available", False)
+ ]
+ self.assertEqual([], unresolved_response_refs)
self.assertIn("runtime", snapshot["groups"])
self.assertIn("missions", snapshot["groups"])
self.assertIn("ops", snapshot["groups"])
@@ -6427,10 +6439,13 @@ def test_server_contract_module_exposes_mesh_route_contract(self):
self.assertEqual(queue_events["request"]["query"]["since"], "integer")
self.assertEqual(queue_events["request"]["query"]["since_seq"], "integer")
self.assertEqual(queue_events["response"]["schema_ref"], "QueueEventList")
+ self.assertTrue(queue_events["response"]["schema_available"])
ack_deadline = server_contract.contract_for("POST", "/mesh/queue/ack-deadline")
self.assertEqual(ack_deadline["request"]["body"]["ttl_seconds"], "integer")
self.assertEqual(ack_deadline["request"]["body"]["ack_deadline_seconds"], "integer")
+ self.assertEqual(ack_deadline["response"]["schema_ref"], "Object")
+ self.assertTrue(ack_deadline["response"]["schema_available"])
manifest_contract = server_contract.contract_for("GET", "/mesh/manifest")
self.assertEqual(manifest_contract["response"]["schema_ref"], "MeshManifest")
@@ -6491,6 +6506,9 @@ def test_server_contract_module_exposes_mesh_route_contract(self):
self.assertIn("ExecutionReadiness", list_protocol_schemas())
self.assertIn("WorkerCapacity", list_protocol_schemas())
self.assertIn("SetupTimelineEvent", list_protocol_schemas())
+ self.assertIn("QueueEventList", list_protocol_schemas())
+ self.assertIn("ArtifactList", list_protocol_schemas())
+ self.assertIn("Object", list_protocol_schemas())
self.assertIn("ProtocolConformanceSnapshot", list_protocol_schemas())
conformance = snapshot["conformance"]