@attested-intelligence/aga-mcp-server 2.2.0 → 2.2.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.
Files changed (80) hide show
  1. package/README.md +77 -65
  2. package/dist/adapters/openclaw.d.ts +0 -1
  3. package/dist/adapters/openclaw.d.ts.map +1 -1
  4. package/dist/adapters/openclaw.js +0 -1
  5. package/dist/adapters/openclaw.js.map +1 -1
  6. package/dist/proxy/evaluator.d.ts +0 -1
  7. package/dist/proxy/evaluator.d.ts.map +1 -1
  8. package/dist/proxy/evaluator.js +0 -1
  9. package/dist/proxy/evaluator.js.map +1 -1
  10. package/dist/proxy/index.d.ts +0 -1
  11. package/dist/proxy/index.d.ts.map +1 -1
  12. package/dist/proxy/index.js +0 -1
  13. package/dist/proxy/index.js.map +1 -1
  14. package/dist/proxy/profiles.d.ts +0 -1
  15. package/dist/proxy/profiles.d.ts.map +1 -1
  16. package/dist/proxy/profiles.js +0 -1
  17. package/dist/proxy/profiles.js.map +1 -1
  18. package/dist/proxy/server.d.ts +0 -1
  19. package/dist/proxy/server.d.ts.map +1 -1
  20. package/dist/proxy/server.js +0 -1
  21. package/dist/proxy/server.js.map +1 -1
  22. package/dist/proxy/stdio-bridge.d.ts +0 -1
  23. package/dist/proxy/stdio-bridge.d.ts.map +1 -1
  24. package/dist/proxy/stdio-bridge.js +0 -1
  25. package/dist/proxy/stdio-bridge.js.map +1 -1
  26. package/dist/proxy/types.d.ts +0 -1
  27. package/dist/proxy/types.d.ts.map +1 -1
  28. package/dist/proxy/types.js +0 -1
  29. package/dist/proxy/types.js.map +1 -1
  30. package/dist/proxy/verify.d.ts +0 -1
  31. package/dist/proxy/verify.d.ts.map +1 -1
  32. package/dist/proxy/verify.js +0 -1
  33. package/dist/proxy/verify.js.map +1 -1
  34. package/package.json +92 -97
  35. package/SECURITY.md +0 -59
  36. package/independent-verifier/README.md +0 -31
  37. package/independent-verifier/package.json +0 -18
  38. package/independent-verifier/verify.ts +0 -211
  39. package/src/adapters/openclaw.ts +0 -125
  40. package/src/core/artifact.ts +0 -45
  41. package/src/core/attestation.ts +0 -33
  42. package/src/core/behavioral.ts +0 -132
  43. package/src/core/bundle.ts +0 -45
  44. package/src/core/chain.ts +0 -72
  45. package/src/core/checkpoint.ts +0 -22
  46. package/src/core/delegation.ts +0 -146
  47. package/src/core/disclosure.ts +0 -32
  48. package/src/core/identity.ts +0 -62
  49. package/src/core/index.ts +0 -14
  50. package/src/core/portal.ts +0 -117
  51. package/src/core/quarantine.ts +0 -16
  52. package/src/core/receipt.ts +0 -33
  53. package/src/core/subject.ts +0 -11
  54. package/src/core/types.ts +0 -285
  55. package/src/crypto/hash.ts +0 -33
  56. package/src/crypto/index.ts +0 -5
  57. package/src/crypto/merkle.ts +0 -43
  58. package/src/crypto/salt.ts +0 -18
  59. package/src/crypto/sign.ts +0 -42
  60. package/src/crypto/types.ts +0 -19
  61. package/src/index.ts +0 -12
  62. package/src/middleware/governance.ts +0 -95
  63. package/src/middleware/index.ts +0 -1
  64. package/src/proxy/evaluator.ts +0 -176
  65. package/src/proxy/index.ts +0 -259
  66. package/src/proxy/profiles.ts +0 -48
  67. package/src/proxy/server.ts +0 -499
  68. package/src/proxy/stdio-bridge.ts +0 -171
  69. package/src/proxy/types.ts +0 -40
  70. package/src/proxy/verify.ts +0 -202
  71. package/src/server.ts +0 -435
  72. package/src/storage/index.ts +0 -3
  73. package/src/storage/interface.ts +0 -21
  74. package/src/storage/memory.ts +0 -27
  75. package/src/storage/sqlite.ts +0 -45
  76. package/src/tools/README.md +0 -13
  77. package/src/utils/canonical.ts +0 -14
  78. package/src/utils/constants.ts +0 -3
  79. package/src/utils/timestamp.ts +0 -12
  80. package/src/utils/uuid.ts +0 -2
@@ -1,62 +0,0 @@
1
- /**
2
- * Identity and Key Lifecycle.
3
- *
4
- * Non-biometric cryptographic identity: agent identity derived from
5
- * cryptographic key pair bound to append-only attestation history in
6
- * continuity chain. Authority from valid signature history, not biometric traits.
7
- *
8
- * Functions:
9
- * - keyFingerprint: re-exported from crypto/sign.ts for convenience
10
- * - isKeyValid: check key TTL expiry
11
- * - rotateKeyPair: generate new key pair for rotation
12
- * - recordKeyRotation: append KEY_ROTATION event to chain
13
- */
14
- import { generateKeyPair, keyFingerprint, pkToHex } from '../crypto/sign.js';
15
- import { isExpired } from '../utils/timestamp.js';
16
- import { appendEvent } from './chain.js';
17
- import type { KeyPair } from '../crypto/types.js';
18
- import type { ContinuityEvent, KeyRotationRecord } from './types.js';
19
-
20
- // Re-export keyFingerprint for identity module consumers (NCCoE §2)
21
- export { keyFingerprint } from '../crypto/sign.js';
22
-
23
- /**
24
- * Check whether a key is still valid given its issuance time and TTL.
25
- * NCCoE §2: non-biometric identity validity check.
26
- */
27
- export function isKeyValid(issuedAt: string, ttlSeconds: number): boolean {
28
- return !isExpired(issuedAt, ttlSeconds);
29
- }
30
-
31
- /**
32
- * Generate a new key pair for rotation, returning both old and new for
33
- * a transition period defined by policy. NCCoE §3: key rotation.
34
- */
35
- export function rotateKeyPair(currentKeyPair: KeyPair): { oldKeyPair: KeyPair; newKeyPair: KeyPair } {
36
- const newKeyPair = generateKeyPair();
37
- return { oldKeyPair: currentKeyPair, newKeyPair };
38
- }
39
-
40
- /**
41
- * Record a key rotation event on the continuity chain.
42
- * NCCoE §3: "Key rotation is handled by including both old and new public keys
43
- * during a transition period defined by policy."
44
- */
45
- export function recordKeyRotation(
46
- prevEvent: ContinuityEvent,
47
- keypairType: string,
48
- oldPublicKeyHex: string,
49
- newPublicKeyHex: string,
50
- reason: string,
51
- signingKeyPair: KeyPair,
52
- ): ContinuityEvent {
53
- const payload: KeyRotationRecord = {
54
- keypair_type: keypairType,
55
- old_public_key: oldPublicKeyHex,
56
- new_public_key: newPublicKeyHex,
57
- reason,
58
- rotation_timestamp: new Date().toISOString(),
59
- chain_sequence: prevEvent.sequence_number + 1,
60
- };
61
- return appendEvent('KEY_ROTATION', payload, prevEvent, signingKeyPair);
62
- }
package/src/core/index.ts DELETED
@@ -1,14 +0,0 @@
1
- export * from './types.js';
2
- export * from './subject.js';
3
- export * from './attestation.js';
4
- export * from './artifact.js';
5
- export * from './receipt.js';
6
- export * from './chain.js';
7
- export * from './portal.js';
8
- export * from './quarantine.js';
9
- export * from './checkpoint.js';
10
- export * from './bundle.js';
11
- export * from './disclosure.js';
12
- export * from './behavioral.js';
13
- export * from './delegation.js';
14
- export * from './identity.js';
@@ -1,117 +0,0 @@
1
- /**
2
- * Portal (Sentinel) - Runtime Enforcement Boundary. Ref 150, 270-280.
3
- * V3: TTL + revocation checked every measurement. Fail-closed semantics.
4
- * Aligned with NCCoE filing Sections 3-4 and NIST-2025-0035.
5
- */
6
- import { sha256Bytes, sha256Str } from '../crypto/hash.js';
7
- import { b64ToSig, hexToPk, verifyStr } from '../crypto/sign.js';
8
- import { canonicalize } from '../utils/canonical.js';
9
- import { isWithinPeriod, isExpired, utcNow } from '../utils/timestamp.js';
10
- import type { PolicyArtifact, PortalState, EnforcementAction, SubjectMetadata } from './types.js';
11
- import type { HashHex } from '../crypto/types.js';
12
-
13
- export interface MeasurementResult {
14
- match: boolean;
15
- currentBytesHash: HashHex;
16
- currentMetaHash: HashHex;
17
- expectedBytesHash: HashHex;
18
- expectedMetaHash: HashHex;
19
- ttl_ok: boolean;
20
- revoked: boolean;
21
- degraded?: boolean;
22
- }
23
-
24
- /** Degradation event record for the continuity chain. */
25
- export interface DegradationEvent {
26
- reason: string;
27
- timestamp: string;
28
- artifact_reference: HashHex;
29
- previous_state: string;
30
- }
31
-
32
- export class Portal {
33
- state: PortalState = 'INITIALIZATION';
34
- artifact: PolicyArtifact | null = null;
35
- sequenceCounter = 0;
36
- lastLeafHash: HashHex | null = null;
37
- revocations: Set<string> = new Set();
38
- degradationLog: DegradationEvent[] = [];
39
-
40
- loadArtifact(artifact: PolicyArtifact, pinnedPkHex: string): { ok: boolean; error?: string } {
41
- this.state = 'ARTIFACT_VERIFICATION';
42
- const { signature, ...unsigned } = artifact;
43
- if (!verifyStr(b64ToSig(signature), canonicalize(unsigned), hexToPk(pinnedPkHex))) {
44
- this.state = 'TERMINATED'; return { ok: false, error: 'Signature verification failed' };
45
- }
46
- if (!isWithinPeriod(utcNow(), artifact.effective_timestamp, artifact.expiration_timestamp)) {
47
- this.state = 'TERMINATED'; return { ok: false, error: 'Artifact outside effective period' };
48
- }
49
- if (this.revocations.has(artifact.sealed_hash)) {
50
- this.state = 'TERMINATED'; return { ok: false, error: 'Artifact has been revoked' };
51
- }
52
- this.artifact = artifact;
53
- this.state = 'ACTIVE_MONITORING';
54
- return { ok: true };
55
- }
56
-
57
- measure(subjectBytes: Uint8Array, meta: SubjectMetadata): MeasurementResult {
58
- if (!this.artifact) throw new Error('No artifact loaded');
59
- if (this.state === 'TERMINATED') throw new Error('Portal is terminated');
60
- // SAFE_STATE allows continued measurement for logging
61
- const empty = { currentBytesHash: '', currentMetaHash: '',
62
- expectedBytesHash: this.artifact.subject_identifier.bytes_hash,
63
- expectedMetaHash: this.artifact.subject_identifier.metadata_hash };
64
-
65
- // Graceful degradation: TTL expiry -> SAFE_STATE + DEGRADATION event + continued logging
66
- const ttl_ok = !isExpired(this.artifact.issued_timestamp, this.artifact.enforcement_parameters.ttl_seconds);
67
- if (!ttl_ok) {
68
- const prevState = this.state;
69
- this.state = 'SAFE_STATE';
70
- this.degradationLog.push({
71
- reason: 'TTL_EXPIRED',
72
- timestamp: utcNow(),
73
- artifact_reference: this.artifact.sealed_hash,
74
- previous_state: prevState,
75
- });
76
- return { match: false, ttl_ok: false, revoked: false, degraded: true, ...empty };
77
- }
78
-
79
- // Fail-closed: revocation check
80
- if (this.revocations.has(this.artifact.sealed_hash)) {
81
- this.state = 'TERMINATED'; return { match: false, ttl_ok: true, revoked: true, ...empty };
82
- }
83
-
84
- const currentBytesHash = sha256Bytes(subjectBytes);
85
- const currentMetaHash = sha256Str(canonicalize(meta));
86
- const match = currentBytesHash === this.artifact.subject_identifier.bytes_hash &&
87
- currentMetaHash === this.artifact.subject_identifier.metadata_hash;
88
-
89
- if (!match && this.state === 'ACTIVE_MONITORING') this.state = 'DRIFT_DETECTED';
90
- return { match, currentBytesHash, currentMetaHash,
91
- expectedBytesHash: this.artifact.subject_identifier.bytes_hash,
92
- expectedMetaHash: this.artifact.subject_identifier.metadata_hash,
93
- ttl_ok: true, revoked: false };
94
- }
95
-
96
- enforce(action: EnforcementAction): void {
97
- if (this.state !== 'DRIFT_DETECTED') throw new Error(`Cannot enforce in state ${this.state}`);
98
- switch (action) {
99
- case 'TERMINATE': case 'SAFE_STATE': this.state = 'TERMINATED'; break;
100
- case 'QUARANTINE': this.state = 'PHANTOM_QUARANTINE'; break;
101
- case 'ALERT_ONLY': this.state = 'ACTIVE_MONITORING'; break;
102
- default: break;
103
- }
104
- }
105
-
106
- revoke(sealedHash: string): void {
107
- this.revocations.add(sealedHash);
108
- if (this.artifact?.sealed_hash === sealedHash) this.state = 'TERMINATED';
109
- }
110
-
111
- isRevoked(sealedHash: string): boolean { return this.revocations.has(sealedHash); }
112
-
113
- reset(): void {
114
- this.state = 'INITIALIZATION'; this.artifact = null;
115
- this.sequenceCounter = 0; this.lastLeafHash = null;
116
- }
117
- }
@@ -1,16 +0,0 @@
1
- import { utcNow } from '../utils/timestamp.js';
2
- import type { QuarantineState } from './types.js';
3
-
4
- export function initQuarantine(): QuarantineState {
5
- return { active: true, started_at: utcNow(), inputs_captured: 0, outputs_severed: true, forensic_buffer: [] };
6
- }
7
-
8
- export function captureInput(q: QuarantineState, inputType: string, data: unknown): void {
9
- q.forensic_buffer.push({ timestamp: utcNow(), type: inputType, data });
10
- q.inputs_captured++;
11
- }
12
-
13
- export function releaseQuarantine(q: QuarantineState): { duration_ms: number; total_captures: number } {
14
- q.active = false;
15
- return { duration_ms: q.started_at ? Date.now() - Date.parse(q.started_at) : 0, total_captures: q.inputs_captured };
16
- }
@@ -1,33 +0,0 @@
1
- /** V3: measurement_type field. Receipts generated for EVERY measurement. */
2
- import { signStr, sigToB64 } from '../crypto/sign.js';
3
- import { canonicalize } from '../utils/canonical.js';
4
- import { utcNow } from '../utils/timestamp.js';
5
- import { uuid } from '../utils/uuid.js';
6
- import type { KeyPair, HashHex } from '../crypto/types.js';
7
- import type { SignedReceipt, SubjectIdentifier, EnforcementAction } from './types.js';
8
-
9
- export interface ReceiptInput {
10
- subjectId: SubjectIdentifier;
11
- artifactRef: HashHex;
12
- currentHash: string;
13
- sealedHash: string;
14
- driftDetected: boolean;
15
- driftDescription: string | null;
16
- action: EnforcementAction | null;
17
- measurementType: string;
18
- seq: number;
19
- prevLeaf: HashHex | null;
20
- portalKP: KeyPair;
21
- }
22
-
23
- export function generateReceipt(input: ReceiptInput): SignedReceipt {
24
- const unsigned = {
25
- receipt_id: uuid(), subject_identifier: input.subjectId,
26
- artifact_reference: input.artifactRef, current_hash: input.currentHash,
27
- sealed_hash: input.sealedHash, drift_detected: input.driftDetected,
28
- drift_description: input.driftDescription, enforcement_action: input.action,
29
- measurement_type: input.measurementType, timestamp: utcNow(),
30
- sequence_number: input.seq, previous_leaf_hash: input.prevLeaf,
31
- };
32
- return { ...unsigned, portal_signature: sigToB64(signStr(canonicalize(unsigned), input.portalKP.secretKey)) };
33
- }
@@ -1,11 +0,0 @@
1
- import { sha256Bytes, sha256Str } from '../crypto/hash.js';
2
- import { canonicalize } from '../utils/canonical.js';
3
- import type { SubjectIdentifier, SubjectMetadata } from './types.js';
4
-
5
- export function computeSubjectId(bytes: Uint8Array, meta: SubjectMetadata): SubjectIdentifier {
6
- return { bytes_hash: sha256Bytes(bytes), metadata_hash: sha256Str(canonicalize(meta)) };
7
- }
8
-
9
- export function computeSubjectIdFromString(content: string, meta: SubjectMetadata): SubjectIdentifier {
10
- return computeSubjectId(new TextEncoder().encode(content), meta);
11
- }
package/src/core/types.ts DELETED
@@ -1,285 +0,0 @@
1
- /**
2
- * V3: Aligned with NIST-2025-0035 and NCCoE AI Agent Identity filings.
3
- */
4
- import type { HashHex, SignatureBase64, SaltHex, MerkleInclusionProof } from '../crypto/types.js';
5
-
6
- // ── Subject (100, 102, 104, 106, 126) ──────────────────────────
7
-
8
- export interface SubjectIdentifier { // Ref 126
9
- bytes_hash: HashHex; // Ref 104
10
- metadata_hash: HashHex; // Ref 106
11
- }
12
-
13
- export interface SubjectMetadata {
14
- filename?: string;
15
- creation_timestamp?: string;
16
- author?: string;
17
- version?: string;
18
- content_type?: string;
19
- [key: string]: unknown;
20
- }
21
-
22
- // ── Enforcement (130–136, 162–168) ──────────────────────────────
23
-
24
- export type EnforcementAction =
25
- | 'TERMINATE' // Ref 162: immediate kill
26
- | 'QUARANTINE' // Ref 164: phantom execution
27
- | 'NETWORK_ISOLATE' // Ref 166: sever network, continue local
28
- | 'SAFE_STATE' // Ref 168: return-to-home / controlled shutdown
29
- | 'KEY_REVOKE' // invalidate crypto keys
30
- | 'TOKEN_INVALIDATE' // revoke access tokens
31
- | 'ACTUATOR_DISCONNECT' // sever physical actuator connections
32
- | 'ALERT_ONLY'; // log without enforcement (gradual deployment)
33
-
34
- export type MeasurementType =
35
- | 'EXECUTABLE_IMAGE' | 'LOADED_MODULES' | 'CONTAINER_IMAGE'
36
- | 'CONFIG_MANIFEST' | 'SBOM' | 'TEE_QUOTE'
37
- | 'MEMORY_REGIONS' | 'CONTROL_FLOW' | 'FILE_SYSTEM_STATE'
38
- | 'NETWORK_CONFIG';
39
-
40
- export interface EnforcementParams { // Ref 130
41
- measurement_cadence_ms: number; // Ref 132
42
- ttl_seconds: number; // Ref 134
43
- enforcement_triggers: EnforcementAction[]; // Ref 136
44
- re_attestation_required: boolean;
45
- measurement_types: MeasurementType[];
46
- behavioral_baseline?: BehavioralBaselineRef; // NCCoE §6: optional behavioral baseline reference
47
- }
48
-
49
- /** Inline behavioral baseline reference for EnforcementParams (NCCoE §6, CAISI §1a) */
50
- export interface BehavioralBaselineRef {
51
- permitted_tools: string[];
52
- forbidden_sequences: string[][];
53
- rate_limits: Record<string, number>;
54
- }
55
-
56
- // ── Policy & Disclosure (112, 138–142) ──────────────────────────
57
-
58
- export type Sensitivity = 'S1_LOW' | 'S2_MODERATE' | 'S3_HIGH' | 'S4_CRITICAL';
59
- export type DisclosureMode = 'PROOF_ONLY' | 'REVEAL_MIN' | 'REVEAL_FULL';
60
-
61
- export interface ClaimRecord { // Ref 140
62
- claim_id: string;
63
- sensitivity: Sensitivity;
64
- substitutes: string[];
65
- inference_risks: string[];
66
- permitted_modes: DisclosureMode[];
67
- }
68
-
69
- export interface SubstitutionRule { // Ref 142
70
- original_claim_id: string;
71
- substitute_claim_id: string;
72
- conditions: Record<string, unknown>;
73
- }
74
-
75
- export interface DisclosurePolicy { // Ref 138
76
- claims_taxonomy: ClaimRecord[];
77
- substitution_rules: SubstitutionRule[];
78
- }
79
-
80
- // ── Evidence Commitment (114) ───────────────────────────────────
81
-
82
- export interface EvidenceCommitmentRecord {
83
- commitment: HashHex;
84
- salt: SaltHex;
85
- label: string;
86
- }
87
-
88
- // ── Policy Artifact (120, 122, 124, 144) ────────────────────────
89
-
90
- export interface PolicyArtifact { // Ref 122 (Weave Piece)
91
- schema_version: string;
92
- protocol_version: string;
93
- subject_identifier: SubjectIdentifier;
94
- policy_reference: HashHex; // Ref 128
95
- policy_version: number;
96
- sealed_hash: HashHex; // Ref 124
97
- seal_salt: SaltHex; // stored for audit
98
- issued_timestamp: string;
99
- effective_timestamp: string;
100
- expiration_timestamp: string | null;
101
- issuer_identifier: string;
102
- enforcement_parameters: EnforcementParams;
103
- disclosure_policy: DisclosurePolicy;
104
- evidence_commitments: EvidenceCommitmentRecord[];
105
- signature: SignatureBase64; // Ref 144
106
- }
107
-
108
- // ── Receipts (170, 172) ─────────────────────────────────────────
109
- // V3: Generated for EVERY measurement, not just drift. Per NIST filing:
110
- // "each measurement generates a signed receipt - match or mismatch"
111
-
112
- export interface SignedReceipt { // Ref 172
113
- receipt_id: string;
114
- subject_identifier: SubjectIdentifier;
115
- artifact_reference: HashHex;
116
- current_hash: string;
117
- sealed_hash: string;
118
- drift_detected: boolean;
119
- drift_description: string | null;
120
- enforcement_action: EnforcementAction | null;
121
- measurement_type: string; // V3: which measurement was performed
122
- timestamp: string;
123
- sequence_number: number;
124
- previous_leaf_hash: HashHex | null;
125
- portal_signature: SignatureBase64;
126
- }
127
-
128
- // ── Continuity Chain (180–196) ──────────────────────────────────
129
-
130
- export type EventType =
131
- | 'GENESIS'
132
- | 'POLICY_ISSUANCE'
133
- | 'INTERACTION_RECEIPT'
134
- | 'REVOCATION' // V3: mid-session revocation
135
- | 'ATTESTATION'
136
- | 'ANCHOR_BATCH'
137
- | 'DISCLOSURE'
138
- | 'SUBSTITUTION'
139
- | 'KEY_ROTATION' // V3: key lifecycle event
140
- | 'BEHAVIORAL_DRIFT' // NCCoE §6: behavioral pattern deviation
141
- | 'DELEGATION' // NCCoE §4: sub-agent delegation
142
- | 'DEGRADATION' // CAISI §4a: graceful degradation event
143
- | 'RE_ATTESTATION'; // TTL re-attestation
144
-
145
- export interface GenesisPayload {
146
- protocol_version: string;
147
- taxonomy_version: string;
148
- root_fingerprint: string;
149
- specification_hash: HashHex;
150
- marker: 'GENESIS';
151
- }
152
-
153
- export interface ContinuityEvent { // Ref 184
154
- schema_version: string;
155
- protocol_version: string;
156
- event_type: EventType;
157
- event_id: string;
158
- sequence_number: number;
159
- timestamp: string;
160
- previous_leaf_hash: HashHex | null;
161
- leaf_hash: HashHex; // Ref 186
162
- payload: unknown; // Ref 192
163
- payload_hash: HashHex; // Ref 194
164
- event_signature: SignatureBase64; // Ref 196
165
- }
166
-
167
- export interface StructuralMetadata { // Ref 190
168
- schema_version: string;
169
- protocol_version: string;
170
- event_type: EventType;
171
- event_id: string;
172
- sequence_number: number;
173
- timestamp: string;
174
- previous_leaf_hash: HashHex | null;
175
- }
176
-
177
- // ── Checkpoints (200–214) ───────────────────────────────────────
178
-
179
- export interface CheckpointReference {
180
- merkle_root: HashHex;
181
- batch_start_sequence: number;
182
- batch_end_sequence: number;
183
- anchor_network: string;
184
- transaction_id: string;
185
- timestamp: string;
186
- }
187
-
188
- export interface AnchorBatchPayload {
189
- checkpoint_reference: CheckpointReference;
190
- leaf_count: number;
191
- }
192
-
193
- // ── Evidence Bundle (240–246) ───────────────────────────────────
194
-
195
- export interface EvidenceBundle {
196
- artifact: PolicyArtifact;
197
- receipts: SignedReceipt[];
198
- merkle_proofs: MerkleInclusionProof[];
199
- checkpoint_reference: CheckpointReference;
200
- public_key: string;
201
- bundle_signature: SignatureBase64;
202
- verification_tier?: VerificationTier; // CAISI §3b: Bronze/Silver/Gold tiering
203
- }
204
-
205
- // ── Disclosure (250–256) ────────────────────────────────────────
206
-
207
- export interface DisclosureRequest {
208
- requested_claim_id: string;
209
- requester_id: string;
210
- mode: DisclosureMode;
211
- timestamp: string;
212
- }
213
-
214
- export interface SubstitutionReceipt {
215
- receipt_id: string;
216
- original_claim_id: string;
217
- substitute_claim_id: string | null;
218
- policy_version: number;
219
- reason_code: string;
220
- timestamp: string;
221
- chain_sequence_ref: number;
222
- signature: SignatureBase64;
223
- }
224
-
225
- // ── Portal State Machine (150, 270–280) ─────────────────────────
226
-
227
- export type PortalState =
228
- | 'INITIALIZATION' // Ref 270
229
- | 'ARTIFACT_VERIFICATION' // Ref 272
230
- | 'ACTIVE_MONITORING' // Ref 274
231
- | 'DRIFT_DETECTED' // Ref 276
232
- | 'PHANTOM_QUARANTINE' // Ref 278
233
- | 'SAFE_STATE' // Graceful degradation (TTL expiry)
234
- | 'TERMINATED'; // Ref 280
235
-
236
- export type VerificationTier = 'BRONZE' | 'SILVER' | 'GOLD';
237
-
238
- // ── Revocation (V3) ────────────────────────────────────────────
239
- // Per NCCoE filing Phase 3b: "An administrator pushes a REVOCATION event
240
- // to the continuity chain, invalidating the agent's active policy artifact."
241
-
242
- export interface RevocationRecord {
243
- artifact_sealed_hash: HashHex;
244
- reason: string;
245
- revoked_by: string; // issuer pk hex
246
- timestamp: string;
247
- }
248
-
249
- // ── Quarantine (220–230) ────────────────────────────────────────
250
-
251
- export interface QuarantineState {
252
- active: boolean;
253
- started_at: string | null;
254
- inputs_captured: number;
255
- outputs_severed: boolean;
256
- forensic_buffer: Array<{ timestamp: string; type: string; data: unknown }>;
257
- forensic_receipts?: string[]; // Receipt IDs from forensic capture
258
- }
259
-
260
- // ── Delegation (NCCoE §4) ──────────────────────────────────────
261
-
262
- export interface DelegationRecord {
263
- sub_agent_id: string;
264
- parent_artifact_reference: HashHex;
265
- child_artifact: PolicyArtifact;
266
- permitted_tools: string[];
267
- ttl_seconds: number;
268
- delegation_timestamp: string;
269
- chain_sequence: number;
270
- }
271
-
272
- // ── Key Lifecycle ──────────────────────────────────────────────
273
-
274
- export interface KeyRotationRecord {
275
- keypair_type: string; // e.g. 'issuer', 'portal', 'chain'
276
- old_public_key: string;
277
- new_public_key: string;
278
- reason: string;
279
- rotation_timestamp: string;
280
- chain_sequence: number;
281
- }
282
-
283
- // ── Sensitivity Level Aliases ────────────────────────────────────
284
- // Existing Sensitivity type uses S1_LOW etc. These aliases map to the short forms.
285
- export type SensitivityLevel = 'S1' | 'S2' | 'S3' | 'S4';
@@ -1,33 +0,0 @@
1
- import { sha256 } from '@noble/hashes/sha256';
2
- import { blake2b } from '@noble/hashes/blake2b';
3
- import { bytesToHex } from '@noble/hashes/utils';
4
- import type { HashHex } from './types.js';
5
-
6
- const enc = new TextEncoder();
7
-
8
- export function sha256Bytes(data: Uint8Array): HashHex {
9
- return bytesToHex(sha256(data));
10
- }
11
-
12
- export function sha256Str(data: string): HashHex {
13
- return sha256Bytes(enc.encode(data));
14
- }
15
-
16
- export function blake2b256(data: Uint8Array): HashHex {
17
- return bytesToHex(blake2b(data, { dkLen: 32 }));
18
- }
19
-
20
- /** Concatenate inputs (NO delimiter) and SHA-256. No delimiters per protocol spec. */
21
- export function sha256Cat(...parts: (Uint8Array | string)[]): HashHex {
22
- const bufs = parts.map(p => typeof p === 'string' ? enc.encode(p) : p);
23
- const total = bufs.reduce((n, b) => n + b.length, 0);
24
- const combined = new Uint8Array(total);
25
- let off = 0;
26
- for (const b of bufs) { combined.set(b, off); off += b.length; }
27
- return sha256Bytes(combined);
28
- }
29
-
30
- /** Concatenate hex strings as text (no decode) and hash. For sealed_hash computation. */
31
- export function sha256HexCat(...hexes: string[]): HashHex {
32
- return sha256Str(hexes.join(''));
33
- }
@@ -1,5 +0,0 @@
1
- export * from './types.js';
2
- export * from './hash.js';
3
- export * from './sign.js';
4
- export * from './salt.js';
5
- export * from './merkle.js';
@@ -1,43 +0,0 @@
1
- import { sha256Str } from './hash.js';
2
- import type { HashHex, MerkleInclusionProof } from './types.js';
3
-
4
- function pair(l: HashHex, r: HashHex): HashHex { return sha256Str(l + r); }
5
-
6
- export function buildMerkleTree(leaves: HashHex[]): { root: HashHex; layers: HashHex[][] } {
7
- if (!leaves.length) throw new Error('Empty leaf set');
8
- if (leaves.length === 1) return { root: leaves[0], layers: [leaves] };
9
- const layers: HashHex[][] = [[...leaves]];
10
- let cur = leaves;
11
- while (cur.length > 1) {
12
- const next: HashHex[] = [];
13
- for (let i = 0; i < cur.length; i += 2) {
14
- next.push(pair(cur[i], i + 1 < cur.length ? cur[i + 1] : cur[i]));
15
- }
16
- layers.push(next);
17
- cur = next;
18
- }
19
- return { root: cur[0], layers };
20
- }
21
-
22
- export function inclusionProof(leaves: HashHex[], idx: number): MerkleInclusionProof {
23
- if (idx < 0 || idx >= leaves.length) throw new RangeError(`Index ${idx} out of [0,${leaves.length})`);
24
- const { root, layers } = buildMerkleTree(leaves);
25
- const siblings: MerkleInclusionProof['siblings'] = [];
26
- let ci = idx;
27
- for (let L = 0; L < layers.length - 1; L++) {
28
- const layer = layers[L];
29
- const isRight = ci % 2 === 1;
30
- const si = isRight ? ci - 1 : (ci + 1 < layer.length ? ci + 1 : ci);
31
- siblings.push({ hash: layer[si], position: isRight ? 'left' : 'right' });
32
- ci = Math.floor(ci / 2);
33
- }
34
- return { leafHash: leaves[idx], leafIndex: idx, siblings, root };
35
- }
36
-
37
- export function verifyProof(proof: MerkleInclusionProof): boolean {
38
- let h = proof.leafHash;
39
- for (const s of proof.siblings) {
40
- h = s.position === 'left' ? pair(s.hash, h) : pair(h, s.hash);
41
- }
42
- return h === proof.root;
43
- }
@@ -1,18 +0,0 @@
1
- import { randomBytes } from 'node:crypto';
2
- import { bytesToHex } from '@noble/hashes/utils';
3
- import { sha256Cat } from './hash.js';
4
- import type { SaltHex, SaltedCommitment, HashHex } from './types.js';
5
-
6
- const enc = new TextEncoder();
7
-
8
- export function generateSalt(): SaltHex { return bytesToHex(randomBytes(16)); }
9
-
10
- export function saltedCommitment(content: Uint8Array | string, salt?: SaltHex): SaltedCommitment {
11
- const s = salt ?? generateSalt();
12
- const c = typeof content === 'string' ? enc.encode(content) : content;
13
- return { commitment: sha256Cat(c, s), salt: s };
14
- }
15
-
16
- export function verifySaltedCommitment(content: Uint8Array | string, salt: SaltHex, expected: HashHex): boolean {
17
- return saltedCommitment(content, salt).commitment === expected;
18
- }