-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstore.ts
More file actions
92 lines (80 loc) · 3.11 KB
/
Copy pathstore.ts
File metadata and controls
92 lines (80 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import type { AuditEvent, Cohort, ScanResult } from "./domain";
import { CLAUSES, REGULATION, seedContracts } from "./seed";
import { buildCohorts, computeTotals } from "./engine";
// In-memory singleton state for the demo. It survives across requests within a
// running server (module singletons persist), and resets on restart — which is
// exactly what you want for a repeatable hackathon demo.
interface State {
scan: ScanResult;
audit: AuditEvent[];
}
declare global {
var __regproof: State | undefined;
}
function isoNow(): string {
return new Date().toISOString();
}
function build(): State {
const contracts = seedContracts();
const cohorts = buildCohorts(contracts);
const scan: ScanResult = {
regulation: { code: REGULATION.code, title: REGULATION.title, inForce: REGULATION.inForce },
clauses: CLAUSES,
totals: computeTotals(contracts, cohorts),
contracts,
cohorts,
};
return {
scan,
audit: [
{
ts: isoNow(),
actor: "agent",
action: "scan.completed",
justification: `Scanned ${scan.totals.contracts} contracts against ${REGULATION.code}; ${scan.totals.cohorts} cohorts built by deterministic group-by.`,
},
],
};
}
function state(): State {
if (!globalThis.__regproof) globalThis.__regproof = build();
return globalThis.__regproof;
}
export function getScan(): ScanResult {
return state().scan;
}
export function getAudit(): AuditEvent[] {
// Return a copy — the audit log is append-only and never handed out mutable.
return [...state().audit].reverse();
}
export class ApprovalError extends Error {}
// The approval gate. INVARIANTS, enforced here in code and not in any prompt:
// 1. Nothing can be approved without a named human approver.
// 2. An escalated (cross-border legal) cohort cannot be auto-approved by the
// agent — it must be resolved by a human legal owner, explicitly.
// 3. Every approval appends an immutable, justified audit event.
export function approveCohort(cohortId: string, approver: string): Cohort {
const s = state();
const cohort = s.scan.cohorts.find((c) => c.id === cohortId);
if (!cohort) throw new ApprovalError(`Unknown cohort ${cohortId}`);
const name = approver.trim();
if (!name) throw new ApprovalError("Approval requires a named human approver.");
if (name.toLowerCase() === "agent")
throw new ApprovalError("The agent may not approve its own work — a human must sign off.");
if (cohort.status === "approved") throw new ApprovalError(`${cohortId} is already approved.`);
cohort.status = "approved";
cohort.approvedBy = name;
s.audit.push({
ts: isoNow(),
actor: name,
action: cohort.requiresEscalation ? "cohort.escalation_resolved" : "cohort.approved",
cohortId,
justification: cohort.requiresEscalation
? `Human resolved cross-border escalation and approved outreach for ${cohort.contractIds.length} contract(s).`
: `Human approved outreach for ${cohort.contractIds.length} contract(s), £${cohort.exposureGBP.toLocaleString("en-GB")} exposure.`,
});
return cohort;
}
export function resetState(): void {
globalThis.__regproof = build();
}