@kashscript/hudhud 0.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.
- package/LICENSE +133 -0
- package/README.md +67 -0
- package/dist/adapters/prisma.d.ts +170 -0
- package/dist/adapters/prisma.d.ts.map +1 -0
- package/dist/adapters/prisma.js +185 -0
- package/dist/adapters/prisma.js.map +1 -0
- package/dist/anchor/index.d.ts +55 -0
- package/dist/anchor/index.d.ts.map +1 -0
- package/dist/anchor/index.js +97 -0
- package/dist/anchor/index.js.map +1 -0
- package/dist/certificate/certificate.d.ts +115 -0
- package/dist/certificate/certificate.d.ts.map +1 -0
- package/dist/certificate/certificate.js +221 -0
- package/dist/certificate/certificate.js.map +1 -0
- package/dist/certificate/html.d.ts +10 -0
- package/dist/certificate/html.d.ts.map +1 -0
- package/dist/certificate/html.js +141 -0
- package/dist/certificate/html.js.map +1 -0
- package/dist/certificate/index.d.ts +3 -0
- package/dist/certificate/index.d.ts.map +1 -0
- package/dist/certificate/index.js +5 -0
- package/dist/certificate/index.js.map +1 -0
- package/dist/did-registry/index.d.ts +3 -0
- package/dist/did-registry/index.d.ts.map +1 -0
- package/dist/did-registry/index.js +10 -0
- package/dist/did-registry/index.js.map +1 -0
- package/dist/errors.d.ts +35 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +65 -0
- package/dist/errors.js.map +1 -0
- package/dist/exception/index.d.ts +97 -0
- package/dist/exception/index.d.ts.map +1 -0
- package/dist/exception/index.js +144 -0
- package/dist/exception/index.js.map +1 -0
- package/dist/identity/index.d.ts +33 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +36 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/ledger/event-schema.d.ts +97 -0
- package/dist/ledger/event-schema.d.ts.map +1 -0
- package/dist/ledger/event-schema.js +54 -0
- package/dist/ledger/event-schema.js.map +1 -0
- package/dist/ledger/index.d.ts +7 -0
- package/dist/ledger/index.d.ts.map +1 -0
- package/dist/ledger/index.js +14 -0
- package/dist/ledger/index.js.map +1 -0
- package/dist/ledger/mutex.d.ts +9 -0
- package/dist/ledger/mutex.d.ts.map +1 -0
- package/dist/ledger/mutex.js +36 -0
- package/dist/ledger/mutex.js.map +1 -0
- package/dist/ledger/store.d.ts +31 -0
- package/dist/ledger/store.d.ts.map +1 -0
- package/dist/ledger/store.js +66 -0
- package/dist/ledger/store.js.map +1 -0
- package/dist/ledger/writer.d.ts +69 -0
- package/dist/ledger/writer.d.ts.map +1 -0
- package/dist/ledger/writer.js +167 -0
- package/dist/ledger/writer.js.map +1 -0
- package/dist/mcp/allowlist.d.ts +53 -0
- package/dist/mcp/allowlist.d.ts.map +1 -0
- package/dist/mcp/allowlist.js +65 -0
- package/dist/mcp/allowlist.js.map +1 -0
- package/dist/mcp/client.d.ts +68 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +198 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +5 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/privacy/index.d.ts +21 -0
- package/dist/privacy/index.d.ts.map +1 -0
- package/dist/privacy/index.js +96 -0
- package/dist/privacy/index.js.map +1 -0
- package/dist/runtime/dispatcher.d.ts +27 -0
- package/dist/runtime/dispatcher.d.ts.map +1 -0
- package/dist/runtime/dispatcher.js +66 -0
- package/dist/runtime/dispatcher.js.map +1 -0
- package/dist/runtime/escalation.d.ts +98 -0
- package/dist/runtime/escalation.d.ts.map +1 -0
- package/dist/runtime/escalation.js +188 -0
- package/dist/runtime/escalation.js.map +1 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +9 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/runner.d.ts +78 -0
- package/dist/runtime/runner.d.ts.map +1 -0
- package/dist/runtime/runner.js +145 -0
- package/dist/runtime/runner.js.map +1 -0
- package/dist/scope/index.d.ts +19 -0
- package/dist/scope/index.d.ts.map +1 -0
- package/dist/scope/index.js +44 -0
- package/dist/scope/index.js.map +1 -0
- package/dist/sop/compiler.d.ts +36 -0
- package/dist/sop/compiler.d.ts.map +1 -0
- package/dist/sop/compiler.js +54 -0
- package/dist/sop/compiler.js.map +1 -0
- package/dist/sop/index.d.ts +3 -0
- package/dist/sop/index.d.ts.map +1 -0
- package/dist/sop/index.js +5 -0
- package/dist/sop/index.js.map +1 -0
- package/dist/sop/service.d.ts +40 -0
- package/dist/sop/service.d.ts.map +1 -0
- package/dist/sop/service.js +140 -0
- package/dist/sop/service.js.map +1 -0
- package/package.json +112 -0
- package/src/adapters/prisma.ts +310 -0
- package/src/anchor/index.ts +149 -0
- package/src/certificate/certificate.ts +340 -0
- package/src/certificate/html.ts +156 -0
- package/src/certificate/index.ts +4 -0
- package/src/did-registry/index.ts +11 -0
- package/src/errors.ts +79 -0
- package/src/exception/index.ts +244 -0
- package/src/identity/index.ts +82 -0
- package/src/index.ts +33 -0
- package/src/ledger/event-schema.ts +61 -0
- package/src/ledger/index.ts +22 -0
- package/src/ledger/mutex.ts +37 -0
- package/src/ledger/store.ts +86 -0
- package/src/ledger/writer.ts +249 -0
- package/src/mcp/allowlist.ts +102 -0
- package/src/mcp/client.ts +284 -0
- package/src/mcp/index.ts +4 -0
- package/src/privacy/index.ts +123 -0
- package/src/runtime/dispatcher.ts +96 -0
- package/src/runtime/escalation.ts +292 -0
- package/src/runtime/index.ts +14 -0
- package/src/runtime/runner.ts +227 -0
- package/src/scope/index.ts +59 -0
- package/src/sop/compiler.ts +99 -0
- package/src/sop/index.ts +4 -0
- package/src/sop/service.ts +184 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Every accepted event type. Unknown `event` discriminators are rejected, as
|
|
3
|
+
* are well-formed objects missing `event` UNLESS they're the empty `{}`. */
|
|
4
|
+
export declare const LedgerEventSchema: z.ZodUnion<[z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>, z.ZodDiscriminatedUnion<"event", [z.ZodObject<{
|
|
5
|
+
event: z.ZodLiteral<"session.bootstrap">;
|
|
6
|
+
sopId: z.ZodString;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
event: "session.bootstrap";
|
|
9
|
+
sopId: string;
|
|
10
|
+
}, {
|
|
11
|
+
event: "session.bootstrap";
|
|
12
|
+
sopId: string;
|
|
13
|
+
}>, z.ZodObject<{
|
|
14
|
+
event: z.ZodLiteral<"tool.invoked">;
|
|
15
|
+
tool: z.ZodString;
|
|
16
|
+
durationMs: z.ZodNumber;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
tool: string;
|
|
19
|
+
event: "tool.invoked";
|
|
20
|
+
durationMs: number;
|
|
21
|
+
}, {
|
|
22
|
+
tool: string;
|
|
23
|
+
event: "tool.invoked";
|
|
24
|
+
durationMs: number;
|
|
25
|
+
}>, z.ZodObject<{
|
|
26
|
+
event: z.ZodLiteral<"tool.failed">;
|
|
27
|
+
tool: z.ZodString;
|
|
28
|
+
errorCode: z.ZodString;
|
|
29
|
+
errorMessage: z.ZodOptional<z.ZodString>;
|
|
30
|
+
}, "strip", z.ZodTypeAny, {
|
|
31
|
+
tool: string;
|
|
32
|
+
event: "tool.failed";
|
|
33
|
+
errorCode: string;
|
|
34
|
+
errorMessage?: string | undefined;
|
|
35
|
+
}, {
|
|
36
|
+
tool: string;
|
|
37
|
+
event: "tool.failed";
|
|
38
|
+
errorCode: string;
|
|
39
|
+
errorMessage?: string | undefined;
|
|
40
|
+
}>, z.ZodObject<{
|
|
41
|
+
event: z.ZodLiteral<"budget.exhausted">;
|
|
42
|
+
spentPaise: z.ZodUnion<[z.ZodBigInt, z.ZodString]>;
|
|
43
|
+
}, "strip", z.ZodTypeAny, {
|
|
44
|
+
event: "budget.exhausted";
|
|
45
|
+
spentPaise: string | bigint;
|
|
46
|
+
}, {
|
|
47
|
+
event: "budget.exhausted";
|
|
48
|
+
spentPaise: string | bigint;
|
|
49
|
+
}>, z.ZodObject<{
|
|
50
|
+
event: z.ZodLiteral<"session.settled">;
|
|
51
|
+
totalSpentPaise: z.ZodUnion<[z.ZodBigInt, z.ZodString]>;
|
|
52
|
+
}, "strip", z.ZodTypeAny, {
|
|
53
|
+
event: "session.settled";
|
|
54
|
+
totalSpentPaise: string | bigint;
|
|
55
|
+
}, {
|
|
56
|
+
event: "session.settled";
|
|
57
|
+
totalSpentPaise: string | bigint;
|
|
58
|
+
}>, z.ZodObject<{
|
|
59
|
+
event: z.ZodLiteral<"session.failed_audit">;
|
|
60
|
+
reason: z.ZodString;
|
|
61
|
+
}, "strip", z.ZodTypeAny, {
|
|
62
|
+
reason: string;
|
|
63
|
+
event: "session.failed_audit";
|
|
64
|
+
}, {
|
|
65
|
+
reason: string;
|
|
66
|
+
event: "session.failed_audit";
|
|
67
|
+
}>, z.ZodObject<{
|
|
68
|
+
event: z.ZodLiteral<"session.process_crashed">;
|
|
69
|
+
signal: z.ZodOptional<z.ZodString>;
|
|
70
|
+
}, "strip", z.ZodTypeAny, {
|
|
71
|
+
event: "session.process_crashed";
|
|
72
|
+
signal?: string | undefined;
|
|
73
|
+
}, {
|
|
74
|
+
event: "session.process_crashed";
|
|
75
|
+
signal?: string | undefined;
|
|
76
|
+
}>, z.ZodObject<{
|
|
77
|
+
event: z.ZodLiteral<"cache.checkpoint">;
|
|
78
|
+
flushedAtIso: z.ZodString;
|
|
79
|
+
lifecycleState: z.ZodOptional<z.ZodEnum<["NOT_STARTED", "RUNNING", "SETTLED", "FAILED_AUDIT", "BUDGET_EXHAUSTED", "PROCESS_CRASHED"]>>;
|
|
80
|
+
computeBudgetPaise: z.ZodOptional<z.ZodUnion<[z.ZodBigInt, z.ZodString]>>;
|
|
81
|
+
slotKeyPrefix: z.ZodString;
|
|
82
|
+
}, "strip", z.ZodTypeAny, {
|
|
83
|
+
event: "cache.checkpoint";
|
|
84
|
+
flushedAtIso: string;
|
|
85
|
+
slotKeyPrefix: string;
|
|
86
|
+
lifecycleState?: "BUDGET_EXHAUSTED" | "FAILED_AUDIT" | "NOT_STARTED" | "RUNNING" | "SETTLED" | "PROCESS_CRASHED" | undefined;
|
|
87
|
+
computeBudgetPaise?: string | bigint | undefined;
|
|
88
|
+
}, {
|
|
89
|
+
event: "cache.checkpoint";
|
|
90
|
+
flushedAtIso: string;
|
|
91
|
+
slotKeyPrefix: string;
|
|
92
|
+
lifecycleState?: "BUDGET_EXHAUSTED" | "FAILED_AUDIT" | "NOT_STARTED" | "RUNNING" | "SETTLED" | "PROCESS_CRASHED" | undefined;
|
|
93
|
+
computeBudgetPaise?: string | bigint | undefined;
|
|
94
|
+
}>]>]>;
|
|
95
|
+
export type LedgerEvent = z.infer<typeof LedgerEventSchema>;
|
|
96
|
+
export declare const KNOWN_LEDGER_EVENTS: readonly ["session.bootstrap", "tool.invoked", "tool.failed", "budget.exhausted", "session.settled", "session.failed_audit", "session.process_crashed", "cache.checkpoint"];
|
|
97
|
+
//# sourceMappingURL=event-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-schema.d.ts","sourceRoot":"","sources":["../../src/ledger/event-schema.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAsBxB;6EAC6E;AAC7E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAY5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,mBAAmB,6KAStB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// @kashscript/hudhud/ledger — closed-vocabulary payloadMutation schema
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
// The ledger's forensic value depends on a CLOSED event vocabulary: an
|
|
5
|
+
// unconstrained payload would chain-hash any JSON. Every accepted
|
|
6
|
+
// payloadMutation validates against this discriminated union before hashing.
|
|
7
|
+
// Extending is APPEND-ONLY — never repurpose an existing `event` discriminator
|
|
8
|
+
// (audit pipelines key on it). Ported from the oreoasis-core-host engine (M5);
|
|
9
|
+
// the venture-specific error-code regex is relaxed to a neutral non-empty string.
|
|
10
|
+
// ============================================================================
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
const NonNegBigInt = z.union([z.bigint(), z.string().regex(/^\d+$/)]);
|
|
13
|
+
const SessionBootstrap = z.object({ event: z.literal("session.bootstrap"), sopId: z.string().min(1) });
|
|
14
|
+
const ToolInvoked = z.object({ event: z.literal("tool.invoked"), tool: z.string().min(1), durationMs: z.number().int().nonnegative() });
|
|
15
|
+
const ToolFailed = z.object({ event: z.literal("tool.failed"), tool: z.string().min(1), errorCode: z.string().min(1), errorMessage: z.string().min(1).optional() });
|
|
16
|
+
const BudgetExhausted = z.object({ event: z.literal("budget.exhausted"), spentPaise: NonNegBigInt });
|
|
17
|
+
const SessionSettled = z.object({ event: z.literal("session.settled"), totalSpentPaise: NonNegBigInt });
|
|
18
|
+
const SessionFailedAudit = z.object({ event: z.literal("session.failed_audit"), reason: z.string().min(1) });
|
|
19
|
+
const SessionProcessCrashed = z.object({ event: z.literal("session.process_crashed"), signal: z.string().min(1).optional() });
|
|
20
|
+
const CacheCheckpoint = z.object({
|
|
21
|
+
event: z.literal("cache.checkpoint"),
|
|
22
|
+
flushedAtIso: z.string().min(1),
|
|
23
|
+
lifecycleState: z.enum(["NOT_STARTED", "RUNNING", "SETTLED", "FAILED_AUDIT", "BUDGET_EXHAUSTED", "PROCESS_CRASHED"]).optional(),
|
|
24
|
+
computeBudgetPaise: NonNegBigInt.optional(),
|
|
25
|
+
slotKeyPrefix: z.string().min(1),
|
|
26
|
+
});
|
|
27
|
+
/** Empty mutation — the bare `{}` object is a valid Empty-track value. */
|
|
28
|
+
const EmptyMutation = z.object({}).strict();
|
|
29
|
+
/** Every accepted event type. Unknown `event` discriminators are rejected, as
|
|
30
|
+
* are well-formed objects missing `event` UNLESS they're the empty `{}`. */
|
|
31
|
+
export const LedgerEventSchema = z.union([
|
|
32
|
+
EmptyMutation,
|
|
33
|
+
z.discriminatedUnion("event", [
|
|
34
|
+
SessionBootstrap,
|
|
35
|
+
ToolInvoked,
|
|
36
|
+
ToolFailed,
|
|
37
|
+
BudgetExhausted,
|
|
38
|
+
SessionSettled,
|
|
39
|
+
SessionFailedAudit,
|
|
40
|
+
SessionProcessCrashed,
|
|
41
|
+
CacheCheckpoint,
|
|
42
|
+
]),
|
|
43
|
+
]);
|
|
44
|
+
export const KNOWN_LEDGER_EVENTS = [
|
|
45
|
+
"session.bootstrap",
|
|
46
|
+
"tool.invoked",
|
|
47
|
+
"tool.failed",
|
|
48
|
+
"budget.exhausted",
|
|
49
|
+
"session.settled",
|
|
50
|
+
"session.failed_audit",
|
|
51
|
+
"session.process_crashed",
|
|
52
|
+
"cache.checkpoint",
|
|
53
|
+
];
|
|
54
|
+
//# sourceMappingURL=event-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-schema.js","sourceRoot":"","sources":["../../src/ledger/event-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from "./store";
|
|
2
|
+
export * from "./mutex";
|
|
3
|
+
export * from "./writer";
|
|
4
|
+
export * from "./event-schema";
|
|
5
|
+
export { OREOASIS_LEDGER_DST, LedgerSignatureError, signLedgerBlock, verifyLedgerSignature, forensicConsistencyScan, } from "@kashscript/attest";
|
|
6
|
+
export type { LedgerSignaturePayload, ForensicScanReport } from "@kashscript/attest";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ledger/index.ts"],"names":[],"mappings":"AAMA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAK/B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// @kashscript/hudhud/ledger — the signed action ledger (write side).
|
|
2
|
+
// The store + mutex + ForensicLedgerService live here; the row shapes, the
|
|
3
|
+
// Ed25519 sign/verify, the forensic scan, and the DID registry are attest's
|
|
4
|
+
// (M1 seed) and are re-exported so ventures reach the whole ledger surface
|
|
5
|
+
// through hudhud.
|
|
6
|
+
export * from "./store";
|
|
7
|
+
export * from "./mutex";
|
|
8
|
+
export * from "./writer";
|
|
9
|
+
export * from "./event-schema";
|
|
10
|
+
// Re-export attest's ledger crypto surface (seeded from the same Oreoasis files).
|
|
11
|
+
// The DID registry lives at `@kashscript/hudhud/did-registry` (not re-exported
|
|
12
|
+
// here, to avoid a same-name overlap in the top-level barrel).
|
|
13
|
+
export { OREOASIS_LEDGER_DST, LedgerSignatureError, signLedgerBlock, verifyLedgerSignature, forensicConsistencyScan, } from "@kashscript/attest";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ledger/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,kBAAkB;AAElB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAE/B,kFAAkF;AAClF,+EAA+E;AAC/E,+DAA+D;AAC/D,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class SessionMutex {
|
|
2
|
+
private readonly tails;
|
|
3
|
+
/** Run `fn` while holding the mutex for `key`. Other acquirers for the same
|
|
4
|
+
* key queue behind this call. */
|
|
5
|
+
run<T>(key: string, fn: () => Promise<T>): Promise<T>;
|
|
6
|
+
/** Number of distinct keys currently locked. */
|
|
7
|
+
activeKeyCount(): number;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=mutex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutex.d.ts","sourceRoot":"","sources":["../../src/ledger/mutex.ts"],"names":[],"mappings":"AASA,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuC;IAE7D;sCACkC;IACrB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAkBlE,gDAAgD;IACzC,cAAc,IAAI,MAAM;CAGhC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// @kashscript/hudhud/ledger — per-key async mutex
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
// Serializes async sections keyed on a string (the ledger sessionId), closing
|
|
5
|
+
// the resolvePreviousBlockHash → appendBlock race two concurrent appends on the
|
|
6
|
+
// same session would otherwise hit. Ported verbatim from the oreoasis-core-host
|
|
7
|
+
// engine (M5).
|
|
8
|
+
// ============================================================================
|
|
9
|
+
export class SessionMutex {
|
|
10
|
+
tails = new Map();
|
|
11
|
+
/** Run `fn` while holding the mutex for `key`. Other acquirers for the same
|
|
12
|
+
* key queue behind this call. */
|
|
13
|
+
async run(key, fn) {
|
|
14
|
+
const prior = this.tails.get(key) ?? Promise.resolve();
|
|
15
|
+
let release = () => { };
|
|
16
|
+
const gate = new Promise((resolve) => {
|
|
17
|
+
release = resolve;
|
|
18
|
+
});
|
|
19
|
+
this.tails.set(key, gate);
|
|
20
|
+
try {
|
|
21
|
+
await prior;
|
|
22
|
+
return await fn();
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
if (this.tails.get(key) === gate) {
|
|
26
|
+
this.tails.delete(key);
|
|
27
|
+
}
|
|
28
|
+
release();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Number of distinct keys currently locked. */
|
|
32
|
+
activeKeyCount() {
|
|
33
|
+
return this.tails.size;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=mutex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutex.js","sourceRoot":"","sources":["../../src/ledger/mutex.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,kDAAkD;AAClD,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,gFAAgF;AAChF,eAAe;AACf,+EAA+E;AAE/E,MAAM,OAAO,YAAY;IACN,KAAK,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE7D;sCACkC;IAC3B,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,EAAoB;QACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACvD,IAAI,OAAO,GAA0B,GAAG,EAAE,GAAE,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACzC,OAAO,GAAG,OAAO,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,KAAK,CAAC;YACZ,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;gBACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,gDAAgD;IACzC,cAAc;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LedgerBlockInput, LedgerBlockRecord } from "@kashscript/attest";
|
|
2
|
+
export type { LedgerBlockInput, LedgerBlockRecord };
|
|
3
|
+
export interface LedgerStore {
|
|
4
|
+
appendBlock(input: LedgerBlockInput): Promise<LedgerBlockRecord>;
|
|
5
|
+
latestBlockForSession(sessionId: string): Promise<LedgerBlockRecord | null>;
|
|
6
|
+
countBlocksForSession(sessionId: string): Promise<number>;
|
|
7
|
+
/** Every row for `sessionId` ordered by stepIndex — MUST NOT skip rows (the
|
|
8
|
+
* forensic scan's whole job is to detect missing/forged entries). */
|
|
9
|
+
listBlocksForSession(sessionId: string): Promise<ReadonlyArray<LedgerBlockRecord>>;
|
|
10
|
+
}
|
|
11
|
+
/** In-memory store keyed by sessionId. Concurrent same-session appends are
|
|
12
|
+
* serialized by the JS event loop + the (sessionId, stepIndex) uniqueness check. */
|
|
13
|
+
export declare class InMemoryLedgerStore implements LedgerStore {
|
|
14
|
+
private readonly bySession;
|
|
15
|
+
private nextLocalId;
|
|
16
|
+
appendBlock(input: LedgerBlockInput): Promise<LedgerBlockRecord>;
|
|
17
|
+
latestBlockForSession(sessionId: string): Promise<LedgerBlockRecord | null>;
|
|
18
|
+
countBlocksForSession(sessionId: string): Promise<number>;
|
|
19
|
+
listBlocksForSession(sessionId: string): Promise<ReadonlyArray<LedgerBlockRecord>>;
|
|
20
|
+
/** TEST-ONLY: splice a forged row bypassing the uniqueness + ordering
|
|
21
|
+
* invariants, so the forensic scan can be exercised against a corrupt chain.
|
|
22
|
+
* Production callers MUST NOT use this. */
|
|
23
|
+
unsafeInsertForgedRow(record: LedgerBlockRecord): void;
|
|
24
|
+
}
|
|
25
|
+
/** Resolve the previous block hash for the next insert into `sessionId`.
|
|
26
|
+
* Genesis (stepIndex 0) → GENESIS_PREV_HASH; else the prior row's currentHash. */
|
|
27
|
+
export declare function resolvePreviousBlockHash(store: LedgerStore, sessionId: string): Promise<{
|
|
28
|
+
previousBlockHash: string;
|
|
29
|
+
nextStepIndex: number;
|
|
30
|
+
}>;
|
|
31
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/ledger/store.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACjE,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC5E,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1D;0EACsE;IACtE,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAAC;CACpF;AAED;qFACqF;AACrF,qBAAa,mBAAoB,YAAW,WAAW;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0C;IACpE,OAAO,CAAC,WAAW,CAAK;IAElB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiBhE,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAM3E,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzD,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAMxF;;gDAE4C;IAC5C,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;CAMvD;AAED;mFACmF;AACnF,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAM/D"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// @kashscript/hudhud/ledger — append-only ledger store (write side)
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
// The write-side store the ForensicLedgerService appends to. The row shapes +
|
|
5
|
+
// the sign/verify/forensic-scan primitives live in `@kashscript/attest` (M1
|
|
6
|
+
// seed); this module ships the store interface + an in-memory reference +
|
|
7
|
+
// `resolvePreviousBlockHash`. A Prisma adapter ships at `./adapters/prisma`.
|
|
8
|
+
// Ported from the oreoasis-core-host engine (M5).
|
|
9
|
+
// ============================================================================
|
|
10
|
+
import { GENESIS_PREV_HASH } from "@kashscript/attest";
|
|
11
|
+
/** In-memory store keyed by sessionId. Concurrent same-session appends are
|
|
12
|
+
* serialized by the JS event loop + the (sessionId, stepIndex) uniqueness check. */
|
|
13
|
+
export class InMemoryLedgerStore {
|
|
14
|
+
bySession = new Map();
|
|
15
|
+
nextLocalId = 1;
|
|
16
|
+
async appendBlock(input) {
|
|
17
|
+
const existing = this.bySession.get(input.sessionId) ?? [];
|
|
18
|
+
if (existing.some((b) => b.stepIndex === input.stepIndex)) {
|
|
19
|
+
throw new Error(`LEDGER_DUPLICATE_STEP: (sessionId=${input.sessionId}, stepIndex=${input.stepIndex})`);
|
|
20
|
+
}
|
|
21
|
+
const record = {
|
|
22
|
+
...input,
|
|
23
|
+
payloadMutation: { ...input.payloadMutation },
|
|
24
|
+
emittedAt: new Date().toISOString(),
|
|
25
|
+
localId: this.nextLocalId++,
|
|
26
|
+
};
|
|
27
|
+
existing.push(record);
|
|
28
|
+
existing.sort((a, b) => a.stepIndex - b.stepIndex);
|
|
29
|
+
this.bySession.set(input.sessionId, existing);
|
|
30
|
+
return record;
|
|
31
|
+
}
|
|
32
|
+
async latestBlockForSession(sessionId) {
|
|
33
|
+
const list = this.bySession.get(sessionId);
|
|
34
|
+
if (!list || list.length === 0)
|
|
35
|
+
return null;
|
|
36
|
+
return list[list.length - 1];
|
|
37
|
+
}
|
|
38
|
+
async countBlocksForSession(sessionId) {
|
|
39
|
+
return (this.bySession.get(sessionId) ?? []).length;
|
|
40
|
+
}
|
|
41
|
+
async listBlocksForSession(sessionId) {
|
|
42
|
+
const list = this.bySession.get(sessionId);
|
|
43
|
+
if (list === undefined)
|
|
44
|
+
return [];
|
|
45
|
+
return list.map((row) => ({ ...row, payloadMutation: { ...row.payloadMutation } }));
|
|
46
|
+
}
|
|
47
|
+
/** TEST-ONLY: splice a forged row bypassing the uniqueness + ordering
|
|
48
|
+
* invariants, so the forensic scan can be exercised against a corrupt chain.
|
|
49
|
+
* Production callers MUST NOT use this. */
|
|
50
|
+
unsafeInsertForgedRow(record) {
|
|
51
|
+
const existing = this.bySession.get(record.sessionId) ?? [];
|
|
52
|
+
existing.push({ ...record, payloadMutation: { ...record.payloadMutation } });
|
|
53
|
+
existing.sort((a, b) => a.stepIndex - b.stepIndex);
|
|
54
|
+
this.bySession.set(record.sessionId, existing);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Resolve the previous block hash for the next insert into `sessionId`.
|
|
58
|
+
* Genesis (stepIndex 0) → GENESIS_PREV_HASH; else the prior row's currentHash. */
|
|
59
|
+
export async function resolvePreviousBlockHash(store, sessionId) {
|
|
60
|
+
const latest = await store.latestBlockForSession(sessionId);
|
|
61
|
+
if (latest === null) {
|
|
62
|
+
return { previousBlockHash: GENESIS_PREV_HASH, nextStepIndex: 0 };
|
|
63
|
+
}
|
|
64
|
+
return { previousBlockHash: latest.currentTransactionBlockHash, nextStepIndex: latest.stepIndex + 1 };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/ledger/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { DidRegistry, ForensicScanReport, LedgerSignaturePayload } from "@kashscript/attest";
|
|
2
|
+
import { SessionMutex } from "./mutex";
|
|
3
|
+
import type { LedgerStore } from "./store";
|
|
4
|
+
export declare const ACTOR_CLASSES: readonly ["AGENT", "SYSTEM_KERNEL", "OPERATOR_ADMIN", "COMPLIANCE_AUDITOR"];
|
|
5
|
+
export type ActorClass = (typeof ACTOR_CLASSES)[number];
|
|
6
|
+
/** An in-process signing identity the host controls (the runtime key that signs
|
|
7
|
+
* autonomous agent actions). The private key stays captured behind `sign()`. */
|
|
8
|
+
export interface HostActorSigner {
|
|
9
|
+
readonly actorDid: string;
|
|
10
|
+
readonly actorClass: ActorClass;
|
|
11
|
+
sign(payload: LedgerSignaturePayload): Promise<string>;
|
|
12
|
+
}
|
|
13
|
+
/** Build a HostActorSigner from a raw Ed25519 private key. `actorDid` must be a
|
|
14
|
+
* did:kash and be registered in the DidRegistry the service verifies against. */
|
|
15
|
+
export declare function createEd25519HostSigner(opts: {
|
|
16
|
+
readonly actorDid: string;
|
|
17
|
+
readonly actorClass: ActorClass;
|
|
18
|
+
readonly privateKey: Uint8Array;
|
|
19
|
+
}): HostActorSigner;
|
|
20
|
+
export interface AppendTransitionLogInput {
|
|
21
|
+
readonly sessionId: string;
|
|
22
|
+
readonly stepIndex: number;
|
|
23
|
+
readonly actorDid: string;
|
|
24
|
+
readonly actorClass: ActorClass;
|
|
25
|
+
readonly payloadMutation: Readonly<Record<string, unknown>>;
|
|
26
|
+
/** `ed25519:<128-hex>` wire form — verified inside the service. */
|
|
27
|
+
readonly signature: string;
|
|
28
|
+
}
|
|
29
|
+
export interface AppendedLedgerBlock {
|
|
30
|
+
readonly sessionId: string;
|
|
31
|
+
readonly stepIndex: number;
|
|
32
|
+
readonly actorDid: string;
|
|
33
|
+
readonly actorClass: ActorClass;
|
|
34
|
+
readonly previousBlockHash: string;
|
|
35
|
+
readonly currentTransactionBlockHash: string;
|
|
36
|
+
readonly signature: string;
|
|
37
|
+
readonly emittedAt: string;
|
|
38
|
+
readonly localLedgerId: number;
|
|
39
|
+
}
|
|
40
|
+
export interface ForensicLedgerServiceDeps {
|
|
41
|
+
readonly ledger: LedgerStore;
|
|
42
|
+
readonly sessionMutex: SessionMutex;
|
|
43
|
+
readonly didRegistry: DidRegistry;
|
|
44
|
+
/** Required only for `appendActorTransition` (the self-signing path). */
|
|
45
|
+
readonly hostSigner?: HostActorSigner;
|
|
46
|
+
}
|
|
47
|
+
export declare class ForensicLedgerService {
|
|
48
|
+
private readonly deps;
|
|
49
|
+
constructor(deps: ForensicLedgerServiceDeps);
|
|
50
|
+
/** Append a caller-pre-signed transition. @throws LedgerAppendError on any
|
|
51
|
+
* validation / signature / store failure. */
|
|
52
|
+
appendTransitionLog(input: AppendTransitionLogInput): Promise<AppendedLedgerBlock>;
|
|
53
|
+
/** Self-signing append for the in-host autonomous actor: resolves + signs +
|
|
54
|
+
* verifies + inserts atomically inside the per-session mutex. Requires
|
|
55
|
+
* `deps.hostSigner`. */
|
|
56
|
+
appendActorTransition(input: {
|
|
57
|
+
readonly sessionId: string;
|
|
58
|
+
readonly payloadMutation: Readonly<Record<string, unknown>>;
|
|
59
|
+
}): Promise<AppendedLedgerBlock>;
|
|
60
|
+
/** MUST be called inside the session mutex — computes the canonical block
|
|
61
|
+
* hash, verifies the signature, and inserts. */
|
|
62
|
+
private commitResolvedBlock;
|
|
63
|
+
/** Walk the whole chain for `sessionId` and re-verify hashes + signatures.
|
|
64
|
+
* Delegates to attest's `forensicConsistencyScan` (throws `TamperError` on
|
|
65
|
+
* the first variance: STEP_INDEX_GAP / PREVIOUS_HASH_MISMATCH /
|
|
66
|
+
* PAYLOAD_HASH_VARIANCE / SIGNATURE_VERIFY_FAILED). */
|
|
67
|
+
forensicConsistencyScan(sessionId: string): Promise<ForensicScanReport>;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/ledger/writer.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAqB,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAGrH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,eAAO,MAAM,aAAa,6EAA8E,CAAC;AACzG,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAExD;iFACiF;AACjF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxD;AAED;kFACkF;AAClF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC,GAAG,eAAe,CASlB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5D,mEAAmE;IACnE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,2BAA2B,EAAE,MAAM,CAAC;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,yEAAyE;IACzE,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;CACvC;AAED,qBAAa,qBAAqB;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,yBAAyB;IAE5D;kDAC8C;IACxC,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAuCxF;;6BAEyB;IACnB,qBAAqB,CAAC,KAAK,EAAE;QACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;KAC7D,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAoChC;qDACiD;YACnC,mBAAmB;IAiEjC;;;4DAGwD;IAClD,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAI9E"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// @kashscript/hudhud/ledger — ForensicLedgerService (the write side)
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
// The single append entry point: acquire the per-session mutex, resolve the
|
|
5
|
+
// chain tip, verify the caller stepIndex, compute the canonical block hash,
|
|
6
|
+
// verify the Ed25519 signature, and atomically insert. The self-signing path
|
|
7
|
+
// (`appendActorTransition`) resolves + signs INSIDE the mutex so two concurrent
|
|
8
|
+
// appends can never sign over a stale (prev, stepIndex). The chain-hash,
|
|
9
|
+
// signature sign/verify, and forensic scan are attest's (M1 seed); this module
|
|
10
|
+
// is the write-side orchestration. Ported from oreoasis-core-host/services/
|
|
11
|
+
// ledger-writer (M5); errors neutralized (append → LedgerAppendError, tamper →
|
|
12
|
+
// attest TamperError).
|
|
13
|
+
// ============================================================================
|
|
14
|
+
import { KASH_DID_PATTERN, LedgerSignatureError, chainBlockHash, forensicConsistencyScan, signLedgerBlock, verifyLedgerSignature, } from "@kashscript/attest";
|
|
15
|
+
import { LedgerAppendError } from "../errors";
|
|
16
|
+
import { SessionMutex } from "./mutex";
|
|
17
|
+
import { resolvePreviousBlockHash } from "./store";
|
|
18
|
+
export const ACTOR_CLASSES = ["AGENT", "SYSTEM_KERNEL", "OPERATOR_ADMIN", "COMPLIANCE_AUDITOR"];
|
|
19
|
+
/** Build a HostActorSigner from a raw Ed25519 private key. `actorDid` must be a
|
|
20
|
+
* did:kash and be registered in the DidRegistry the service verifies against. */
|
|
21
|
+
export function createEd25519HostSigner(opts) {
|
|
22
|
+
if (!KASH_DID_PATTERN.test(opts.actorDid)) {
|
|
23
|
+
throw new LedgerAppendError("host signer actorDid is not a valid did:kash:… identifier");
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
actorDid: opts.actorDid,
|
|
27
|
+
actorClass: opts.actorClass,
|
|
28
|
+
sign: (payload) => signLedgerBlock(payload, opts.privateKey),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export class ForensicLedgerService {
|
|
32
|
+
deps;
|
|
33
|
+
constructor(deps) {
|
|
34
|
+
this.deps = deps;
|
|
35
|
+
}
|
|
36
|
+
/** Append a caller-pre-signed transition. @throws LedgerAppendError on any
|
|
37
|
+
* validation / signature / store failure. */
|
|
38
|
+
async appendTransitionLog(input) {
|
|
39
|
+
if (typeof input.sessionId !== "string" || input.sessionId.length === 0) {
|
|
40
|
+
throw new LedgerAppendError("sessionId is required");
|
|
41
|
+
}
|
|
42
|
+
if (typeof input.actorDid !== "string" || !KASH_DID_PATTERN.test(input.actorDid)) {
|
|
43
|
+
throw new LedgerAppendError("actorDid must be a valid did:kash:… identifier");
|
|
44
|
+
}
|
|
45
|
+
if (typeof input.signature !== "string" || input.signature.length === 0) {
|
|
46
|
+
throw new LedgerAppendError("signature is required");
|
|
47
|
+
}
|
|
48
|
+
if (!ACTOR_CLASSES.includes(input.actorClass)) {
|
|
49
|
+
throw new LedgerAppendError(`actorClass must be one of [${ACTOR_CLASSES.join(", ")}]`);
|
|
50
|
+
}
|
|
51
|
+
if (!Number.isInteger(input.stepIndex) || input.stepIndex < 0) {
|
|
52
|
+
throw new LedgerAppendError("stepIndex must be a non-negative integer");
|
|
53
|
+
}
|
|
54
|
+
return this.deps.sessionMutex.run(input.sessionId, async () => {
|
|
55
|
+
const { previousBlockHash: resolvedPrev, nextStepIndex } = await resolvePreviousBlockHash(this.deps.ledger, input.sessionId);
|
|
56
|
+
if (input.stepIndex !== nextStepIndex) {
|
|
57
|
+
throw new LedgerAppendError(`stepIndex ${input.stepIndex} does not match next expected ${nextStepIndex} for session ${input.sessionId}`);
|
|
58
|
+
}
|
|
59
|
+
return this.commitResolvedBlock({
|
|
60
|
+
sessionId: input.sessionId,
|
|
61
|
+
stepIndex: input.stepIndex,
|
|
62
|
+
actorDid: input.actorDid,
|
|
63
|
+
actorClass: input.actorClass,
|
|
64
|
+
payloadMutation: input.payloadMutation,
|
|
65
|
+
signature: input.signature,
|
|
66
|
+
resolvedPrev,
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/** Self-signing append for the in-host autonomous actor: resolves + signs +
|
|
71
|
+
* verifies + inserts atomically inside the per-session mutex. Requires
|
|
72
|
+
* `deps.hostSigner`. */
|
|
73
|
+
async appendActorTransition(input) {
|
|
74
|
+
const signer = this.deps.hostSigner;
|
|
75
|
+
if (signer === undefined) {
|
|
76
|
+
throw new LedgerAppendError("appendActorTransition requires a configured hostSigner");
|
|
77
|
+
}
|
|
78
|
+
if (typeof input.sessionId !== "string" || input.sessionId.length === 0) {
|
|
79
|
+
throw new LedgerAppendError("sessionId is required");
|
|
80
|
+
}
|
|
81
|
+
if (input.payloadMutation === null || typeof input.payloadMutation !== "object" || Array.isArray(input.payloadMutation)) {
|
|
82
|
+
throw new LedgerAppendError("payloadMutation must be a plain object");
|
|
83
|
+
}
|
|
84
|
+
return this.deps.sessionMutex.run(input.sessionId, async () => {
|
|
85
|
+
const { previousBlockHash: resolvedPrev, nextStepIndex } = await resolvePreviousBlockHash(this.deps.ledger, input.sessionId);
|
|
86
|
+
const signature = await signer.sign({
|
|
87
|
+
sessionId: input.sessionId,
|
|
88
|
+
stepIndex: nextStepIndex,
|
|
89
|
+
actorDid: signer.actorDid,
|
|
90
|
+
previousBlockHash: resolvedPrev,
|
|
91
|
+
payloadMutation: input.payloadMutation,
|
|
92
|
+
});
|
|
93
|
+
return this.commitResolvedBlock({
|
|
94
|
+
sessionId: input.sessionId,
|
|
95
|
+
stepIndex: nextStepIndex,
|
|
96
|
+
actorDid: signer.actorDid,
|
|
97
|
+
actorClass: signer.actorClass,
|
|
98
|
+
payloadMutation: input.payloadMutation,
|
|
99
|
+
signature,
|
|
100
|
+
resolvedPrev,
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/** MUST be called inside the session mutex — computes the canonical block
|
|
105
|
+
* hash, verifies the signature, and inserts. */
|
|
106
|
+
async commitResolvedBlock(args) {
|
|
107
|
+
const currentTransactionBlockHash = await chainBlockHash({
|
|
108
|
+
sessionId: args.sessionId,
|
|
109
|
+
stepIndex: args.stepIndex,
|
|
110
|
+
actorDid: args.actorDid,
|
|
111
|
+
payloadMutation: args.payloadMutation,
|
|
112
|
+
signature: args.signature,
|
|
113
|
+
}, args.resolvedPrev);
|
|
114
|
+
try {
|
|
115
|
+
await verifyLedgerSignature({
|
|
116
|
+
signatureWire: args.signature,
|
|
117
|
+
payload: {
|
|
118
|
+
sessionId: args.sessionId,
|
|
119
|
+
stepIndex: args.stepIndex,
|
|
120
|
+
actorDid: args.actorDid,
|
|
121
|
+
previousBlockHash: args.resolvedPrev,
|
|
122
|
+
payloadMutation: args.payloadMutation,
|
|
123
|
+
},
|
|
124
|
+
didRegistry: this.deps.didRegistry,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
catch (cause) {
|
|
128
|
+
const reason = cause instanceof LedgerSignatureError ? cause.reason : "UNKNOWN";
|
|
129
|
+
throw new LedgerAppendError(`Ed25519 signature verification failed (${reason})`);
|
|
130
|
+
}
|
|
131
|
+
let record;
|
|
132
|
+
try {
|
|
133
|
+
record = await this.deps.ledger.appendBlock({
|
|
134
|
+
sessionId: args.sessionId,
|
|
135
|
+
stepIndex: args.stepIndex,
|
|
136
|
+
previousBlockHash: args.resolvedPrev,
|
|
137
|
+
currentTransactionBlockHash,
|
|
138
|
+
actorDid: args.actorDid,
|
|
139
|
+
payloadMutation: args.payloadMutation,
|
|
140
|
+
signature: args.signature,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch (cause) {
|
|
144
|
+
throw new LedgerAppendError(`Ledger store write failed — ${cause instanceof Error ? cause.message : "unknown"}`);
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
sessionId: record.sessionId,
|
|
148
|
+
stepIndex: record.stepIndex,
|
|
149
|
+
actorDid: record.actorDid,
|
|
150
|
+
actorClass: args.actorClass,
|
|
151
|
+
previousBlockHash: record.previousBlockHash,
|
|
152
|
+
currentTransactionBlockHash: record.currentTransactionBlockHash,
|
|
153
|
+
signature: record.signature,
|
|
154
|
+
emittedAt: record.emittedAt,
|
|
155
|
+
localLedgerId: record.localId,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/** Walk the whole chain for `sessionId` and re-verify hashes + signatures.
|
|
159
|
+
* Delegates to attest's `forensicConsistencyScan` (throws `TamperError` on
|
|
160
|
+
* the first variance: STEP_INDEX_GAP / PREVIOUS_HASH_MISMATCH /
|
|
161
|
+
* PAYLOAD_HASH_VARIANCE / SIGNATURE_VERIFY_FAILED). */
|
|
162
|
+
async forensicConsistencyScan(sessionId) {
|
|
163
|
+
const rows = await this.deps.ledger.listBlocksForSession(sessionId);
|
|
164
|
+
return forensicConsistencyScan(sessionId, rows, this.deps.didRegistry);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/ledger/writer.ts"],"names":[],"mappings":"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"}
|