@grc-claw/evidence 2.0.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,48 @@
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
+ /** Build a redacted, portable action receipt from hash-chained ledger events. */
41
+ export declare function createAssuranceEnvelope(input: {
42
+ intent: ActionLedgerEvent;
43
+ decision?: ActionLedgerEvent;
44
+ result?: ActionLedgerEvent;
45
+ identity?: AssuranceEnvelope['identity'];
46
+ assurance?: AssuranceEnvelope['assurance'];
47
+ }): AssuranceEnvelope;
48
+ //# 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":"AAAA,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,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"}
@@ -0,0 +1,36 @@
1
+ /** Build a redacted, portable action receipt from hash-chained ledger events. */
2
+ export function createAssuranceEnvelope(input) {
3
+ const { intent, decision, result } = input;
4
+ return {
5
+ version: 'v1',
6
+ actionId: intent.actionId,
7
+ tenantId: intent.tenantId,
8
+ sessionId: intent.sessionId,
9
+ tool: intent.tool,
10
+ idempotencyKey: intent.idempotencyKey,
11
+ createdAt: intent.at,
12
+ updatedAt: result?.at ?? decision?.at ?? intent.at,
13
+ intent: { argsHash: intent.argsHash, argKeys: intent.argKeys, ledgerHash: intent.hash },
14
+ policy: decision
15
+ ? {
16
+ executionState: decision.executionState,
17
+ allowed: decision.executionState === 'executing',
18
+ reason: decision.decisionReason,
19
+ requiresApproval: decision.requiresApproval,
20
+ ledgerHash: decision.hash,
21
+ }
22
+ : undefined,
23
+ result: result
24
+ ? {
25
+ executionState: result.executionState,
26
+ outputHash: result.outputHash,
27
+ evidenceId: result.evidenceId,
28
+ targetReceipt: result.targetReceipt,
29
+ ledgerHash: result.hash,
30
+ }
31
+ : undefined,
32
+ identity: input.identity,
33
+ assurance: input.assurance,
34
+ };
35
+ }
36
+ //# sourceMappingURL=assurance-envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assurance-envelope.js","sourceRoot":"","sources":["../src/assurance-envelope.ts"],"names":[],"mappings":"AAwBA,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"}
@@ -0,0 +1,34 @@
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
+ constructor(database?: EvidenceDatabase);
26
+ static hashContent(buffer: Buffer | string): string;
27
+ attach(input: Omit<EvidenceRecord, 'id' | 'sha256'> & {
28
+ content?: Buffer | string;
29
+ }): EvidenceRecord;
30
+ get(id: string): EvidenceRecord | undefined;
31
+ listByControl(controlId: string): EvidenceRecord[];
32
+ loadFromDatabase(): Promise<void>;
33
+ }
34
+ //# 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;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAmB;gBAE3B,QAAQ,CAAC,EAAE,gBAAgB;IAIvC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAInD,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,QAAQ,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,cAAc;IAiCpG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI3C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE;IAI5C,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;CA8BxC"}
package/dist/index.js ADDED
@@ -0,0 +1,68 @@
1
+ import { createHash } from 'node:crypto';
2
+ export * from './action-ledger.js';
3
+ export * from './assurance-envelope.js';
4
+ export class EvidenceStore {
5
+ records = new Map();
6
+ db;
7
+ constructor(database) {
8
+ this.db = database;
9
+ }
10
+ static hashContent(buffer) {
11
+ return createHash('sha256').update(buffer).digest('hex');
12
+ }
13
+ attach(input) {
14
+ const sha256 = input.content !== undefined
15
+ ? EvidenceStore.hashContent(input.content)
16
+ : EvidenceStore.hashContent(`${input.uri}|${input.collectedAt}`);
17
+ const id = `ev-${sha256.slice(0, 16)}`;
18
+ const record = { ...input, id, sha256 };
19
+ this.records.set(id, record);
20
+ if (this.db) {
21
+ const db = this.db;
22
+ void db.execute(`INSERT INTO evidence (id, tenant_id, control_id, sha256, uri, metadata, lineage, collected_at, created_at)
23
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW())
24
+ ON CONFLICT (id) DO NOTHING`, [
25
+ id,
26
+ String(input.tenantId),
27
+ input.controlId,
28
+ sha256,
29
+ input.uri,
30
+ JSON.stringify({}),
31
+ JSON.stringify(input.lineage),
32
+ input.collectedAt,
33
+ ]).catch(() => {
34
+ // fall back to in-memory only
35
+ });
36
+ }
37
+ return record;
38
+ }
39
+ get(id) {
40
+ return this.records.get(id);
41
+ }
42
+ listByControl(controlId) {
43
+ return [...this.records.values()].filter((r) => r.controlId === controlId);
44
+ }
45
+ async loadFromDatabase() {
46
+ if (!this.db)
47
+ return;
48
+ try {
49
+ const { rows } = await this.db.query(`SELECT id, control_id, tenant_id, sha256, uri, collected_at, lineage FROM evidence`);
50
+ for (const row of rows) {
51
+ const record = {
52
+ id: row.id,
53
+ controlId: row.control_id,
54
+ tenantId: Number(row.tenant_id),
55
+ sha256: row.sha256,
56
+ uri: row.uri,
57
+ collectedAt: row.collected_at,
58
+ lineage: row.lineage,
59
+ };
60
+ this.records.set(record.id, record);
61
+ }
62
+ }
63
+ catch {
64
+ // fall back to empty in-memory state
65
+ }
66
+ }
67
+ }
68
+ //# 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,26 @@
1
+ {
2
+ "name": "@grc-claw/evidence",
3
+ "version": "2.0.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
+ },
17
+ "dependencies": {
18
+ "@grc-claw/core": "*"
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ }
26
+ }