@continuonai/rcan-ts 0.6.0 → 1.1.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.
@@ -56,18 +56,18 @@ declare enum MessageType {
56
56
  HEARTBEAT = 4,
57
57
  CONFIG = 5,
58
58
  SAFETY = 6,
59
- SENSOR_DATA = 7,
60
- AUDIT = 8,
59
+ AUTH = 7,
60
+ ERROR = 8,
61
61
  DISCOVER = 9,
62
- TRAINING_DATA = 10,
63
- TRANSPARENCY = 11,
64
- FEDERATION_SYNC = 12,
65
- ALERT = 13,
66
- TELEOP = 14,
67
- CHAT = 15,
68
- ERROR = 16,
62
+ PENDING_AUTH = 10,
63
+ INVOKE = 11,
64
+ INVOKE_RESULT = 12,
65
+ INVOKE_CANCEL = 13,
66
+ REGISTRY_REGISTER = 14,
67
+ REGISTRY_RESOLVE = 15,
68
+ TRANSPARENCY = 16,// EU AI Act Art. 13 audit record
69
69
  COMMAND_ACK = 17,
70
- COMMAND_COMMIT = 18,
70
+ COMMAND_NACK = 18,
71
71
  ROBOT_REVOCATION = 19,
72
72
  CONSENT_REQUEST = 20,
73
73
  CONSENT_GRANT = 21,
@@ -76,7 +76,28 @@ declare enum MessageType {
76
76
  SUBSCRIBE = 24,
77
77
  UNSUBSCRIBE = 25,
78
78
  FAULT_REPORT = 26,
79
- COMMAND_NACK = 27
79
+ KEY_ROTATION = 27,
80
+ COMMAND_COMMIT = 28,
81
+ SENSOR_DATA = 29,
82
+ TRAINING_CONSENT_REQUEST = 30,
83
+ TRAINING_CONSENT_GRANT = 31,
84
+ TRAINING_CONSENT_DENY = 32,
85
+ CONTRIBUTE_REQUEST = 33,
86
+ CONTRIBUTE_RESULT = 34,
87
+ CONTRIBUTE_CANCEL = 35,
88
+ TRAINING_DATA = 36,
89
+ COMPETITION_ENTER = 37,
90
+ COMPETITION_SCORE = 38,
91
+ SEASON_STANDING = 39,
92
+ PERSONAL_RESEARCH_RESULT = 40,
93
+ /** authority → robot: EU AI Act Art. 16(j) audit data request */
94
+ AUTHORITY_ACCESS = 41,
95
+ /** robot → authority: audit data response */
96
+ AUTHORITY_RESPONSE = 42,
97
+ /** robot → RRF: publish signed firmware manifest */
98
+ FIRMWARE_ATTESTATION = 43,
99
+ /** robot → RRF: publish updated CycloneDX SBOM */
100
+ SBOM_UPDATE = 44
80
101
  }
81
102
  /** §8.5 — Sender Type and Service Identity */
82
103
  type SenderType = "robot" | "human" | "cloud_function" | "system";
@@ -127,6 +148,10 @@ interface RCANMessageData {
127
148
  transportEncoding?: string;
128
149
  /** v1.6: GAP-18 multi-modal media chunks */
129
150
  mediaChunks?: Array<Record<string, unknown>>;
151
+ /** v2.1: SHA-256 of sender's firmware manifest (envelope field 13). Required at L2+. */
152
+ firmwareHash?: string;
153
+ /** v2.1: URI to sender's SBOM attestation endpoint (envelope field 14). Required at L2+. */
154
+ attestationRef?: string;
130
155
  [key: string]: unknown;
131
156
  }
132
157
  declare class RCANMessageError extends Error {
@@ -159,6 +184,10 @@ declare class RCANMessage {
159
184
  readonly transportEncoding: string | undefined;
160
185
  /** v1.6: GAP-18 multi-modal media chunks */
161
186
  readonly mediaChunks: Array<Record<string, unknown>> | undefined;
187
+ /** v2.1: SHA-256 of sender's firmware manifest */
188
+ readonly firmwareHash: string | undefined;
189
+ /** v2.1: URI to sender's SBOM attestation endpoint */
190
+ readonly attestationRef: string | undefined;
162
191
  constructor(data: RCANMessageData);
163
192
  /** Whether this message has a signature block */
164
193
  get isSigned(): boolean;
@@ -726,14 +755,13 @@ declare function makeTransparencyMessage(ruri: string, disclosure: string, deleg
726
755
  * §3.5 — Protocol Version Compatibility
727
756
  */
728
757
  /** The RCAN spec version this SDK implements. */
729
- declare const SPEC_VERSION = "1.6";
758
+ declare const SPEC_VERSION = "2.1.0";
730
759
  /** The SDK release version. */
731
- declare const SDK_VERSION = "0.6.0";
760
+ declare const SDK_VERSION = "1.1.0";
732
761
  /**
733
762
  * Validate version compatibility.
734
763
  *
735
- * A receiver MUST accept messages from senders with the same MAJOR version
736
- * and lower-or-equal MINOR version. MAJOR mismatch → incompatible.
764
+ * MAJOR must match. Lower-or-equal MINOR is acceptable.
737
765
  *
738
766
  * @param incomingVersion - The rcanVersion from the incoming message
739
767
  * @param localVersion - The local SPEC_VERSION (defaults to SPEC_VERSION)
@@ -997,7 +1025,7 @@ interface RevocationStatus {
997
1025
  /**
998
1026
  * RevocationCache — TTL-based cache for revocation status records.
999
1027
  */
1000
- declare class RevocationCache {
1028
+ declare class RevocationCache$1 {
1001
1029
  private readonly _cache;
1002
1030
  /** Get a cached status if still fresh */
1003
1031
  get(rrn: string, nowMs?: number): RevocationStatus | undefined;
@@ -1016,7 +1044,7 @@ declare class RevocationCache {
1016
1044
  * @param registryUrl - Base URL of the registry (e.g. "https://registry.rcan.dev")
1017
1045
  * @param cache - Optional RevocationCache to use (creates ephemeral one if not provided)
1018
1046
  */
1019
- declare function checkRevocation(rrn: string, registryUrl: string, cache?: RevocationCache): Promise<RevocationStatus>;
1047
+ declare function checkRevocation(rrn: string, registryUrl: string, cache?: RevocationCache$1): Promise<RevocationStatus>;
1020
1048
  /**
1021
1049
  * Build a ROBOT_REVOCATION broadcast message.
1022
1050
  *
@@ -1190,43 +1218,94 @@ interface AuditExportRequest {
1190
1218
  }
1191
1219
 
1192
1220
  /**
1193
- * RCAN Identity & Level of Assurance (LoA) GAP-14.
1221
+ * rcan/identity RCAN v2.1 Role-Based Access Control and Identity.
1194
1222
  *
1195
- * Provides JWT-based LoA extraction and per-scope policy enforcement.
1196
- * Backward compatible: DEFAULT_LOA_POLICY requires only ANONYMOUS (LoA 1).
1197
- */
1198
- declare enum LevelOfAssurance {
1199
- ANONYMOUS = 1,
1200
- EMAIL_VERIFIED = 2,
1201
- HARDWARE_TOKEN = 3
1223
+ * Defines the seven-level role hierarchy (§2), JWT claim parsing, scope
1224
+ * validation, and identity record types.
1225
+ *
1226
+ * Roles (v2.1):
1227
+ * GUEST (JWT 1) — read-only, anonymous
1228
+ * OPERATOR (JWT 2) — operational control
1229
+ * CONTRIBUTOR (JWT 2.5) — idle compute donation scope
1230
+ * ADMIN (JWT 3) — configuration, user management
1231
+ * M2M_PEER (JWT 4) — robot-to-robot; issued by ADMIN
1232
+ * CREATOR (JWT 5) — full hardware/software control
1233
+ * M2M_TRUSTED (JWT 6) — fleet orchestration; RRF-issued only
1234
+ *
1235
+ * Spec: §2 — Role-Based Access Control
1236
+ */
1237
+ /** RCAN v2.1 role hierarchy. Use ROLE_JWT_LEVEL to map to JWT level values. */
1238
+ declare enum Role {
1239
+ GUEST = 1,
1240
+ OPERATOR = 2,
1241
+ CONTRIBUTOR = 3,// JWT level 2.5
1242
+ ADMIN = 4,// JWT level 3
1243
+ M2M_PEER = 5,// JWT level 4
1244
+ CREATOR = 6,// JWT level 5
1245
+ M2M_TRUSTED = 7
1246
+ }
1247
+ /** @deprecated Use Role instead. Kept for v1.x backward compatibility. */
1248
+ declare const LevelOfAssurance: typeof Role;
1249
+ type LevelOfAssurance = Role;
1250
+ /** Maps Role enum value to JWT rcan_role level (fractional for CONTRIBUTOR). */
1251
+ declare const ROLE_JWT_LEVEL: Record<Role, number>;
1252
+ /** Return the Role for a JWT rcan_role numeric level, or undefined. */
1253
+ declare function roleFromJwtLevel(level: number): Role | undefined;
1254
+ declare const SCOPE_MIN_ROLE: Record<string, Role>;
1255
+ interface IdentityRecord {
1256
+ /** Subject identifier (UUID, RRN, or orchestrator id). */
1257
+ sub: string;
1258
+ /** RCAN v2.1 Role. */
1259
+ role: Role;
1260
+ /** JWT-level value for this role. */
1261
+ jwtLevel: number;
1262
+ /** Registry that issued this identity. */
1263
+ registryUrl?: string;
1264
+ /** Granted scopes. */
1265
+ scopes: string[];
1266
+ /** UTC ISO-8601 timestamp of most recent verification. */
1267
+ verifiedAt?: string;
1268
+ /** For M2M_PEER tokens — the authorized peer's RRN. */
1269
+ peerRrn?: string;
1270
+ /** For M2M_TRUSTED tokens — explicit fleet allowlist. */
1271
+ fleetRrns?: string[];
1202
1272
  }
1203
1273
  interface LoaPolicy {
1204
- minLoaDiscover: LevelOfAssurance;
1205
- minLoaStatus: LevelOfAssurance;
1206
- minLoaChat: LevelOfAssurance;
1207
- minLoaControl: LevelOfAssurance;
1208
- minLoaSafety: LevelOfAssurance;
1274
+ minRoleForDiscover: Role;
1275
+ minRoleForStatus: Role;
1276
+ minRoleForChat: Role;
1277
+ minRoleForControl: Role;
1278
+ minRoleForSafety: Role;
1209
1279
  }
1210
- /** Backward-compatible policy — every scope accepts anonymous callers. */
1280
+ /** Backward-compatible default policy — every scope accepts GUEST callers. */
1211
1281
  declare const DEFAULT_LOA_POLICY: LoaPolicy;
1212
- /** Production-hardened policy — control needs e-mail, safety needs hardware token. */
1282
+ /** Production-hardened policy — control needs OPERATOR, safety needs CREATOR. */
1213
1283
  declare const PRODUCTION_LOA_POLICY: LoaPolicy;
1214
1284
  /**
1215
- * Decode a JWT (header.payload.sig) and return the `loa` claim.
1216
- * Defaults to ANONYMOUS when the claim is absent or the token is malformed.
1285
+ * Parse an RCAN v2.1 JWT and return the Role.
1286
+ *
1287
+ * Reads `rcan_role` (v2.1) with fallback to `loa` (v1.x).
1288
+ * Defaults to GUEST on parse failure.
1217
1289
  */
1218
- declare function extractLoaFromJwt(token: string): LevelOfAssurance;
1290
+ declare function extractRoleFromJwt(token: string): Role;
1291
+ /** @deprecated Use extractRoleFromJwt. Kept for v1.x backward compatibility. */
1292
+ declare function extractLoaFromJwt(token: string): Role;
1219
1293
  /**
1220
- * Check whether `loa` satisfies the minimum required for `scope`.
1294
+ * Parse an RCAN v2.1 JWT and return a full IdentityRecord.
1221
1295
  *
1222
- * @param loa - Caller's assurance level
1223
- * @param scope - One of discover | status | chat | control | safety
1224
- * @param policy - Defaults to DEFAULT_LOA_POLICY (backward compatible)
1296
+ * Does NOT verify the JWT signature.
1225
1297
  */
1226
- declare function validateLoaForScope(loa: LevelOfAssurance, scope: string, policy?: LoaPolicy): {
1227
- valid: boolean;
1298
+ declare function extractIdentityFromJwt(token: string): IdentityRecord;
1299
+ interface ScopeValidationResult {
1300
+ ok: boolean;
1228
1301
  reason: string;
1229
- };
1302
+ }
1303
+ /**
1304
+ * Check whether `role` meets the minimum requirement for `scope`.
1305
+ */
1306
+ declare function validateRoleForScope(role: Role, scope: string): ScopeValidationResult;
1307
+ /** @deprecated Use validateRoleForScope. */
1308
+ declare function validateLoaForScope(role: Role, scope: string): ScopeValidationResult;
1230
1309
 
1231
1310
  /**
1232
1311
  * RCAN Federation — cross-registry trust and sync (GAP-16).
@@ -1420,6 +1499,359 @@ declare function makeTrainingDataMessage(media: Array<{
1420
1499
  */
1421
1500
  declare function makeStreamChunk(streamId: string, data: Uint8Array, mimeType: string, chunkIndex: number, isFinal: boolean): Promise<RCANMessage>;
1422
1501
 
1502
+ /**
1503
+ * rcan/contribute — Idle Compute Contribution messages and scope.
1504
+ *
1505
+ * Implements the contribute scope and message types for RCAN v1.7+.
1506
+ * Robots can donate idle NPU/GPU/CPU compute to distributed science projects.
1507
+ *
1508
+ * Spec: §3 MessageTypes 33–35, Identity scope level 2.5
1509
+ */
1510
+
1511
+ /** Contribute scope level — between chat (2) and control (3). */
1512
+ declare const CONTRIBUTE_SCOPE_LEVEL = 2.5;
1513
+ type WorkUnitStatus = "pending" | "running" | "completed" | "failed" | "cancelled" | "preempted";
1514
+ type ComputeResource = "npu" | "gpu" | "cpu" | "sensor";
1515
+ interface ContributeRequest {
1516
+ type: typeof MessageType.CONTRIBUTE_REQUEST;
1517
+ request_id: string;
1518
+ project_id: string;
1519
+ project_name: string;
1520
+ work_unit_id: string;
1521
+ resource_type: ComputeResource;
1522
+ estimated_duration_s: number;
1523
+ priority: number;
1524
+ payload: Record<string, unknown>;
1525
+ timestamp: number;
1526
+ }
1527
+ interface ContributeResult {
1528
+ type: typeof MessageType.CONTRIBUTE_RESULT;
1529
+ request_id: string;
1530
+ work_unit_id: string;
1531
+ status: WorkUnitStatus;
1532
+ resource_type: ComputeResource;
1533
+ duration_s: number;
1534
+ compute_units: number;
1535
+ result_payload: Record<string, unknown>;
1536
+ error_message?: string;
1537
+ timestamp: number;
1538
+ }
1539
+ interface ContributeCancel {
1540
+ type: typeof MessageType.CONTRIBUTE_CANCEL;
1541
+ request_id: string;
1542
+ work_unit_id: string;
1543
+ reason: string;
1544
+ timestamp: number;
1545
+ }
1546
+ declare function makeContributeRequest(params?: Partial<Omit<ContributeRequest, "type">>): ContributeRequest;
1547
+ declare function makeContributeResult(params?: Partial<Omit<ContributeResult, "type">>): ContributeResult;
1548
+ declare function makeContributeCancel(params?: Partial<Omit<ContributeCancel, "type">>): ContributeCancel;
1549
+ /**
1550
+ * Check if the given scope level permits contribute operations.
1551
+ *
1552
+ * Contribute requires scope >= 2.5 (between chat and control).
1553
+ */
1554
+ declare function validateContributeScope(scopeLevel: number, action?: "request" | "result" | "cancel"): boolean;
1555
+ /**
1556
+ * Check if the given scope level preempts contribution.
1557
+ *
1558
+ * Any scope >= control (3.0) preempts contribute immediately.
1559
+ * This is the P66 safety invariant — non-negotiable.
1560
+ */
1561
+ declare function isPreemptedBy(scopeLevel: number): boolean;
1562
+
1563
+ /**
1564
+ * rcan/competition — Competition protocol messages and scope.
1565
+ *
1566
+ * Implements the competition scope and message types for RCAN v1.10+.
1567
+ * Robots can enter competitions, publish scores, receive season standings,
1568
+ * and log private personal research results.
1569
+ *
1570
+ * Spec: §3 MessageTypes 37–40
1571
+ */
1572
+
1573
+ /** Competition scope level — chat-level scope (observation, not control). */
1574
+ declare const COMPETITION_SCOPE_LEVEL = 2;
1575
+ type CompetitionFormat = "sprint" | "endurance" | "precision" | "efficiency";
1576
+ type CompetitionBadge = "gold" | "silver" | "bronze" | "participant";
1577
+ type RunType = "personal" | "community";
1578
+ interface StandingEntry {
1579
+ rank: number;
1580
+ rrn: string;
1581
+ score: number;
1582
+ badge: CompetitionBadge;
1583
+ }
1584
+ interface ResearchMetrics {
1585
+ success_rate: number;
1586
+ p66_rate: number;
1587
+ token_efficiency: number;
1588
+ latency_score: number;
1589
+ [key: string]: number;
1590
+ }
1591
+ interface CompetitionEnter {
1592
+ type: typeof MessageType.COMPETITION_ENTER;
1593
+ competition_id: string;
1594
+ competition_format: CompetitionFormat;
1595
+ hardware_tier: string;
1596
+ model_id: string;
1597
+ robot_rrn: string;
1598
+ entered_at: number;
1599
+ }
1600
+ interface CompetitionScore {
1601
+ type: typeof MessageType.COMPETITION_SCORE;
1602
+ competition_id: string;
1603
+ candidate_id: string;
1604
+ score: number;
1605
+ hardware_tier: string;
1606
+ verified: boolean;
1607
+ submitted_at: number;
1608
+ }
1609
+ interface SeasonStanding {
1610
+ type: typeof MessageType.SEASON_STANDING;
1611
+ season_id: string;
1612
+ class_id: string;
1613
+ standings: StandingEntry[];
1614
+ days_remaining: number;
1615
+ broadcast_at: number;
1616
+ }
1617
+ interface PersonalResearchResult {
1618
+ type: typeof MessageType.PERSONAL_RESEARCH_RESULT;
1619
+ run_id: string;
1620
+ run_type: RunType;
1621
+ candidate_id: string;
1622
+ score: number;
1623
+ hardware_tier: string;
1624
+ model_id: string;
1625
+ owner_uid: string;
1626
+ metrics: ResearchMetrics;
1627
+ submitted_to_community: boolean;
1628
+ created_at: number;
1629
+ }
1630
+ declare function makeCompetitionEnter(params?: Partial<Omit<CompetitionEnter, "type">>): CompetitionEnter;
1631
+ declare function makeCompetitionScore(params?: Partial<Omit<CompetitionScore, "type">>): CompetitionScore;
1632
+ declare function makeSeasonStanding(params?: Partial<Omit<SeasonStanding, "type">>): SeasonStanding;
1633
+ declare function makePersonalResearchResult(params?: Partial<Omit<PersonalResearchResult, "type">>): PersonalResearchResult;
1634
+ /**
1635
+ * Check if the given scope level permits competition operations.
1636
+ * Competition messages require scope >= 2.0 (chat level).
1637
+ */
1638
+ declare function validateCompetitionScope(scopeLevel: number): boolean;
1639
+
1640
+ /**
1641
+ * rcan/firmware — RCAN v2.1 Firmware Manifest types and helpers.
1642
+ *
1643
+ * Every RCAN v2.1 robot MUST publish a signed firmware manifest at:
1644
+ * {ruri}/.well-known/rcan-firmware-manifest.json
1645
+ *
1646
+ * The manifest is Ed25519-signed by the manufacturer's key registered in the RRF.
1647
+ * The envelope field `firmwareHash` (field 13) carries a SHA-256 of the manifest.
1648
+ *
1649
+ * Spec: §11 — Firmware Manifests
1650
+ */
1651
+ /** Well-known endpoint path for firmware manifests. */
1652
+ declare const FIRMWARE_MANIFEST_PATH = "/.well-known/rcan-firmware-manifest.json";
1653
+ /** A single component entry in the firmware manifest. */
1654
+ interface FirmwareComponent {
1655
+ /** Component name, e.g. "brain-runtime" */
1656
+ name: string;
1657
+ /** Semantic version string */
1658
+ version: string;
1659
+ /** SHA-256 hash prefixed with "sha256:" */
1660
+ hash: string;
1661
+ }
1662
+ /** RCAN v2.1 firmware manifest. */
1663
+ interface FirmwareManifest {
1664
+ /** Robot Registration Number */
1665
+ rrn: string;
1666
+ /** Semver or CalVer version string */
1667
+ firmwareVersion: string;
1668
+ /** SHA-256 of the full firmware bundle, prefixed "sha256:" */
1669
+ buildHash: string;
1670
+ /** Per-component records */
1671
+ components: FirmwareComponent[];
1672
+ /** UTC ISO-8601 timestamp when the manifest was signed */
1673
+ signedAt: string;
1674
+ /** Ed25519 signature over canonical JSON (base64url), empty if unsigned */
1675
+ signature?: string;
1676
+ }
1677
+ /**
1678
+ * Serialized (wire) format of a firmware manifest.
1679
+ * Uses snake_case keys to match the JSON spec.
1680
+ */
1681
+ interface FirmwareManifestWire {
1682
+ rrn: string;
1683
+ firmware_version: string;
1684
+ build_hash: string;
1685
+ components: FirmwareComponent[];
1686
+ signed_at: string;
1687
+ signature?: string;
1688
+ }
1689
+ /** Convert a camelCase FirmwareManifest to the wire (snake_case) format. */
1690
+ declare function manifestToWire(m: FirmwareManifest): FirmwareManifestWire;
1691
+ /** Parse a wire-format manifest into the typed FirmwareManifest. */
1692
+ declare function manifestFromWire(w: FirmwareManifestWire): FirmwareManifest;
1693
+ /**
1694
+ * Return the canonical JSON bytes of a manifest (no signature field, sorted keys).
1695
+ * This is the byte string that the Ed25519 signature covers.
1696
+ */
1697
+ declare function canonicalManifestJson(m: FirmwareManifest): string;
1698
+ /** Thrown when firmware manifest signature verification fails. */
1699
+ declare class FirmwareIntegrityError extends Error {
1700
+ constructor(message: string);
1701
+ }
1702
+ /** Validate a manifest structure and return a list of errors. */
1703
+ declare function validateManifest(m: FirmwareManifest): string[];
1704
+
1705
+ /**
1706
+ * rcan/authority — RCAN v2.1 Authority Access Protocol (EU AI Act §16(j)).
1707
+ *
1708
+ * Defines payload types for AUTHORITY_ACCESS (41) and AUTHORITY_RESPONSE (42)
1709
+ * message types, and helpers for building/validating authority requests.
1710
+ *
1711
+ * The authority access protocol enables regulatory bodies to request audit data
1712
+ * from robots under EU AI Act Article 16(j) and similar frameworks.
1713
+ *
1714
+ * Spec: §13 (Authority Access) — EU AI Act Art. 16 mapping
1715
+ */
1716
+ /** Allowed audit data categories that an authority may request. */
1717
+ type AuthorityDataCategory = "audit_chain" | "transparency_records" | "sbom" | "firmware_manifest";
1718
+ /** Payload for AUTHORITY_ACCESS (41) — sent by a regulatory authority to a robot. */
1719
+ interface AuthorityAccessPayload {
1720
+ /** Unique request identifier (correlated in the response). */
1721
+ requestId: string;
1722
+ /** Authority identifier, e.g. "EU-AI-ACT-NCA-DE" */
1723
+ authorityId: string;
1724
+ /** Audit data categories requested. */
1725
+ requestedData: AuthorityDataCategory[];
1726
+ /** Human-readable justification for the request. */
1727
+ justification: string;
1728
+ /** Unix timestamp — request must be responded to before this time. */
1729
+ expiresAt: number;
1730
+ }
1731
+ /** Provided audit data in an AUTHORITY_RESPONSE. */
1732
+ interface AuthorityResponseData {
1733
+ auditChain?: unknown[];
1734
+ transparencyRecords?: unknown[];
1735
+ sbomUrl?: string;
1736
+ firmwareManifestUrl?: string;
1737
+ }
1738
+ /** Payload for AUTHORITY_RESPONSE (42) — sent by the robot in reply. */
1739
+ interface AuthorityResponsePayload {
1740
+ /** Correlates with the AUTHORITY_ACCESS requestId. */
1741
+ requestId: string;
1742
+ /** Robot Registration Number of the responding robot. */
1743
+ rrn: string;
1744
+ /** Unix timestamp when the data was packaged. */
1745
+ providedAt: number;
1746
+ /** Provided audit data. */
1747
+ data: AuthorityResponseData;
1748
+ }
1749
+ /** Convert AuthorityAccessPayload to/from snake_case wire format. */
1750
+ interface AuthorityAccessPayloadWire {
1751
+ request_id: string;
1752
+ authority_id: string;
1753
+ requested_data: AuthorityDataCategory[];
1754
+ justification: string;
1755
+ expires_at: number;
1756
+ }
1757
+ declare function authorityAccessToWire(p: AuthorityAccessPayload): AuthorityAccessPayloadWire;
1758
+ declare function authorityAccessFromWire(w: AuthorityAccessPayloadWire): AuthorityAccessPayload;
1759
+ /**
1760
+ * Validate an authority access payload.
1761
+ * Returns an array of error strings (empty = valid).
1762
+ */
1763
+ declare function validateAuthorityAccess(p: AuthorityAccessPayload): string[];
1764
+ /** Return true if an AUTHORITY_ACCESS request is still within its deadline. */
1765
+ declare function isAuthorityRequestValid(p: AuthorityAccessPayload): boolean;
1766
+ declare const AUTHORITY_ERROR_CODES: {
1767
+ readonly NOT_RECOGNIZED: "AUTHORITY_NOT_RECOGNIZED";
1768
+ readonly REQUEST_EXPIRED: "AUTHORITY_REQUEST_EXPIRED";
1769
+ readonly INVALID_TOKEN: "AUTHORITY_INVALID_TOKEN";
1770
+ readonly RATE_LIMITED: "AUTHORITY_RATE_LIMITED";
1771
+ };
1772
+
1773
+ declare const RRF_REVOCATION_URL = "https://api.rrf.rcan.dev/v2/revocations";
1774
+ declare const M2M_TRUSTED_ISSUER = "rrf.rcan.dev";
1775
+ /** Revocation cache TTL in milliseconds (≤ 60 s per spec). */
1776
+ declare const RRF_REVOCATION_CACHE_TTL_MS = 55000;
1777
+ /** Parsed claims from an M2M_PEER JWT. */
1778
+ interface M2MPeerClaims {
1779
+ /** Subject RRN of the peer robot. */
1780
+ sub: string;
1781
+ /** The robot this peer is authorized to command. */
1782
+ peerRrn: string;
1783
+ /** Authorized scopes. */
1784
+ scopes: string[];
1785
+ /** Unix expiry timestamp. */
1786
+ exp: number;
1787
+ /** Issuing principal (ADMIN or CREATOR RRN). */
1788
+ iss: string;
1789
+ }
1790
+ /** Parsed claims from an M2M_TRUSTED JWT (RRF-issued). */
1791
+ interface M2MTrustedClaims {
1792
+ /** Orchestrator identifier (not a robot RRN). */
1793
+ sub: string;
1794
+ /** Explicit allowlist of robots this token may command. */
1795
+ fleetRrns: string[];
1796
+ /** Must include "fleet.trusted". */
1797
+ scopes: string[];
1798
+ /** Unix expiry timestamp (max 24 h from issuance). */
1799
+ exp: number;
1800
+ /** Must be "rrf.rcan.dev". */
1801
+ iss: string;
1802
+ /** RRF Ed25519 signature over claims (base64url). */
1803
+ rrfSig: string;
1804
+ }
1805
+ /** Thrown when M2M token verification fails. */
1806
+ declare class M2MAuthError extends Error {
1807
+ constructor(message: string);
1808
+ }
1809
+ /**
1810
+ * Parse an M2M_PEER JWT without signature verification.
1811
+ * Validates expiry and required claims.
1812
+ */
1813
+ declare function parseM2mPeerToken(token: string): M2MPeerClaims;
1814
+ /**
1815
+ * Parse an M2M_TRUSTED JWT claims WITHOUT signature verification.
1816
+ *
1817
+ * Checks issuer, scope, and expiry. Does not contact RRF.
1818
+ * For full verification use `verifyM2mTrustedTokenClaims`.
1819
+ */
1820
+ declare function parseM2mTrustedToken(token: string): M2MTrustedClaims;
1821
+ /**
1822
+ * Verify M2M_TRUSTED token claims and check that it authorizes `targetRrn`.
1823
+ *
1824
+ * This method validates claims structure only (no RRF network call).
1825
+ * In production, also check the RRF revocation list with `RRFRevocationCache`.
1826
+ */
1827
+ declare function verifyM2mTrustedTokenClaims(token: string, targetRrn: string): M2MTrustedClaims;
1828
+ interface RevocationCache {
1829
+ revokedOrchestrators: Set<string>;
1830
+ revokedJtis: Set<string>;
1831
+ fetchedAt: number;
1832
+ }
1833
+ /**
1834
+ * Fetch the RRF revocation list and cache it.
1835
+ *
1836
+ * Uses `fetch()` (available in Node 18+ and all modern browsers).
1837
+ * TTL: 55 s (spec max: 60 s).
1838
+ */
1839
+ declare function fetchRRFRevocations(url?: string): Promise<RevocationCache>;
1840
+ /**
1841
+ * Check whether an M2M_TRUSTED orchestrator sub is revoked.
1842
+ * Fetches the revocation list if the cache is stale.
1843
+ */
1844
+ declare function isM2mTrustedRevoked(claims: M2MTrustedClaims, jti?: string): Promise<boolean>;
1845
+ /**
1846
+ * Full async M2M_TRUSTED verification: claims check + revocation list.
1847
+ *
1848
+ * Note: Signature verification requires the RRF public key and is typically
1849
+ * done server-side using the rcan-py SDK or castor.auth middleware.
1850
+ */
1851
+ declare function verifyM2mTrustedToken(token: string, targetRrn: string, options?: {
1852
+ skipRevocationCheck?: boolean;
1853
+ }): Promise<M2MTrustedClaims>;
1854
+
1423
1855
  /**
1424
1856
  * rcan-ts — Official TypeScript SDK for RCAN v1.6
1425
1857
  * Robot Communication and Accountability Network
@@ -1432,4 +1864,4 @@ declare const VERSION = "0.6.0";
1432
1864
  /** @deprecated Use SPEC_VERSION from ./version instead */
1433
1865
  declare const RCAN_VERSION = "1.6";
1434
1866
 
1435
- export { type ApprovalStatus, AuditChain, AuditError, type AuditExportRequest, type CachedKey, type ChainVerifyResult, ClockDriftError, type ClockSyncStatus, CommitmentRecord, type CommitmentRecordData, type CommitmentRecordJSON, ConfidenceGate, type ConsentRequestParams, type ConsentResponseParams, type ConsentType, DEFAULT_LOA_POLICY, DataCategory, type DelegationHop, FaultCode, type FaultReportParams, type FaultSeverity, type FederationSyncPayload, FederationSyncType, GateError, HiTLGate, type JWKEntry, type JWKSDocument, KeyStore, LevelOfAssurance, type ListResult, type LoaPolicy, type MediaChunk, MediaEncoding, MessageType, NodeClient, type OfflineCommandResult, OfflineModeManager, type OfflineState, PRODUCTION_LOA_POLICY, type PendingApproval, QoSAckTimeoutError, QoSLevel, QoSManager, type QoSResult, type QoSSendOptions, RCANAddressError, type RCANAgentConfig, type RCANConfig, RCANConfigAuthorizationError, RCANDelegationChainError, RCANError, RCANGateError, RCANMessage, type RCANMessageData, type RCANMessageEnvelope, RCANMessageError, type RCANMetadata, RCANNodeError, RCANNodeNotFoundError, RCANNodeSyncError, RCANNodeTrustError, RCANRegistryError, type RCANRegistryNode, RCANReplayAttackError, type RCANResolveResult, RCANSignatureError, RCANValidationError, RCANVersionIncompatibleError, RCAN_VERSION, type RegistrationResult, RegistryClient, type RegistryIdentity, RegistryTier, ReplayCache, type ReplayCheckResult, type ReplayableMessage, RevocationCache, type RevocationStatus, type RevocationStatusValue, type Robot, type RobotRegistration, RobotURI, RobotURIError, type RobotURIOptions, SAFETY_MESSAGE_TYPE, SDK_VERSION, SPEC_VERSION, type SafetyEvent, type SafetyMessage, type SenderType, type SignatureBlock, type StreamChunk, type TrainingConsentRequestParams, type TransparencyMessage, TransportEncoding, TransportError, TrustAnchorCache, VERSION, type ValidationResult, addDelegationHop, addMediaInline, addMediaRef, assertClockSynced, checkClockSync, checkRevocation, decodeBleFrames, decodeCompact, decodeMinimal, encodeBleFrames, encodeCompact, encodeMinimal, extractLoaFromJwt, fetchCanonicalSchema, isSafetyMessage, makeCloudRelayMessage, makeConfigUpdate, makeConsentDeny, makeConsentGrant, makeConsentRequest, makeEstopMessage, makeEstopWithQoS, makeFaultReport, makeFederationSync, makeKeyRotationMessage, makeResumeMessage, makeRevocationBroadcast, makeStopMessage, makeStreamChunk, makeTrainingConsentDeny, makeTrainingConsentGrant, makeTrainingConsentRequest, makeTrainingDataMessage, makeTransparencyMessage, selectTransport, validateConfig, validateConfigAgainstSchema, validateConfigUpdate, validateConsentMessage, validateCrossRegistryCommand, validateDelegationChain, validateLoaForScope, validateMediaChunks, validateMessage, validateNodeAgainstSchema, validateReplay, validateSafetyMessage, validateTrainingDataMessage, validateURI, validateVersionCompat };
1867
+ export { AUTHORITY_ERROR_CODES, type ApprovalStatus, AuditChain, AuditError, type AuditExportRequest, type AuthorityAccessPayload, type AuthorityAccessPayloadWire, type AuthorityDataCategory, type AuthorityResponseData, type AuthorityResponsePayload, COMPETITION_SCOPE_LEVEL, CONTRIBUTE_SCOPE_LEVEL, type CachedKey, type ChainVerifyResult, ClockDriftError, type ClockSyncStatus, CommitmentRecord, type CommitmentRecordData, type CommitmentRecordJSON, type CompetitionBadge, type CompetitionEnter, type CompetitionFormat, type CompetitionScore, type ComputeResource, ConfidenceGate, type ConsentRequestParams, type ConsentResponseParams, type ConsentType, type ContributeCancel, type ContributeRequest, type ContributeResult, DEFAULT_LOA_POLICY, DataCategory, type DelegationHop, FIRMWARE_MANIFEST_PATH, FaultCode, type FaultReportParams, type FaultSeverity, type FederationSyncPayload, FederationSyncType, type FirmwareComponent, FirmwareIntegrityError, type FirmwareManifest, type FirmwareManifestWire, GateError, HiTLGate, type IdentityRecord, type JWKEntry, type JWKSDocument, KeyStore, LevelOfAssurance, type ListResult, type LoaPolicy, M2MAuthError, type M2MPeerClaims, type M2MTrustedClaims, M2M_TRUSTED_ISSUER, type MediaChunk, MediaEncoding, MessageType, NodeClient, type OfflineCommandResult, OfflineModeManager, type OfflineState, PRODUCTION_LOA_POLICY, type PendingApproval, type PersonalResearchResult, QoSAckTimeoutError, QoSLevel, QoSManager, type QoSResult, type QoSSendOptions, RCANAddressError, type RCANAgentConfig, type RCANConfig, RCANConfigAuthorizationError, RCANDelegationChainError, RCANError, RCANGateError, RCANMessage, type RCANMessageData, type RCANMessageEnvelope, RCANMessageError, type RCANMetadata, RCANNodeError, RCANNodeNotFoundError, RCANNodeSyncError, RCANNodeTrustError, RCANRegistryError, type RCANRegistryNode, RCANReplayAttackError, type RCANResolveResult, RCANSignatureError, RCANValidationError, RCANVersionIncompatibleError, RCAN_VERSION, ROLE_JWT_LEVEL, RRF_REVOCATION_CACHE_TTL_MS, RRF_REVOCATION_URL, type RegistrationResult, RegistryClient, type RegistryIdentity, RegistryTier, ReplayCache, type ReplayCheckResult, type ReplayableMessage, type ResearchMetrics, RevocationCache$1 as RevocationCache, type RevocationStatus, type RevocationStatusValue, type Robot, type RobotRegistration, RobotURI, RobotURIError, type RobotURIOptions, Role, type RunType, SAFETY_MESSAGE_TYPE, SCOPE_MIN_ROLE, SDK_VERSION, SPEC_VERSION, type SafetyEvent, type SafetyMessage, type ScopeValidationResult, type SeasonStanding, type SenderType, type SignatureBlock, type StandingEntry, type StreamChunk, type TrainingConsentRequestParams, type TransparencyMessage, TransportEncoding, TransportError, TrustAnchorCache, VERSION, type ValidationResult, type WorkUnitStatus, addDelegationHop, addMediaInline, addMediaRef, assertClockSynced, authorityAccessFromWire, authorityAccessToWire, canonicalManifestJson, checkClockSync, checkRevocation, decodeBleFrames, decodeCompact, decodeMinimal, encodeBleFrames, encodeCompact, encodeMinimal, extractIdentityFromJwt, extractLoaFromJwt, extractRoleFromJwt, fetchCanonicalSchema, fetchRRFRevocations, isAuthorityRequestValid, isM2mTrustedRevoked, isPreemptedBy, isSafetyMessage, makeCloudRelayMessage, makeCompetitionEnter, makeCompetitionScore, makeConfigUpdate, makeConsentDeny, makeConsentGrant, makeConsentRequest, makeContributeCancel, makeContributeRequest, makeContributeResult, makeEstopMessage, makeEstopWithQoS, makeFaultReport, makeFederationSync, makeKeyRotationMessage, makePersonalResearchResult, makeResumeMessage, makeRevocationBroadcast, makeSeasonStanding, makeStopMessage, makeStreamChunk, makeTrainingConsentDeny, makeTrainingConsentGrant, makeTrainingConsentRequest, makeTrainingDataMessage, makeTransparencyMessage, manifestFromWire, manifestToWire, parseM2mPeerToken, parseM2mTrustedToken, roleFromJwtLevel, selectTransport, validateAuthorityAccess, validateCompetitionScope, validateConfig, validateConfigAgainstSchema, validateConfigUpdate, validateConsentMessage, validateContributeScope, validateCrossRegistryCommand, validateDelegationChain, validateLoaForScope, validateManifest, validateMediaChunks, validateMessage, validateNodeAgainstSchema, validateReplay, validateRoleForScope, validateSafetyMessage, validateTrainingDataMessage, validateURI, validateVersionCompat, verifyM2mTrustedToken, verifyM2mTrustedTokenClaims };