mirror of
https://github.com/stablyai/orca.git
synced 2026-11-04 02:57:36 +00:00
Desktop, CLI, web and runtime transports now take a PairedRuntimeConnection (endpoint, pinned host key, credential) instead of a PairingOffer. Offers stay on the pairing input path (codes, QR, links, environment add) and are converted with pairedRuntimeConnectionFromOffer. The credential is token-only today; request envelopes still carry the same deviceToken, so the wire is unchanged. This lets device-key and ticket credentials replace the token later without touching every connect call site again. Co-authored-by: m4air <m4air@Mac.localdomain>
153 lines
4.3 KiB
TypeScript
153 lines
4.3 KiB
TypeScript
import type { PairedRuntimeConnection } from '../../shared/paired-runtime-connection'
|
|
|
|
export type RuntimeEnvironmentCapabilityVerdict = 'capable' | 'absent'
|
|
|
|
export type RuntimeEnvironmentCapabilityEvidence = {
|
|
environmentId: string
|
|
pairingKey: string
|
|
epoch: number
|
|
sequence: number
|
|
}
|
|
|
|
export type RuntimeEnvironmentCapabilityOutcome =
|
|
| { kind: 'supported'; evidence: RuntimeEnvironmentCapabilityEvidence; runtimeId: string }
|
|
| { kind: 'unsupported'; evidence: RuntimeEnvironmentCapabilityEvidence; runtimeId: string }
|
|
| { kind: 'stale_incarnation' }
|
|
|
|
type AcceptedEvidence = {
|
|
evidence: RuntimeEnvironmentCapabilityEvidence
|
|
verdict: RuntimeEnvironmentCapabilityVerdict
|
|
runtimeId: string
|
|
}
|
|
|
|
type EvidenceState = {
|
|
epoch: number
|
|
nextSequence: number
|
|
accepted: AcceptedEvidence | null
|
|
}
|
|
|
|
const evidenceByEnvironment = new Map<string, EvidenceState>()
|
|
|
|
export function resetRuntimeEnvironmentCapabilityEvidence(): void {
|
|
evidenceByEnvironment.clear()
|
|
}
|
|
|
|
export function clearRuntimeEnvironmentCapabilityEvidence(environmentId: string): void {
|
|
evidenceByEnvironment.delete(environmentId)
|
|
}
|
|
|
|
function stateFor(environmentId: string): EvidenceState {
|
|
let state = evidenceByEnvironment.get(environmentId)
|
|
if (!state) {
|
|
state = { epoch: 0, nextSequence: 0, accepted: null }
|
|
evidenceByEnvironment.set(environmentId, state)
|
|
}
|
|
return state
|
|
}
|
|
|
|
export function captureRuntimeEnvironmentCapabilityEvidence(
|
|
environmentId: string,
|
|
connection: PairedRuntimeConnection
|
|
): RuntimeEnvironmentCapabilityEvidence {
|
|
const state = stateFor(environmentId)
|
|
return {
|
|
environmentId,
|
|
pairingKey: pairingKey(connection),
|
|
epoch: state.epoch,
|
|
sequence: ++state.nextSequence
|
|
}
|
|
}
|
|
|
|
export function advanceRuntimeEnvironmentCapabilityIncarnation(environmentId: string): void {
|
|
const state = stateFor(environmentId)
|
|
state.epoch += 1
|
|
state.accepted = null
|
|
}
|
|
|
|
export function getRuntimeEnvironmentCapabilityIncarnation(environmentId: string): number {
|
|
return stateFor(environmentId).epoch
|
|
}
|
|
|
|
export function applyRuntimeEnvironmentCapabilityVerdict(args: {
|
|
evidence: RuntimeEnvironmentCapabilityEvidence
|
|
verdict: RuntimeEnvironmentCapabilityVerdict
|
|
runtimeId: string
|
|
}): boolean {
|
|
const state = stateFor(args.evidence.environmentId)
|
|
if (
|
|
args.evidence.epoch !== state.epoch ||
|
|
(state.accepted !== null && args.evidence.sequence <= state.accepted.evidence.sequence)
|
|
) {
|
|
return false
|
|
}
|
|
state.accepted = {
|
|
evidence: args.evidence,
|
|
verdict: args.verdict,
|
|
runtimeId: args.runtimeId
|
|
}
|
|
return true
|
|
}
|
|
|
|
export function runtimeEnvironmentCapabilityOutcome(
|
|
evidence: RuntimeEnvironmentCapabilityEvidence,
|
|
verdict: RuntimeEnvironmentCapabilityVerdict,
|
|
runtimeId: string
|
|
): RuntimeEnvironmentCapabilityOutcome {
|
|
return {
|
|
kind: verdict === 'capable' ? 'supported' : 'unsupported',
|
|
evidence,
|
|
runtimeId
|
|
}
|
|
}
|
|
|
|
export function getAcceptedRuntimeEnvironmentCapabilityOutcome(
|
|
environmentId: string,
|
|
connection: PairedRuntimeConnection,
|
|
runtimeId: string | null
|
|
): RuntimeEnvironmentCapabilityOutcome | null {
|
|
const accepted = stateFor(environmentId).accepted
|
|
if (
|
|
!accepted ||
|
|
accepted.evidence.pairingKey !== pairingKey(connection) ||
|
|
(runtimeId !== null && accepted.runtimeId !== runtimeId)
|
|
) {
|
|
return null
|
|
}
|
|
return runtimeEnvironmentCapabilityOutcome(
|
|
accepted.evidence,
|
|
accepted.verdict,
|
|
accepted.runtimeId
|
|
)
|
|
}
|
|
|
|
export function isRuntimeEnvironmentCapabilityOutcomeCurrent(
|
|
outcome: RuntimeEnvironmentCapabilityOutcome
|
|
): boolean {
|
|
if (outcome.kind === 'stale_incarnation') {
|
|
return false
|
|
}
|
|
const state = stateFor(outcome.evidence.environmentId)
|
|
if (outcome.evidence.epoch !== state.epoch) {
|
|
return false
|
|
}
|
|
const accepted = state.accepted
|
|
if (!accepted || accepted.evidence.sequence <= outcome.evidence.sequence) {
|
|
return true
|
|
}
|
|
return (
|
|
((outcome.kind === 'supported' && accepted.verdict === 'capable') ||
|
|
(outcome.kind === 'unsupported' && accepted.verdict === 'absent')) &&
|
|
accepted.runtimeId === outcome.runtimeId
|
|
)
|
|
}
|
|
|
|
export function isRuntimeEnvironmentCapabilityPaused(environmentId: string): boolean {
|
|
return stateFor(environmentId).accepted?.verdict === 'absent'
|
|
}
|
|
|
|
function pairingKey(connection: PairedRuntimeConnection): string {
|
|
return [connection.endpoint, connection.credential.deviceToken, connection.hostPublicKeyB64].join(
|
|
'\0'
|
|
)
|
|
}
|