@continuonai/rcan-ts 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -0
- package/dist/browser.d.mts +353 -0
- package/dist/browser.mjs +888 -0
- package/dist/browser.mjs.map +1 -0
- package/dist/index.d.mts +353 -0
- package/dist/index.d.ts +353 -0
- package/dist/index.js +924 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +883 -0
- package/dist/index.mjs.map +1 -0
- package/dist/rcan-validate.js +3593 -0
- package/package.json +66 -0
|
@@ -0,0 +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"]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RCAN Robot URI — addressing scheme for RCAN v1.2.
|
|
3
|
+
*
|
|
4
|
+
* Format: rcan://<registry>/<manufacturer>/<model>/<version>/<device-id>
|
|
5
|
+
* Example: rcan://registry.rcan.dev/acme/robotarm/v2/unit-001
|
|
6
|
+
*/
|
|
7
|
+
declare class RobotURIError extends Error {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
10
|
+
interface RobotURIOptions {
|
|
11
|
+
manufacturer: string;
|
|
12
|
+
model: string;
|
|
13
|
+
version: string;
|
|
14
|
+
deviceId: string;
|
|
15
|
+
registry?: string;
|
|
16
|
+
}
|
|
17
|
+
declare class RobotURI {
|
|
18
|
+
readonly registry: string;
|
|
19
|
+
readonly manufacturer: string;
|
|
20
|
+
readonly model: string;
|
|
21
|
+
readonly version: string;
|
|
22
|
+
readonly deviceId: string;
|
|
23
|
+
private constructor();
|
|
24
|
+
/** Parse a RCAN URI string. Throws RobotURIError on invalid input. */
|
|
25
|
+
static parse(uri: string): RobotURI;
|
|
26
|
+
/** Build a RCAN URI from components. */
|
|
27
|
+
static build(opts: RobotURIOptions): RobotURI;
|
|
28
|
+
/** Full URI string: rcan://registry/manufacturer/model/version/device-id */
|
|
29
|
+
toString(): string;
|
|
30
|
+
/** Short namespace: manufacturer/model */
|
|
31
|
+
get namespace(): string;
|
|
32
|
+
/** HTTPS registry URL for this robot */
|
|
33
|
+
get registryUrl(): string;
|
|
34
|
+
/** Check if two URIs refer to the same robot */
|
|
35
|
+
equals(other: RobotURI): boolean;
|
|
36
|
+
toJSON(): object;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* RCAN Message — command envelope for RCAN v1.2.
|
|
41
|
+
*
|
|
42
|
+
* A RCANMessage wraps a robot command with:
|
|
43
|
+
* - RCAN protocol version
|
|
44
|
+
* - Target Robot URI
|
|
45
|
+
* - Command name and parameters
|
|
46
|
+
* - Optional AI confidence score (§16)
|
|
47
|
+
* - Optional model identity (§16)
|
|
48
|
+
* - Optional Ed25519 signature
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
interface SignatureBlock {
|
|
52
|
+
alg: string;
|
|
53
|
+
kid: string;
|
|
54
|
+
sig: string;
|
|
55
|
+
}
|
|
56
|
+
interface RCANMessageData {
|
|
57
|
+
rcan?: string;
|
|
58
|
+
cmd: string;
|
|
59
|
+
target: string | RobotURI;
|
|
60
|
+
params?: Record<string, unknown>;
|
|
61
|
+
confidence?: number;
|
|
62
|
+
modelIdentity?: string;
|
|
63
|
+
model_identity?: string;
|
|
64
|
+
signature?: SignatureBlock;
|
|
65
|
+
timestamp?: string;
|
|
66
|
+
[key: string]: unknown;
|
|
67
|
+
}
|
|
68
|
+
declare class RCANMessageError extends Error {
|
|
69
|
+
constructor(message: string);
|
|
70
|
+
}
|
|
71
|
+
declare class RCANMessage {
|
|
72
|
+
readonly rcan: string;
|
|
73
|
+
readonly cmd: string;
|
|
74
|
+
readonly target: string;
|
|
75
|
+
readonly params: Record<string, unknown>;
|
|
76
|
+
readonly confidence: number | undefined;
|
|
77
|
+
readonly modelIdentity: string | undefined;
|
|
78
|
+
readonly signature: SignatureBlock | undefined;
|
|
79
|
+
readonly timestamp: string;
|
|
80
|
+
constructor(data: RCANMessageData);
|
|
81
|
+
/** Whether this message has a signature block */
|
|
82
|
+
get isSigned(): boolean;
|
|
83
|
+
/** Whether this message was generated by an AI model (has confidence score) */
|
|
84
|
+
get isAiDriven(): boolean;
|
|
85
|
+
/** Serialize to a plain object */
|
|
86
|
+
toJSON(): Record<string, unknown>;
|
|
87
|
+
/** Serialize to JSON string */
|
|
88
|
+
toJSONString(indent?: number): string;
|
|
89
|
+
/** Parse from a plain object or JSON string */
|
|
90
|
+
static fromJSON(data: string | Record<string, unknown>): RCANMessage;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* RCAN Safety Gates — confidence and human-in-the-loop gating (§16).
|
|
95
|
+
*/
|
|
96
|
+
declare class GateError extends Error {
|
|
97
|
+
constructor(message: string);
|
|
98
|
+
}
|
|
99
|
+
declare class ConfidenceGate {
|
|
100
|
+
readonly threshold: number;
|
|
101
|
+
constructor(threshold?: number);
|
|
102
|
+
/** Returns true if the confidence score meets the threshold. */
|
|
103
|
+
allows(confidence: number): boolean;
|
|
104
|
+
/** Returns the margin (positive = allowed, negative = blocked). */
|
|
105
|
+
margin(confidence: number): number;
|
|
106
|
+
/** Throw if confidence is below threshold. */
|
|
107
|
+
assert(confidence: number, action?: string): void;
|
|
108
|
+
}
|
|
109
|
+
type ApprovalStatus = "approved" | "denied" | "pending";
|
|
110
|
+
interface PendingApproval {
|
|
111
|
+
token: string;
|
|
112
|
+
action: string;
|
|
113
|
+
context: Record<string, unknown>;
|
|
114
|
+
createdAt: string;
|
|
115
|
+
status: ApprovalStatus;
|
|
116
|
+
reason?: string;
|
|
117
|
+
}
|
|
118
|
+
declare class HiTLGate {
|
|
119
|
+
private _pending;
|
|
120
|
+
/**
|
|
121
|
+
* Request human approval for an action.
|
|
122
|
+
* Returns an approval token to poll or pass to approve/deny.
|
|
123
|
+
*/
|
|
124
|
+
request(action: string, context?: Record<string, unknown>): string;
|
|
125
|
+
/** Approve a pending request. */
|
|
126
|
+
approve(token: string): void;
|
|
127
|
+
/** Deny a pending request with an optional reason. */
|
|
128
|
+
deny(token: string, reason?: string): void;
|
|
129
|
+
/** Check the status of a pending approval. */
|
|
130
|
+
check(token: string): ApprovalStatus;
|
|
131
|
+
/** Get all pending approvals. */
|
|
132
|
+
get pendingApprovals(): PendingApproval[];
|
|
133
|
+
/** Get the full approval record. */
|
|
134
|
+
getApproval(token: string): PendingApproval | undefined;
|
|
135
|
+
/** Clear resolved (approved/denied) approvals. */
|
|
136
|
+
clearResolved(): void;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* RCAN Audit Chain — tamper-evident commitment records (§16).
|
|
141
|
+
*
|
|
142
|
+
* Each CommitmentRecord is sealed with an HMAC-SHA256 over its content.
|
|
143
|
+
* Records are chained via previousHash, creating a forensic audit trail.
|
|
144
|
+
*/
|
|
145
|
+
interface CommitmentRecordData {
|
|
146
|
+
action: string;
|
|
147
|
+
robotUri?: string;
|
|
148
|
+
confidence?: number;
|
|
149
|
+
modelIdentity?: string;
|
|
150
|
+
params?: Record<string, unknown>;
|
|
151
|
+
safetyApproved?: boolean;
|
|
152
|
+
}
|
|
153
|
+
interface CommitmentRecordJSON {
|
|
154
|
+
recordId: string;
|
|
155
|
+
action: string;
|
|
156
|
+
robotUri: string;
|
|
157
|
+
confidence?: number;
|
|
158
|
+
modelIdentity?: string;
|
|
159
|
+
params: Record<string, unknown>;
|
|
160
|
+
safetyApproved: boolean;
|
|
161
|
+
timestamp: string;
|
|
162
|
+
contentHash: string;
|
|
163
|
+
previousHash: string | null;
|
|
164
|
+
hmac: string;
|
|
165
|
+
}
|
|
166
|
+
declare class AuditError extends Error {
|
|
167
|
+
constructor(message: string);
|
|
168
|
+
}
|
|
169
|
+
declare class CommitmentRecord {
|
|
170
|
+
readonly recordId: string;
|
|
171
|
+
readonly action: string;
|
|
172
|
+
readonly robotUri: string;
|
|
173
|
+
readonly confidence: number | undefined;
|
|
174
|
+
readonly modelIdentity: string | undefined;
|
|
175
|
+
readonly params: Record<string, unknown>;
|
|
176
|
+
readonly safetyApproved: boolean;
|
|
177
|
+
readonly timestamp: string;
|
|
178
|
+
readonly contentHash: string;
|
|
179
|
+
readonly previousHash: string | null;
|
|
180
|
+
readonly hmac: string;
|
|
181
|
+
private constructor();
|
|
182
|
+
static create(data: CommitmentRecordData, secret: string, previousHash?: string | null): CommitmentRecord;
|
|
183
|
+
verify(secret: string): boolean;
|
|
184
|
+
toJSON(): CommitmentRecordJSON;
|
|
185
|
+
static fromJSON(obj: CommitmentRecordJSON): CommitmentRecord;
|
|
186
|
+
}
|
|
187
|
+
interface ChainVerifyResult {
|
|
188
|
+
valid: boolean;
|
|
189
|
+
count: number;
|
|
190
|
+
errors: string[];
|
|
191
|
+
}
|
|
192
|
+
declare class AuditChain {
|
|
193
|
+
private _records;
|
|
194
|
+
private _secret;
|
|
195
|
+
constructor(secret: string);
|
|
196
|
+
get records(): readonly CommitmentRecord[];
|
|
197
|
+
append(data: CommitmentRecordData): CommitmentRecord;
|
|
198
|
+
verifyAll(): ChainVerifyResult;
|
|
199
|
+
toJSONL(): string;
|
|
200
|
+
static fromJSONL(text: string, secret: string): AuditChain;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* RCAN Validation — validate messages, configs, and URIs.
|
|
205
|
+
*
|
|
206
|
+
* Each function returns a ValidationResult with ok, issues, warnings, info.
|
|
207
|
+
*/
|
|
208
|
+
interface ValidationResult {
|
|
209
|
+
ok: boolean;
|
|
210
|
+
issues: string[];
|
|
211
|
+
warnings: string[];
|
|
212
|
+
info: string[];
|
|
213
|
+
}
|
|
214
|
+
declare function validateURI(uri: string): ValidationResult;
|
|
215
|
+
declare function validateMessage(data: unknown): ValidationResult;
|
|
216
|
+
interface RCANConfig {
|
|
217
|
+
rcan_version?: string;
|
|
218
|
+
metadata?: {
|
|
219
|
+
manufacturer?: string;
|
|
220
|
+
model?: string;
|
|
221
|
+
version?: string;
|
|
222
|
+
rrn?: string;
|
|
223
|
+
rcan_uri?: string;
|
|
224
|
+
};
|
|
225
|
+
agent?: {
|
|
226
|
+
provider?: string;
|
|
227
|
+
model?: string;
|
|
228
|
+
confidence_gates?: Array<{
|
|
229
|
+
threshold?: number;
|
|
230
|
+
}>;
|
|
231
|
+
hitl_gates?: Array<Record<string, unknown>>;
|
|
232
|
+
commitment_chain?: {
|
|
233
|
+
enabled?: boolean;
|
|
234
|
+
};
|
|
235
|
+
signing?: {
|
|
236
|
+
enabled?: boolean;
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
rcan_protocol?: {
|
|
240
|
+
jwt_auth?: {
|
|
241
|
+
enabled?: boolean;
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
[key: string]: unknown;
|
|
245
|
+
}
|
|
246
|
+
declare function validateConfig(config: RCANConfig): ValidationResult;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* RCAN error class hierarchy.
|
|
250
|
+
* All errors extend RCANError which extends the built-in Error.
|
|
251
|
+
*/
|
|
252
|
+
declare class RCANError extends Error {
|
|
253
|
+
constructor(message: string);
|
|
254
|
+
}
|
|
255
|
+
declare class RCANAddressError extends RCANError {
|
|
256
|
+
constructor(message: string);
|
|
257
|
+
}
|
|
258
|
+
declare class RCANValidationError extends RCANError {
|
|
259
|
+
constructor(message: string);
|
|
260
|
+
}
|
|
261
|
+
declare class RCANGateError extends RCANError {
|
|
262
|
+
gateType: string;
|
|
263
|
+
value?: number | undefined;
|
|
264
|
+
threshold?: number | undefined;
|
|
265
|
+
constructor(message: string, gateType: string, value?: number | undefined, threshold?: number | undefined);
|
|
266
|
+
}
|
|
267
|
+
declare class RCANSignatureError extends RCANError {
|
|
268
|
+
constructor(message: string);
|
|
269
|
+
}
|
|
270
|
+
declare class RCANRegistryError extends RCANError {
|
|
271
|
+
constructor(message: string);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* rcan-ts — RegistryClient
|
|
276
|
+
* TypeScript parity with rcan-py RegistryClient.
|
|
277
|
+
*
|
|
278
|
+
* @see https://rcan.dev/spec#section-registry
|
|
279
|
+
*/
|
|
280
|
+
interface RobotRegistration {
|
|
281
|
+
manufacturer: string;
|
|
282
|
+
model: string;
|
|
283
|
+
version: string;
|
|
284
|
+
device_id: string;
|
|
285
|
+
description?: string;
|
|
286
|
+
contact_email?: string;
|
|
287
|
+
verification_tier?: string;
|
|
288
|
+
source?: string;
|
|
289
|
+
}
|
|
290
|
+
interface Robot extends RobotRegistration {
|
|
291
|
+
rrn: string;
|
|
292
|
+
registered_at: string;
|
|
293
|
+
updated_at: string;
|
|
294
|
+
verification_tier: string;
|
|
295
|
+
status: string;
|
|
296
|
+
}
|
|
297
|
+
interface RegistrationResult {
|
|
298
|
+
rrn: string;
|
|
299
|
+
api_key: string;
|
|
300
|
+
}
|
|
301
|
+
interface ListResult {
|
|
302
|
+
robots: Robot[];
|
|
303
|
+
total: number;
|
|
304
|
+
limit: number;
|
|
305
|
+
offset: number;
|
|
306
|
+
}
|
|
307
|
+
declare class RegistryClient {
|
|
308
|
+
private baseUrl;
|
|
309
|
+
private apiKey?;
|
|
310
|
+
private timeout;
|
|
311
|
+
constructor(opts?: {
|
|
312
|
+
baseUrl?: string;
|
|
313
|
+
apiKey?: string;
|
|
314
|
+
timeout?: number;
|
|
315
|
+
});
|
|
316
|
+
private _fetch;
|
|
317
|
+
private _authHeaders;
|
|
318
|
+
private _checkResponse;
|
|
319
|
+
/** Register a new robot. Returns RRN + API key. */
|
|
320
|
+
register(robot: RobotRegistration): Promise<RegistrationResult>;
|
|
321
|
+
/** Look up a robot by RRN. */
|
|
322
|
+
get(rrn: string): Promise<Robot>;
|
|
323
|
+
/** List robots with optional pagination and tier filter. */
|
|
324
|
+
list(opts?: {
|
|
325
|
+
limit?: number;
|
|
326
|
+
offset?: number;
|
|
327
|
+
tier?: string;
|
|
328
|
+
}): Promise<ListResult>;
|
|
329
|
+
/** Update robot fields. Requires API key. */
|
|
330
|
+
patch(rrn: string, updates: Partial<Robot>): Promise<Robot>;
|
|
331
|
+
/** Delete (soft-delete) a robot. Requires API key. */
|
|
332
|
+
delete(rrn: string): Promise<void>;
|
|
333
|
+
/** Search robots by query, manufacturer, model, or tier. */
|
|
334
|
+
search(opts: {
|
|
335
|
+
q?: string;
|
|
336
|
+
manufacturer?: string;
|
|
337
|
+
model?: string;
|
|
338
|
+
tier?: string;
|
|
339
|
+
}): Promise<Robot[]>;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* rcan-ts — Official TypeScript SDK for RCAN v1.2
|
|
344
|
+
* Robot Communication and Accountability Network
|
|
345
|
+
*
|
|
346
|
+
* @see https://rcan.dev
|
|
347
|
+
* @see https://github.com/continuonai/rcan-ts
|
|
348
|
+
*/
|
|
349
|
+
|
|
350
|
+
declare const VERSION = "0.1.0";
|
|
351
|
+
declare const RCAN_VERSION = "1.2";
|
|
352
|
+
|
|
353
|
+
export { type ApprovalStatus, AuditChain, AuditError, type ChainVerifyResult, CommitmentRecord, type CommitmentRecordData, type CommitmentRecordJSON, ConfidenceGate, GateError, HiTLGate, type ListResult, type PendingApproval, RCANAddressError, type RCANConfig, RCANError, RCANGateError, RCANMessage, type RCANMessageData, RCANMessageError, RCANRegistryError, RCANSignatureError, RCANValidationError, RCAN_VERSION, type RegistrationResult, RegistryClient, type Robot, type RobotRegistration, RobotURI, RobotURIError, type RobotURIOptions, type SignatureBlock, VERSION, type ValidationResult, validateConfig, validateMessage, validateURI };
|