@grc-claw/evidence 0.8.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.
@@ -0,0 +1,56 @@
1
+ export type ActionExecutionState = 'intent_recorded' | 'approval_required' | 'denied' | 'executing' | 'simulated' | 'recorded' | 'executed' | 'verified' | 'not_configured' | 'failed';
2
+ export interface ActionLedgerEvent {
3
+ sequence: number;
4
+ actionId: string;
5
+ at: string;
6
+ kind: 'intent' | 'decision' | 'result';
7
+ tenantId: number;
8
+ sessionId: string;
9
+ tool: string;
10
+ idempotencyKey?: string;
11
+ executionState: ActionExecutionState;
12
+ decisionReason?: string;
13
+ requiresApproval?: boolean;
14
+ argsHash?: string;
15
+ argKeys?: string[];
16
+ outputHash?: string;
17
+ evidenceId?: string;
18
+ targetReceipt?: string;
19
+ previousHash: string;
20
+ hash: string;
21
+ }
22
+ /**
23
+ * Append-only local proof of an agent action. Payloads are represented by hashes and key names,
24
+ * keeping sensitive request and response content out of the operational ledger.
25
+ */
26
+ export declare class ActionLedger {
27
+ private readonly filePath?;
28
+ private readonly events;
29
+ constructor(filePath?: string | undefined);
30
+ recordIntent(input: {
31
+ tenantId: number;
32
+ sessionId: string;
33
+ tool: string;
34
+ args: Record<string, unknown>;
35
+ idempotencyKey?: string;
36
+ }): ActionLedgerEvent;
37
+ recordDecision(intent: ActionLedgerEvent, input: {
38
+ allowed: boolean;
39
+ reason: string;
40
+ requiresApproval: boolean;
41
+ }): ActionLedgerEvent;
42
+ recordResult(intent: ActionLedgerEvent, input: {
43
+ executionState: Exclude<ActionExecutionState, 'intent_recorded' | 'approval_required' | 'denied' | 'executing'>;
44
+ output?: Record<string, unknown>;
45
+ evidenceId?: string;
46
+ targetReceipt?: string;
47
+ }): ActionLedgerEvent;
48
+ list(limit?: number): ActionLedgerEvent[];
49
+ verify(): {
50
+ ok: boolean;
51
+ checked: number;
52
+ error?: string;
53
+ };
54
+ private append;
55
+ }
56
+ //# sourceMappingURL=action-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-ledger.d.ts","sourceRoot":"","sources":["../src/action-ledger.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,oBAAoB,GAC5B,iBAAiB,GACjB,mBAAmB,GACnB,QAAQ,GACR,WAAW,GACX,WAAW,GACX,UAAU,GACV,UAAU,GACV,UAAU,GACV,gBAAgB,GAChB,QAAQ,CAAC;AAEb,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,oBAAoB,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAkCD;;;GAGG;AACH,qBAAa,YAAY;IAGX,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAFtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;gBAErB,QAAQ,CAAC,EAAE,MAAM,YAAA;IAQ9C,YAAY,CAAC,KAAK,EAAE;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,iBAAiB;IAcrB,cAAc,CACZ,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE,GACrE,iBAAiB;IAkBpB,YAAY,CACV,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE;QACL,cAAc,EAAE,OAAO,CAAC,oBAAoB,EAAE,iBAAiB,GAAG,mBAAmB,GAAG,QAAQ,GAAG,WAAW,CAAC,CAAC;QAChH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,GACA,iBAAiB;IAepB,IAAI,CAAC,KAAK,SAAM,GAAG,iBAAiB,EAAE;IAItC,MAAM,IAAI;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAe1D,OAAO,CAAC,MAAM;CAgBf"}
@@ -0,0 +1,122 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ const GENESIS_HASH = '0'.repeat(64);
5
+ function sha256(value) {
6
+ return createHash('sha256').update(value).digest('hex');
7
+ }
8
+ function hashable(event) {
9
+ return JSON.stringify({
10
+ sequence: event.sequence,
11
+ actionId: event.actionId,
12
+ at: event.at,
13
+ kind: event.kind,
14
+ tenantId: event.tenantId,
15
+ sessionId: event.sessionId,
16
+ tool: event.tool,
17
+ idempotencyKey: event.idempotencyKey,
18
+ executionState: event.executionState,
19
+ decisionReason: event.decisionReason,
20
+ requiresApproval: event.requiresApproval,
21
+ argsHash: event.argsHash,
22
+ argKeys: event.argKeys,
23
+ outputHash: event.outputHash,
24
+ evidenceId: event.evidenceId,
25
+ targetReceipt: event.targetReceipt,
26
+ previousHash: event.previousHash,
27
+ });
28
+ }
29
+ /**
30
+ * Append-only local proof of an agent action. Payloads are represented by hashes and key names,
31
+ * keeping sensitive request and response content out of the operational ledger.
32
+ */
33
+ export class ActionLedger {
34
+ filePath;
35
+ events = [];
36
+ constructor(filePath) {
37
+ this.filePath = filePath;
38
+ if (filePath && existsSync(filePath)) {
39
+ for (const line of readFileSync(filePath, 'utf8').split('\n').filter(Boolean)) {
40
+ this.events.push(JSON.parse(line));
41
+ }
42
+ }
43
+ }
44
+ recordIntent(input) {
45
+ return this.append({
46
+ actionId: randomUUID(),
47
+ kind: 'intent',
48
+ tenantId: input.tenantId,
49
+ sessionId: input.sessionId,
50
+ tool: input.tool,
51
+ idempotencyKey: input.idempotencyKey,
52
+ executionState: 'intent_recorded',
53
+ argsHash: sha256(JSON.stringify(input.args)),
54
+ argKeys: Object.keys(input.args).sort(),
55
+ });
56
+ }
57
+ recordDecision(intent, input) {
58
+ return this.append({
59
+ actionId: intent.actionId,
60
+ kind: 'decision',
61
+ tenantId: intent.tenantId,
62
+ sessionId: intent.sessionId,
63
+ tool: intent.tool,
64
+ idempotencyKey: intent.idempotencyKey,
65
+ executionState: input.allowed
66
+ ? 'executing'
67
+ : input.requiresApproval
68
+ ? 'approval_required'
69
+ : 'denied',
70
+ decisionReason: input.reason,
71
+ requiresApproval: input.requiresApproval,
72
+ });
73
+ }
74
+ recordResult(intent, input) {
75
+ return this.append({
76
+ actionId: intent.actionId,
77
+ kind: 'result',
78
+ tenantId: intent.tenantId,
79
+ sessionId: intent.sessionId,
80
+ tool: intent.tool,
81
+ idempotencyKey: intent.idempotencyKey,
82
+ executionState: input.executionState,
83
+ outputHash: input.output ? sha256(JSON.stringify(input.output)) : undefined,
84
+ evidenceId: input.evidenceId,
85
+ targetReceipt: input.targetReceipt,
86
+ });
87
+ }
88
+ list(limit = 100) {
89
+ return this.events.slice(-Math.max(1, Math.min(limit, 500))).reverse();
90
+ }
91
+ verify() {
92
+ let previousHash = GENESIS_HASH;
93
+ for (const event of this.events) {
94
+ if (event.previousHash !== previousHash) {
95
+ return { ok: false, checked: event.sequence - 1, error: `chain_break_at_${event.sequence}` };
96
+ }
97
+ const { hash, ...body } = event;
98
+ if (sha256(hashable(body)) !== hash) {
99
+ return { ok: false, checked: event.sequence - 1, error: `hash_mismatch_at_${event.sequence}` };
100
+ }
101
+ previousHash = event.hash;
102
+ }
103
+ return { ok: true, checked: this.events.length };
104
+ }
105
+ append(input) {
106
+ const previousHash = this.events.at(-1)?.hash ?? GENESIS_HASH;
107
+ const withoutHash = {
108
+ ...input,
109
+ sequence: this.events.length + 1,
110
+ at: input.at ?? new Date().toISOString(),
111
+ previousHash,
112
+ };
113
+ const event = { ...withoutHash, hash: sha256(hashable(withoutHash)) };
114
+ this.events.push(event);
115
+ if (this.filePath) {
116
+ mkdirSync(dirname(this.filePath), { recursive: true });
117
+ appendFileSync(this.filePath, `${JSON.stringify(event)}\n`, { mode: 0o600 });
118
+ }
119
+ return event;
120
+ }
121
+ }
122
+ //# sourceMappingURL=action-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-ledger.js","sourceRoot":"","sources":["../src/action-ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type { ActionLedgerEvent } from './action-ledger.js';
2
+ export interface AssuranceEnvelope {
3
+ version: 'v1';
4
+ actionId: string;
5
+ tenantId: number;
6
+ sessionId: string;
7
+ tool: string;
8
+ idempotencyKey?: string;
9
+ createdAt: string;
10
+ updatedAt: string;
11
+ intent: {
12
+ argsHash?: string;
13
+ argKeys?: string[];
14
+ ledgerHash: string;
15
+ };
16
+ policy?: {
17
+ executionState: string;
18
+ allowed: boolean;
19
+ reason?: string;
20
+ requiresApproval?: boolean;
21
+ ledgerHash: string;
22
+ };
23
+ result?: {
24
+ executionState: string;
25
+ outputHash?: string;
26
+ evidenceId?: string;
27
+ targetReceipt?: string;
28
+ ledgerHash: string;
29
+ };
30
+ identity?: {
31
+ agentDid?: string;
32
+ status?: 'provisional' | 'verified';
33
+ };
34
+ assurance?: {
35
+ riskScore?: number;
36
+ blastRadiusImpact?: number;
37
+ controlId?: string;
38
+ };
39
+ }
40
+ export interface AssuranceEnvelopeVerification {
41
+ ok: boolean;
42
+ actionId: string;
43
+ envelopeHash: string;
44
+ checkedAt: string;
45
+ errors: string[];
46
+ }
47
+ export declare function hashAssuranceEnvelope(envelope: AssuranceEnvelope): string;
48
+ /** Build a redacted, portable action receipt from hash-chained ledger events. */
49
+ export declare function createAssuranceEnvelope(input: {
50
+ intent: ActionLedgerEvent;
51
+ decision?: ActionLedgerEvent;
52
+ result?: ActionLedgerEvent;
53
+ identity?: AssuranceEnvelope['identity'];
54
+ assurance?: AssuranceEnvelope['assurance'];
55
+ }): AssuranceEnvelope;
56
+ /** Verify an assurance receipt is complete enough for auditors and contains no raw payloads. */
57
+ export declare function verifyAssuranceEnvelope(envelope: AssuranceEnvelope): AssuranceEnvelopeVerification;
58
+ /** Return an auditor-safe receipt with only hashes, identity, policy, and assurance metadata. */
59
+ export declare function redactAssuranceEnvelopeForSharing(envelope: AssuranceEnvelope): AssuranceEnvelope;
60
+ //# sourceMappingURL=assurance-envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assurance-envelope.d.ts","sourceRoot":"","sources":["../src/assurance-envelope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,IAAI,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,MAAM,CAAC,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACvH,MAAM,CAAC,EAAE;QACP,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,aAAa,GAAG,UAAU,CAAA;KAAE,CAAC;IACtE,SAAS,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpF;AAED,MAAM,WAAW,6BAA6B;IAC5C,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAgBD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAEzE;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,CAAC,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACzC,SAAS,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;CAC5C,GAAG,iBAAiB,CAiCpB;AAED,gGAAgG;AAChG,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,6BAA6B,CAiClG;AAED,iGAAiG;AACjG,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,iBAAiB,GAAG,iBAAiB,CAYhG"}
@@ -0,0 +1,109 @@
1
+ import { createHash } from 'node:crypto';
2
+ function stableSerialize(value) {
3
+ if (Array.isArray(value)) {
4
+ return `[${value.map((item) => stableSerialize(item)).join(',')}]`;
5
+ }
6
+ if (value && typeof value === 'object') {
7
+ return `{${Object.entries(value)
8
+ .filter(([, item]) => item !== undefined)
9
+ .sort(([a], [b]) => a.localeCompare(b))
10
+ .map(([key, item]) => `${JSON.stringify(key)}:${stableSerialize(item)}`)
11
+ .join(',')}}`;
12
+ }
13
+ return JSON.stringify(value);
14
+ }
15
+ export function hashAssuranceEnvelope(envelope) {
16
+ return createHash('sha256').update(stableSerialize(envelope)).digest('hex');
17
+ }
18
+ /** Build a redacted, portable action receipt from hash-chained ledger events. */
19
+ export function createAssuranceEnvelope(input) {
20
+ const { intent, decision, result } = input;
21
+ return {
22
+ version: 'v1',
23
+ actionId: intent.actionId,
24
+ tenantId: intent.tenantId,
25
+ sessionId: intent.sessionId,
26
+ tool: intent.tool,
27
+ idempotencyKey: intent.idempotencyKey,
28
+ createdAt: intent.at,
29
+ updatedAt: result?.at ?? decision?.at ?? intent.at,
30
+ intent: { argsHash: intent.argsHash, argKeys: intent.argKeys, ledgerHash: intent.hash },
31
+ policy: decision
32
+ ? {
33
+ executionState: decision.executionState,
34
+ allowed: decision.executionState === 'executing',
35
+ reason: decision.decisionReason,
36
+ requiresApproval: decision.requiresApproval,
37
+ ledgerHash: decision.hash,
38
+ }
39
+ : undefined,
40
+ result: result
41
+ ? {
42
+ executionState: result.executionState,
43
+ outputHash: result.outputHash,
44
+ evidenceId: result.evidenceId,
45
+ targetReceipt: result.targetReceipt,
46
+ ledgerHash: result.hash,
47
+ }
48
+ : undefined,
49
+ identity: input.identity,
50
+ assurance: input.assurance,
51
+ };
52
+ }
53
+ /** Verify an assurance receipt is complete enough for auditors and contains no raw payloads. */
54
+ export function verifyAssuranceEnvelope(envelope) {
55
+ const errors = [];
56
+ if (envelope.version !== 'v1')
57
+ errors.push('unsupported_version');
58
+ if (!envelope.actionId)
59
+ errors.push('missing_action_id');
60
+ if (!Number.isFinite(envelope.tenantId))
61
+ errors.push('missing_tenant_id');
62
+ if (!envelope.sessionId)
63
+ errors.push('missing_session_id');
64
+ if (!envelope.tool)
65
+ errors.push('missing_tool');
66
+ if (!envelope.createdAt)
67
+ errors.push('missing_created_at');
68
+ if (!envelope.updatedAt)
69
+ errors.push('missing_updated_at');
70
+ if (!envelope.intent?.ledgerHash)
71
+ errors.push('missing_intent_ledger_hash');
72
+ if (envelope.policy && !envelope.policy.ledgerHash)
73
+ errors.push('missing_policy_ledger_hash');
74
+ if (envelope.result && !envelope.result.ledgerHash)
75
+ errors.push('missing_result_ledger_hash');
76
+ const serialized = JSON.stringify({
77
+ idempotencyKey: envelope.idempotencyKey,
78
+ identity: envelope.identity,
79
+ assurance: envelope.assurance,
80
+ });
81
+ const rawPayloadMarkers = ['password', 'secret', 'token', 'apiKey', 'privateKey'];
82
+ for (const marker of rawPayloadMarkers) {
83
+ if (serialized.includes(`"${marker}":`)) {
84
+ errors.push(`raw_payload_marker_${marker}`);
85
+ }
86
+ }
87
+ return {
88
+ ok: errors.length === 0,
89
+ actionId: envelope.actionId,
90
+ envelopeHash: hashAssuranceEnvelope(envelope),
91
+ checkedAt: new Date().toISOString(),
92
+ errors,
93
+ };
94
+ }
95
+ /** Return an auditor-safe receipt with only hashes, identity, policy, and assurance metadata. */
96
+ export function redactAssuranceEnvelopeForSharing(envelope) {
97
+ return {
98
+ ...envelope,
99
+ idempotencyKey: envelope.idempotencyKey ? `redacted:${hashAssuranceEnvelope(envelope).slice(0, 12)}` : undefined,
100
+ intent: {
101
+ argsHash: envelope.intent.argsHash,
102
+ argKeys: envelope.intent.argKeys,
103
+ ledgerHash: envelope.intent.ledgerHash,
104
+ },
105
+ policy: envelope.policy,
106
+ result: envelope.result,
107
+ };
108
+ }
109
+ //# sourceMappingURL=assurance-envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assurance-envelope.js","sourceRoot":"","sources":["../src/assurance-envelope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiCzC,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACrE,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC;aACxD,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC;aACxC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;aACvE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAA2B;IAC/D,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,uBAAuB,CAAC,KAMvC;IACC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAC3C,OAAO;QACL,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS,EAAE,MAAM,CAAC,EAAE;QACpB,SAAS,EAAE,MAAM,EAAE,EAAE,IAAI,QAAQ,EAAE,EAAE,IAAI,MAAM,CAAC,EAAE;QAClD,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE;QACvF,MAAM,EAAE,QAAQ;YACd,CAAC,CAAC;gBACE,cAAc,EAAE,QAAQ,CAAC,cAAc;gBACvC,OAAO,EAAE,QAAQ,CAAC,cAAc,KAAK,WAAW;gBAChD,MAAM,EAAE,QAAQ,CAAC,cAAc;gBAC/B,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;gBAC3C,UAAU,EAAE,QAAQ,CAAC,IAAI;aAC1B;YACH,CAAC,CAAC,SAAS;QACb,MAAM,EAAE,MAAM;YACZ,CAAC,CAAC;gBACE,cAAc,EAAE,MAAM,CAAC,cAAc;gBACrC,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,UAAU,EAAE,MAAM,CAAC,IAAI;aACxB;YACH,CAAC,CAAC,SAAS;QACb,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;AACJ,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,uBAAuB,CAAC,QAA2B;IACjE,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI;QAAE,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAClE,IAAI,CAAC,QAAQ,CAAC,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC1E,IAAI,CAAC,QAAQ,CAAC,SAAS;QAAE,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC3D,IAAI,CAAC,QAAQ,CAAC,IAAI;QAAE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAChD,IAAI,CAAC,QAAQ,CAAC,SAAS;QAAE,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC3D,IAAI,CAAC,QAAQ,CAAC,SAAS;QAAE,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC3D,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU;QAAE,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC5E,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU;QAAE,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC9F,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU;QAAE,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAE9F,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,SAAS,EAAE,QAAQ,CAAC,SAAS;KAC9B,CAAC,CAAC;IACH,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAClF,KAAK,MAAM,MAAM,IAAI,iBAAiB,EAAE,CAAC;QACvC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,YAAY,EAAE,qBAAqB,CAAC,QAAQ,CAAC;QAC7C,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,MAAM;KACP,CAAC;AACJ,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,iCAAiC,CAAC,QAA2B;IAC3E,OAAO;QACL,GAAG,QAAQ;QACX,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,qBAAqB,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;QAChH,MAAM,EAAE;YACN,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ;YAClC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO;YAChC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU;SACvC;QACD,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=assurance-envelope.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assurance-envelope.test.d.ts","sourceRoot":"","sources":["../src/assurance-envelope.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,60 @@
1
+ import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+ import { ActionLedger, createAssuranceEnvelope, hashAssuranceEnvelope, redactAssuranceEnvelopeForSharing, verifyAssuranceEnvelope, } from './index.js';
4
+ describe('assurance envelopes', () => {
5
+ it('creates deterministic, auditor-safe receipts without raw invocation payloads', () => {
6
+ const ledger = new ActionLedger();
7
+ const intent = ledger.recordIntent({
8
+ tenantId: 42,
9
+ sessionId: 'agentic-assurance-test',
10
+ tool: 'evidence.attach',
11
+ args: { controlId: 'CMMC-AC.L1-3.1.1', secret: 'do-not-leak' },
12
+ idempotencyKey: 'receipt-test-key',
13
+ });
14
+ const decision = ledger.recordDecision(intent, {
15
+ allowed: true,
16
+ reason: 'within_policy',
17
+ requiresApproval: false,
18
+ });
19
+ const result = ledger.recordResult(intent, {
20
+ executionState: 'recorded',
21
+ evidenceId: 'ev-test',
22
+ output: { token: 'also-do-not-leak' },
23
+ });
24
+ const envelope = createAssuranceEnvelope({
25
+ intent,
26
+ decision,
27
+ result,
28
+ identity: { agentDid: 'did:grc:test-agent', status: 'verified' },
29
+ assurance: { riskScore: 4, blastRadiusImpact: 2, controlId: 'CMMC-AC.L1-3.1.1' },
30
+ });
31
+ const serialized = JSON.stringify(envelope);
32
+ assert.equal(serialized.includes('do-not-leak'), false);
33
+ assert.equal(serialized.includes('also-do-not-leak'), false);
34
+ assert.equal(envelope.intent.argKeys?.includes('secret'), true);
35
+ const verification = verifyAssuranceEnvelope(envelope);
36
+ assert.equal(verification.ok, true);
37
+ assert.equal(verification.errors.length, 0);
38
+ assert.equal(verification.envelopeHash, hashAssuranceEnvelope(envelope));
39
+ const shared = redactAssuranceEnvelopeForSharing(envelope);
40
+ assert.match(shared.idempotencyKey ?? '', /^redacted:/);
41
+ assert.equal(hashAssuranceEnvelope(envelope), hashAssuranceEnvelope(envelope));
42
+ });
43
+ it('flags structurally incomplete receipts', () => {
44
+ const incomplete = {
45
+ version: 'v1',
46
+ actionId: '',
47
+ tenantId: Number.NaN,
48
+ sessionId: '',
49
+ tool: '',
50
+ createdAt: '',
51
+ updatedAt: '',
52
+ intent: { ledgerHash: '' },
53
+ };
54
+ const verification = verifyAssuranceEnvelope(incomplete);
55
+ assert.equal(verification.ok, false);
56
+ assert.ok(verification.errors.includes('missing_action_id'));
57
+ assert.ok(verification.errors.includes('missing_intent_ledger_hash'));
58
+ });
59
+ });
60
+ //# sourceMappingURL=assurance-envelope.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assurance-envelope.test.js","sourceRoot":"","sources":["../src/assurance-envelope.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export * from './action-ledger.js';
2
+ export * from './assurance-envelope.js';
3
+ export interface EvidenceRecord {
4
+ id: string;
5
+ controlId: string;
6
+ tenantId: number;
7
+ sha256: string;
8
+ uri: string;
9
+ collectedAt: string;
10
+ lineage: {
11
+ parentHash?: string;
12
+ source: string;
13
+ };
14
+ }
15
+ export interface EvidenceDatabase {
16
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<{
17
+ rows: T[];
18
+ rowCount: number;
19
+ }>;
20
+ execute(sql: string, params?: unknown[]): Promise<void>;
21
+ }
22
+ export declare class EvidenceStore {
23
+ private readonly records;
24
+ private readonly db?;
25
+ private pendingWrites;
26
+ constructor(database?: EvidenceDatabase);
27
+ static hashContent(buffer: Buffer | string): string;
28
+ private writeToDbWithRetry;
29
+ attach(input: Omit<EvidenceRecord, 'id' | 'sha256'> & {
30
+ content?: Buffer | string;
31
+ }): EvidenceRecord;
32
+ get(id: string): EvidenceRecord | undefined;
33
+ /** Read a single evidence record from PostgreSQL (primary) with in-memory fallback */
34
+ getFromDb(id: string): Promise<EvidenceRecord | undefined>;
35
+ /** Synchronous read from in-memory write-through cache */
36
+ listByControl(controlId: string): EvidenceRecord[];
37
+ /** Read evidence for a control from PostgreSQL (primary) with in-memory fallback */
38
+ listByControlFromDb(controlId: string): Promise<EvidenceRecord[]>;
39
+ /** Flush all pending PostgreSQL writes */
40
+ flush(): Promise<void>;
41
+ loadFromDatabase(): Promise<void>;
42
+ }
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AAExC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAClD;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9G,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AASD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAmB;IACvC,OAAO,CAAC,aAAa,CAAuB;gBAEhC,QAAQ,CAAC,EAAE,gBAAgB;IAIvC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;YAIrC,kBAAkB;IAkChC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,QAAQ,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,cAAc;IAkBpG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI3C,sFAAsF;IAChF,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAoChE,0DAA0D;IAC1D,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE;IAIlD,oFAAoF;IAC9E,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAsCvE,0CAA0C;IACpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;CA8BxC"}
package/dist/index.js ADDED
@@ -0,0 +1,151 @@
1
+ import { createHash } from 'node:crypto';
2
+ export * from './action-ledger.js';
3
+ export * from './assurance-envelope.js';
4
+ const MAX_RETRIES = 3;
5
+ const BASE_BACKOFF_MS = 100;
6
+ async function sleep(ms) {
7
+ return new Promise((resolve) => setTimeout(resolve, ms));
8
+ }
9
+ export class EvidenceStore {
10
+ records = new Map();
11
+ db;
12
+ pendingWrites = [];
13
+ constructor(database) {
14
+ this.db = database;
15
+ }
16
+ static hashContent(buffer) {
17
+ return createHash('sha256').update(buffer).digest('hex');
18
+ }
19
+ async writeToDbWithRetry(record) {
20
+ if (!this.db)
21
+ return;
22
+ let lastError;
23
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
24
+ try {
25
+ await this.db.execute(`INSERT INTO evidence (id, tenant_id, control_id, sha256, uri, metadata, lineage, collected_at, created_at)
26
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW())
27
+ ON CONFLICT (id) DO NOTHING`, [
28
+ record.id,
29
+ String(record.tenantId),
30
+ record.controlId,
31
+ record.sha256,
32
+ record.uri,
33
+ JSON.stringify({}),
34
+ JSON.stringify(record.lineage),
35
+ record.collectedAt,
36
+ ]);
37
+ return;
38
+ }
39
+ catch (err) {
40
+ lastError = err instanceof Error ? err : new Error(String(err));
41
+ if (attempt < MAX_RETRIES - 1) {
42
+ await sleep(BASE_BACKOFF_MS * Math.pow(2, attempt));
43
+ }
44
+ }
45
+ }
46
+ console.warn(`[EVIDENCE] PostgreSQL write failed after ${MAX_RETRIES} retries for ${record.id}:`, lastError?.message);
47
+ }
48
+ attach(input) {
49
+ const sha256 = input.content !== undefined
50
+ ? EvidenceStore.hashContent(input.content)
51
+ : EvidenceStore.hashContent(`${input.uri}|${input.collectedAt}`);
52
+ const id = `ev-${sha256.slice(0, 16)}`;
53
+ const record = { ...input, id, sha256 };
54
+ // Write to PostgreSQL first, then update in-memory cache
55
+ const writePromise = this.writeToDbWithRetry(record);
56
+ this.pendingWrites.push(writePromise);
57
+ // Update in-memory cache immediately for fast reads
58
+ this.records.set(id, record);
59
+ return record;
60
+ }
61
+ get(id) {
62
+ return this.records.get(id);
63
+ }
64
+ /** Read a single evidence record from PostgreSQL (primary) with in-memory fallback */
65
+ async getFromDb(id) {
66
+ if (this.db) {
67
+ try {
68
+ const { rows } = await this.db.query(`SELECT id, control_id, tenant_id, sha256, uri, collected_at, lineage FROM evidence WHERE id = $1`, [id]);
69
+ if (rows.length > 0) {
70
+ const row = rows[0];
71
+ const record = {
72
+ id: row.id,
73
+ controlId: row.control_id,
74
+ tenantId: Number(row.tenant_id),
75
+ sha256: row.sha256,
76
+ uri: row.uri,
77
+ collectedAt: row.collected_at,
78
+ lineage: row.lineage,
79
+ };
80
+ this.records.set(id, record);
81
+ return record;
82
+ }
83
+ }
84
+ catch {
85
+ // fall back to in-memory
86
+ }
87
+ }
88
+ return this.records.get(id);
89
+ }
90
+ /** Synchronous read from in-memory write-through cache */
91
+ listByControl(controlId) {
92
+ return [...this.records.values()].filter((r) => r.controlId === controlId);
93
+ }
94
+ /** Read evidence for a control from PostgreSQL (primary) with in-memory fallback */
95
+ async listByControlFromDb(controlId) {
96
+ if (this.db) {
97
+ try {
98
+ const { rows } = await this.db.query(`SELECT id, control_id, tenant_id, sha256, uri, collected_at, lineage FROM evidence WHERE control_id = $1`, [controlId]);
99
+ if (rows.length > 0) {
100
+ const results = rows.map((row) => ({
101
+ id: row.id,
102
+ controlId: row.control_id,
103
+ tenantId: Number(row.tenant_id),
104
+ sha256: row.sha256,
105
+ uri: row.uri,
106
+ collectedAt: row.collected_at,
107
+ lineage: row.lineage,
108
+ }));
109
+ // Update cache with DB results
110
+ for (const r of results) {
111
+ this.records.set(r.id, r);
112
+ }
113
+ return results;
114
+ }
115
+ }
116
+ catch {
117
+ // fall back to in-memory
118
+ }
119
+ }
120
+ return [...this.records.values()].filter((r) => r.controlId === controlId);
121
+ }
122
+ /** Flush all pending PostgreSQL writes */
123
+ async flush() {
124
+ const pending = [...this.pendingWrites];
125
+ this.pendingWrites = [];
126
+ await Promise.allSettled(pending);
127
+ }
128
+ async loadFromDatabase() {
129
+ if (!this.db)
130
+ return;
131
+ try {
132
+ const { rows } = await this.db.query(`SELECT id, control_id, tenant_id, sha256, uri, collected_at, lineage FROM evidence`);
133
+ for (const row of rows) {
134
+ const record = {
135
+ id: row.id,
136
+ controlId: row.control_id,
137
+ tenantId: Number(row.tenant_id),
138
+ sha256: row.sha256,
139
+ uri: row.uri,
140
+ collectedAt: row.collected_at,
141
+ lineage: row.lineage,
142
+ };
143
+ this.records.set(record.id, record);
144
+ }
145
+ }
146
+ catch {
147
+ // fall back to empty in-memory state
148
+ }
149
+ }
150
+ }
151
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@grc-claw/evidence",
3
+ "version": "0.8.0",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsc -p tsconfig.json",
16
+ "test": "node --import tsx --test src/**/*.test.ts"
17
+ },
18
+ "dependencies": {
19
+ "@grc-claw/core": "*"
20
+ },
21
+ "devDependencies": {
22
+ "tsx": "^4.19.0",
23
+ "typescript": "^5.7.0"
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/AAH20/GRC_Claw"
34
+ }
35
+ }