@continuonai/rcan-ts 0.1.2 → 0.2.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.
@@ -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\";\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 interface RCANConfig {\n rcan_version?: string;\n metadata?: {\n manufacturer?: string;\n model?: string;\n version?: string;\n rrn?: string;\n rcan_uri?: string;\n };\n agent?: {\n provider?: string;\n model?: string;\n confidence_gates?: Array<{ threshold?: number }>;\n hitl_gates?: Array<Record<string, unknown>>;\n commitment_chain?: { enabled?: boolean };\n signing?: { enabled?: boolean };\n };\n rcan_protocol?: {\n jwt_auth?: { enabled?: boolean };\n };\n [key: string]: unknown;\n}\n\nexport function validateConfig(config: RCANConfig): ValidationResult {\n const result = makeResult();\n const meta = config.metadata ?? {};\n const agent = config.agent ?? {};\n const rcanProto = config.rcan_protocol ?? {};\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 (!config.rcan_version) warn(result, \"L1: rcan_version not declared (recommended)\");\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\";\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/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"]}
@@ -3112,9 +3112,22 @@ function validateConfig(config) {
3112
3112
  const meta = config.metadata ?? {};
3113
3113
  const agent = config.agent ?? {};
3114
3114
  const rcanProto = config.rcan_protocol ?? {};
3115
+ for (const key of ["rcan_version", "metadata", "agent"]) {
3116
+ if (!(key in config) || config[key] === void 0 || config[key] === null) {
3117
+ fail(result, `Missing required key: '${key}'`);
3118
+ }
3119
+ }
3120
+ const rv = config.rcan_version;
3121
+ if (rv) {
3122
+ if (!/^\d+\.\d+$/.test(rv)) {
3123
+ fail(result, `rcan_version '${rv}' must match pattern N.N (e.g. '1.2')`);
3124
+ }
3125
+ }
3115
3126
  if (!meta.manufacturer) fail(result, "L1: metadata.manufacturer is required (\xA72)");
3116
3127
  if (!meta.model) fail(result, "L1: metadata.model is required (\xA72)");
3117
- if (!config.rcan_version) warn(result, "L1: rcan_version not declared (recommended)");
3128
+ if (!meta.device_id && !meta.robot_name) {
3129
+ fail(result, "L1: metadata.device_id (or robot_name) is required (\xA72)");
3130
+ }
3118
3131
  if (!rcanProto.jwt_auth?.enabled) {
3119
3132
  warn(result, "L2: jwt_auth not enabled (required for L2 conformance, \xA78)");
3120
3133
  }
package/dist/rcan.iife.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var RCAN=(()=>{var G=Object.defineProperty;var gt=Object.getOwnPropertyDescriptor;var ut=Object.getOwnPropertyNames;var mt=Object.prototype.hasOwnProperty;var lt=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var ft=(n,t)=>{for(var e in t)G(n,e,{get:t[e],enumerable:!0})},ht=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ut(t))!mt.call(n,s)&&s!==e&&G(n,s,{get:()=>t[s],enumerable:!(r=gt(t,s))||r.enumerable});return n};var pt=n=>ht(G({},"__esModule",{value:!0}),n);var It={};ft(It,{AuditChain:()=>P,AuditError:()=>H,CommitmentRecord:()=>O,ConfidenceGate:()=>J,GateError:()=>x,HiTLGate:()=>E,RCANAddressError:()=>D,RCANError:()=>b,RCANGateError:()=>M,RCANMessage:()=>U,RCANMessageError:()=>f,RCANRegistryError:()=>_,RCANSignatureError:()=>B,RCANValidationError:()=>q,RCAN_VERSION:()=>wt,RegistryClient:()=>V,RobotURI:()=>I,RobotURIError:()=>w,VERSION:()=>vt,validateConfig:()=>st,validateMessage:()=>nt,validateURI:()=>rt});var w=class extends Error{constructor(t){super(t),this.name="RobotURIError"}},I=class n{registry;manufacturer;model;version;deviceId;constructor(t){this.registry=t.registry,this.manufacturer=t.manufacturer,this.model=t.model,this.version=t.version,this.deviceId=t.deviceId}static parse(t){if(!t.startsWith("rcan://"))throw new w(`URI must start with 'rcan://' \u2014 got: ${t}`);let r=t.slice(7).split("/");if(r.length!==5)throw new w(`URI must have exactly 5 path segments (registry/manufacturer/model/version/device-id) \u2014 got ${r.length} in: ${t}`);let[s,i,o,c,g]=r;for(let[d,h]of[["registry",s],["manufacturer",i],["model",o],["version",c],["device-id",g]])if(!h||h.trim()==="")throw new w(`URI segment '${d}' must not be empty`);return new n({registry:s,manufacturer:i,model:o,version:c,deviceId:g})}static build(t){let e=t.registry??"registry.rcan.dev",{manufacturer:r,model:s,version:i,deviceId:o}=t;for(let[c,g]of[["manufacturer",r],["model",s],["version",i],["deviceId",o]])if(!g||g.trim()==="")throw new w(`'${c}' must not be empty`);return new n({registry:e,manufacturer:r,model:s,version:i,deviceId:o})}toString(){return`rcan://${this.registry}/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`}get namespace(){return`${this.manufacturer}/${this.model}`}get registryUrl(){return`https://${this.registry}/registry/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`}equals(t){return this.toString()===t.toString()}toJSON(){return{uri:this.toString(),registry:this.registry,manufacturer:this.manufacturer,model:this.model,version:this.version,deviceId:this.deviceId}}};var f=class extends Error{constructor(t){super(t),this.name="RCANMessageError"}},U=class n{rcan;cmd;target;params;confidence;modelIdentity;signature;timestamp;constructor(t){if(!t.cmd||t.cmd.trim()==="")throw new f("'cmd' is required");if(!t.target)throw new f("'target' is required");if(this.rcan=t.rcan??"1.2",this.cmd=t.cmd,this.target=t.target instanceof I?t.target.toString():String(t.target),this.params=t.params??{},this.confidence=t.confidence,this.modelIdentity=t.modelIdentity??t.model_identity,this.signature=t.signature,this.timestamp=t.timestamp??new Date().toISOString(),this.confidence!==void 0&&(this.confidence<0||this.confidence>1))throw new f(`confidence must be in [0.0, 1.0] \u2014 got ${this.confidence}`)}get isSigned(){return this.signature!==void 0&&this.signature.sig!==""}get isAiDriven(){return this.confidence!==void 0}toJSON(){let t={rcan:this.rcan,cmd:this.cmd,target:this.target,timestamp:this.timestamp};return Object.keys(this.params).length>0&&(t.params=this.params),this.confidence!==void 0&&(t.confidence=this.confidence),this.modelIdentity&&(t.model_identity=this.modelIdentity),this.signature&&(t.signature=this.signature),t}toJSONString(t){return JSON.stringify(this.toJSON(),null,t)}static fromJSON(t){let e;if(typeof t=="string")try{e=JSON.parse(t)}catch{throw new f("Invalid JSON string")}else e=t;if(!e.cmd)throw new f("Missing required field: 'cmd'");if(!e.target)throw new f("Missing required field: 'target'");if(!e.rcan)throw new f("Missing required field: 'rcan'");return new n({rcan:e.rcan,cmd:e.cmd,target:e.target,params:e.params??{},confidence:e.confidence,modelIdentity:e.model_identity??e.modelIdentity,signature:e.signature,timestamp:e.timestamp})}};function j(){if(typeof globalThis.crypto<"u"&&typeof globalThis.crypto.randomUUID=="function")return globalThis.crypto.randomUUID();try{let{randomUUID:n}=lt("crypto");return n()}catch{return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let t=Math.random()*16|0;return(n==="x"?t:t&3|8).toString(16)})}}function Q(n,t){return typeof process<"u",xt(n,t)}function z(n){let t=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],e=1779033703,r=3144134277,s=1013904242,i=2773480762,o=1359893119,c=2600822924,g=528734635,d=1541459225,it=n.length*8,y=[...n];for(y.push(128);y.length%64!==56;)y.push(0);for(let l=7;l>=0;l--)y.push(it/Math.pow(2,l*8)&255);for(let l=0;l<y.length;l+=64){let u=[];for(let a=0;a<16;a++)u[a]=y[l+a*4]<<24|y[l+a*4+1]<<16|y[l+a*4+2]<<8|y[l+a*4+3];for(let a=16;a<64;a++){let W=p(u[a-15],7)^p(u[a-15],18)^u[a-15]>>>3,F=p(u[a-2],17)^p(u[a-2],19)^u[a-2]>>>10;u[a]=u[a-16]+W+u[a-7]+F>>>0}let[R,k,N,K,v,$,L,T]=[e,r,s,i,o,c,g,d];for(let a=0;a<64;a++){let W=p(v,6)^p(v,11)^p(v,25),F=v&$^~v&L,Z=T+W+F+t[a]+u[a]>>>0,at=p(R,2)^p(R,13)^p(R,22),ct=R&k^R&N^k&N,dt=at+ct>>>0;[T,L,$,v,K,N,k,R]=[L,$,v,K+Z>>>0,N,k,R,Z+dt>>>0]}e=e+R>>>0,r=r+k>>>0,s=s+N>>>0,i=i+K>>>0,o=o+v>>>0,c=c+$>>>0,g=g+L>>>0,d=d+T>>>0}let Y=new Uint8Array(32),ot=new DataView(Y.buffer);return[e,r,s,i,o,c,g,d].forEach((l,u)=>ot.setUint32(u*4,l)),Y}function p(n,t){return n>>>t|n<<32-t}function tt(n){if(typeof TextEncoder<"u")return new TextEncoder().encode(n);let t=new Uint8Array(n.length);for(let e=0;e<n.length;e++)t[e]=n.charCodeAt(e)&255;return t}function yt(n){return Array.from(n).map(t=>t.toString(16).padStart(2,"0")).join("")}function xt(n,t){let r=tt(n);r.length>64&&(r=z(r));let s=new Uint8Array(64),i=new Uint8Array(64);for(let h=0;h<64;h++)s[h]=(r[h]??0)^54,i[h]=(r[h]??0)^92;let o=tt(t),c=new Uint8Array(64+o.length);c.set(s),c.set(o,64);let g=z(c),d=new Uint8Array(96);return d.set(i),d.set(g,64),yt(z(d))}var x=class extends Error{constructor(t){super(t),this.name="GateError"}},J=class{threshold;constructor(t=.8){if(t<0||t>1)throw new x(`threshold must be in [0.0, 1.0] \u2014 got ${t}`);this.threshold=t}allows(t){return t>=this.threshold}margin(t){return t-this.threshold}assert(t,e){if(!this.allows(t)){let r=e?` for action '${e}'`:"";throw new x(`Confidence ${t}${r} is below threshold ${this.threshold}`)}}},E=class{_pending=new Map;request(t,e={}){let r=j();return this._pending.set(r,{token:r,action:t,context:e,createdAt:new Date().toISOString(),status:"pending"}),r}approve(t){let e=this._pending.get(t);if(!e)throw new x(`Unknown token: ${t}`);e.status="approved"}deny(t,e){let r=this._pending.get(t);if(!r)throw new x(`Unknown token: ${t}`);r.status="denied",e&&(r.reason=e)}check(t){let e=this._pending.get(t);if(!e)throw new x(`Unknown token: ${t}`);return e.status}get pendingApprovals(){return Array.from(this._pending.values()).filter(t=>t.status==="pending")}getApproval(t){return this._pending.get(t)}clearResolved(){for(let[t,e]of this._pending.entries())e.status!=="pending"&&this._pending.delete(t)}};var H=class extends Error{constructor(t){super(t),this.name="AuditError"}};function bt(n,t,e,r,s){let i=JSON.stringify({recordId:n,action:t,robotUri:e,timestamp:r,params:s},Object.keys({recordId:n,action:t,robotUri:e,timestamp:r,params:s}).sort());return Q("rcan-content-hash",i)}function et(n,t){let{hmac:e,...r}=t,s=JSON.stringify(r,Object.keys(r).sort());return Q(n,s)}var O=class n{recordId;action;robotUri;confidence;modelIdentity;params;safetyApproved;timestamp;contentHash;previousHash;hmac;constructor(t){this.recordId=t.recordId,this.action=t.action,this.robotUri=t.robotUri,this.confidence=t.confidence,this.modelIdentity=t.modelIdentity,this.params=t.params,this.safetyApproved=t.safetyApproved,this.timestamp=t.timestamp,this.contentHash=t.contentHash,this.previousHash=t.previousHash,this.hmac=t.hmac}static create(t,e,r=null){let s=j(),i=new Date().toISOString(),o=t.params??{},c=t.robotUri??"",g=bt(s,t.action,c,i,o),d={recordId:s,action:t.action,robotUri:c,confidence:t.confidence,modelIdentity:t.modelIdentity,params:o,safetyApproved:t.safetyApproved??!0,timestamp:i,contentHash:g,previousHash:r,hmac:""};return d.hmac=et(e,d),new n(d)}verify(t){return et(t,this.toJSON())===this.hmac}toJSON(){return{recordId:this.recordId,action:this.action,robotUri:this.robotUri,confidence:this.confidence,modelIdentity:this.modelIdentity,params:this.params,safetyApproved:this.safetyApproved,timestamp:this.timestamp,contentHash:this.contentHash,previousHash:this.previousHash,hmac:this.hmac}}static fromJSON(t){return new n(t)}},P=class n{_records=[];_secret;constructor(t){this._secret=t}get records(){return this._records}append(t){let r=this._records[this._records.length-1]?.contentHash??null,s=O.create(t,this._secret,r);return this._records.push(s),s}verifyAll(){let t=[],e=null;for(let r of this._records)r.verify(this._secret)||t.push(`HMAC invalid for record ${r.recordId.slice(0,8)}`),e!==null&&r.previousHash!==e&&t.push(`Chain broken at ${r.recordId.slice(0,8)}: expected prev=${e.slice(0,12)}`),e=r.contentHash;return{valid:t.length===0,count:this._records.length,errors:t}}toJSONL(){return this._records.map(t=>JSON.stringify(t.toJSON())).join(`
1
+ "use strict";var RCAN=(()=>{var G=Object.defineProperty;var gt=Object.getOwnPropertyDescriptor;var ut=Object.getOwnPropertyNames;var mt=Object.prototype.hasOwnProperty;var ft=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var lt=(n,t)=>{for(var e in t)G(n,e,{get:t[e],enumerable:!0})},pt=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ut(t))!mt.call(n,s)&&s!==e&&G(n,s,{get:()=>t[s],enumerable:!(r=gt(t,s))||r.enumerable});return n};var ht=n=>pt(G({},"__esModule",{value:!0}),n);var At={};lt(At,{AuditChain:()=>P,AuditError:()=>H,CommitmentRecord:()=>_,ConfidenceGate:()=>J,GateError:()=>b,HiTLGate:()=>E,RCANAddressError:()=>M,RCANError:()=>R,RCANGateError:()=>D,RCANMessage:()=>O,RCANMessageError:()=>p,RCANRegistryError:()=>U,RCANSignatureError:()=>B,RCANValidationError:()=>q,RCAN_VERSION:()=>wt,RegistryClient:()=>T,RobotURI:()=>I,RobotURIError:()=>A,VERSION:()=>vt,validateConfig:()=>st,validateMessage:()=>nt,validateURI:()=>rt});var A=class extends Error{constructor(t){super(t),this.name="RobotURIError"}},I=class n{registry;manufacturer;model;version;deviceId;constructor(t){this.registry=t.registry,this.manufacturer=t.manufacturer,this.model=t.model,this.version=t.version,this.deviceId=t.deviceId}static parse(t){if(!t.startsWith("rcan://"))throw new A(`URI must start with 'rcan://' \u2014 got: ${t}`);let r=t.slice(7).split("/");if(r.length!==5)throw new A(`URI must have exactly 5 path segments (registry/manufacturer/model/version/device-id) \u2014 got ${r.length} in: ${t}`);let[s,i,o,a,u]=r;for(let[d,g]of[["registry",s],["manufacturer",i],["model",o],["version",a],["device-id",u]])if(!g||g.trim()==="")throw new A(`URI segment '${d}' must not be empty`);return new n({registry:s,manufacturer:i,model:o,version:a,deviceId:u})}static build(t){let e=t.registry??"registry.rcan.dev",{manufacturer:r,model:s,version:i,deviceId:o}=t;for(let[a,u]of[["manufacturer",r],["model",s],["version",i],["deviceId",o]])if(!u||u.trim()==="")throw new A(`'${a}' must not be empty`);return new n({registry:e,manufacturer:r,model:s,version:i,deviceId:o})}toString(){return`rcan://${this.registry}/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`}get namespace(){return`${this.manufacturer}/${this.model}`}get registryUrl(){return`https://${this.registry}/registry/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`}equals(t){return this.toString()===t.toString()}toJSON(){return{uri:this.toString(),registry:this.registry,manufacturer:this.manufacturer,model:this.model,version:this.version,deviceId:this.deviceId}}};var p=class extends Error{constructor(t){super(t),this.name="RCANMessageError"}},O=class n{rcan;cmd;target;params;confidence;modelIdentity;signature;timestamp;constructor(t){if(!t.cmd||t.cmd.trim()==="")throw new p("'cmd' is required");if(!t.target)throw new p("'target' is required");if(this.rcan=t.rcan??"1.2",this.cmd=t.cmd,this.target=t.target instanceof I?t.target.toString():String(t.target),this.params=t.params??{},this.confidence=t.confidence,this.modelIdentity=t.modelIdentity??t.model_identity,this.signature=t.signature,this.timestamp=t.timestamp??new Date().toISOString(),this.confidence!==void 0&&(this.confidence<0||this.confidence>1))throw new p(`confidence must be in [0.0, 1.0] \u2014 got ${this.confidence}`)}get isSigned(){return this.signature!==void 0&&this.signature.sig!==""}get isAiDriven(){return this.confidence!==void 0}toJSON(){let t={rcan:this.rcan,cmd:this.cmd,target:this.target,timestamp:this.timestamp};return Object.keys(this.params).length>0&&(t.params=this.params),this.confidence!==void 0&&(t.confidence=this.confidence),this.modelIdentity&&(t.model_identity=this.modelIdentity),this.signature&&(t.signature=this.signature),t}toJSONString(t){return JSON.stringify(this.toJSON(),null,t)}static fromJSON(t){let e;if(typeof t=="string")try{e=JSON.parse(t)}catch{throw new p("Invalid JSON string")}else e=t;if(!e.cmd)throw new p("Missing required field: 'cmd'");if(!e.target)throw new p("Missing required field: 'target'");if(!e.rcan)throw new p("Missing required field: 'rcan'");return new n({rcan:e.rcan,cmd:e.cmd,target:e.target,params:e.params??{},confidence:e.confidence,modelIdentity:e.model_identity??e.modelIdentity,signature:e.signature,timestamp:e.timestamp})}};function j(){if(typeof globalThis.crypto<"u"&&typeof globalThis.crypto.randomUUID=="function")return globalThis.crypto.randomUUID();try{let{randomUUID:n}=ft("crypto");return n()}catch{return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let t=Math.random()*16|0;return(n==="x"?t:t&3|8).toString(16)})}}function Q(n,t){return typeof process<"u",xt(n,t)}function z(n){let t=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],e=1779033703,r=3144134277,s=1013904242,i=2773480762,o=1359893119,a=2600822924,u=528734635,d=1541459225,it=n.length*8,x=[...n];for(x.push(128);x.length%64!==56;)x.push(0);for(let l=7;l>=0;l--)x.push(it/Math.pow(2,l*8)&255);for(let l=0;l<x.length;l+=64){let m=[];for(let c=0;c<16;c++)m[c]=x[l+c*4]<<24|x[l+c*4+1]<<16|x[l+c*4+2]<<8|x[l+c*4+3];for(let c=16;c<64;c++){let W=h(m[c-15],7)^h(m[c-15],18)^m[c-15]>>>3,F=h(m[c-2],17)^h(m[c-2],19)^m[c-2]>>>10;m[c]=m[c-16]+W+m[c-7]+F>>>0}let[v,N,k,V,w,$,L,K]=[e,r,s,i,o,a,u,d];for(let c=0;c<64;c++){let W=h(w,6)^h(w,11)^h(w,25),F=w&$^~w&L,Z=K+W+F+t[c]+m[c]>>>0,at=h(v,2)^h(v,13)^h(v,22),ct=v&N^v&k^N&k,dt=at+ct>>>0;[K,L,$,w,V,k,N,v]=[L,$,w,V+Z>>>0,k,N,v,Z+dt>>>0]}e=e+v>>>0,r=r+N>>>0,s=s+k>>>0,i=i+V>>>0,o=o+w>>>0,a=a+$>>>0,u=u+L>>>0,d=d+K>>>0}let Y=new Uint8Array(32),ot=new DataView(Y.buffer);return[e,r,s,i,o,a,u,d].forEach((l,m)=>ot.setUint32(m*4,l)),Y}function h(n,t){return n>>>t|n<<32-t}function tt(n){if(typeof TextEncoder<"u")return new TextEncoder().encode(n);let t=new Uint8Array(n.length);for(let e=0;e<n.length;e++)t[e]=n.charCodeAt(e)&255;return t}function yt(n){return Array.from(n).map(t=>t.toString(16).padStart(2,"0")).join("")}function xt(n,t){let r=tt(n);r.length>64&&(r=z(r));let s=new Uint8Array(64),i=new Uint8Array(64);for(let g=0;g<64;g++)s[g]=(r[g]??0)^54,i[g]=(r[g]??0)^92;let o=tt(t),a=new Uint8Array(64+o.length);a.set(s),a.set(o,64);let u=z(a),d=new Uint8Array(96);return d.set(i),d.set(u,64),yt(z(d))}var b=class extends Error{constructor(t){super(t),this.name="GateError"}},J=class{threshold;constructor(t=.8){if(t<0||t>1)throw new b(`threshold must be in [0.0, 1.0] \u2014 got ${t}`);this.threshold=t}allows(t){return t>=this.threshold}margin(t){return t-this.threshold}assert(t,e){if(!this.allows(t)){let r=e?` for action '${e}'`:"";throw new b(`Confidence ${t}${r} is below threshold ${this.threshold}`)}}},E=class{_pending=new Map;request(t,e={}){let r=j();return this._pending.set(r,{token:r,action:t,context:e,createdAt:new Date().toISOString(),status:"pending"}),r}approve(t){let e=this._pending.get(t);if(!e)throw new b(`Unknown token: ${t}`);e.status="approved"}deny(t,e){let r=this._pending.get(t);if(!r)throw new b(`Unknown token: ${t}`);r.status="denied",e&&(r.reason=e)}check(t){let e=this._pending.get(t);if(!e)throw new b(`Unknown token: ${t}`);return e.status}get pendingApprovals(){return Array.from(this._pending.values()).filter(t=>t.status==="pending")}getApproval(t){return this._pending.get(t)}clearResolved(){for(let[t,e]of this._pending.entries())e.status!=="pending"&&this._pending.delete(t)}};var H=class extends Error{constructor(t){super(t),this.name="AuditError"}};function bt(n,t,e,r,s){let i=JSON.stringify({recordId:n,action:t,robotUri:e,timestamp:r,params:s},Object.keys({recordId:n,action:t,robotUri:e,timestamp:r,params:s}).sort());return Q("rcan-content-hash",i)}function et(n,t){let{hmac:e,...r}=t,s=JSON.stringify(r,Object.keys(r).sort());return Q(n,s)}var _=class n{recordId;action;robotUri;confidence;modelIdentity;params;safetyApproved;timestamp;contentHash;previousHash;hmac;constructor(t){this.recordId=t.recordId,this.action=t.action,this.robotUri=t.robotUri,this.confidence=t.confidence,this.modelIdentity=t.modelIdentity,this.params=t.params,this.safetyApproved=t.safetyApproved,this.timestamp=t.timestamp,this.contentHash=t.contentHash,this.previousHash=t.previousHash,this.hmac=t.hmac}static create(t,e,r=null){let s=j(),i=new Date().toISOString(),o=t.params??{},a=t.robotUri??"",u=bt(s,t.action,a,i,o),d={recordId:s,action:t.action,robotUri:a,confidence:t.confidence,modelIdentity:t.modelIdentity,params:o,safetyApproved:t.safetyApproved??!0,timestamp:i,contentHash:u,previousHash:r,hmac:""};return d.hmac=et(e,d),new n(d)}verify(t){return et(t,this.toJSON())===this.hmac}toJSON(){return{recordId:this.recordId,action:this.action,robotUri:this.robotUri,confidence:this.confidence,modelIdentity:this.modelIdentity,params:this.params,safetyApproved:this.safetyApproved,timestamp:this.timestamp,contentHash:this.contentHash,previousHash:this.previousHash,hmac:this.hmac}}static fromJSON(t){return new n(t)}},P=class n{_records=[];_secret;constructor(t){this._secret=t}get records(){return this._records}append(t){let r=this._records[this._records.length-1]?.contentHash??null,s=_.create(t,this._secret,r);return this._records.push(s),s}verifyAll(){let t=[],e=null;for(let r of this._records)r.verify(this._secret)||t.push(`HMAC invalid for record ${r.recordId.slice(0,8)}`),e!==null&&r.previousHash!==e&&t.push(`Chain broken at ${r.recordId.slice(0,8)}: expected prev=${e.slice(0,12)}`),e=r.contentHash;return{valid:t.length===0,count:this._records.length,errors:t}}toJSONL(){return this._records.map(t=>JSON.stringify(t.toJSON())).join(`
2
2
  `)+`
3
3
  `}static fromJSONL(t,e){let r=new n(e),s=t.trim().split(`
4
- `).filter(i=>i.trim()!=="");for(let i of s){let o=JSON.parse(i);r._records.push(O.fromJSON(o))}return r}};function X(){return{ok:!0,issues:[],warnings:[],info:[]}}function C(n,t){n.ok=!1,n.issues.push(t)}function A(n,t){n.warnings.push(t)}function m(n,t){n.info.push(t)}function rt(n){let t=X();try{let e=I.parse(n);m(t,"\u2705 Valid RCAN URI"),m(t,` Registry: ${e.registry}`),m(t,` Manufacturer: ${e.manufacturer}`),m(t,` Model: ${e.model}`),m(t,` Version: ${e.version}`),m(t,` Device ID: ${e.deviceId}`)}catch(e){C(t,`Invalid RCAN URI: ${e instanceof Error?e.message:e}`)}return t}function nt(n){let t=X(),e;if(typeof n=="string")try{e=JSON.parse(n)}catch{return C(t,"Invalid JSON string"),t}else if(typeof n=="object"&&n!==null)e=n;else return C(t,"Expected object or JSON string"),t;for(let r of["rcan","cmd","target"])(!(r in e)||!e[r])&&C(t,`Missing required field: '${r}'`);if(!t.ok)return t;try{let r=U.fromJSON(e);m(t,`\u2705 RCAN message valid (v${r.rcan})`),m(t,` cmd: ${r.cmd}`),m(t,` target: ${r.target}`),r.confidence!==void 0?m(t,` confidence: ${r.confidence}`):A(t,"No confidence score \u2014 add for RCAN \xA716 AI accountability"),r.isSigned?m(t,` signature: alg=${r.signature?.alg}, kid=${r.signature?.kid}`):A(t,"Message is unsigned (recommended for production)")}catch(r){C(t,`Message validation failed: ${r instanceof Error?r.message:r}`)}return t}function st(n){let t=X(),e=n.metadata??{},r=n.agent??{},s=n.rcan_protocol??{};if(e.manufacturer||C(t,"L1: metadata.manufacturer is required (\xA72)"),e.model||C(t,"L1: metadata.model is required (\xA72)"),n.rcan_version||A(t,"L1: rcan_version not declared (recommended)"),s.jwt_auth?.enabled||A(t,"L2: jwt_auth not enabled (required for L2 conformance, \xA78)"),(!r.confidence_gates||r.confidence_gates.length===0)&&A(t,"L2: confidence_gates not configured (\xA716)"),(!r.hitl_gates||r.hitl_gates.length===0)&&A(t,"L3: hitl_gates not configured (\xA716)"),r.commitment_chain?.enabled||A(t,"L3: commitment_chain not enabled (\xA716)"),e.rrn?m(t,`\u2705 RRN registered: ${e.rrn}`):A(t,"Robot not registered \u2014 visit rcan.dev/registry/register"),t.ok&&t.issues.length===0){let i=!t.warnings.some(d=>d.startsWith("L1")),o=i&&!t.warnings.some(d=>d.startsWith("L2")),g=o&&!t.warnings.some(d=>d.startsWith("L3"))?"L3":o?"L2":i?"L1":"FAIL";m(t,`\u2705 Config valid \u2014 conformance level: ${g}`)}return t}var b=class extends Error{constructor(t){super(t),this.name="RCANError",Object.setPrototypeOf(this,new.target.prototype)}},D=class extends b{constructor(t){super(t),this.name="RCANAddressError",Object.setPrototypeOf(this,new.target.prototype)}},q=class extends b{constructor(t){super(t),this.name="RCANValidationError",Object.setPrototypeOf(this,new.target.prototype)}},M=class extends b{constructor(e,r,s,i){super(e);this.gateType=r;this.value=s;this.threshold=i;this.name="RCANGateError",Object.setPrototypeOf(this,new.target.prototype)}},B=class extends b{constructor(t){super(t),this.name="RCANSignatureError",Object.setPrototypeOf(this,new.target.prototype)}},_=class extends b{constructor(t){super(t),this.name="RCANRegistryError",Object.setPrototypeOf(this,new.target.prototype)}};var Rt="https://rcan-spec.pages.dev",V=class{baseUrl;apiKey;timeout;constructor(t){this.baseUrl=(t?.baseUrl??Rt).replace(/\/$/,""),this.apiKey=t?.apiKey,this.timeout=t?.timeout??1e4}async _fetch(t,e={}){let r=`${this.baseUrl}${t}`,s=new AbortController,i=setTimeout(()=>s.abort(),this.timeout);try{return await fetch(r,{...e,signal:s.signal,headers:{"Content-Type":"application/json",...e.headers??{}}})}finally{clearTimeout(i)}}_authHeaders(){if(!this.apiKey)throw new _("API key required for write operations. Pass apiKey to RegistryClient.");return{Authorization:`Bearer ${this.apiKey}`}}async _checkResponse(t){if(!t.ok){let e=`Registry API error: ${t.status}`;try{let r=await t.json();r?.error&&(e=r.error)}catch{}throw new _(e)}return await t.json()}async register(t){let e=await this._fetch("/api/v1/robots",{method:"POST",body:JSON.stringify(t)});return this._checkResponse(e)}async get(t){let e=await this._fetch(`/api/v1/robots/${encodeURIComponent(t)}`);return this._checkResponse(e)}async list(t){let e=new URLSearchParams;t?.limit!==void 0&&e.set("limit",String(t.limit)),t?.offset!==void 0&&e.set("offset",String(t.offset)),t?.tier&&e.set("tier",t.tier);let r=e.toString()?`?${e}`:"",s=await this._fetch(`/api/v1/robots${r}`);return this._checkResponse(s)}async patch(t,e){let r=await this._fetch(`/api/v1/robots/${encodeURIComponent(t)}`,{method:"PATCH",headers:this._authHeaders(),body:JSON.stringify(e)});return this._checkResponse(r)}async delete(t){let e=await this._fetch(`/api/v1/robots/${encodeURIComponent(t)}`,{method:"DELETE",headers:this._authHeaders()});e.ok||await this._checkResponse(e)}async search(t){let e=new URLSearchParams;t.q&&e.set("q",t.q),t.manufacturer&&e.set("manufacturer",t.manufacturer),t.model&&e.set("model",t.model),t.tier&&e.set("tier",t.tier);let r=e.toString()?`?${e}`:"",s=await this._fetch(`/api/v1/robots/search${r}`);if(!s.ok){let o=await this._fetch(`/api/v1/robots${r}`),c=await this._checkResponse(o);return"robots"in c?c.robots:"results"in c&&c.results?c.results:[]}let i=await s.json();return Array.isArray(i)?i:"results"in i&&i.results?i.results:"robots"in i?i.robots:[]}};var vt="0.1.0",wt="1.2";return pt(It);})();
4
+ `).filter(i=>i.trim()!=="");for(let i of s){let o=JSON.parse(i);r._records.push(_.fromJSON(o))}return r}};function X(){return{ok:!0,issues:[],warnings:[],info:[]}}function y(n,t){n.ok=!1,n.issues.push(t)}function C(n,t){n.warnings.push(t)}function f(n,t){n.info.push(t)}function rt(n){let t=X();try{let e=I.parse(n);f(t,"\u2705 Valid RCAN URI"),f(t,` Registry: ${e.registry}`),f(t,` Manufacturer: ${e.manufacturer}`),f(t,` Model: ${e.model}`),f(t,` Version: ${e.version}`),f(t,` Device ID: ${e.deviceId}`)}catch(e){y(t,`Invalid RCAN URI: ${e instanceof Error?e.message:e}`)}return t}function nt(n){let t=X(),e;if(typeof n=="string")try{e=JSON.parse(n)}catch{return y(t,"Invalid JSON string"),t}else if(typeof n=="object"&&n!==null)e=n;else return y(t,"Expected object or JSON string"),t;for(let r of["rcan","cmd","target"])(!(r in e)||!e[r])&&y(t,`Missing required field: '${r}'`);if(!t.ok)return t;try{let r=O.fromJSON(e);f(t,`\u2705 RCAN message valid (v${r.rcan})`),f(t,` cmd: ${r.cmd}`),f(t,` target: ${r.target}`),r.confidence!==void 0?f(t,` confidence: ${r.confidence}`):C(t,"No confidence score \u2014 add for RCAN \xA716 AI accountability"),r.isSigned?f(t,` signature: alg=${r.signature?.alg}, kid=${r.signature?.kid}`):C(t,"Message is unsigned (recommended for production)")}catch(r){y(t,`Message validation failed: ${r instanceof Error?r.message:r}`)}return t}function st(n){let t=X(),e=n.metadata??{},r=n.agent??{},s=n.rcan_protocol??{};for(let o of["rcan_version","metadata","agent"])(!(o in n)||n[o]===void 0||n[o]===null)&&y(t,`Missing required key: '${o}'`);let i=n.rcan_version;if(i&&(/^\d+\.\d+$/.test(i)||y(t,`rcan_version '${i}' must match pattern N.N (e.g. '1.2')`)),e.manufacturer||y(t,"L1: metadata.manufacturer is required (\xA72)"),e.model||y(t,"L1: metadata.model is required (\xA72)"),!e.device_id&&!e.robot_name&&y(t,"L1: metadata.device_id (or robot_name) is required (\xA72)"),s.jwt_auth?.enabled||C(t,"L2: jwt_auth not enabled (required for L2 conformance, \xA78)"),(!r.confidence_gates||r.confidence_gates.length===0)&&C(t,"L2: confidence_gates not configured (\xA716)"),(!r.hitl_gates||r.hitl_gates.length===0)&&C(t,"L3: hitl_gates not configured (\xA716)"),r.commitment_chain?.enabled||C(t,"L3: commitment_chain not enabled (\xA716)"),e.rrn?f(t,`\u2705 RRN registered: ${e.rrn}`):C(t,"Robot not registered \u2014 visit rcan.dev/registry/register"),t.ok&&t.issues.length===0){let o=!t.warnings.some(g=>g.startsWith("L1")),a=o&&!t.warnings.some(g=>g.startsWith("L2")),d=a&&!t.warnings.some(g=>g.startsWith("L3"))?"L3":a?"L2":o?"L1":"FAIL";f(t,`\u2705 Config valid \u2014 conformance level: ${d}`)}return t}var R=class extends Error{constructor(t){super(t),this.name="RCANError",Object.setPrototypeOf(this,new.target.prototype)}},M=class extends R{constructor(t){super(t),this.name="RCANAddressError",Object.setPrototypeOf(this,new.target.prototype)}},q=class extends R{constructor(t){super(t),this.name="RCANValidationError",Object.setPrototypeOf(this,new.target.prototype)}},D=class extends R{constructor(e,r,s,i){super(e);this.gateType=r;this.value=s;this.threshold=i;this.name="RCANGateError",Object.setPrototypeOf(this,new.target.prototype)}},B=class extends R{constructor(t){super(t),this.name="RCANSignatureError",Object.setPrototypeOf(this,new.target.prototype)}},U=class extends R{constructor(t){super(t),this.name="RCANRegistryError",Object.setPrototypeOf(this,new.target.prototype)}};var Rt="https://rcan-spec.pages.dev",T=class{baseUrl;apiKey;timeout;constructor(t){this.baseUrl=(t?.baseUrl??Rt).replace(/\/$/,""),this.apiKey=t?.apiKey,this.timeout=t?.timeout??1e4}async _fetch(t,e={}){let r=`${this.baseUrl}${t}`,s=new AbortController,i=setTimeout(()=>s.abort(),this.timeout);try{return await fetch(r,{...e,signal:s.signal,headers:{"Content-Type":"application/json",...e.headers??{}}})}finally{clearTimeout(i)}}_authHeaders(){if(!this.apiKey)throw new U("API key required for write operations. Pass apiKey to RegistryClient.");return{Authorization:`Bearer ${this.apiKey}`}}async _checkResponse(t){if(!t.ok){let e=`Registry API error: ${t.status}`;try{let r=await t.json();r?.error&&(e=r.error)}catch{}throw new U(e)}return await t.json()}async register(t){let e=await this._fetch("/api/v1/robots",{method:"POST",body:JSON.stringify(t)});return this._checkResponse(e)}async get(t){let e=await this._fetch(`/api/v1/robots/${encodeURIComponent(t)}`);return this._checkResponse(e)}async list(t){let e=new URLSearchParams;t?.limit!==void 0&&e.set("limit",String(t.limit)),t?.offset!==void 0&&e.set("offset",String(t.offset)),t?.tier&&e.set("tier",t.tier);let r=e.toString()?`?${e}`:"",s=await this._fetch(`/api/v1/robots${r}`);return this._checkResponse(s)}async patch(t,e){let r=await this._fetch(`/api/v1/robots/${encodeURIComponent(t)}`,{method:"PATCH",headers:this._authHeaders(),body:JSON.stringify(e)});return this._checkResponse(r)}async delete(t){let e=await this._fetch(`/api/v1/robots/${encodeURIComponent(t)}`,{method:"DELETE",headers:this._authHeaders()});e.ok||await this._checkResponse(e)}async search(t){let e=new URLSearchParams;t.q&&e.set("q",t.q),t.manufacturer&&e.set("manufacturer",t.manufacturer),t.model&&e.set("model",t.model),t.tier&&e.set("tier",t.tier);let r=e.toString()?`?${e}`:"",s=await this._fetch(`/api/v1/robots/search${r}`);if(!s.ok){let o=await this._fetch(`/api/v1/robots${r}`),a=await this._checkResponse(o);return"robots"in a?a.robots:"results"in a&&a.results?a.results:[]}let i=await s.json();return Array.isArray(i)?i:"results"in i&&i.results?i.results:"robots"in i?i.robots:[]}};var vt="0.1.0",wt="1.2";return ht(At);})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@continuonai/rcan-ts",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Official TypeScript SDK for the RCAN v1.2 robot communication protocol",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",