@continuonai/rcan-ts 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -3
- package/bin/rcan-validate.mjs +86 -0
- package/dist/browser.d.mts +814 -5
- package/dist/browser.mjs +1217 -5
- package/dist/browser.mjs.map +1 -1
- package/dist/index.d.mts +814 -5
- package/dist/index.d.ts +814 -5
- package/dist/index.js +1267 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1213 -5
- package/dist/index.mjs.map +1 -1
- package/dist/rcan-validate.js +47 -2
- package/dist/rcan.iife.js +3 -3
- package/package.json +5 -5
package/dist/browser.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/address.ts","../src/message.ts","../src/crypto.ts","../src/gates.ts","../src/audit.ts","../src/validate.ts","../src/errors.ts","../src/registry.ts","../src/index.ts"],"sourcesContent":["/**\n * RCAN Robot URI — addressing scheme for RCAN v1.2.\n *\n * Format: rcan://<registry>/<manufacturer>/<model>/<version>/<device-id>\n * Example: rcan://registry.rcan.dev/acme/robotarm/v2/unit-001\n */\n\nexport class RobotURIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RobotURIError\";\n }\n}\n\nexport interface RobotURIOptions {\n manufacturer: string;\n model: string;\n version: string;\n deviceId: string;\n registry?: string;\n}\n\nexport class RobotURI {\n readonly registry: string;\n readonly manufacturer: string;\n readonly model: string;\n readonly version: string;\n readonly deviceId: string;\n\n private constructor(opts: Required<RobotURIOptions>) {\n this.registry = opts.registry;\n this.manufacturer = opts.manufacturer;\n this.model = opts.model;\n this.version = opts.version;\n this.deviceId = opts.deviceId;\n }\n\n /** Parse a RCAN URI string. Throws RobotURIError on invalid input. */\n static parse(uri: string): RobotURI {\n if (!uri.startsWith(\"rcan://\")) {\n throw new RobotURIError(`URI must start with 'rcan://' — got: ${uri}`);\n }\n const withoutScheme = uri.slice(\"rcan://\".length);\n const parts = withoutScheme.split(\"/\");\n if (parts.length !== 5) {\n throw new RobotURIError(\n `URI must have exactly 5 path segments (registry/manufacturer/model/version/device-id) — got ${parts.length} in: ${uri}`\n );\n }\n const [registry, manufacturer, model, version, deviceId] = parts;\n for (const [name, value] of [\n [\"registry\", registry],\n [\"manufacturer\", manufacturer],\n [\"model\", model],\n [\"version\", version],\n [\"device-id\", deviceId],\n ] as [string, string][]) {\n if (!value || value.trim() === \"\") {\n throw new RobotURIError(`URI segment '${name}' must not be empty`);\n }\n }\n return new RobotURI({ registry, manufacturer, model, version, deviceId });\n }\n\n /** Build a RCAN URI from components. */\n static build(opts: RobotURIOptions): RobotURI {\n const registry = opts.registry ?? \"registry.rcan.dev\";\n const { manufacturer, model, version, deviceId } = opts;\n for (const [name, value] of [\n [\"manufacturer\", manufacturer],\n [\"model\", model],\n [\"version\", version],\n [\"deviceId\", deviceId],\n ] as [string, string][]) {\n if (!value || value.trim() === \"\") {\n throw new RobotURIError(`'${name}' must not be empty`);\n }\n }\n return new RobotURI({ registry, manufacturer, model, version, deviceId });\n }\n\n /** Full URI string: rcan://registry/manufacturer/model/version/device-id */\n toString(): string {\n return `rcan://${this.registry}/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`;\n }\n\n /** Short namespace: manufacturer/model */\n get namespace(): string {\n return `${this.manufacturer}/${this.model}`;\n }\n\n /** HTTPS registry URL for this robot */\n get registryUrl(): string {\n return `https://${this.registry}/registry/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`;\n }\n\n /** Check if two URIs refer to the same robot */\n equals(other: RobotURI): boolean {\n return this.toString() === other.toString();\n }\n\n toJSON(): object {\n return {\n uri: this.toString(),\n registry: this.registry,\n manufacturer: this.manufacturer,\n model: this.model,\n version: this.version,\n deviceId: this.deviceId,\n };\n }\n}\n","/**\n * RCAN Message — command envelope for RCAN v1.2.\n *\n * A RCANMessage wraps a robot command with:\n * - RCAN protocol version\n * - Target Robot URI\n * - Command name and parameters\n * - Optional AI confidence score (§16)\n * - Optional model identity (§16)\n * - Optional Ed25519 signature\n */\n\nimport { RobotURI } from \"./address\";\n\nexport interface SignatureBlock {\n alg: string;\n kid: string;\n sig: string;\n}\n\nexport interface RCANMessageData {\n rcan?: string;\n cmd: string;\n target: string | RobotURI;\n params?: Record<string, unknown>;\n confidence?: number;\n modelIdentity?: string;\n model_identity?: string; // snake_case alias\n signature?: SignatureBlock;\n timestamp?: string;\n [key: string]: unknown;\n}\n\nexport class RCANMessageError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RCANMessageError\";\n }\n}\n\nexport class RCANMessage {\n readonly rcan: string;\n readonly cmd: string;\n readonly target: string;\n readonly params: Record<string, unknown>;\n readonly confidence: number | undefined;\n readonly modelIdentity: string | undefined;\n readonly signature: SignatureBlock | undefined;\n readonly timestamp: string;\n\n constructor(data: RCANMessageData) {\n if (!data.cmd || data.cmd.trim() === \"\") {\n throw new RCANMessageError(\"'cmd' is required\");\n }\n if (!data.target) {\n throw new RCANMessageError(\"'target' is required\");\n }\n\n this.rcan = data.rcan ?? \"1.2\";\n this.cmd = data.cmd;\n this.target =\n data.target instanceof RobotURI ? data.target.toString() : String(data.target);\n this.params = data.params ?? {};\n this.confidence = data.confidence;\n this.modelIdentity = data.modelIdentity ?? data.model_identity;\n this.signature = data.signature;\n this.timestamp = data.timestamp ?? new Date().toISOString();\n\n if (this.confidence !== undefined) {\n if (this.confidence < 0 || this.confidence > 1) {\n throw new RCANMessageError(\n `confidence must be in [0.0, 1.0] — got ${this.confidence}`\n );\n }\n }\n }\n\n /** Whether this message has a signature block */\n get isSigned(): boolean {\n return this.signature !== undefined && this.signature.sig !== \"\";\n }\n\n /** Whether this message was generated by an AI model (has confidence score) */\n get isAiDriven(): boolean {\n return this.confidence !== undefined;\n }\n\n /** Serialize to a plain object */\n toJSON(): Record<string, unknown> {\n const obj: Record<string, unknown> = {\n rcan: this.rcan,\n cmd: this.cmd,\n target: this.target,\n timestamp: this.timestamp,\n };\n if (Object.keys(this.params).length > 0) obj.params = this.params;\n if (this.confidence !== undefined) obj.confidence = this.confidence;\n if (this.modelIdentity) obj.model_identity = this.modelIdentity;\n if (this.signature) obj.signature = this.signature;\n return obj;\n }\n\n /** Serialize to JSON string */\n toJSONString(indent?: number): string {\n return JSON.stringify(this.toJSON(), null, indent);\n }\n\n /** Parse from a plain object or JSON string */\n static fromJSON(data: string | Record<string, unknown>): RCANMessage {\n let obj: Record<string, unknown>;\n if (typeof data === \"string\") {\n try {\n obj = JSON.parse(data) as Record<string, unknown>;\n } catch {\n throw new RCANMessageError(\"Invalid JSON string\");\n }\n } else {\n obj = data;\n }\n\n if (!obj.cmd) throw new RCANMessageError(\"Missing required field: 'cmd'\");\n if (!obj.target) throw new RCANMessageError(\"Missing required field: 'target'\");\n if (!obj.rcan) throw new RCANMessageError(\"Missing required field: 'rcan'\");\n\n return new RCANMessage({\n rcan: obj.rcan as string,\n cmd: obj.cmd as string,\n target: obj.target as string,\n params: (obj.params as Record<string, unknown>) ?? {},\n confidence: obj.confidence as number | undefined,\n modelIdentity:\n (obj.model_identity as string | undefined) ??\n (obj.modelIdentity as string | undefined),\n signature: obj.signature as SignatureBlock | undefined,\n timestamp: obj.timestamp as string | undefined,\n });\n }\n}\n","/**\n * Cross-platform crypto utilities — Node.js, browser, Cloudflare Workers, Deno.\n *\n * Uses Web Crypto API (SubtleCrypto) as the primary implementation, with a\n * Node.js `crypto` module fallback for environments that predate the global\n * `crypto` object (Node < 19).\n */\n\n/** Generate a UUID v4. Works in all modern environments. */\nexport function generateUUID(): string {\n if (typeof globalThis.crypto !== \"undefined\" && typeof globalThis.crypto.randomUUID === \"function\") {\n return globalThis.crypto.randomUUID();\n }\n // Node.js < 19 fallback\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { randomUUID } = require(\"crypto\") as { randomUUID: () => string };\n return randomUUID();\n } catch {\n // Last-resort UUID fallback (no external deps)\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n}\n\n/**\n * Compute HMAC-SHA256 and return hex string.\n * Synchronous via Node.js `crypto`; falls back to a pure-JS impl in browsers.\n */\nexport function hmacSha256Sync(secret: string, data: string): string {\n // Node.js environment\n if (typeof process !== \"undefined\" && process.versions?.node) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { createHmac } = require(\"crypto\") as {\n createHmac: (alg: string, key: string) => { update: (d: string) => { digest: (enc: string) => string } };\n };\n return createHmac(\"sha256\", secret).update(data).digest(\"hex\");\n } catch {\n // fall through to pure-JS\n }\n }\n // Pure-JS HMAC-SHA256 (browser / Workers / Deno without native crypto)\n return pureHmacSha256(secret, data);\n}\n\n// ── Pure-JS SHA-256 + HMAC (no deps) ─────────────────────────────────────────\n// Based on the public-domain SHA-256 implementation.\n\nfunction sha256(msg: Uint8Array): Uint8Array {\n const K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\n 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\n 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\n 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\n 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n ];\n let h0 = 0x6a09e667, h1 = 0xbb67ae85, h2 = 0x3c6ef372, h3 = 0xa54ff53a;\n let h4 = 0x510e527f, h5 = 0x9b05688c, h6 = 0x1f83d9ab, h7 = 0x5be0cd19;\n\n const msgLen = msg.length;\n const bitLen = msgLen * 8;\n const padded: number[] = [...msg];\n padded.push(0x80);\n while ((padded.length % 64) !== 56) padded.push(0);\n for (let i = 7; i >= 0; i--) padded.push((bitLen / Math.pow(2, i * 8)) & 0xff);\n\n for (let i = 0; i < padded.length; i += 64) {\n const w: number[] = [];\n for (let j = 0; j < 16; j++) {\n w[j] = (padded[i+j*4]<<24)|(padded[i+j*4+1]<<16)|(padded[i+j*4+2]<<8)|padded[i+j*4+3];\n }\n for (let j = 16; j < 64; j++) {\n const s0 = ror(w[j-15],7)^ror(w[j-15],18)^(w[j-15]>>>3);\n const s1 = ror(w[j-2],17)^ror(w[j-2],19)^(w[j-2]>>>10);\n w[j] = (w[j-16]+s0+w[j-7]+s1) >>> 0;\n }\n let [a,b,c,d,e,f,g,h] = [h0,h1,h2,h3,h4,h5,h6,h7];\n for (let j = 0; j < 64; j++) {\n const S1 = ror(e,6)^ror(e,11)^ror(e,25);\n const ch = (e&f)^(~e&g);\n const temp1 = (h+S1+ch+K[j]+w[j])>>>0;\n const S0 = ror(a,2)^ror(a,13)^ror(a,22);\n const maj = (a&b)^(a&c)^(b&c);\n const temp2 = (S0+maj)>>>0;\n [h,g,f,e,d,c,b,a] = [g,f,e,(d+temp1)>>>0,c,b,a,(temp1+temp2)>>>0];\n }\n h0=(h0+a)>>>0; h1=(h1+b)>>>0; h2=(h2+c)>>>0; h3=(h3+d)>>>0;\n h4=(h4+e)>>>0; h5=(h5+f)>>>0; h6=(h6+g)>>>0; h7=(h7+h)>>>0;\n }\n const out = new Uint8Array(32);\n const view = new DataView(out.buffer);\n [h0,h1,h2,h3,h4,h5,h6,h7].forEach((v,i) => view.setUint32(i*4, v));\n return out;\n}\n\nfunction ror(x: number, n: number): number { return (x>>>n)|(x<<(32-n)); }\n\nfunction toBytes(s: string): Uint8Array {\n if (typeof TextEncoder !== \"undefined\") return new TextEncoder().encode(s);\n const out = new Uint8Array(s.length);\n for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i) & 0xff;\n return out;\n}\n\nfunction toHex(bytes: Uint8Array): string {\n return Array.from(bytes).map(b => b.toString(16).padStart(2,\"0\")).join(\"\");\n}\n\nfunction pureHmacSha256(key: string, data: string): string {\n const BLOCK = 64;\n let keyBytes = toBytes(key);\n if (keyBytes.length > BLOCK) keyBytes = sha256(keyBytes);\n const ipad = new Uint8Array(BLOCK), opad = new Uint8Array(BLOCK);\n for (let i = 0; i < BLOCK; i++) {\n ipad[i] = (keyBytes[i] ?? 0) ^ 0x36;\n opad[i] = (keyBytes[i] ?? 0) ^ 0x5c;\n }\n const dataBytes = toBytes(data);\n const inner = new Uint8Array(BLOCK + dataBytes.length);\n inner.set(ipad); inner.set(dataBytes, BLOCK);\n const innerHash = sha256(inner);\n const outer = new Uint8Array(BLOCK + 32);\n outer.set(opad); outer.set(innerHash, BLOCK);\n return toHex(sha256(outer));\n}\n","/**\n * RCAN Safety Gates — confidence and human-in-the-loop gating (§16).\n */\n\nimport { generateUUID } from \"./crypto.js\";\n\nexport class GateError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"GateError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// ConfidenceGate\n// ---------------------------------------------------------------------------\n\nexport class ConfidenceGate {\n readonly threshold: number;\n\n constructor(threshold = 0.8) {\n if (threshold < 0 || threshold > 1) {\n throw new GateError(`threshold must be in [0.0, 1.0] — got ${threshold}`);\n }\n this.threshold = threshold;\n }\n\n /** Returns true if the confidence score meets the threshold. */\n allows(confidence: number): boolean {\n return confidence >= this.threshold;\n }\n\n /** Returns the margin (positive = allowed, negative = blocked). */\n margin(confidence: number): number {\n return confidence - this.threshold;\n }\n\n /** Throw if confidence is below threshold. */\n assert(confidence: number, action?: string): void {\n if (!this.allows(confidence)) {\n const label = action ? ` for action '${action}'` : \"\";\n throw new GateError(\n `Confidence ${confidence}${label} is below threshold ${this.threshold}`\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// HiTLGate\n// ---------------------------------------------------------------------------\n\nexport type ApprovalStatus = \"approved\" | \"denied\" | \"pending\";\n\nexport interface PendingApproval {\n token: string;\n action: string;\n context: Record<string, unknown>;\n createdAt: string;\n status: ApprovalStatus;\n reason?: string;\n}\n\nexport class HiTLGate {\n private _pending: Map<string, PendingApproval> = new Map();\n\n /**\n * Request human approval for an action.\n * Returns an approval token to poll or pass to approve/deny.\n */\n request(action: string, context: Record<string, unknown> = {}): string {\n const token = generateUUID();\n this._pending.set(token, {\n token,\n action,\n context,\n createdAt: new Date().toISOString(),\n status: \"pending\",\n });\n return token;\n }\n\n /** Approve a pending request. */\n approve(token: string): void {\n const approval = this._pending.get(token);\n if (!approval) throw new GateError(`Unknown token: ${token}`);\n approval.status = \"approved\";\n }\n\n /** Deny a pending request with an optional reason. */\n deny(token: string, reason?: string): void {\n const approval = this._pending.get(token);\n if (!approval) throw new GateError(`Unknown token: ${token}`);\n approval.status = \"denied\";\n if (reason) approval.reason = reason;\n }\n\n /** Check the status of a pending approval. */\n check(token: string): ApprovalStatus {\n const approval = this._pending.get(token);\n if (!approval) throw new GateError(`Unknown token: ${token}`);\n return approval.status;\n }\n\n /** Get all pending approvals. */\n get pendingApprovals(): PendingApproval[] {\n return Array.from(this._pending.values()).filter((a) => a.status === \"pending\");\n }\n\n /** Get the full approval record. */\n getApproval(token: string): PendingApproval | undefined {\n return this._pending.get(token);\n }\n\n /** Clear resolved (approved/denied) approvals. */\n clearResolved(): void {\n for (const [token, approval] of this._pending.entries()) {\n if (approval.status !== \"pending\") {\n this._pending.delete(token);\n }\n }\n }\n}\n","/**\n * RCAN Audit Chain — tamper-evident commitment records (§16).\n *\n * Each CommitmentRecord is sealed with an HMAC-SHA256 over its content.\n * Records are chained via previousHash, creating a forensic audit trail.\n */\n\nimport { hmacSha256Sync, generateUUID } from \"./crypto.js\";\n\nexport interface CommitmentRecordData {\n action: string;\n robotUri?: string;\n confidence?: number;\n modelIdentity?: string;\n params?: Record<string, unknown>;\n safetyApproved?: boolean;\n}\n\nexport interface CommitmentRecordJSON {\n recordId: string;\n action: string;\n robotUri: string;\n confidence?: number;\n modelIdentity?: string;\n params: Record<string, unknown>;\n safetyApproved: boolean;\n timestamp: string;\n contentHash: string;\n previousHash: string | null;\n hmac: string;\n}\n\nexport class AuditError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AuditError\";\n }\n}\n\nfunction computeContentHash(\n recordId: string,\n action: string,\n robotUri: string,\n timestamp: string,\n params: Record<string, unknown>\n): string {\n const payload = JSON.stringify(\n { recordId, action, robotUri, timestamp, params },\n Object.keys({ recordId, action, robotUri, timestamp, params }).sort()\n );\n return hmacSha256Sync(\"rcan-content-hash\", payload);\n}\n\nfunction computeHmac(secret: string, data: CommitmentRecordJSON): string {\n const { hmac: _ignored, ...rest } = data;\n const payload = JSON.stringify(rest, Object.keys(rest).sort());\n return hmacSha256Sync(secret, payload);\n}\n\nexport class CommitmentRecord {\n readonly recordId: string;\n readonly action: string;\n readonly robotUri: string;\n readonly confidence: number | undefined;\n readonly modelIdentity: string | undefined;\n readonly params: Record<string, unknown>;\n readonly safetyApproved: boolean;\n readonly timestamp: string;\n readonly contentHash: string;\n readonly previousHash: string | null;\n readonly hmac: string;\n\n private constructor(data: CommitmentRecordJSON) {\n this.recordId = data.recordId;\n this.action = data.action;\n this.robotUri = data.robotUri;\n this.confidence = data.confidence;\n this.modelIdentity = data.modelIdentity;\n this.params = data.params;\n this.safetyApproved = data.safetyApproved;\n this.timestamp = data.timestamp;\n this.contentHash = data.contentHash;\n this.previousHash = data.previousHash;\n this.hmac = data.hmac;\n }\n\n static create(\n data: CommitmentRecordData,\n secret: string,\n previousHash: string | null = null\n ): CommitmentRecord {\n const recordId = generateUUID();\n const timestamp = new Date().toISOString();\n const params = data.params ?? {};\n const robotUri = data.robotUri ?? \"\";\n const contentHash = computeContentHash(recordId, data.action, robotUri, timestamp, params);\n\n const draft: CommitmentRecordJSON = {\n recordId,\n action: data.action,\n robotUri,\n confidence: data.confidence,\n modelIdentity: data.modelIdentity,\n params,\n safetyApproved: data.safetyApproved ?? true,\n timestamp,\n contentHash,\n previousHash,\n hmac: \"\",\n };\n draft.hmac = computeHmac(secret, draft);\n return new CommitmentRecord(draft);\n }\n\n verify(secret: string): boolean {\n const expected = computeHmac(secret, this.toJSON());\n return expected === this.hmac;\n }\n\n toJSON(): CommitmentRecordJSON {\n return {\n recordId: this.recordId,\n action: this.action,\n robotUri: this.robotUri,\n confidence: this.confidence,\n modelIdentity: this.modelIdentity,\n params: this.params,\n safetyApproved: this.safetyApproved,\n timestamp: this.timestamp,\n contentHash: this.contentHash,\n previousHash: this.previousHash,\n hmac: this.hmac,\n };\n }\n\n static fromJSON(obj: CommitmentRecordJSON): CommitmentRecord {\n return new CommitmentRecord(obj);\n }\n}\n\n// ---------------------------------------------------------------------------\n// AuditChain\n// ---------------------------------------------------------------------------\n\nexport interface ChainVerifyResult {\n valid: boolean;\n count: number;\n errors: string[];\n}\n\nexport class AuditChain {\n private _records: CommitmentRecord[] = [];\n private _secret: string;\n\n constructor(secret: string) {\n this._secret = secret;\n }\n\n get records(): readonly CommitmentRecord[] {\n return this._records;\n }\n\n append(data: CommitmentRecordData): CommitmentRecord {\n const prev = this._records[this._records.length - 1];\n const prevHash = prev?.contentHash ?? null;\n const record = CommitmentRecord.create(data, this._secret, prevHash);\n this._records.push(record);\n return record;\n }\n\n verifyAll(): ChainVerifyResult {\n const errors: string[] = [];\n let prevHash: string | null = null;\n\n for (const record of this._records) {\n if (!record.verify(this._secret)) {\n errors.push(`HMAC invalid for record ${record.recordId.slice(0, 8)}`);\n }\n if (prevHash !== null && record.previousHash !== prevHash) {\n errors.push(\n `Chain broken at ${record.recordId.slice(0, 8)}: expected prev=${prevHash.slice(0, 12)}`\n );\n }\n prevHash = record.contentHash;\n }\n\n return { valid: errors.length === 0, count: this._records.length, errors };\n }\n\n toJSONL(): string {\n return this._records.map((r) => JSON.stringify(r.toJSON())).join(\"\\n\") + \"\\n\";\n }\n\n static fromJSONL(text: string, secret: string): AuditChain {\n const chain = new AuditChain(secret);\n const lines = text.trim().split(\"\\n\").filter((l) => l.trim() !== \"\");\n for (const line of lines) {\n const obj = JSON.parse(line) as CommitmentRecordJSON;\n chain._records.push(CommitmentRecord.fromJSON(obj));\n }\n return chain;\n }\n}\n","/**\n * RCAN Validation — validate messages, configs, and URIs.\n *\n * Each function returns a ValidationResult with ok, issues, warnings, info.\n */\n\nimport { RobotURI, RobotURIError } from \"./address\";\nimport { RCANMessage, RCANMessageError } from \"./message\";\nimport type { RCANConfig as RCANConfigType } from \"./types\";\n\nexport type { RCANConfig } from \"./types\";\n\nexport interface ValidationResult {\n ok: boolean;\n issues: string[];\n warnings: string[];\n info: string[];\n}\n\nfunction makeResult(): ValidationResult {\n return { ok: true, issues: [], warnings: [], info: [] };\n}\n\nfunction fail(result: ValidationResult, msg: string): void {\n result.ok = false;\n result.issues.push(msg);\n}\n\nfunction warn(result: ValidationResult, msg: string): void {\n result.warnings.push(msg);\n}\n\nfunction note(result: ValidationResult, msg: string): void {\n result.info.push(msg);\n}\n\n// ---------------------------------------------------------------------------\n// URI validation\n// ---------------------------------------------------------------------------\n\nexport function validateURI(uri: string): ValidationResult {\n const result = makeResult();\n try {\n const parsed = RobotURI.parse(uri);\n note(result, `✅ Valid RCAN URI`);\n note(result, ` Registry: ${parsed.registry}`);\n note(result, ` Manufacturer: ${parsed.manufacturer}`);\n note(result, ` Model: ${parsed.model}`);\n note(result, ` Version: ${parsed.version}`);\n note(result, ` Device ID: ${parsed.deviceId}`);\n } catch (e) {\n fail(result, `Invalid RCAN URI: ${e instanceof Error ? e.message : e}`);\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Message validation\n// ---------------------------------------------------------------------------\n\nexport function validateMessage(data: unknown): ValidationResult {\n const result = makeResult();\n\n let obj: Record<string, unknown>;\n if (typeof data === \"string\") {\n try {\n obj = JSON.parse(data) as Record<string, unknown>;\n } catch {\n fail(result, \"Invalid JSON string\");\n return result;\n }\n } else if (typeof data === \"object\" && data !== null) {\n obj = data as Record<string, unknown>;\n } else {\n fail(result, \"Expected object or JSON string\");\n return result;\n }\n\n // Required fields\n for (const field of [\"rcan\", \"cmd\", \"target\"]) {\n if (!(field in obj) || !obj[field]) {\n fail(result, `Missing required field: '${field}'`);\n }\n }\n\n if (!result.ok) return result;\n\n try {\n const msg = RCANMessage.fromJSON(obj);\n note(result, `✅ RCAN message valid (v${msg.rcan})`);\n note(result, ` cmd: ${msg.cmd}`);\n note(result, ` target: ${msg.target}`);\n if (msg.confidence !== undefined) {\n note(result, ` confidence: ${msg.confidence}`);\n } else {\n warn(result, \"No confidence score — add for RCAN §16 AI accountability\");\n }\n if (msg.isSigned) {\n note(result, ` signature: alg=${msg.signature?.alg}, kid=${msg.signature?.kid}`);\n } else {\n warn(result, \"Message is unsigned (recommended for production)\");\n }\n } catch (e) {\n fail(result, `Message validation failed: ${e instanceof Error ? e.message : e}`);\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Config validation (L1 / L2 / L3)\n// ---------------------------------------------------------------------------\n\nexport function validateConfig(config: RCANConfigType): ValidationResult {\n const result = makeResult();\n const meta = config.metadata ?? {};\n const agent = config.agent ?? {};\n const rcanProto = config.rcan_protocol ?? {};\n\n // Required top-level keys\n for (const key of [\"rcan_version\", \"metadata\", \"agent\"] as const) {\n if (!(key in config) || config[key] === undefined || config[key] === null) {\n fail(result, `Missing required key: '${key}'`);\n }\n }\n\n // rcan_version format\n const rv = config.rcan_version;\n if (rv) {\n if (!/^\\d+\\.\\d+$/.test(rv)) {\n fail(result, `rcan_version '${rv}' must match pattern N.N (e.g. '1.2')`);\n }\n }\n\n // L1 — required fields\n if (!meta.manufacturer) fail(result, \"L1: metadata.manufacturer is required (§2)\");\n if (!meta.model) fail(result, \"L1: metadata.model is required (§2)\");\n if (!meta.device_id && !meta.robot_name) {\n fail(result, \"L1: metadata.device_id (or robot_name) is required (§2)\");\n }\n\n // L2 — auth + confidence\n if (!rcanProto.jwt_auth?.enabled) {\n warn(result, \"L2: jwt_auth not enabled (required for L2 conformance, §8)\");\n }\n if (!agent.confidence_gates || agent.confidence_gates.length === 0) {\n warn(result, \"L2: confidence_gates not configured (§16)\");\n }\n\n // L3 — hitl + commitment chain\n if (!agent.hitl_gates || agent.hitl_gates.length === 0) {\n warn(result, \"L3: hitl_gates not configured (§16)\");\n }\n if (!agent.commitment_chain?.enabled) {\n warn(result, \"L3: commitment_chain not enabled (§16)\");\n }\n\n // Registration\n if (meta.rrn) {\n note(result, `✅ RRN registered: ${meta.rrn}`);\n } else {\n warn(result, \"Robot not registered — visit rcan.dev/registry/register\");\n }\n\n if (result.ok && result.issues.length === 0) {\n const l1ok = !result.warnings.some((w) => w.startsWith(\"L1\"));\n const l2ok = l1ok && !result.warnings.some((w) => w.startsWith(\"L2\"));\n const l3ok = l2ok && !result.warnings.some((w) => w.startsWith(\"L3\"));\n const level = l3ok ? \"L3\" : l2ok ? \"L2\" : l1ok ? \"L1\" : \"FAIL\";\n note(result, `✅ Config valid — conformance level: ${level}`);\n }\n\n return result;\n}\n","/**\n * RCAN error class hierarchy.\n * All errors extend RCANError which extends the built-in Error.\n */\n\nexport class RCANError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RCANError\";\n // Restore prototype chain for instanceof checks in transpiled code\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RCANAddressError extends RCANError {\n constructor(message: string) {\n super(message);\n this.name = \"RCANAddressError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RCANValidationError extends RCANError {\n constructor(message: string) {\n super(message);\n this.name = \"RCANValidationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RCANGateError extends RCANError {\n constructor(\n message: string,\n public gateType: string,\n public value?: number,\n public threshold?: number\n ) {\n super(message);\n this.name = \"RCANGateError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RCANSignatureError extends RCANError {\n constructor(message: string) {\n super(message);\n this.name = \"RCANSignatureError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RCANRegistryError extends RCANError {\n constructor(message: string) {\n super(message);\n this.name = \"RCANRegistryError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * rcan-ts — RegistryClient\n * TypeScript parity with rcan-py RegistryClient.\n *\n * @see https://rcan.dev/spec#section-registry\n */\n\nimport { RCANRegistryError } from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://rcan-spec.pages.dev\";\n\n// ── Interfaces ────────────────────────────────────────────────────────────────\n\nexport interface RobotRegistration {\n manufacturer: string;\n model: string;\n version: string;\n device_id: string;\n description?: string;\n contact_email?: string;\n verification_tier?: string;\n source?: string;\n}\n\nexport interface Robot extends RobotRegistration {\n rrn: string;\n registered_at: string;\n updated_at: string;\n verification_tier: string;\n status: string;\n}\n\nexport interface RegistrationResult {\n rrn: string;\n api_key: string;\n}\n\nexport interface ListResult {\n robots: Robot[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ── RegistryClient ────────────────────────────────────────────────────────────\n\nexport class RegistryClient {\n private baseUrl: string;\n private apiKey?: string;\n private timeout: number;\n\n constructor(opts?: { baseUrl?: string; apiKey?: string; timeout?: number }) {\n this.baseUrl = (opts?.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n this.apiKey = opts?.apiKey;\n this.timeout = opts?.timeout ?? 10000;\n }\n\n // ── Private helpers ─────────────────────────────────────────────────────────\n\n private async _fetch(\n path: string,\n init: RequestInit = {}\n ): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n ...init,\n signal: controller.signal,\n headers: {\n \"Content-Type\": \"application/json\",\n ...(init.headers ?? {}),\n },\n });\n return response;\n } finally {\n clearTimeout(timer);\n }\n }\n\n private _authHeaders(): Record<string, string> {\n if (!this.apiKey) {\n throw new RCANRegistryError(\n \"API key required for write operations. Pass apiKey to RegistryClient.\"\n );\n }\n return { Authorization: `Bearer ${this.apiKey}` };\n }\n\n private async _checkResponse<T>(resp: Response): Promise<T> {\n if (!resp.ok) {\n let msg = `Registry API error: ${resp.status}`;\n try {\n const body = (await resp.json()) as { error?: string };\n if (body?.error) msg = body.error;\n } catch {\n /* ignore */\n }\n throw new RCANRegistryError(msg);\n }\n return (await resp.json()) as T;\n }\n\n // ── Public API ───────────────────────────────────────────────────────────────\n\n /** Register a new robot. Returns RRN + API key. */\n async register(robot: RobotRegistration): Promise<RegistrationResult> {\n const resp = await this._fetch(\"/api/v1/robots\", {\n method: \"POST\",\n body: JSON.stringify(robot),\n });\n return this._checkResponse<RegistrationResult>(resp);\n }\n\n /** Look up a robot by RRN. */\n async get(rrn: string): Promise<Robot> {\n const resp = await this._fetch(`/api/v1/robots/${encodeURIComponent(rrn)}`);\n return this._checkResponse<Robot>(resp);\n }\n\n /** List robots with optional pagination and tier filter. */\n async list(opts?: {\n limit?: number;\n offset?: number;\n tier?: string;\n }): Promise<ListResult> {\n const params = new URLSearchParams();\n if (opts?.limit !== undefined) params.set(\"limit\", String(opts.limit));\n if (opts?.offset !== undefined) params.set(\"offset\", String(opts.offset));\n if (opts?.tier) params.set(\"tier\", opts.tier);\n const qs = params.toString() ? `?${params}` : \"\";\n const resp = await this._fetch(`/api/v1/robots${qs}`);\n return this._checkResponse<ListResult>(resp);\n }\n\n /** Update robot fields. Requires API key. */\n async patch(rrn: string, updates: Partial<Robot>): Promise<Robot> {\n const resp = await this._fetch(\n `/api/v1/robots/${encodeURIComponent(rrn)}`,\n {\n method: \"PATCH\",\n headers: this._authHeaders(),\n body: JSON.stringify(updates),\n }\n );\n return this._checkResponse<Robot>(resp);\n }\n\n /** Delete (soft-delete) a robot. Requires API key. */\n async delete(rrn: string): Promise<void> {\n const resp = await this._fetch(\n `/api/v1/robots/${encodeURIComponent(rrn)}`,\n {\n method: \"DELETE\",\n headers: this._authHeaders(),\n }\n );\n if (!resp.ok) {\n await this._checkResponse<void>(resp);\n }\n }\n\n /** Search robots by query, manufacturer, model, or tier. */\n async search(opts: {\n q?: string;\n manufacturer?: string;\n model?: string;\n tier?: string;\n }): Promise<Robot[]> {\n const params = new URLSearchParams();\n if (opts.q) params.set(\"q\", opts.q);\n if (opts.manufacturer) params.set(\"manufacturer\", opts.manufacturer);\n if (opts.model) params.set(\"model\", opts.model);\n if (opts.tier) params.set(\"tier\", opts.tier);\n const qs = params.toString() ? `?${params}` : \"\";\n const resp = await this._fetch(`/api/v1/robots/search${qs}`);\n if (!resp.ok) {\n // Fall back to list endpoint with filters\n const listResp = await this._fetch(`/api/v1/robots${qs}`);\n const data = await this._checkResponse<ListResult | { results?: Robot[] }>(listResp);\n if (\"robots\" in data) return data.robots;\n if (\"results\" in data && data.results) return data.results;\n return [];\n }\n const data = (await resp.json()) as Robot[] | { results?: Robot[] } | ListResult;\n if (Array.isArray(data)) return data;\n if (\"results\" in data && data.results) return data.results;\n if (\"robots\" in data) return (data as ListResult).robots;\n return [];\n }\n}\n","/**\n * rcan-ts — Official TypeScript SDK for RCAN v1.2\n * Robot Communication and Accountability Network\n *\n * @see https://rcan.dev\n * @see https://github.com/continuonai/rcan-ts\n */\n\nexport { RobotURI, RobotURIError } from \"./address.js\";\nexport type { RobotURIOptions } from \"./address.js\";\n\nexport { RCANMessage, RCANMessageError } from \"./message.js\";\nexport type { RCANMessageData, SignatureBlock } from \"./message.js\";\n\nexport { ConfidenceGate, HiTLGate, GateError } from \"./gates.js\";\nexport type { ApprovalStatus, PendingApproval } from \"./gates.js\";\n\nexport { CommitmentRecord, AuditChain, AuditError } from \"./audit.js\";\nexport type {\n CommitmentRecordData,\n CommitmentRecordJSON,\n ChainVerifyResult,\n} from \"./audit.js\";\n\nexport { validateURI, validateMessage, validateConfig } from \"./validate.js\";\nexport type { ValidationResult, RCANConfig } from \"./validate.js\";\nexport type { RCANMetadata, RCANAgentConfig, RCANMessageEnvelope } from \"./types.js\";\n\nexport {\n RCANError,\n RCANAddressError,\n RCANValidationError,\n RCANGateError,\n RCANSignatureError,\n RCANRegistryError,\n} from \"./errors.js\";\n\nexport { RegistryClient } from \"./registry.js\";\nexport type {\n RobotRegistration,\n Robot,\n RegistrationResult,\n ListResult,\n} from \"./registry.js\";\n\nexport const VERSION = \"0.1.0\";\nexport const RCAN_VERSION = \"1.2\";\n"],"mappings":"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","names":["data"]}
|
|
1
|
+
{"version":3,"sources":["../src/address.ts","../src/version.ts","../src/message.ts","../src/crypto.ts","../src/gates.ts","../src/audit.ts","../src/validate.ts","../src/errors.ts","../src/registry.ts","../src/node.ts","../src/schema.ts","../src/qos.ts","../src/safety.ts","../src/replay.ts","../src/clock.ts","../src/configUpdate.ts","../src/keys.ts","../src/consent.ts","../src/revocation.ts","../src/trainingConsent.ts","../src/offline.ts","../src/faultReport.ts","../src/index.ts"],"sourcesContent":["/**\n * RCAN Robot URI — addressing scheme for RCAN v1.2.\n *\n * Format: rcan://<registry>/<manufacturer>/<model>/<version>/<device-id>\n * Example: rcan://registry.rcan.dev/acme/robotarm/v2/unit-001\n */\n\nexport class RobotURIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RobotURIError\";\n }\n}\n\nexport interface RobotURIOptions {\n manufacturer: string;\n model: string;\n version: string;\n deviceId: string;\n registry?: string;\n}\n\nexport class RobotURI {\n readonly registry: string;\n readonly manufacturer: string;\n readonly model: string;\n readonly version: string;\n readonly deviceId: string;\n\n private constructor(opts: Required<RobotURIOptions>) {\n this.registry = opts.registry;\n this.manufacturer = opts.manufacturer;\n this.model = opts.model;\n this.version = opts.version;\n this.deviceId = opts.deviceId;\n }\n\n /** Parse a RCAN URI string. Throws RobotURIError on invalid input. */\n static parse(uri: string): RobotURI {\n if (!uri.startsWith(\"rcan://\")) {\n throw new RobotURIError(`URI must start with 'rcan://' — got: ${uri}`);\n }\n const withoutScheme = uri.slice(\"rcan://\".length);\n const parts = withoutScheme.split(\"/\");\n if (parts.length !== 5) {\n throw new RobotURIError(\n `URI must have exactly 5 path segments (registry/manufacturer/model/version/device-id) — got ${parts.length} in: ${uri}`\n );\n }\n const [registry, manufacturer, model, version, deviceId] = parts;\n for (const [name, value] of [\n [\"registry\", registry],\n [\"manufacturer\", manufacturer],\n [\"model\", model],\n [\"version\", version],\n [\"device-id\", deviceId],\n ] as [string, string][]) {\n if (!value || value.trim() === \"\") {\n throw new RobotURIError(`URI segment '${name}' must not be empty`);\n }\n }\n return new RobotURI({ registry, manufacturer, model, version, deviceId });\n }\n\n /** Build a RCAN URI from components. */\n static build(opts: RobotURIOptions): RobotURI {\n const registry = opts.registry ?? \"registry.rcan.dev\";\n const { manufacturer, model, version, deviceId } = opts;\n for (const [name, value] of [\n [\"manufacturer\", manufacturer],\n [\"model\", model],\n [\"version\", version],\n [\"deviceId\", deviceId],\n ] as [string, string][]) {\n if (!value || value.trim() === \"\") {\n throw new RobotURIError(`'${name}' must not be empty`);\n }\n }\n return new RobotURI({ registry, manufacturer, model, version, deviceId });\n }\n\n /** Full URI string: rcan://registry/manufacturer/model/version/device-id */\n toString(): string {\n return `rcan://${this.registry}/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`;\n }\n\n /** Short namespace: manufacturer/model */\n get namespace(): string {\n return `${this.manufacturer}/${this.model}`;\n }\n\n /** HTTPS registry URL for this robot */\n get registryUrl(): string {\n return `https://${this.registry}/registry/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`;\n }\n\n /** Check if two URIs refer to the same robot */\n equals(other: RobotURI): boolean {\n return this.toString() === other.toString();\n }\n\n toJSON(): object {\n return {\n uri: this.toString(),\n registry: this.registry,\n manufacturer: this.manufacturer,\n model: this.model,\n version: this.version,\n deviceId: this.deviceId,\n };\n }\n}\n","/**\n * RCAN Protocol Version — single source of truth.\n *\n * All modules that need SPEC_VERSION import from here.\n * §3.5 — Protocol Version Compatibility\n */\n\n/** The RCAN spec version this SDK implements. */\nexport const SPEC_VERSION = \"1.5\";\n\n/**\n * Validate version compatibility.\n *\n * A receiver MUST accept messages from senders with the same MAJOR version\n * and lower-or-equal MINOR version. MAJOR mismatch → incompatible.\n *\n * @param incomingVersion - The rcanVersion from the incoming message\n * @param localVersion - The local SPEC_VERSION (defaults to SPEC_VERSION)\n * @returns true if compatible, false if MAJOR mismatch\n */\nexport function validateVersionCompat(\n incomingVersion: string,\n localVersion: string = SPEC_VERSION\n): boolean {\n const parseParts = (v: string): [number, number] => {\n const parts = v.split(\".\");\n const major = parseInt(parts[0] ?? \"0\", 10);\n const minor = parseInt(parts[1] ?? \"0\", 10);\n return [isNaN(major) ? 0 : major, isNaN(minor) ? 0 : minor];\n };\n\n const [inMajor] = parseParts(incomingVersion);\n const [localMajor] = parseParts(localVersion);\n\n // MAJOR must match\n return inMajor === localMajor;\n}\n","/**\n * RCAN Message — command envelope for RCAN v1.5.\n *\n * A RCANMessage wraps a robot command with:\n * - RCAN protocol version\n * - Target Robot URI\n * - Command name and parameters\n * - Optional AI confidence score (§16)\n * - Optional model identity (§16)\n * - Optional Ed25519 signature\n * - v1.5: rcanVersion, senderType, cloudProvider, keyId, delegation chain, QoS, etc.\n */\n\nimport { RobotURI } from \"./address.js\";\nimport { SPEC_VERSION } from \"./version.js\";\n\n// ── v1.5 Canonical MessageType table ─────────────────────────────────────────\n// These integers MUST match rcan-py.\n\nexport enum MessageType {\n COMMAND = 1,\n RESPONSE = 2,\n STATUS = 3,\n HEARTBEAT = 4,\n CONFIG = 5,\n SAFETY = 6,\n SENSOR_DATA = 7,\n AUDIT = 8,\n DISCOVER = 9,\n TRAINING_DATA = 10,\n TRANSPARENCY = 11,\n FEDERATION_SYNC = 12,\n ALERT = 13,\n TELEOP = 14,\n CHAT = 15,\n ERROR = 16,\n COMMAND_ACK = 17,\n COMMAND_COMMIT = 18,\n ROBOT_REVOCATION = 19,\n CONSENT_REQUEST = 20,\n CONSENT_GRANT = 21,\n CONSENT_DENY = 22,\n FLEET_COMMAND = 23,\n SUBSCRIBE = 24,\n UNSUBSCRIBE = 25,\n FAULT_REPORT = 26,\n COMMAND_NACK = 27,\n}\n\n// ── v1.5 SenderType ───────────────────────────────────────────────────────────\n/** §8.5 — Sender Type and Service Identity */\nexport type SenderType = \"robot\" | \"human\" | \"cloud_function\" | \"system\";\n\n// ── v1.5 DelegationHop ────────────────────────────────────────────────────────\n/** §12 — Command Delegation and Chain of Custody */\nexport interface DelegationHop {\n issuerRuri: string;\n humanSubject: string;\n timestamp: string;\n scope: string;\n signature: string;\n}\n\nexport interface SignatureBlock {\n alg: string;\n kid: string;\n sig: string;\n}\n\nexport interface RCANMessageData {\n rcan?: string;\n /** v1.5: explicit protocol version field (defaults to SPEC_VERSION) */\n rcanVersion?: string;\n cmd: string;\n target: string | RobotURI;\n params?: Record<string, unknown>;\n confidence?: number;\n modelIdentity?: string;\n model_identity?: string; // snake_case alias\n signature?: SignatureBlock;\n timestamp?: string;\n /** v1.5: GAP-08 sender identity */\n senderType?: SenderType;\n cloudProvider?: string;\n /** v1.5: GAP-09 key id */\n keyId?: string;\n /** v1.5: GAP-01 delegation chain */\n delegationChain?: DelegationHop[];\n /** v1.5: GAP-13 fleet group */\n groupId?: string;\n /** v1.5: GAP-11 QoS level */\n qos?: number;\n /** v1.5: GAP-19 physical presence */\n presenceVerified?: boolean;\n proximityMeters?: number;\n /** v1.5: GAP-15 observer */\n readOnly?: boolean;\n [key: string]: unknown;\n}\n\nexport class RCANMessageError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RCANMessageError\";\n }\n}\n\nexport class RCANMessage {\n readonly rcan: string;\n /** v1.5: rcanVersion field — defaults to SPEC_VERSION */\n readonly rcanVersion: string;\n readonly cmd: string;\n readonly target: string;\n readonly params: Record<string, unknown>;\n readonly confidence: number | undefined;\n readonly modelIdentity: string | undefined;\n readonly signature: SignatureBlock | undefined;\n readonly timestamp: string;\n /** v1.5 fields */\n readonly senderType: SenderType | undefined;\n readonly cloudProvider: string | undefined;\n readonly keyId: string | undefined;\n readonly delegationChain: DelegationHop[] | undefined;\n readonly groupId: string | undefined;\n readonly qos: number | undefined;\n readonly presenceVerified: boolean | undefined;\n readonly proximityMeters: number | undefined;\n readonly readOnly: boolean | undefined;\n\n constructor(data: RCANMessageData) {\n if (!data.cmd || data.cmd.trim() === \"\") {\n throw new RCANMessageError(\"'cmd' is required\");\n }\n if (!data.target) {\n throw new RCANMessageError(\"'target' is required\");\n }\n\n this.rcan = data.rcan ?? SPEC_VERSION;\n this.rcanVersion = data.rcanVersion ?? SPEC_VERSION;\n this.cmd = data.cmd;\n this.target =\n data.target instanceof RobotURI ? data.target.toString() : String(data.target);\n this.params = data.params ?? {};\n this.confidence = data.confidence;\n this.modelIdentity = data.modelIdentity ?? data.model_identity;\n this.signature = data.signature;\n this.timestamp = data.timestamp ?? new Date().toISOString();\n this.senderType = data.senderType;\n this.cloudProvider = data.cloudProvider;\n this.keyId = data.keyId;\n this.delegationChain = data.delegationChain;\n this.groupId = data.groupId;\n this.qos = data.qos;\n this.presenceVerified = data.presenceVerified;\n this.proximityMeters = data.proximityMeters;\n this.readOnly = data.readOnly;\n\n if (this.confidence !== undefined) {\n if (this.confidence < 0 || this.confidence > 1) {\n throw new RCANMessageError(\n `confidence must be in [0.0, 1.0] — got ${this.confidence}`\n );\n }\n }\n }\n\n /** Whether this message has a signature block */\n get isSigned(): boolean {\n return this.signature !== undefined && this.signature.sig !== \"\";\n }\n\n /** Whether this message was generated by an AI model (has confidence score) */\n get isAiDriven(): boolean {\n return this.confidence !== undefined;\n }\n\n /** Serialize to a plain object */\n toJSON(): Record<string, unknown> {\n const obj: Record<string, unknown> = {\n rcan: this.rcan,\n rcanVersion: this.rcanVersion,\n cmd: this.cmd,\n target: this.target,\n timestamp: this.timestamp,\n };\n if (Object.keys(this.params).length > 0) obj.params = this.params;\n if (this.confidence !== undefined) obj.confidence = this.confidence;\n if (this.modelIdentity) obj.model_identity = this.modelIdentity;\n if (this.signature) obj.signature = this.signature;\n if (this.senderType !== undefined) obj.senderType = this.senderType;\n if (this.cloudProvider !== undefined) obj.cloudProvider = this.cloudProvider;\n if (this.keyId !== undefined) obj.keyId = this.keyId;\n if (this.delegationChain !== undefined) obj.delegationChain = this.delegationChain;\n if (this.groupId !== undefined) obj.groupId = this.groupId;\n if (this.qos !== undefined) obj.qos = this.qos;\n if (this.presenceVerified !== undefined) obj.presenceVerified = this.presenceVerified;\n if (this.proximityMeters !== undefined) obj.proximityMeters = this.proximityMeters;\n if (this.readOnly !== undefined) obj.readOnly = this.readOnly;\n return obj;\n }\n\n /** Serialize to JSON string */\n toJSONString(indent?: number): string {\n return JSON.stringify(this.toJSON(), null, indent);\n }\n\n /** Parse from a plain object or JSON string */\n static fromJSON(data: string | Record<string, unknown>): RCANMessage {\n let obj: Record<string, unknown>;\n if (typeof data === \"string\") {\n try {\n obj = JSON.parse(data) as Record<string, unknown>;\n } catch {\n throw new RCANMessageError(\"Invalid JSON string\");\n }\n } else {\n obj = data;\n }\n\n if (!obj.cmd) throw new RCANMessageError(\"Missing required field: 'cmd'\");\n if (!obj.target) throw new RCANMessageError(\"Missing required field: 'target'\");\n if (!obj.rcan) throw new RCANMessageError(\"Missing required field: 'rcan'\");\n\n return new RCANMessage({\n rcan: obj.rcan as string,\n rcanVersion: (obj.rcanVersion as string | undefined),\n cmd: obj.cmd as string,\n target: obj.target as string,\n params: (obj.params as Record<string, unknown>) ?? {},\n confidence: obj.confidence as number | undefined,\n modelIdentity:\n (obj.model_identity as string | undefined) ??\n (obj.modelIdentity as string | undefined),\n signature: obj.signature as SignatureBlock | undefined,\n timestamp: obj.timestamp as string | undefined,\n senderType: obj.senderType as SenderType | undefined,\n cloudProvider: obj.cloudProvider as string | undefined,\n keyId: obj.keyId as string | undefined,\n delegationChain: obj.delegationChain as DelegationHop[] | undefined,\n groupId: obj.groupId as string | undefined,\n qos: obj.qos as number | undefined,\n presenceVerified: obj.presenceVerified as boolean | undefined,\n proximityMeters: obj.proximityMeters as number | undefined,\n readOnly: obj.readOnly as boolean | undefined,\n });\n }\n}\n\n// ── v1.5 Cloud Relay helper ───────────────────────────────────────────────────\n\n/**\n * §8.5 — Create a cloud-relay-stamped copy of a message.\n *\n * Sets senderType to \"cloud_function\" and records the cloud provider.\n */\nexport function makeCloudRelayMessage(\n base: RCANMessage,\n provider: string\n): RCANMessage {\n const data = base.toJSON() as RCANMessageData;\n data.senderType = \"cloud_function\";\n data.cloudProvider = provider;\n return new RCANMessage(data);\n}\n\n// ── v1.5 Delegation Chain helpers ────────────────────────────────────────────\n\n/**\n * §12 — Add a delegation hop to a message.\n */\nexport function addDelegationHop(\n msg: RCANMessage,\n hop: DelegationHop\n): RCANMessage {\n const chain = msg.delegationChain ? [...msg.delegationChain, hop] : [hop];\n const data = msg.toJSON() as RCANMessageData;\n data.delegationChain = chain;\n return new RCANMessage(data);\n}\n\n/**\n * §12 — Validate a delegation chain (structure only; signature verification\n * requires crypto module).\n *\n * Rules:\n * - Max depth 4 hops\n * - Each hop must have issuerRuri, humanSubject, timestamp, scope, signature\n */\nexport function validateDelegationChain(\n chain: DelegationHop[]\n): { valid: boolean; reason: string } {\n if (chain.length > 4) {\n return { valid: false, reason: \"DELEGATION_CHAIN_EXCEEDED: max depth is 4 hops\" };\n }\n for (let i = 0; i < chain.length; i++) {\n const hop = chain[i];\n if (!hop) return { valid: false, reason: `hop ${i} is undefined` };\n if (!hop.issuerRuri) return { valid: false, reason: `hop ${i}: missing issuerRuri` };\n if (!hop.humanSubject) return { valid: false, reason: `hop ${i}: missing humanSubject` };\n if (!hop.timestamp) return { valid: false, reason: `hop ${i}: missing timestamp` };\n if (!hop.scope) return { valid: false, reason: `hop ${i}: missing scope` };\n if (!hop.signature) return { valid: false, reason: `hop ${i}: missing signature` };\n }\n return { valid: true, reason: \"ok\" };\n}\n","/**\n * Cross-platform crypto utilities — Node.js, browser, Cloudflare Workers, Deno.\n *\n * Uses Web Crypto API (SubtleCrypto) as the primary implementation, with a\n * Node.js `crypto` module fallback for environments that predate the global\n * `crypto` object (Node < 19).\n */\n\n/** Generate a UUID v4. Works in all modern environments. */\nexport function generateUUID(): string {\n if (typeof globalThis.crypto !== \"undefined\" && typeof globalThis.crypto.randomUUID === \"function\") {\n return globalThis.crypto.randomUUID();\n }\n // Node.js < 19 fallback\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { randomUUID } = require(\"crypto\") as { randomUUID: () => string };\n return randomUUID();\n } catch {\n // Last-resort UUID fallback (no external deps)\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n}\n\n/**\n * Compute HMAC-SHA256 and return hex string.\n * Synchronous via Node.js `crypto`; falls back to a pure-JS impl in browsers.\n */\nexport function hmacSha256Sync(secret: string, data: string): string {\n // Node.js environment\n if (typeof process !== \"undefined\" && process.versions?.node) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { createHmac } = require(\"crypto\") as {\n createHmac: (alg: string, key: string) => { update: (d: string) => { digest: (enc: string) => string } };\n };\n return createHmac(\"sha256\", secret).update(data).digest(\"hex\");\n } catch {\n // fall through to pure-JS\n }\n }\n // Pure-JS HMAC-SHA256 (browser / Workers / Deno without native crypto)\n return pureHmacSha256(secret, data);\n}\n\n// ── Pure-JS SHA-256 + HMAC (no deps) ─────────────────────────────────────────\n// Based on the public-domain SHA-256 implementation.\n\nfunction sha256(msg: Uint8Array): Uint8Array {\n const K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\n 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\n 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\n 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\n 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n ];\n let h0 = 0x6a09e667, h1 = 0xbb67ae85, h2 = 0x3c6ef372, h3 = 0xa54ff53a;\n let h4 = 0x510e527f, h5 = 0x9b05688c, h6 = 0x1f83d9ab, h7 = 0x5be0cd19;\n\n const msgLen = msg.length;\n const bitLen = msgLen * 8;\n const padded: number[] = [...msg];\n padded.push(0x80);\n while ((padded.length % 64) !== 56) padded.push(0);\n for (let i = 7; i >= 0; i--) padded.push((bitLen / Math.pow(2, i * 8)) & 0xff);\n\n for (let i = 0; i < padded.length; i += 64) {\n const w: number[] = [];\n for (let j = 0; j < 16; j++) {\n w[j] = (padded[i+j*4]<<24)|(padded[i+j*4+1]<<16)|(padded[i+j*4+2]<<8)|padded[i+j*4+3];\n }\n for (let j = 16; j < 64; j++) {\n const s0 = ror(w[j-15],7)^ror(w[j-15],18)^(w[j-15]>>>3);\n const s1 = ror(w[j-2],17)^ror(w[j-2],19)^(w[j-2]>>>10);\n w[j] = (w[j-16]+s0+w[j-7]+s1) >>> 0;\n }\n let [a,b,c,d,e,f,g,h] = [h0,h1,h2,h3,h4,h5,h6,h7];\n for (let j = 0; j < 64; j++) {\n const S1 = ror(e,6)^ror(e,11)^ror(e,25);\n const ch = (e&f)^(~e&g);\n const temp1 = (h+S1+ch+K[j]+w[j])>>>0;\n const S0 = ror(a,2)^ror(a,13)^ror(a,22);\n const maj = (a&b)^(a&c)^(b&c);\n const temp2 = (S0+maj)>>>0;\n [h,g,f,e,d,c,b,a] = [g,f,e,(d+temp1)>>>0,c,b,a,(temp1+temp2)>>>0];\n }\n h0=(h0+a)>>>0; h1=(h1+b)>>>0; h2=(h2+c)>>>0; h3=(h3+d)>>>0;\n h4=(h4+e)>>>0; h5=(h5+f)>>>0; h6=(h6+g)>>>0; h7=(h7+h)>>>0;\n }\n const out = new Uint8Array(32);\n const view = new DataView(out.buffer);\n [h0,h1,h2,h3,h4,h5,h6,h7].forEach((v,i) => view.setUint32(i*4, v));\n return out;\n}\n\nfunction ror(x: number, n: number): number { return (x>>>n)|(x<<(32-n)); }\n\nfunction toBytes(s: string): Uint8Array {\n if (typeof TextEncoder !== \"undefined\") return new TextEncoder().encode(s);\n const out = new Uint8Array(s.length);\n for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i) & 0xff;\n return out;\n}\n\nfunction toHex(bytes: Uint8Array): string {\n return Array.from(bytes).map(b => b.toString(16).padStart(2,\"0\")).join(\"\");\n}\n\nfunction pureHmacSha256(key: string, data: string): string {\n const BLOCK = 64;\n let keyBytes = toBytes(key);\n if (keyBytes.length > BLOCK) keyBytes = sha256(keyBytes);\n const ipad = new Uint8Array(BLOCK), opad = new Uint8Array(BLOCK);\n for (let i = 0; i < BLOCK; i++) {\n ipad[i] = (keyBytes[i] ?? 0) ^ 0x36;\n opad[i] = (keyBytes[i] ?? 0) ^ 0x5c;\n }\n const dataBytes = toBytes(data);\n const inner = new Uint8Array(BLOCK + dataBytes.length);\n inner.set(ipad); inner.set(dataBytes, BLOCK);\n const innerHash = sha256(inner);\n const outer = new Uint8Array(BLOCK + 32);\n outer.set(opad); outer.set(innerHash, BLOCK);\n return toHex(sha256(outer));\n}\n","/**\n * RCAN Safety Gates — confidence and human-in-the-loop gating (§16).\n */\n\nimport { generateUUID } from \"./crypto.js\";\n\nexport class GateError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"GateError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// ConfidenceGate\n// ---------------------------------------------------------------------------\n\nexport class ConfidenceGate {\n readonly threshold: number;\n\n constructor(threshold = 0.8) {\n if (threshold < 0 || threshold > 1) {\n throw new GateError(`threshold must be in [0.0, 1.0] — got ${threshold}`);\n }\n this.threshold = threshold;\n }\n\n /** Returns true if the confidence score meets the threshold. */\n allows(confidence: number): boolean {\n return confidence >= this.threshold;\n }\n\n /** Returns the margin (positive = allowed, negative = blocked). */\n margin(confidence: number): number {\n return confidence - this.threshold;\n }\n\n /** Throw if confidence is below threshold. */\n assert(confidence: number, action?: string): void {\n if (!this.allows(confidence)) {\n const label = action ? ` for action '${action}'` : \"\";\n throw new GateError(\n `Confidence ${confidence}${label} is below threshold ${this.threshold}`\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// HiTLGate\n// ---------------------------------------------------------------------------\n\nexport type ApprovalStatus = \"approved\" | \"denied\" | \"pending\";\n\nexport interface PendingApproval {\n token: string;\n action: string;\n context: Record<string, unknown>;\n createdAt: string;\n status: ApprovalStatus;\n reason?: string;\n}\n\nexport class HiTLGate {\n private _pending: Map<string, PendingApproval> = new Map();\n\n /**\n * Request human approval for an action.\n * Returns an approval token to poll or pass to approve/deny.\n */\n request(action: string, context: Record<string, unknown> = {}): string {\n const token = generateUUID();\n this._pending.set(token, {\n token,\n action,\n context,\n createdAt: new Date().toISOString(),\n status: \"pending\",\n });\n return token;\n }\n\n /** Approve a pending request. */\n approve(token: string): void {\n const approval = this._pending.get(token);\n if (!approval) throw new GateError(`Unknown token: ${token}`);\n approval.status = \"approved\";\n }\n\n /** Deny a pending request with an optional reason. */\n deny(token: string, reason?: string): void {\n const approval = this._pending.get(token);\n if (!approval) throw new GateError(`Unknown token: ${token}`);\n approval.status = \"denied\";\n if (reason) approval.reason = reason;\n }\n\n /** Check the status of a pending approval. */\n check(token: string): ApprovalStatus {\n const approval = this._pending.get(token);\n if (!approval) throw new GateError(`Unknown token: ${token}`);\n return approval.status;\n }\n\n /** Get all pending approvals. */\n get pendingApprovals(): PendingApproval[] {\n return Array.from(this._pending.values()).filter((a) => a.status === \"pending\");\n }\n\n /** Get the full approval record. */\n getApproval(token: string): PendingApproval | undefined {\n return this._pending.get(token);\n }\n\n /** Clear resolved (approved/denied) approvals. */\n clearResolved(): void {\n for (const [token, approval] of this._pending.entries()) {\n if (approval.status !== \"pending\") {\n this._pending.delete(token);\n }\n }\n }\n}\n","/**\n * RCAN Audit Chain — tamper-evident commitment records (§16).\n *\n * Each CommitmentRecord is sealed with an HMAC-SHA256 over its content.\n * Records are chained via previousHash, creating a forensic audit trail.\n */\n\nimport { hmacSha256Sync, generateUUID } from \"./crypto.js\";\n\nexport interface CommitmentRecordData {\n action: string;\n robotUri?: string;\n confidence?: number;\n modelIdentity?: string;\n params?: Record<string, unknown>;\n safetyApproved?: boolean;\n}\n\nexport interface CommitmentRecordJSON {\n recordId: string;\n action: string;\n robotUri: string;\n confidence?: number;\n modelIdentity?: string;\n params: Record<string, unknown>;\n safetyApproved: boolean;\n timestamp: string;\n contentHash: string;\n previousHash: string | null;\n hmac: string;\n}\n\nexport class AuditError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AuditError\";\n }\n}\n\nfunction computeContentHash(\n recordId: string,\n action: string,\n robotUri: string,\n timestamp: string,\n params: Record<string, unknown>\n): string {\n const payload = JSON.stringify(\n { recordId, action, robotUri, timestamp, params },\n Object.keys({ recordId, action, robotUri, timestamp, params }).sort()\n );\n return hmacSha256Sync(\"rcan-content-hash\", payload);\n}\n\nfunction computeHmac(secret: string, data: CommitmentRecordJSON): string {\n const { hmac: _ignored, ...rest } = data;\n const payload = JSON.stringify(rest, Object.keys(rest).sort());\n return hmacSha256Sync(secret, payload);\n}\n\nexport class CommitmentRecord {\n readonly recordId: string;\n readonly action: string;\n readonly robotUri: string;\n readonly confidence: number | undefined;\n readonly modelIdentity: string | undefined;\n readonly params: Record<string, unknown>;\n readonly safetyApproved: boolean;\n readonly timestamp: string;\n readonly contentHash: string;\n readonly previousHash: string | null;\n readonly hmac: string;\n\n private constructor(data: CommitmentRecordJSON) {\n this.recordId = data.recordId;\n this.action = data.action;\n this.robotUri = data.robotUri;\n this.confidence = data.confidence;\n this.modelIdentity = data.modelIdentity;\n this.params = data.params;\n this.safetyApproved = data.safetyApproved;\n this.timestamp = data.timestamp;\n this.contentHash = data.contentHash;\n this.previousHash = data.previousHash;\n this.hmac = data.hmac;\n }\n\n static create(\n data: CommitmentRecordData,\n secret: string,\n previousHash: string | null = null\n ): CommitmentRecord {\n const recordId = generateUUID();\n const timestamp = new Date().toISOString();\n const params = data.params ?? {};\n const robotUri = data.robotUri ?? \"\";\n const contentHash = computeContentHash(recordId, data.action, robotUri, timestamp, params);\n\n const draft: CommitmentRecordJSON = {\n recordId,\n action: data.action,\n robotUri,\n confidence: data.confidence,\n modelIdentity: data.modelIdentity,\n params,\n safetyApproved: data.safetyApproved ?? true,\n timestamp,\n contentHash,\n previousHash,\n hmac: \"\",\n };\n draft.hmac = computeHmac(secret, draft);\n return new CommitmentRecord(draft);\n }\n\n verify(secret: string): boolean {\n const expected = computeHmac(secret, this.toJSON());\n return expected === this.hmac;\n }\n\n toJSON(): CommitmentRecordJSON {\n return {\n recordId: this.recordId,\n action: this.action,\n robotUri: this.robotUri,\n confidence: this.confidence,\n modelIdentity: this.modelIdentity,\n params: this.params,\n safetyApproved: this.safetyApproved,\n timestamp: this.timestamp,\n contentHash: this.contentHash,\n previousHash: this.previousHash,\n hmac: this.hmac,\n };\n }\n\n static fromJSON(obj: CommitmentRecordJSON): CommitmentRecord {\n return new CommitmentRecord(obj);\n }\n}\n\n// ---------------------------------------------------------------------------\n// AuditChain\n// ---------------------------------------------------------------------------\n\nexport interface ChainVerifyResult {\n valid: boolean;\n count: number;\n errors: string[];\n}\n\nexport class AuditChain {\n private _records: CommitmentRecord[] = [];\n private _secret: string;\n\n constructor(secret: string) {\n this._secret = secret;\n }\n\n get records(): readonly CommitmentRecord[] {\n return this._records;\n }\n\n append(data: CommitmentRecordData): CommitmentRecord {\n const prev = this._records[this._records.length - 1];\n const prevHash = prev?.contentHash ?? null;\n const record = CommitmentRecord.create(data, this._secret, prevHash);\n this._records.push(record);\n return record;\n }\n\n verifyAll(): ChainVerifyResult {\n const errors: string[] = [];\n let prevHash: string | null = null;\n\n for (const record of this._records) {\n if (!record.verify(this._secret)) {\n errors.push(`HMAC invalid for record ${record.recordId.slice(0, 8)}`);\n }\n if (prevHash !== null && record.previousHash !== prevHash) {\n errors.push(\n `Chain broken at ${record.recordId.slice(0, 8)}: expected prev=${prevHash.slice(0, 12)}`\n );\n }\n prevHash = record.contentHash;\n }\n\n return { valid: errors.length === 0, count: this._records.length, errors };\n }\n\n toJSONL(): string {\n return this._records.map((r) => JSON.stringify(r.toJSON())).join(\"\\n\") + \"\\n\";\n }\n\n static fromJSONL(text: string, secret: string): AuditChain {\n const chain = new AuditChain(secret);\n const lines = text.trim().split(\"\\n\").filter((l) => l.trim() !== \"\");\n for (const line of lines) {\n const obj = JSON.parse(line) as CommitmentRecordJSON;\n chain._records.push(CommitmentRecord.fromJSON(obj));\n }\n return chain;\n }\n}\n","/**\n * RCAN Validation — validate messages, configs, and URIs.\n *\n * Each function returns a ValidationResult with ok, issues, warnings, info.\n */\n\nimport { RobotURI, RobotURIError } from \"./address\";\nimport { RCANMessage, RCANMessageError } from \"./message\";\nimport type { RCANConfig as RCANConfigType } from \"./types\";\n\nexport type { RCANConfig } from \"./types\";\n\nexport interface ValidationResult {\n ok: boolean;\n issues: string[];\n warnings: string[];\n info: string[];\n}\n\nfunction makeResult(): ValidationResult {\n return { ok: true, issues: [], warnings: [], info: [] };\n}\n\nfunction fail(result: ValidationResult, msg: string): void {\n result.ok = false;\n result.issues.push(msg);\n}\n\nfunction warn(result: ValidationResult, msg: string): void {\n result.warnings.push(msg);\n}\n\nfunction note(result: ValidationResult, msg: string): void {\n result.info.push(msg);\n}\n\n// ---------------------------------------------------------------------------\n// URI validation\n// ---------------------------------------------------------------------------\n\nexport function validateURI(uri: string): ValidationResult {\n const result = makeResult();\n try {\n const parsed = RobotURI.parse(uri);\n note(result, `✅ Valid RCAN URI`);\n note(result, ` Registry: ${parsed.registry}`);\n note(result, ` Manufacturer: ${parsed.manufacturer}`);\n note(result, ` Model: ${parsed.model}`);\n note(result, ` Version: ${parsed.version}`);\n note(result, ` Device ID: ${parsed.deviceId}`);\n } catch (e) {\n fail(result, `Invalid RCAN URI: ${e instanceof Error ? e.message : e}`);\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Message validation\n// ---------------------------------------------------------------------------\n\nexport function validateMessage(data: unknown): ValidationResult {\n const result = makeResult();\n\n let obj: Record<string, unknown>;\n if (typeof data === \"string\") {\n try {\n obj = JSON.parse(data) as Record<string, unknown>;\n } catch {\n fail(result, \"Invalid JSON string\");\n return result;\n }\n } else if (typeof data === \"object\" && data !== null) {\n obj = data as Record<string, unknown>;\n } else {\n fail(result, \"Expected object or JSON string\");\n return result;\n }\n\n // Required fields\n for (const field of [\"rcan\", \"cmd\", \"target\"]) {\n if (!(field in obj) || !obj[field]) {\n fail(result, `Missing required field: '${field}'`);\n }\n }\n\n if (!result.ok) return result;\n\n try {\n const msg = RCANMessage.fromJSON(obj);\n note(result, `✅ RCAN message valid (v${msg.rcan})`);\n note(result, ` cmd: ${msg.cmd}`);\n note(result, ` target: ${msg.target}`);\n if (msg.confidence !== undefined) {\n note(result, ` confidence: ${msg.confidence}`);\n } else {\n warn(result, \"No confidence score — add for RCAN §16 AI accountability\");\n }\n if (msg.isSigned) {\n note(result, ` signature: alg=${msg.signature?.alg}, kid=${msg.signature?.kid}`);\n } else {\n warn(result, \"Message is unsigned (recommended for production)\");\n }\n } catch (e) {\n fail(result, `Message validation failed: ${e instanceof Error ? e.message : e}`);\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Config validation (L1 / L2 / L3)\n// ---------------------------------------------------------------------------\n\nexport function validateConfig(config: RCANConfigType): ValidationResult {\n const result = makeResult();\n const meta = config.metadata ?? {};\n const agent = config.agent ?? {};\n const rcanProto = config.rcan_protocol ?? {};\n\n // Required top-level keys\n for (const key of [\"rcan_version\", \"metadata\", \"agent\"] as const) {\n if (!(key in config) || config[key] === undefined || config[key] === null) {\n fail(result, `Missing required key: '${key}'`);\n }\n }\n\n // rcan_version format\n const rv = config.rcan_version;\n if (rv) {\n if (!/^\\d+\\.\\d+$/.test(rv)) {\n fail(result, `rcan_version '${rv}' must match pattern N.N (e.g. '1.2')`);\n }\n }\n\n // L1 — required fields\n if (!meta.manufacturer) fail(result, \"L1: metadata.manufacturer is required (§2)\");\n if (!meta.model) fail(result, \"L1: metadata.model is required (§2)\");\n if (!meta.device_id && !meta.robot_name) {\n fail(result, \"L1: metadata.device_id (or robot_name) is required (§2)\");\n }\n\n // L2 — auth + confidence\n if (!rcanProto.jwt_auth?.enabled) {\n warn(result, \"L2: jwt_auth not enabled (required for L2 conformance, §8)\");\n }\n if (!agent.confidence_gates || agent.confidence_gates.length === 0) {\n warn(result, \"L2: confidence_gates not configured (§16)\");\n }\n\n // L3 — hitl + commitment chain\n if (!agent.hitl_gates || agent.hitl_gates.length === 0) {\n warn(result, \"L3: hitl_gates not configured (§16)\");\n }\n if (!agent.commitment_chain?.enabled) {\n warn(result, \"L3: commitment_chain not enabled (§16)\");\n }\n\n // Registration\n if (meta.rrn) {\n note(result, `✅ RRN registered: ${meta.rrn}`);\n } else {\n warn(result, \"Robot not registered — visit rcan.dev/registry/register\");\n }\n\n if (result.ok && result.issues.length === 0) {\n const l1ok = !result.warnings.some((w) => w.startsWith(\"L1\"));\n const l2ok = l1ok && !result.warnings.some((w) => w.startsWith(\"L2\"));\n const l3ok = l2ok && !result.warnings.some((w) => w.startsWith(\"L3\"));\n const level = l3ok ? \"L3\" : l2ok ? \"L2\" : l1ok ? \"L1\" : \"FAIL\";\n note(result, `✅ Config valid — conformance level: ${level}`);\n }\n\n return result;\n}\n","/**\n * RCAN error class hierarchy.\n * All errors extend RCANError which extends the built-in Error.\n */\n\nexport class RCANError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RCANError\";\n // Restore prototype chain for instanceof checks in transpiled code\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RCANAddressError extends RCANError {\n constructor(message: string) {\n super(message);\n this.name = \"RCANAddressError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RCANValidationError extends RCANError {\n constructor(message: string) {\n super(message);\n this.name = \"RCANValidationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RCANGateError extends RCANError {\n constructor(\n message: string,\n public gateType: string,\n public value?: number,\n public threshold?: number\n ) {\n super(message);\n this.name = \"RCANGateError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RCANSignatureError extends RCANError {\n constructor(message: string) {\n super(message);\n this.name = \"RCANSignatureError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RCANRegistryError extends RCANError {\n constructor(message: string) {\n super(message);\n this.name = \"RCANRegistryError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n// ── Node / Federation errors ──────────────────────────────────────────────────\n\nexport class RCANNodeError extends RCANError {\n constructor(message: string, public readonly nodeUrl?: string) {\n super(message);\n this.name = \"RCANNodeError\";\n Object.setPrototypeOf(this, RCANNodeError.prototype);\n }\n}\n\nexport class RCANNodeNotFoundError extends RCANNodeError {\n constructor(public readonly rrn: string, nodeUrl?: string) {\n super(`RRN not found in federation: ${rrn}`, nodeUrl);\n this.name = \"RCANNodeNotFoundError\";\n Object.setPrototypeOf(this, RCANNodeNotFoundError.prototype);\n }\n}\n\nexport class RCANNodeSyncError extends RCANNodeError {\n constructor(\n message: string,\n nodeUrl?: string,\n public readonly cause?: Error\n ) {\n super(message, nodeUrl);\n this.name = \"RCANNodeSyncError\";\n Object.setPrototypeOf(this, RCANNodeSyncError.prototype);\n }\n}\n\nexport class RCANNodeTrustError extends RCANNodeError {\n public readonly reason: \"invalid_signature\" | \"expired_cert\" | \"unknown_issuer\" | \"missing_pubkey\";\n\n constructor(reason: RCANNodeTrustError[\"reason\"], nodeUrl?: string) {\n super(`Node trust verification failed: ${reason}`, nodeUrl);\n this.name = \"RCANNodeTrustError\";\n this.reason = reason;\n Object.setPrototypeOf(this, RCANNodeTrustError.prototype);\n }\n}\n\n// ── v1.5 errors ───────────────────────────────────────────────────────────────\n\n/** Thrown when an incoming message has an incompatible MAJOR version */\nexport class RCANVersionIncompatibleError extends RCANError {\n constructor(incomingVersion: string, localVersion: string) {\n super(`VERSION_INCOMPATIBLE: incoming=${incomingVersion}, local=${localVersion}`);\n this.name = \"RCANVersionIncompatibleError\";\n Object.setPrototypeOf(this, RCANVersionIncompatibleError.prototype);\n }\n}\n\n/** Thrown when a replay attack is detected */\nexport class RCANReplayAttackError extends RCANError {\n constructor(reason: string) {\n super(`REPLAY_DETECTED: ${reason}`);\n this.name = \"RCANReplayAttackError\";\n Object.setPrototypeOf(this, RCANReplayAttackError.prototype);\n }\n}\n\n/** Thrown when a delegation chain is invalid or too deep */\nexport class RCANDelegationChainError extends RCANError {\n constructor(reason: string) {\n super(`DELEGATION_CHAIN_ERROR: ${reason}`);\n this.name = \"RCANDelegationChainError\";\n Object.setPrototypeOf(this, RCANDelegationChainError.prototype);\n }\n}\n\n/** Thrown when a config update is unauthorized or has a hash mismatch */\nexport class RCANConfigAuthorizationError extends RCANError {\n constructor(reason: string) {\n super(`CONFIG_AUTH_ERROR: ${reason}`);\n this.name = \"RCANConfigAuthorizationError\";\n Object.setPrototypeOf(this, RCANConfigAuthorizationError.prototype);\n }\n}\n","/**\n * rcan-ts — RegistryClient\n * TypeScript parity with rcan-py RegistryClient.\n *\n * @see https://rcan.dev/spec#section-registry\n */\n\nimport { RCANRegistryError } from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://rcan-spec.pages.dev\";\n\n// ── Interfaces ────────────────────────────────────────────────────────────────\n\nexport interface RobotRegistration {\n manufacturer: string;\n model: string;\n version: string;\n device_id: string;\n description?: string;\n contact_email?: string;\n verification_tier?: string;\n source?: string;\n}\n\nexport interface Robot extends RobotRegistration {\n rrn: string;\n registered_at: string;\n updated_at: string;\n verification_tier: string;\n status: string;\n}\n\nexport interface RegistrationResult {\n rrn: string;\n api_key: string;\n}\n\nexport interface ListResult {\n robots: Robot[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ── RegistryClient ────────────────────────────────────────────────────────────\n\nexport class RegistryClient {\n private baseUrl: string;\n private apiKey?: string;\n private timeout: number;\n\n constructor(opts?: { baseUrl?: string; apiKey?: string; timeout?: number }) {\n this.baseUrl = (opts?.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n this.apiKey = opts?.apiKey;\n this.timeout = opts?.timeout ?? 10000;\n }\n\n // ── Private helpers ─────────────────────────────────────────────────────────\n\n private async _fetch(\n path: string,\n init: RequestInit = {}\n ): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n ...init,\n signal: controller.signal,\n headers: {\n \"Content-Type\": \"application/json\",\n ...(init.headers ?? {}),\n },\n });\n return response;\n } finally {\n clearTimeout(timer);\n }\n }\n\n private _authHeaders(): Record<string, string> {\n if (!this.apiKey) {\n throw new RCANRegistryError(\n \"API key required for write operations. Pass apiKey to RegistryClient.\"\n );\n }\n return { Authorization: `Bearer ${this.apiKey}` };\n }\n\n private async _checkResponse<T>(resp: Response): Promise<T> {\n if (!resp.ok) {\n let msg = `Registry API error: ${resp.status}`;\n try {\n const body = (await resp.json()) as { error?: string };\n if (body?.error) msg = body.error;\n } catch {\n /* ignore */\n }\n throw new RCANRegistryError(msg);\n }\n return (await resp.json()) as T;\n }\n\n // ── Public API ───────────────────────────────────────────────────────────────\n\n /** Register a new robot. Returns RRN + API key. */\n async register(robot: RobotRegistration): Promise<RegistrationResult> {\n const resp = await this._fetch(\"/api/v1/robots\", {\n method: \"POST\",\n body: JSON.stringify(robot),\n });\n return this._checkResponse<RegistrationResult>(resp);\n }\n\n /** Look up a robot by RRN. */\n async get(rrn: string): Promise<Robot> {\n const resp = await this._fetch(`/api/v1/robots/${encodeURIComponent(rrn)}`);\n return this._checkResponse<Robot>(resp);\n }\n\n /** List robots with optional pagination and tier filter. */\n async list(opts?: {\n limit?: number;\n offset?: number;\n tier?: string;\n }): Promise<ListResult> {\n const params = new URLSearchParams();\n if (opts?.limit !== undefined) params.set(\"limit\", String(opts.limit));\n if (opts?.offset !== undefined) params.set(\"offset\", String(opts.offset));\n if (opts?.tier) params.set(\"tier\", opts.tier);\n const qs = params.toString() ? `?${params}` : \"\";\n const resp = await this._fetch(`/api/v1/robots${qs}`);\n return this._checkResponse<ListResult>(resp);\n }\n\n /** Update robot fields. Requires API key. */\n async patch(rrn: string, updates: Partial<Robot>): Promise<Robot> {\n const resp = await this._fetch(\n `/api/v1/robots/${encodeURIComponent(rrn)}`,\n {\n method: \"PATCH\",\n headers: this._authHeaders(),\n body: JSON.stringify(updates),\n }\n );\n return this._checkResponse<Robot>(resp);\n }\n\n /** Delete (soft-delete) a robot. Requires API key. */\n async delete(rrn: string): Promise<void> {\n const resp = await this._fetch(\n `/api/v1/robots/${encodeURIComponent(rrn)}`,\n {\n method: \"DELETE\",\n headers: this._authHeaders(),\n }\n );\n if (!resp.ok) {\n await this._checkResponse<void>(resp);\n }\n }\n\n /** Search robots by query, manufacturer, model, or tier. */\n async search(opts: {\n q?: string;\n manufacturer?: string;\n model?: string;\n tier?: string;\n }): Promise<Robot[]> {\n const params = new URLSearchParams();\n if (opts.q) params.set(\"q\", opts.q);\n if (opts.manufacturer) params.set(\"manufacturer\", opts.manufacturer);\n if (opts.model) params.set(\"model\", opts.model);\n if (opts.tier) params.set(\"tier\", opts.tier);\n const qs = params.toString() ? `?${params}` : \"\";\n const resp = await this._fetch(`/api/v1/robots/search${qs}`);\n if (!resp.ok) {\n // Fall back to list endpoint with filters\n const listResp = await this._fetch(`/api/v1/robots${qs}`);\n const data = await this._checkResponse<ListResult | { results?: Robot[] }>(listResp);\n if (\"robots\" in data) return data.robots;\n if (\"results\" in data && data.results) return data.results;\n return [];\n }\n const data = (await resp.json()) as Robot[] | { results?: Robot[] } | ListResult;\n if (Array.isArray(data)) return data;\n if (\"results\" in data && data.results) return data.results;\n if (\"robots\" in data) return (data as ListResult).robots;\n return [];\n }\n}\n","/**\n * rcan-ts — NodeClient\n * Federation-aware node discovery and RRN resolution.\n *\n * Zero runtime dependencies — uses globalThis.fetch (Node 18+, browsers, CF Workers).\n *\n * @see https://rcan.dev/spec#section-federation\n */\n\nimport {\n RCANNodeNotFoundError,\n RCANNodeSyncError,\n RCANNodeTrustError,\n} from \"./errors.js\";\nimport type { RCANRegistryNode, RCANResolveResult } from \"./types.js\";\n\n// ── Constants ─────────────────────────────────────────────────────────────────\n\nconst ROOT_NODE_URL = \"https://rcan.dev\";\nconst NODE_MANIFEST_PATH = \"/.well-known/rcan-node.json\";\n\nconst VALID_NODE_TYPES = new Set<string>([\n \"root\",\n \"authoritative\",\n \"resolver\",\n \"cache\",\n]);\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\n/**\n * Parse an RRN string into its namespace components.\n *\n * @example\n * parseRRNNamespace(\"RRN-BD-00000001\") → { type: \"delegated\", prefix: \"BD\", serial: \"00000001\" }\n * parseRRNNamespace(\"RRN-00000042\") → { type: \"root\", serial: \"00000042\" }\n * parseRRNNamespace(\"INVALID\") → null\n */\nfunction parseRRNNamespace(\n rrn: string\n):\n | { type: \"root\"; serial: string }\n | { type: \"delegated\"; prefix: string; serial: string }\n | null {\n const delegated = rrn.match(/^RRN-([A-Z0-9]{2,8})-(\\d{8,16})$/);\n if (delegated) return { type: \"delegated\", prefix: delegated[1], serial: delegated[2] };\n const root = rrn.match(/^RRN-(\\d{8,16})$/);\n if (root) return { type: \"root\", serial: root[1] };\n return null;\n}\n\n// ── NodeClient ────────────────────────────────────────────────────────────────\n\nexport class NodeClient {\n private readonly rootUrl: string;\n private readonly timeoutMs: number;\n\n constructor(rootUrl = ROOT_NODE_URL, timeoutMs = 10_000) {\n this.rootUrl = rootUrl.replace(/\\/$/, \"\");\n this.timeoutMs = timeoutMs;\n }\n\n // ── Private helpers ─────────────────────────────────────────────────────────\n\n private async _fetch(url: string): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n return await globalThis.fetch(url, { signal: controller.signal });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new RCANNodeSyncError(`Request timed out: ${url}`, url, err);\n }\n throw new RCANNodeSyncError(\n `Network error fetching ${url}: ${(err as Error).message}`,\n url,\n err instanceof Error ? err : undefined\n );\n } finally {\n clearTimeout(timer);\n }\n }\n\n // ── Public API ───────────────────────────────────────────────────────────────\n\n /**\n * Fetch /.well-known/rcan-node.json from any node URL.\n * Throws RCANNodeTrustError if the manifest is malformed.\n * Throws RCANNodeSyncError on network failure.\n */\n async getNodeManifest(nodeUrl: string): Promise<RCANRegistryNode> {\n const url = `${nodeUrl.replace(/\\/$/, \"\")}${NODE_MANIFEST_PATH}`;\n const resp = await this._fetch(url);\n\n if (!resp.ok) {\n if (resp.status === 404) {\n throw new RCANNodeNotFoundError(url, nodeUrl);\n }\n throw new RCANNodeSyncError(\n `Failed to fetch node manifest from ${nodeUrl}: HTTP ${resp.status}`,\n nodeUrl\n );\n }\n\n let data: unknown;\n try {\n data = await resp.json();\n } catch (err) {\n throw new RCANNodeSyncError(\n `Invalid JSON in node manifest from ${nodeUrl}`,\n nodeUrl,\n err instanceof Error ? err : undefined\n );\n }\n\n if (!this.verifyNode(data)) {\n throw new RCANNodeTrustError(\"missing_pubkey\", nodeUrl);\n }\n return data;\n }\n\n /**\n * Get list of known registry nodes from root /api/v1/nodes.\n * Optionally filter by namespace prefix (e.g. \"BD\").\n */\n async listNodes(prefix?: string): Promise<RCANRegistryNode[]> {\n const qs = prefix ? `?prefix=${encodeURIComponent(prefix)}` : \"\";\n const url = `${this.rootUrl}/api/v1/nodes${qs}`;\n const resp = await this._fetch(url);\n\n if (!resp.ok) {\n throw new RCANNodeSyncError(\n `Failed to list nodes from ${url}: HTTP ${resp.status}`,\n url\n );\n }\n\n let data: unknown;\n try {\n data = await resp.json();\n } catch (err) {\n throw new RCANNodeSyncError(\n `Invalid JSON in nodes list from ${url}`,\n url,\n err instanceof Error ? err : undefined\n );\n }\n\n if (Array.isArray(data)) return data as RCANRegistryNode[];\n if (data && typeof data === \"object\" && \"nodes\" in data) {\n return (data as { nodes: RCANRegistryNode[] }).nodes;\n }\n return [];\n }\n\n /**\n * Find the authoritative node for an RRN.\n * - Delegated RRN (RRN-BD-00000001): GET /api/v1/nodes?prefix=BD, return first match.\n * - Root RRN (RRN-00000042): return root node manifest.\n * - Unknown format: throws RCANNodeNotFoundError.\n */\n async discover(rrn: string): Promise<RCANRegistryNode> {\n const parsed = parseRRNNamespace(rrn);\n\n if (!parsed) {\n throw new RCANNodeNotFoundError(rrn, this.rootUrl);\n }\n\n if (parsed.type === \"root\") {\n return this.getNodeManifest(this.rootUrl);\n }\n\n // delegated\n const nodes = await this.listNodes(parsed.prefix);\n if (nodes.length === 0) {\n throw new RCANNodeNotFoundError(rrn, this.rootUrl);\n }\n return nodes[0];\n }\n\n /**\n * Resolve an RRN across the federation.\n * First tries {rootUrl}/api/v1/resolve/{rrn}.\n * On 404, discovers the authoritative node and tries {node.api_base}/robots/{rrn}.\n */\n async resolve(rrn: string): Promise<RCANResolveResult> {\n const primaryUrl = `${this.rootUrl}/api/v1/resolve/${encodeURIComponent(rrn)}`;\n\n let resp: Response;\n try {\n resp = await this._fetch(primaryUrl);\n } catch (err) {\n // Network-level failure; bubble up as-is\n throw err;\n }\n\n if (resp.ok) {\n try {\n return (await resp.json()) as RCANResolveResult;\n } catch (err) {\n throw new RCANNodeSyncError(\n `Invalid JSON in resolve response for ${rrn}`,\n this.rootUrl,\n err instanceof Error ? err : undefined\n );\n }\n }\n\n if (resp.status !== 404) {\n throw new RCANNodeSyncError(\n `Unexpected HTTP ${resp.status} resolving ${rrn}`,\n this.rootUrl\n );\n }\n\n // 404 → discover authoritative node and try its /robots/{rrn} endpoint\n const node = await this.discover(rrn);\n const fallbackUrl = `${node.api_base.replace(/\\/$/, \"\")}/robots/${encodeURIComponent(rrn)}`;\n const fallbackResp = await this._fetch(fallbackUrl);\n\n if (!fallbackResp.ok) {\n if (fallbackResp.status === 404) {\n throw new RCANNodeNotFoundError(rrn, node.api_base);\n }\n throw new RCANNodeSyncError(\n `HTTP ${fallbackResp.status} from authoritative node for ${rrn}`,\n node.api_base\n );\n }\n\n try {\n return (await fallbackResp.json()) as RCANResolveResult;\n } catch (err) {\n throw new RCANNodeSyncError(\n `Invalid JSON in fallback resolve response for ${rrn}`,\n node.api_base,\n err instanceof Error ? err : undefined\n );\n }\n }\n\n /**\n * Verify a node manifest is well-formed.\n * Checks required fields, ed25519: public_key prefix, valid node_type, https:// api_base.\n */\n verifyNode(manifest: unknown): manifest is RCANRegistryNode {\n if (!manifest || typeof manifest !== \"object\") return false;\n const m = manifest as Record<string, unknown>;\n\n if (typeof m.rcan_node_version !== \"string\" || !m.rcan_node_version) return false;\n if (typeof m.node_type !== \"string\" || !VALID_NODE_TYPES.has(m.node_type as string)) return false;\n if (typeof m.operator !== \"string\" || !m.operator) return false;\n if (typeof m.namespace_prefix !== \"string\" || !m.namespace_prefix) return false;\n if (typeof m.public_key !== \"string\" || !m.public_key.startsWith(\"ed25519:\")) return false;\n if (typeof m.api_base !== \"string\" || !m.api_base.startsWith(\"https://\")) return false;\n\n return true;\n }\n}\n","/**\n * Fetch and validate against canonical RCAN JSON schemas from rcan.dev.\n * Caches schema in memory for the session (no filesystem deps for browser compat).\n */\n\nconst SCHEMA_BASE = 'https://rcan.dev/schemas';\nconst schemaCache = new Map<string, object>();\n\n/** Clear the in-memory schema cache. Intended for use in tests only. */\nexport function _clearSchemaCache(): void {\n schemaCache.clear();\n}\n\nexport async function fetchCanonicalSchema(schemaName: string): Promise<object | null> {\n if (schemaCache.has(schemaName)) return schemaCache.get(schemaName)!;\n try {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 5000);\n const res = await fetch(`${SCHEMA_BASE}/${schemaName}`, { signal: controller.signal });\n clearTimeout(timer);\n if (!res.ok) return null;\n const schema = await res.json();\n schemaCache.set(schemaName, schema);\n return schema;\n } catch {\n return null; // graceful degradation\n }\n}\n\n/**\n * Validate a config object against the canonical rcan-config schema from rcan.dev.\n * Returns { valid: true } or { valid: false, errors: string[] }.\n * Gracefully returns { valid: true, skipped: true } if schema unreachable.\n */\nexport async function validateConfigAgainstSchema(\n config: unknown\n): Promise<{ valid: boolean; errors?: string[]; skipped?: boolean }> {\n const schema = await fetchCanonicalSchema('rcan-config.schema.json');\n if (!schema) return { valid: true, skipped: true };\n\n // Basic structural validation (no heavy jsonschema dep — just check required keys)\n const errors: string[] = [];\n if (typeof config !== 'object' || config === null) {\n return { valid: false, errors: ['Config must be an object'] };\n }\n const cfg = config as Record<string, unknown>;\n const required = (schema as any).required ?? [];\n for (const key of required) {\n if (!(key in cfg)) errors.push(`Missing required field: ${key}`);\n }\n return errors.length === 0 ? { valid: true } : { valid: false, errors };\n}\n\nexport async function validateNodeAgainstSchema(\n manifest: unknown\n): Promise<{ valid: boolean; errors?: string[]; skipped?: boolean }> {\n const schema = await fetchCanonicalSchema('rcan-node.schema.json');\n if (!schema) return { valid: true, skipped: true };\n\n const errors: string[] = [];\n if (typeof manifest !== 'object' || manifest === null) {\n return { valid: false, errors: ['Manifest must be an object'] };\n }\n const m = manifest as Record<string, unknown>;\n const required = (schema as any).required ?? [];\n for (const key of required) {\n if (!(key in m)) errors.push(`Missing required field: ${key}`);\n }\n return errors.length === 0 ? { valid: true } : { valid: false, errors };\n}\n","/**\n * RCAN Quality of Service — §5.3\n *\n * QoSLevel:\n * FIRE_AND_FORGET = 0 — no ack required\n * ACKNOWLEDGED = 1 — at-least-once; sender retries until COMMAND_ACK\n * EXACTLY_ONCE = 2 — two-phase commit: COMMAND_ACK + COMMAND_COMMIT\n *\n * Safety messages MUST use qos >= 1.\n * ESTOP MUST use qos = 2 (EXACTLY_ONCE).\n * TELEOP MUST use qos = 0 (FIRE_AND_FORGET).\n */\n\nimport type { SafetyMessage } from \"./safety.js\";\n\nexport enum QoSLevel {\n FIRE_AND_FORGET = 0,\n ACKNOWLEDGED = 1,\n EXACTLY_ONCE = 2,\n}\n\n/** Thrown when an ACK times out for a safety message */\nexport class QoSAckTimeoutError extends Error {\n constructor(msgId: string) {\n super(`ACK timeout for message ${msgId} — safety halt required`);\n this.name = \"QoSAckTimeoutError\";\n Object.setPrototypeOf(this, QoSAckTimeoutError.prototype);\n }\n}\n\nexport interface QoSSendOptions {\n /** QoS level (default: FIRE_AND_FORGET) */\n qos?: QoSLevel;\n /** Max retries for qos >= 1 (default: 3) */\n maxRetries?: number;\n /** Initial backoff ms for qos >= 1 (default: 100) */\n initialBackoffMs?: number;\n /** ACK timeout ms for qos >= 1 (default: 500) */\n ackTimeoutMs?: number;\n}\n\nexport interface QoSResult {\n delivered: boolean;\n attempts: number;\n reason: string;\n}\n\n/**\n * QoSManager — manages send-with-ack pattern for RCAN messages.\n *\n * Usage:\n * const mgr = new QoSManager(sendFn, ackFn);\n * await mgr.sendWithQoS(msg, { qos: QoSLevel.EXACTLY_ONCE });\n */\nexport class QoSManager {\n private readonly _send: (msg: unknown) => Promise<void>;\n private readonly _waitForAck: (msgId: string, timeoutMs: number) => Promise<boolean>;\n\n constructor(\n send: (msg: unknown) => Promise<void>,\n waitForAck: (msgId: string, timeoutMs: number) => Promise<boolean>\n ) {\n this._send = send;\n this._waitForAck = waitForAck;\n }\n\n /**\n * Send a message with the specified QoS level.\n *\n * For QoS 0: fire and forget.\n * For QoS 1: retry until ACK received or maxRetries exhausted.\n * For QoS 2: same as QoS 1 but sends a COMMAND_COMMIT after ACK.\n */\n async sendWithQoS(\n msg: unknown,\n opts: QoSSendOptions = {}\n ): Promise<QoSResult> {\n const qos = opts.qos ?? QoSLevel.FIRE_AND_FORGET;\n const maxRetries = opts.maxRetries ?? 3;\n const initialBackoffMs = opts.initialBackoffMs ?? 100;\n const ackTimeoutMs = opts.ackTimeoutMs ?? 500;\n\n if (qos === QoSLevel.FIRE_AND_FORGET) {\n await this._send(msg);\n return { delivered: true, attempts: 1, reason: \"fire-and-forget\" };\n }\n\n // QoS 1 or 2: retry loop\n const msgId = (msg as { message_id?: string; msg_id?: string }).message_id\n ?? (msg as { message_id?: string; msg_id?: string }).msg_id\n ?? \"unknown\";\n\n let attempts = 0;\n let backoffMs = initialBackoffMs;\n\n while (attempts <= maxRetries) {\n await this._send(msg);\n attempts++;\n\n const acked = await this._waitForAck(msgId, ackTimeoutMs);\n if (acked) {\n return { delivered: true, attempts, reason: qos === QoSLevel.EXACTLY_ONCE ? \"exactly-once\" : \"acknowledged\" };\n }\n\n if (attempts > maxRetries) break;\n\n // Exponential backoff\n await sleep(backoffMs);\n backoffMs = Math.min(backoffMs * 2, 5000);\n }\n\n return { delivered: false, attempts, reason: `ACK not received after ${maxRetries} retries` };\n }\n}\n\n/**\n * Override makeEstopMessage to force QoS=EXACTLY_ONCE.\n * Returns a SafetyMessage annotated with qos: 2.\n */\nexport function makeEstopWithQoS(\n ruri: string,\n reason: string\n): SafetyMessage & { qos: QoSLevel } {\n const msg: SafetyMessage & { qos: QoSLevel } = {\n message_type: 6 as const,\n ruri,\n safety_event: \"ESTOP\",\n reason: reason.slice(0, 512),\n timestamp_ms: Date.now(),\n message_id: generateId(),\n qos: QoSLevel.EXACTLY_ONCE,\n };\n return msg;\n}\n\nfunction generateId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n const bytes = Array.from({ length: 16 }, () => Math.floor(Math.random() * 256));\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n const hex = bytes.map((b) => b.toString(16).padStart(2, \"0\"));\n return `${hex.slice(0, 4).join(\"\")}-${hex.slice(4, 6).join(\"\")}-${hex.slice(6, 8).join(\"\")}-${hex.slice(8, 10).join(\"\")}-${hex.slice(10).join(\"\")}`;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * RCAN Safety Message helpers (MessageType 6).\n *\n * Safety messages bypass all queues and confidence gates per RCAN §6.\n * Use these helpers to build and validate ESTOP/STOP/RESUME messages.\n *\n * v1.5 updates:\n * - makeEstopMessage now includes qos: 2 (EXACTLY_ONCE)\n * - makeTransparencyMessage includes delegationChain (GAP-22)\n */\n\nimport type { DelegationHop } from \"./message.js\";\nimport { QoSLevel } from \"./qos.js\";\n\nexport const SAFETY_MESSAGE_TYPE = 6;\nexport type SafetyEvent = 'ESTOP' | 'STOP' | 'RESUME';\n\nexport interface SafetyMessage {\n message_type: 6;\n ruri: string;\n safety_event: SafetyEvent;\n reason: string;\n timestamp_ms: number;\n message_id: string;\n /** v1.5: QoS level (ESTOP always 2) */\n qos?: QoSLevel;\n}\n\nfunction generateId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n // Fallback for older Node versions: simple random hex\n const bytes = Array.from({ length: 16 }, () => Math.floor(Math.random() * 256));\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n const hex = bytes.map((b) => b.toString(16).padStart(2, '0'));\n return `${hex.slice(0, 4).join('')}-${hex.slice(4, 6).join('')}-${hex.slice(6, 8).join('')}-${hex.slice(8, 10).join('')}-${hex.slice(10).join('')}`;\n}\n\n/**\n * Create an ESTOP message — immediate actuator cut.\n *\n * Protocol 66 safety invariant: ESTOP is NEVER blocked by new mechanisms.\n * v1.5: forces qos=EXACTLY_ONCE (2) per §5.3.\n */\nexport function makeEstopMessage(ruri: string, reason: string): SafetyMessage {\n return {\n message_type: 6,\n ruri,\n safety_event: 'ESTOP',\n reason: reason.slice(0, 512),\n timestamp_ms: Date.now(),\n message_id: generateId(),\n qos: QoSLevel.EXACTLY_ONCE,\n };\n}\n\n/**\n * Create a STOP message — controlled deceleration to rest.\n * Use for non-emergency halts where deceleration is safe.\n */\nexport function makeStopMessage(ruri: string, reason: string): SafetyMessage {\n return {\n message_type: 6,\n ruri,\n safety_event: 'STOP',\n reason: reason.slice(0, 512),\n timestamp_ms: Date.now(),\n message_id: generateId(),\n };\n}\n\n/**\n * Create a RESUME message — clear a prior STOP.\n * Note: ESTOP requires explicit hardware-level clear; RESUME only clears STOP.\n */\nexport function makeResumeMessage(ruri: string, reason: string): SafetyMessage {\n return {\n message_type: 6,\n ruri,\n safety_event: 'RESUME',\n reason: reason.slice(0, 512),\n timestamp_ms: Date.now(),\n message_id: generateId(),\n };\n}\n\n/**\n * Check if a message dict is a RCAN safety message.\n */\nexport function isSafetyMessage(msg: unknown): msg is SafetyMessage {\n return (\n typeof msg === 'object' &&\n msg !== null &&\n (msg as Record<string, unknown>).message_type === SAFETY_MESSAGE_TYPE\n );\n}\n\n/**\n * Validate a safety message. Returns array of error strings (empty = valid).\n */\nexport function validateSafetyMessage(msg: Partial<SafetyMessage>): string[] {\n const errors: string[] = [];\n if (msg.message_type !== 6) errors.push('message_type must be 6');\n if (!msg.ruri) errors.push('ruri is required');\n if (!['ESTOP', 'STOP', 'RESUME'].includes(msg.safety_event ?? '')) {\n errors.push('safety_event must be ESTOP, STOP, or RESUME');\n }\n if (!msg.reason || msg.reason.length === 0) errors.push('reason is required');\n if (!msg.message_id) errors.push('message_id is required');\n if (!msg.timestamp_ms || msg.timestamp_ms <= 0) errors.push('timestamp_ms must be positive');\n return errors;\n}\n\n// ── v1.5: Transparency message ────────────────────────────────────────────────\n\nexport interface TransparencyMessage {\n message_type: 11; // TRANSPARENCY\n ruri: string;\n disclosure: string;\n timestamp_ms: number;\n message_id: string;\n /** v1.5 GAP-22: third-party control chain */\n delegation_chain?: DelegationHop[];\n}\n\n/**\n * Build a TRANSPARENCY message for EU AI Act Article 13 compliance.\n *\n * v1.5 (GAP-22): includes delegation_chain when available.\n */\nexport function makeTransparencyMessage(\n ruri: string,\n disclosure: string,\n delegationChain?: DelegationHop[]\n): TransparencyMessage {\n return {\n message_type: 11,\n ruri,\n disclosure,\n timestamp_ms: Date.now(),\n message_id: generateId(),\n delegation_chain: delegationChain,\n };\n}\n","/**\n * RCAN Replay Attack Prevention — §8.3\n *\n * Robots MUST reject messages where timestamp is >30s old (configurable).\n * A sliding-window seen-set of msg_ids prevents duplicate delivery.\n * Safety messages (MessageType 6) use a 10s window maximum.\n */\n\nimport type { SafetyMessage } from \"./safety.js\";\n\nconst SAFETY_MESSAGE_TYPE = 6;\nconst SAFETY_MAX_WINDOW_S = 10;\nconst DEFAULT_WINDOW_S = 30;\nconst DEFAULT_MAX_SIZE = 10000;\n\n/** A message shape that has the fields the replay cache needs */\nexport interface ReplayableMessage {\n message_id?: string;\n msg_id?: string;\n timestamp_ms?: number;\n timestamp?: string | number;\n message_type?: number;\n}\n\nexport interface ReplayCheckResult {\n allowed: boolean;\n reason: string;\n}\n\n/**\n * Sliding-window replay cache.\n *\n * constructor(windowSeconds = 30, maxSize = 10000)\n */\nexport class ReplayCache {\n private readonly windowSeconds: number;\n private readonly maxSize: number;\n /** Map<msgId, expiresAtMs> */\n private readonly _seen: Map<string, number>;\n\n constructor(windowSeconds: number = DEFAULT_WINDOW_S, maxSize: number = DEFAULT_MAX_SIZE) {\n this.windowSeconds = windowSeconds;\n this.maxSize = maxSize;\n this._seen = new Map();\n }\n\n /**\n * Check a message id + timestamp and record it if allowed.\n *\n * @param msgId - unique message identifier\n * @param timestamp - ISO 8601 string or Unix seconds (float)\n * @param isSafety - if true, enforce the 10s safety window cap\n */\n checkAndRecord(\n msgId: string,\n timestamp: string,\n isSafety = false\n ): ReplayCheckResult {\n const now = Date.now();\n\n // Evict stale entries to keep memory bounded\n this._evict(now);\n\n // Resolve effective window\n const window = isSafety\n ? Math.min(this.windowSeconds, SAFETY_MAX_WINDOW_S)\n : this.windowSeconds;\n\n // Parse timestamp → ms\n const tMs = parseTimestampMs(timestamp);\n if (tMs === null) {\n return { allowed: false, reason: `invalid timestamp format: ${timestamp}` };\n }\n\n // Freshness check\n const ageMs = now - tMs;\n const windowMs = window * 1000;\n if (ageMs > windowMs) {\n return {\n allowed: false,\n reason: `message too old: age=${Math.round(ageMs / 1000)}s > window=${window}s`,\n };\n }\n if (tMs > now + 5000) {\n // Allow 5s future drift for clock skew\n return {\n allowed: false,\n reason: `message timestamp is in the future`,\n };\n }\n\n // Duplicate check\n if (this._seen.has(msgId)) {\n return { allowed: false, reason: `replay detected: msg_id ${msgId} already seen` };\n }\n\n // Enforce max size by evicting oldest entry\n if (this._seen.size >= this.maxSize) {\n const firstKey = this._seen.keys().next().value as string;\n this._seen.delete(firstKey);\n }\n\n // Record it\n const expiresAt = now + windowMs;\n this._seen.set(msgId, expiresAt);\n\n return { allowed: true, reason: \"ok\" };\n }\n\n /** Evict entries whose window has passed */\n private _evict(now: number): void {\n for (const [id, expiresAt] of this._seen) {\n if (expiresAt <= now) {\n this._seen.delete(id);\n }\n }\n }\n\n /** Number of entries currently tracked */\n get size(): number {\n return this._seen.size;\n }\n}\n\n/**\n * Validate replay for a SafetyMessage or ReplayableMessage.\n */\nexport function validateReplay(\n message: SafetyMessage | ReplayableMessage,\n cache: ReplayCache\n): { valid: boolean; reason: string } {\n const msg = message as ReplayableMessage & Partial<SafetyMessage>;\n\n // Resolve msg_id\n const msgId: string | undefined =\n (msg as SafetyMessage).message_id ?? (msg as ReplayableMessage).msg_id;\n if (!msgId) {\n return { valid: false, reason: \"missing message_id / msg_id\" };\n }\n\n // Resolve timestamp\n let timestamp: string | undefined;\n if (typeof (msg as SafetyMessage).timestamp_ms === \"number\") {\n // SafetyMessage uses timestamp_ms (unix ms)\n timestamp = String((msg as SafetyMessage).timestamp_ms! / 1000);\n } else if (msg.timestamp !== undefined) {\n timestamp = String(msg.timestamp);\n }\n if (!timestamp) {\n return { valid: false, reason: \"missing timestamp\" };\n }\n\n const isSafety = (msg as SafetyMessage).message_type === SAFETY_MESSAGE_TYPE ||\n (msg as ReplayableMessage).message_type === SAFETY_MESSAGE_TYPE;\n\n const result = cache.checkAndRecord(msgId, timestamp, isSafety);\n return { valid: result.allowed, reason: result.reason };\n}\n\n// ── helpers ───────────────────────────────────────────────────────────────────\n\n/**\n * Parse a timestamp to milliseconds.\n * Accepts:\n * - ISO 8601 strings (\"2026-03-16T12:00:00.000Z\")\n * - Unix seconds as string (\"1710000000.123\" or \"1710000000\")\n * - Unix milliseconds as string (13-digit integers)\n */\nfunction parseTimestampMs(ts: string): number | null {\n // Try ISO 8601\n if (ts.includes(\"T\") || ts.includes(\"-\")) {\n const d = new Date(ts);\n if (!isNaN(d.getTime())) return d.getTime();\n }\n // Try numeric\n const n = parseFloat(ts);\n if (isNaN(n)) return null;\n // Heuristic: if > 1e12, treat as milliseconds; otherwise seconds\n if (n > 1e12) return n;\n return n * 1000;\n}\n","/**\n * RCAN Time Synchronization — §8.4\n *\n * All RCAN robots MUST sync their clocks via NTP/NTS before operational mode.\n * Max drift tolerance ±5 seconds.\n */\n\n/** Clock synchronization status returned by checkClockSync() */\nexport interface ClockSyncStatus {\n synchronized: boolean;\n offsetSeconds: number;\n source: string;\n}\n\n/** Thrown by assertClockSynced() when drift exceeds the allowed threshold */\nexport class ClockDriftError extends Error {\n readonly offsetSeconds: number;\n constructor(offsetSeconds: number, maxDriftSeconds: number) {\n super(\n `Clock drift too large: offset=${offsetSeconds.toFixed(3)}s > max=${maxDriftSeconds}s`\n );\n this.name = \"ClockDriftError\";\n this.offsetSeconds = offsetSeconds;\n Object.setPrototypeOf(this, ClockDriftError.prototype);\n }\n}\n\n/**\n * Check clock synchronization.\n *\n * In a browser / Node environment without access to chronyc or ntplib, we\n * perform a lightweight sanity check: compare local time against a trusted\n * time source by issuing an HTTP HEAD request and comparing the Date header.\n * Falls back to \"assumed-synced\" when running in environments where network\n * is unavailable (e.g., unit tests).\n *\n * Returns ClockSyncStatus with:\n * synchronized: whether drift is within ±5s\n * offsetSeconds: measured offset (positive = local is ahead)\n * source: description of what was checked\n */\nexport async function checkClockSync(\n timeServer?: string\n): Promise<ClockSyncStatus> {\n const server = timeServer ?? \"https://worldtimeapi.org/api/ip\";\n\n try {\n const before = Date.now();\n const resp = await fetch(server, { method: \"HEAD\", signal: AbortSignal.timeout(3000) });\n const after = Date.now();\n\n // Use the Date header from the response as a rough time reference\n const dateHeader = resp.headers.get(\"Date\") ?? resp.headers.get(\"date\");\n if (!dateHeader) {\n // No Date header — can't determine offset\n return {\n synchronized: true,\n offsetSeconds: 0,\n source: \"assumed (no Date header)\",\n };\n }\n\n const serverMs = new Date(dateHeader).getTime();\n if (isNaN(serverMs)) {\n return { synchronized: true, offsetSeconds: 0, source: \"assumed (unparseable Date header)\" };\n }\n\n // Use midpoint of request as estimate of server time\n const localMidpoint = (before + after) / 2;\n const offsetSeconds = (localMidpoint - serverMs) / 1000;\n const synchronized = Math.abs(offsetSeconds) <= 5;\n\n return { synchronized, offsetSeconds, source: server };\n } catch {\n // Network unavailable or timeout — assume synced (unit test / offline environment)\n return { synchronized: true, offsetSeconds: 0, source: \"assumed (network unavailable)\" };\n }\n}\n\n/**\n * Assert that the local clock is synchronized within maxDriftSeconds.\n *\n * Throws ClockDriftError if the measured offset exceeds the threshold.\n *\n * @param maxDriftSeconds - Maximum allowed |offset| in seconds (default 5)\n */\nexport async function assertClockSynced(maxDriftSeconds = 5): Promise<void> {\n const status = await checkClockSync();\n if (!status.synchronized || Math.abs(status.offsetSeconds) > maxDriftSeconds) {\n throw new ClockDriftError(status.offsetSeconds, maxDriftSeconds);\n }\n}\n","/**\n * RCAN CONFIG_UPDATE Wire Protocol — §9.2\n *\n * CONFIG_UPDATE messages MUST carry config_hash, config_version, diff, and\n * rollback. Safety parameter changes MUST have safety_overrides=true AND\n * role: creator JWT.\n */\n\nimport { RCANMessage, MessageType } from \"./message.js\";\nimport { SPEC_VERSION } from \"./version.js\";\n\nfunction generateId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n}\n\n/** Compute a simple SHA-256-like hash of the diff for integrity checking. */\nasync function hashDiff(diff: Record<string, unknown>): Promise<string> {\n const text = JSON.stringify(diff, Object.keys(diff).sort());\n if (typeof crypto !== \"undefined\" && crypto.subtle) {\n const encoded = new TextEncoder().encode(text);\n const hashBuf = await crypto.subtle.digest(\"SHA-256\", encoded);\n return Array.from(new Uint8Array(hashBuf))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n // Fallback: simple FNV-1a hex (not cryptographic but OK for tests)\n let hash = 2166136261;\n for (let i = 0; i < text.length; i++) {\n hash ^= text.charCodeAt(i);\n hash = (hash * 16777619) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n\n/**\n * Build a CONFIG_UPDATE RCANMessage.\n *\n * @param diff - The configuration delta to apply\n * @param scope - Authorization scope (e.g. \"config\")\n * @param rollback - The previous config snapshot for rollback\n * @param target - Target robot URI\n */\nexport async function makeConfigUpdate(\n diff: Record<string, unknown>,\n scope: string,\n rollback: Record<string, unknown>,\n target = \"rcan://local/config\",\n safetyOverrides = false\n): Promise<RCANMessage> {\n const configHash = await hashDiff(diff);\n return new RCANMessage({\n rcan: SPEC_VERSION,\n cmd: \"CONFIG_UPDATE\",\n target,\n params: {\n message_type: MessageType.CONFIG,\n diff,\n rollback,\n scope,\n config_hash: configHash,\n safety_overrides: safetyOverrides,\n },\n });\n}\n\n/**\n * Validate a CONFIG_UPDATE message.\n *\n * Checks:\n * - params.diff is present\n * - params.config_hash is present\n * - params.rollback is present\n * - if safety_overrides=true, scope must be \"creator\"\n */\nexport function validateConfigUpdate(\n msg: RCANMessage\n): { valid: boolean; reason: string } {\n const p = msg.params;\n\n if (!p.diff || typeof p.diff !== \"object\") {\n return { valid: false, reason: \"missing required field: params.diff\" };\n }\n if (!p.config_hash || typeof p.config_hash !== \"string\") {\n return { valid: false, reason: \"missing required field: params.config_hash\" };\n }\n if (!(\"rollback\" in p)) {\n return { valid: false, reason: \"missing required field: params.rollback\" };\n }\n if (p.safety_overrides === true && p.scope !== \"creator\") {\n return {\n valid: false,\n reason: \"safety_overrides=true requires scope=creator (owner is insufficient)\",\n };\n }\n\n return { valid: true, reason: \"ok\" };\n}\n","/**\n * RCAN Key Rotation — §8.6\n *\n * Operators SHOULD maintain a JWKS at /.well-known/rcan-keys.json.\n * Keys MUST include an exp field (max 365-day validity).\n * Rotation: add new key, set exp on old key.\n */\n\nimport { RCANMessage, MessageType } from \"./message.js\";\nimport { SPEC_VERSION } from \"./version.js\";\n\nfunction generateId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n}\n\nexport interface JWKEntry {\n kid: string;\n alg: string;\n use: string;\n key_ops?: string[];\n /** Public key material (base64url) */\n x?: string;\n /** Unix timestamp — when this key expires */\n exp?: number;\n /** Unix timestamp — when this key was revoked (optional) */\n revoked_at?: number;\n}\n\nexport interface JWKSDocument {\n keys: JWKEntry[];\n}\n\n/**\n * KeyStore — in-memory JWKS with rotation support.\n */\nexport class KeyStore {\n private _keys: JWKEntry[] = [];\n\n /** Add a key to the store */\n addKey(entry: JWKEntry): void {\n this._keys.push(entry);\n }\n\n /** Get the current JWKS document (all non-revoked keys) */\n getJWKS(): JWKSDocument {\n return { keys: [...this._keys] };\n }\n\n /** Find a key by kid */\n findKey(kid: string): JWKEntry | undefined {\n return this._keys.find((k) => k.kid === kid);\n }\n\n /** Check if a key is valid (not expired, not revoked) */\n isKeyValid(kid: string, nowMs?: number): boolean {\n const entry = this.findKey(kid);\n if (!entry) return false;\n const now = (nowMs ?? Date.now()) / 1000;\n if (entry.revoked_at !== undefined && entry.revoked_at <= now) return false;\n if (entry.exp !== undefined && entry.exp < now) return false;\n return true;\n }\n\n /** Mark a key as expired (rotate out) */\n expireKey(kid: string, expiresAt?: number): void {\n const entry = this.findKey(kid);\n if (entry) {\n entry.exp = expiresAt ?? Math.floor(Date.now() / 1000);\n }\n }\n\n /** Revoke a key immediately */\n revokeKey(kid: string): void {\n const entry = this.findKey(kid);\n if (entry) {\n entry.revoked_at = Math.floor(Date.now() / 1000);\n }\n }\n\n /** All valid keys (not expired, not revoked) */\n validKeys(nowMs?: number): JWKEntry[] {\n return this._keys.filter((k) => this.isKeyValid(k.kid, nowMs));\n }\n}\n\n/**\n * Build a key-rotation RCAN message.\n *\n * @param newPublicKey - Base64url-encoded new Ed25519 public key\n * @param oldKeyId - kid of the key being rotated out\n * @param overlapSeconds - How long old key remains valid (default: 120)\n * @param target - Target robot URI\n */\nexport function makeKeyRotationMessage(\n newPublicKey: string,\n oldKeyId: string,\n overlapSeconds = 120,\n target = \"rcan://local/keys\"\n): RCANMessage {\n const newKid = generateId().slice(0, 8);\n return new RCANMessage({\n rcan: SPEC_VERSION,\n cmd: \"KEY_ROTATION\",\n target,\n params: {\n message_type: MessageType.CONFIG,\n new_public_key: newPublicKey,\n new_kid: newKid,\n old_kid: oldKeyId,\n overlap_seconds: overlapSeconds,\n initiated_at: new Date().toISOString(),\n },\n keyId: newKid,\n });\n}\n","/**\n * RCAN Consent Wire Protocol — §11.2\n *\n * Three message types:\n * CONSENT_REQUEST (20) — requester asks target's owner for access\n * CONSENT_GRANT (21) — owner approves\n * CONSENT_DENY (22) — owner denies\n *\n * API mirrors rcan-py consent module exactly (camelCased).\n */\n\nimport { RCANMessage, MessageType } from \"./message.js\";\nimport { SPEC_VERSION } from \"./version.js\";\n\nfunction generateId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n}\n\nexport type ConsentType = \"cross_robot\" | \"training_data\" | \"observer\";\n\nexport interface ConsentRequestParams {\n requesterRuri: string;\n requesterOwner: string;\n targetRuri: string;\n requestedScopes: string[];\n durationHours: number;\n justification: string;\n requestId?: string;\n consentType?: ConsentType;\n dataCategories?: string[];\n}\n\nexport interface ConsentResponseParams {\n requestId: string;\n grantedScopes?: string[];\n expiresAt?: string;\n reason?: string;\n}\n\n/**\n * Build a CONSENT_REQUEST message.\n *\n * Mirrors rcan-py: build_consent_request()\n */\nexport function makeConsentRequest(params: ConsentRequestParams): RCANMessage {\n const requestId = params.requestId ?? generateId();\n return new RCANMessage({\n rcan: SPEC_VERSION,\n cmd: \"CONSENT_REQUEST\",\n target: params.targetRuri,\n params: {\n message_type: MessageType.CONSENT_REQUEST,\n requester_ruri: params.requesterRuri,\n requester_owner: params.requesterOwner,\n target_ruri: params.targetRuri,\n requested_scopes: params.requestedScopes,\n duration_hours: params.durationHours,\n justification: params.justification,\n request_id: requestId,\n consent_type: params.consentType ?? \"cross_robot\",\n data_categories: params.dataCategories ?? [],\n },\n });\n}\n\n/**\n * Build a CONSENT_GRANT message.\n *\n * Mirrors rcan-py: build_consent_grant()\n */\nexport function makeConsentGrant(params: ConsentResponseParams): RCANMessage {\n const expiresAt =\n params.expiresAt ?? new Date(Date.now() + 24 * 3600 * 1000).toISOString();\n return new RCANMessage({\n rcan: SPEC_VERSION,\n cmd: \"CONSENT_GRANT\",\n target: \"rcan://local/consent\",\n params: {\n message_type: MessageType.CONSENT_GRANT,\n request_id: params.requestId,\n granted_scopes: params.grantedScopes ?? [],\n expires_at: expiresAt,\n reason: params.reason ?? \"approved\",\n },\n });\n}\n\n/**\n * Build a CONSENT_DENY message.\n *\n * Mirrors rcan-py: build_consent_deny()\n */\nexport function makeConsentDeny(params: ConsentResponseParams): RCANMessage {\n return new RCANMessage({\n rcan: SPEC_VERSION,\n cmd: \"CONSENT_DENY\",\n target: \"rcan://local/consent\",\n params: {\n message_type: MessageType.CONSENT_DENY,\n request_id: params.requestId,\n reason: params.reason ?? \"denied\",\n },\n });\n}\n\n/**\n * Validate a consent message (CONSENT_REQUEST, CONSENT_GRANT, or CONSENT_DENY).\n *\n * Mirrors rcan-py: verify_consent_signature() (structure check only — JWT\n * signature verification is performed by the auth layer).\n */\nexport function validateConsentMessage(\n msg: RCANMessage\n): { valid: boolean; reason: string } {\n const cmd = msg.cmd;\n const p = msg.params;\n const msgType = p.message_type as number | undefined;\n\n if (cmd === \"CONSENT_REQUEST\") {\n if (msgType !== MessageType.CONSENT_REQUEST) {\n return { valid: false, reason: \"message_type must be CONSENT_REQUEST (20)\" };\n }\n if (!p.requester_ruri) return { valid: false, reason: \"missing requester_ruri\" };\n if (!p.target_ruri) return { valid: false, reason: \"missing target_ruri\" };\n if (!p.requested_scopes || !Array.isArray(p.requested_scopes) || (p.requested_scopes as string[]).length === 0) {\n return { valid: false, reason: \"requested_scopes must be a non-empty array\" };\n }\n if (!p.request_id) return { valid: false, reason: \"missing request_id\" };\n if (!p.justification) return { valid: false, reason: \"missing justification\" };\n return { valid: true, reason: \"ok\" };\n }\n\n if (cmd === \"CONSENT_GRANT\") {\n if (msgType !== MessageType.CONSENT_GRANT) {\n return { valid: false, reason: \"message_type must be CONSENT_GRANT (21)\" };\n }\n if (!p.request_id) return { valid: false, reason: \"missing request_id\" };\n if (!p.expires_at) return { valid: false, reason: \"missing expires_at\" };\n return { valid: true, reason: \"ok\" };\n }\n\n if (cmd === \"CONSENT_DENY\") {\n if (msgType !== MessageType.CONSENT_DENY) {\n return { valid: false, reason: \"message_type must be CONSENT_DENY (22)\" };\n }\n if (!p.request_id) return { valid: false, reason: \"missing request_id\" };\n return { valid: true, reason: \"ok\" };\n }\n\n return { valid: false, reason: `unknown consent command: ${cmd}` };\n}\n","/**\n * RCAN Robot Identity Revocation — §13\n *\n * Registry exposes GET /api/v1/robots/{rrn}/revocation-status.\n * Peers cache results with 1h TTL.\n * ROBOT_REVOCATION (19) broadcast invalidates cached trust material.\n */\n\nimport { RCANMessage, MessageType } from \"./message.js\";\nimport { SPEC_VERSION } from \"./version.js\";\n\nexport type RevocationStatusValue = \"active\" | \"revoked\" | \"suspended\";\n\nexport interface RevocationStatus {\n rrn: string;\n status: RevocationStatusValue;\n revokedAt?: string;\n reason?: string;\n authority?: string;\n /** When this cached entry expires */\n cachedUntil?: number;\n}\n\nconst CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour\n\n/**\n * RevocationCache — TTL-based cache for revocation status records.\n */\nexport class RevocationCache {\n private readonly _cache: Map<string, RevocationStatus> = new Map();\n\n /** Get a cached status if still fresh */\n get(rrn: string, nowMs?: number): RevocationStatus | undefined {\n const entry = this._cache.get(rrn);\n if (!entry) return undefined;\n const now = nowMs ?? Date.now();\n if (entry.cachedUntil !== undefined && entry.cachedUntil < now) {\n this._cache.delete(rrn);\n return undefined;\n }\n return entry;\n }\n\n /** Store a status record with a 1h TTL */\n set(status: RevocationStatus, nowMs?: number): void {\n const now = nowMs ?? Date.now();\n this._cache.set(status.rrn, {\n ...status,\n cachedUntil: now + CACHE_TTL_MS,\n });\n }\n\n /** Invalidate a cached entry immediately */\n invalidate(rrn: string): void {\n this._cache.delete(rrn);\n }\n\n /** Number of cached entries */\n get size(): number {\n return this._cache.size;\n }\n}\n\n/**\n * Check the revocation status of a robot via the registry REST API.\n * Caches results for 1 hour.\n *\n * @param rrn - Robot Registry Number\n * @param registryUrl - Base URL of the registry (e.g. \"https://registry.rcan.dev\")\n * @param cache - Optional RevocationCache to use (creates ephemeral one if not provided)\n */\nexport async function checkRevocation(\n rrn: string,\n registryUrl: string,\n cache?: RevocationCache\n): Promise<RevocationStatus> {\n const c = cache ?? new RevocationCache();\n\n // Check cache first\n const cached = c.get(rrn);\n if (cached) return cached;\n\n const url = `${registryUrl.replace(/\\/$/, \"\")}/api/v1/robots/${encodeURIComponent(rrn)}/revocation-status`;\n\n try {\n const resp = await fetch(url, { signal: AbortSignal.timeout(5000) });\n if (!resp.ok) {\n // Treat non-200 as unable to determine — return active (fail-open, log separately)\n const status: RevocationStatus = { rrn, status: \"active\", reason: `registry returned ${resp.status}` };\n c.set(status);\n return status;\n }\n const data = (await resp.json()) as Partial<RevocationStatus>;\n const status: RevocationStatus = {\n rrn,\n status: (data.status as RevocationStatusValue) ?? \"active\",\n revokedAt: data.revokedAt,\n reason: data.reason,\n authority: data.authority,\n };\n c.set(status);\n return status;\n } catch {\n // Network unavailable — assume active (offline mode)\n const status: RevocationStatus = { rrn, status: \"active\", reason: \"network unavailable\" };\n return status;\n }\n}\n\n/**\n * Build a ROBOT_REVOCATION broadcast message.\n *\n * @param rrn - The RRN being revoked\n * @param reason - Human-readable revocation reason\n */\nexport function makeRevocationBroadcast(\n rrn: string,\n reason: string\n): RCANMessage {\n return new RCANMessage({\n rcan: SPEC_VERSION,\n cmd: \"ROBOT_REVOCATION\",\n target: \"rcan://broadcast/revocation\",\n params: {\n message_type: MessageType.ROBOT_REVOCATION,\n rrn,\n reason,\n revoked_at: new Date().toISOString(),\n },\n });\n}\n","/**\n * RCAN Training Data Consent — §17\n *\n * Any TRAINING_DATA collection involving biometric/audio/visual data MUST\n * first obtain a DATA_CONSENT token via CONSENT_REQUEST with\n * consent_type: \"training_data\".\n *\n * EU AI Act Annex III §5 compliance.\n */\n\nimport { RCANMessage, MessageType } from \"./message.js\";\nimport { makeConsentRequest, makeConsentGrant, makeConsentDeny } from \"./consent.js\";\nimport { SPEC_VERSION } from \"./version.js\";\nimport type { ConsentResponseParams } from \"./consent.js\";\n\n/** §17 — Data categories that require training consent */\nexport enum DataCategory {\n VIDEO = \"video\",\n AUDIO = \"audio\",\n LOCATION = \"location\",\n BIOMETRIC = \"biometric\",\n TELEMETRY = \"telemetry\",\n}\n\nexport interface TrainingConsentRequestParams {\n requesterRuri: string;\n requesterOwner: string;\n targetRuri: string;\n dataCategories: DataCategory[];\n durationHours: number;\n justification: string;\n requestId?: string;\n}\n\n/**\n * Build a training-data consent request.\n * Sets consent_type: \"training_data\" automatically.\n *\n * Mirrors rcan-py: request_training_consent()\n */\nexport function makeTrainingConsentRequest(\n params: TrainingConsentRequestParams\n): RCANMessage {\n return makeConsentRequest({\n requesterRuri: params.requesterRuri,\n requesterOwner: params.requesterOwner,\n targetRuri: params.targetRuri,\n requestedScopes: [\"training_data\"],\n durationHours: params.durationHours,\n justification: params.justification,\n requestId: params.requestId,\n consentType: \"training_data\",\n dataCategories: params.dataCategories,\n });\n}\n\n/**\n * Build a training-data consent grant.\n *\n * Mirrors rcan-py: build_consent_grant() for training scope.\n */\nexport function makeTrainingConsentGrant(\n params: ConsentResponseParams\n): RCANMessage {\n return makeConsentGrant(params);\n}\n\n/**\n * Build a training-data consent denial.\n *\n * Mirrors rcan-py: build_consent_deny() for training scope.\n */\nexport function makeTrainingConsentDeny(\n params: ConsentResponseParams\n): RCANMessage {\n return makeConsentDeny(params);\n}\n\n/**\n * Validate that a TRAINING_DATA message carries a consent_token.\n *\n * A TRAINING_DATA message without consent_token MUST be rejected.\n */\nexport function validateTrainingDataMessage(\n msg: RCANMessage\n): { valid: boolean; reason: string } {\n if (msg.params.message_type !== MessageType.TRAINING_DATA) {\n return { valid: false, reason: \"not a TRAINING_DATA message\" };\n }\n const token = msg.params.consent_token;\n if (!token || typeof token !== \"string\" || token.trim() === \"\") {\n return {\n valid: false,\n reason: \"TRAINING_DATA message missing consent_token (§17)\",\n };\n }\n return { valid: true, reason: \"ok\" };\n}\n","/**\n * RCAN Offline Operation Mode — §14\n *\n * Robots MUST cache registry public keys locally (max TTL 24h).\n * Owner-role tokens accepted from local network when registry unreachable.\n * Cross-owner commands blocked after offline_cross_owner_grace_s (default 3600s).\n * ESTOP is ALWAYS accepted in offline mode per Protocol 66 safety invariants.\n */\n\nimport type { SafetyMessage } from \"./safety.js\";\n\nconst SAFETY_MESSAGE_TYPE = 6;\nconst DEFAULT_CROSS_OWNER_GRACE_S = 3600;\nconst DEFAULT_KEY_TTL_S = 86400;\n\nexport interface OfflineState {\n isOffline: boolean;\n offlineSinceMs?: number;\n localNetwork: boolean;\n}\n\nexport interface OfflineCommandResult {\n allowed: boolean;\n reason: string;\n}\n\nexport interface CachedKey {\n kid: string;\n publicKey: string;\n cachedAtMs: number;\n ttlSeconds: number;\n}\n\n/**\n * OfflineModeManager — controls what commands are accepted when offline.\n *\n * Protocol 66 invariants respected:\n * - ESTOP is ALWAYS allowed, regardless of offline mode\n * - Owner-level commands from local network: allowed within grace period\n * - Cross-owner commands: blocked after crossOwnerGraceS\n */\nexport class OfflineModeManager {\n private readonly crossOwnerGraceS: number;\n private readonly keyTtlS: number;\n private _cachedKeys: CachedKey[] = [];\n\n constructor(\n crossOwnerGraceS: number = DEFAULT_CROSS_OWNER_GRACE_S,\n keyTtlS: number = DEFAULT_KEY_TTL_S\n ) {\n this.crossOwnerGraceS = crossOwnerGraceS;\n this.keyTtlS = keyTtlS;\n }\n\n /**\n * Determine whether a command can be accepted in the current offline state.\n *\n * @param msg - The incoming message (SafetyMessage or plain object with message_type)\n * @param isOffline - Whether we are currently in offline mode\n * @param localNetwork - Whether the sender is on the local network\n * @param isOwner - Whether the sender has owner-level role (validated locally)\n * @param isCrossOwner - Whether this is a cross-owner (non-same-owner) command\n * @param nowMs - Optional current time in ms (for testing)\n */\n canAcceptCommand(\n msg: { message_type?: number; safety_event?: string } | null,\n isOffline: boolean,\n localNetwork: boolean,\n isOwner = true,\n isCrossOwner = false,\n offlineSinceMs?: number,\n nowMs?: number\n ): OfflineCommandResult {\n // Protocol 66: ESTOP is ALWAYS allowed\n if (\n msg &&\n msg.message_type === SAFETY_MESSAGE_TYPE &&\n msg.safety_event === \"ESTOP\"\n ) {\n return { allowed: true, reason: \"ESTOP always accepted (Protocol 66)\" };\n }\n\n if (!isOffline) {\n return { allowed: true, reason: \"online mode\" };\n }\n\n // Offline mode\n if (!localNetwork) {\n return {\n allowed: false,\n reason: \"offline mode: cross-network commands blocked\",\n };\n }\n\n if (!isOwner) {\n return {\n allowed: false,\n reason: \"offline mode: only owner-role commands accepted from local network\",\n };\n }\n\n // Cross-owner grace period check\n if (isCrossOwner && offlineSinceMs !== undefined) {\n const now = nowMs ?? Date.now();\n const offlineSeconds = (now - offlineSinceMs) / 1000;\n if (offlineSeconds > this.crossOwnerGraceS) {\n return {\n allowed: false,\n reason: `offline mode: cross-owner grace period expired (${Math.round(offlineSeconds)}s > ${this.crossOwnerGraceS}s)`,\n };\n }\n }\n\n return {\n allowed: true,\n reason: \"offline mode: owner command on local network accepted\",\n };\n }\n\n /** Cache a public key for offline use */\n cacheKey(entry: Omit<CachedKey, \"cachedAtMs\" | \"ttlSeconds\">, nowMs?: number): void {\n const now = nowMs ?? Date.now();\n // Remove existing entry for same kid\n this._cachedKeys = this._cachedKeys.filter((k) => k.kid !== entry.kid);\n this._cachedKeys.push({\n ...entry,\n cachedAtMs: now,\n ttlSeconds: this.keyTtlS,\n });\n }\n\n /** Get a cached public key if still valid */\n getCachedKey(kid: string, nowMs?: number): CachedKey | undefined {\n const now = nowMs ?? Date.now();\n const entry = this._cachedKeys.find((k) => k.kid === kid);\n if (!entry) return undefined;\n const age = (now - entry.cachedAtMs) / 1000;\n if (age > entry.ttlSeconds) {\n this._cachedKeys = this._cachedKeys.filter((k) => k.kid !== kid);\n return undefined;\n }\n return entry;\n }\n\n /** Protocol 66 manifest fields for offline mode */\n getManifestFields(\n offlineSinceMs?: number,\n nowMs?: number\n ): { offline_mode: boolean; offline_since_s: number } {\n if (offlineSinceMs === undefined) {\n return { offline_mode: false, offline_since_s: 0 };\n }\n const now = nowMs ?? Date.now();\n return {\n offline_mode: true,\n offline_since_s: Math.round((now - offlineSinceMs) / 1000),\n };\n }\n}\n","/**\n * RCAN Structured Fault Reporting — §16\n *\n * FAULT_REPORT (26) carries structured information about robot faults.\n * Safety-affecting faults MUST update Protocol 66 manifest.\n */\n\nimport { RCANMessage, MessageType } from \"./message.js\";\nimport { SPEC_VERSION } from \"./version.js\";\n\nexport type FaultSeverity = \"info\" | \"warning\" | \"error\" | \"critical\";\n\n/** Standard fault code taxonomy — prefixed by subsystem */\nexport enum FaultCode {\n // Sensor subsystem\n SENSOR_PROXIMITY_FAILURE = \"SENSOR_PROXIMITY_FAILURE\",\n SENSOR_CAMERA_FAILURE = \"SENSOR_CAMERA_FAILURE\",\n SENSOR_IMU_FAILURE = \"SENSOR_IMU_FAILURE\",\n // Motor subsystem\n MOTOR_OVERCURRENT = \"MOTOR_OVERCURRENT\",\n MOTOR_OVERTEMP = \"MOTOR_OVERTEMP\",\n MOTOR_STALL = \"MOTOR_STALL\",\n // Battery subsystem\n BATTERY_CRITICAL = \"BATTERY_CRITICAL\",\n BATTERY_LOW = \"BATTERY_LOW\",\n // Network subsystem\n NETWORK_TIMEOUT = \"NETWORK_TIMEOUT\",\n NETWORK_REGISTRY_UNREACHABLE = \"NETWORK_REGISTRY_UNREACHABLE\",\n // Safety subsystem\n SAFETY_ESTOP_STUCK = \"SAFETY_ESTOP_STUCK\",\n SAFETY_WATCHDOG_TIMEOUT = \"SAFETY_WATCHDOG_TIMEOUT\",\n // Generic\n UNKNOWN = \"UNKNOWN\",\n}\n\nexport interface FaultReportParams {\n faultCode: FaultCode | string;\n severity: FaultSeverity;\n subsystem: string;\n affectsSafety: boolean;\n safeToContinue: boolean;\n description?: string;\n target?: string;\n}\n\n/**\n * Build a FAULT_REPORT message.\n *\n * Mirrors rcan-py: make_fault_report()\n */\nexport function makeFaultReport(params: FaultReportParams): RCANMessage {\n return new RCANMessage({\n rcan: SPEC_VERSION,\n cmd: \"FAULT_REPORT\",\n target: params.target ?? \"rcan://local/fault\",\n params: {\n message_type: MessageType.FAULT_REPORT,\n fault_code: params.faultCode,\n severity: params.severity,\n subsystem: params.subsystem,\n affects_safety: params.affectsSafety,\n safe_to_continue: params.safeToContinue,\n description: params.description ?? \"\",\n reported_at: new Date().toISOString(),\n },\n });\n}\n\n/** §16 — Audit export request interface */\nexport interface AuditExportRequest {\n from: Date;\n to: Date;\n format: \"jsonl\" | \"csv\";\n robotRrn?: string;\n}\n","/**\n * rcan-ts — Official TypeScript SDK for RCAN v1.5\n * Robot Communication and Accountability Network\n *\n * @see https://rcan.dev\n * @see https://github.com/continuonai/rcan-ts\n */\n\nexport { RobotURI, RobotURIError } from \"./address.js\";\nexport type { RobotURIOptions } from \"./address.js\";\n\nexport { RCANMessage, RCANMessageError, MessageType, makeCloudRelayMessage, addDelegationHop, validateDelegationChain } from \"./message.js\";\nexport type { RCANMessageData, SignatureBlock, SenderType, DelegationHop } from \"./message.js\";\n\nexport { ConfidenceGate, HiTLGate, GateError } from \"./gates.js\";\nexport type { ApprovalStatus, PendingApproval } from \"./gates.js\";\n\nexport { CommitmentRecord, AuditChain, AuditError } from \"./audit.js\";\nexport type {\n CommitmentRecordData,\n CommitmentRecordJSON,\n ChainVerifyResult,\n} from \"./audit.js\";\n\nexport { validateURI, validateMessage, validateConfig } from \"./validate.js\";\nexport type { ValidationResult, RCANConfig } from \"./validate.js\";\nexport type { RCANMetadata, RCANAgentConfig, RCANMessageEnvelope } from \"./types.js\";\n\nexport {\n RCANError,\n RCANAddressError,\n RCANValidationError,\n RCANGateError,\n RCANSignatureError,\n RCANRegistryError,\n RCANNodeError,\n RCANNodeNotFoundError,\n RCANNodeSyncError,\n RCANNodeTrustError,\n // v1.5 errors\n RCANVersionIncompatibleError,\n RCANReplayAttackError,\n RCANDelegationChainError,\n RCANConfigAuthorizationError,\n} from \"./errors.js\";\n\nexport { RegistryClient } from \"./registry.js\";\nexport type {\n RobotRegistration,\n Robot,\n RegistrationResult,\n ListResult,\n} from \"./registry.js\";\n\nexport { NodeClient } from \"./node.js\";\nexport type { RCANRegistryNode, RCANResolveResult } from \"./types.js\";\n\nexport { fetchCanonicalSchema, validateConfigAgainstSchema, validateNodeAgainstSchema } from \"./schema.js\";\n\nexport {\n makeEstopMessage,\n makeStopMessage,\n makeResumeMessage,\n makeTransparencyMessage,\n isSafetyMessage,\n validateSafetyMessage,\n SAFETY_MESSAGE_TYPE,\n} from \"./safety.js\";\nexport type { SafetyMessage, SafetyEvent, TransparencyMessage } from \"./safety.js\";\n\n// ── v1.5: version ──────────────────────────────────────────────────────────────\nexport { SPEC_VERSION, validateVersionCompat } from \"./version.js\";\n\n// ── v1.5: replay attack prevention (GAP-03) ────────────────────────────────────\nexport { ReplayCache, validateReplay } from \"./replay.js\";\nexport type { ReplayCheckResult, ReplayableMessage } from \"./replay.js\";\n\n// ── v1.5: clock synchronization (GAP-04) ───────────────────────────────────────\nexport { checkClockSync, assertClockSynced, ClockDriftError } from \"./clock.js\";\nexport type { ClockSyncStatus } from \"./clock.js\";\n\n// ── v1.5: QoS (GAP-11) ────────────────────────────────────────────────────────\nexport { QoSLevel, QoSManager, QoSAckTimeoutError, makeEstopWithQoS } from \"./qos.js\";\nexport type { QoSSendOptions, QoSResult } from \"./qos.js\";\n\n// ── v1.5: config update (GAP-07) ──────────────────────────────────────────────\nexport { makeConfigUpdate, validateConfigUpdate } from \"./configUpdate.js\";\n\n// ── v1.5: key rotation (GAP-09) ───────────────────────────────────────────────\nexport { KeyStore, makeKeyRotationMessage } from \"./keys.js\";\nexport type { JWKEntry, JWKSDocument } from \"./keys.js\";\n\n// ── v1.5: consent wire (GAP-05) ───────────────────────────────────────────────\nexport {\n makeConsentRequest,\n makeConsentGrant,\n makeConsentDeny,\n validateConsentMessage,\n} from \"./consent.js\";\nexport type { ConsentType, ConsentRequestParams, ConsentResponseParams } from \"./consent.js\";\n\n// ── v1.5: revocation (GAP-02) ─────────────────────────────────────────────────\nexport {\n RevocationCache,\n checkRevocation,\n makeRevocationBroadcast,\n} from \"./revocation.js\";\nexport type { RevocationStatus, RevocationStatusValue } from \"./revocation.js\";\n\n// ── v1.5: training data consent (GAP-10) ──────────────────────────────────────\nexport {\n DataCategory,\n makeTrainingConsentRequest,\n makeTrainingConsentGrant,\n makeTrainingConsentDeny,\n validateTrainingDataMessage,\n} from \"./trainingConsent.js\";\nexport type { TrainingConsentRequestParams } from \"./trainingConsent.js\";\n\n// ── v1.5: offline mode (GAP-06) ───────────────────────────────────────────────\nexport { OfflineModeManager } from \"./offline.js\";\nexport type { OfflineState, OfflineCommandResult, CachedKey } from \"./offline.js\";\n\n// ── v1.5: fault reporting (GAP-20) ────────────────────────────────────────────\nexport { FaultCode, makeFaultReport } from \"./faultReport.js\";\nexport type { FaultSeverity, FaultReportParams, AuditExportRequest } from \"./faultReport.js\";\n\nexport const VERSION = \"0.5.0\";\n/** @deprecated Use SPEC_VERSION from ./version instead */\nexport const RCAN_VERSION = \"1.5\";\n"],"mappings":"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","names":["MessageType","data","QoSLevel","generateId","SAFETY_MESSAGE_TYPE","generateId","generateId","status","DataCategory","SAFETY_MESSAGE_TYPE","FaultCode"]}
|