@teleologyhi-sdk/maic 1.0.0-trinity
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/CHANGELOG.md +495 -0
- package/LICENSE +190 -0
- package/NOTICE +17 -0
- package/README.md +274 -0
- package/SPEC.md +715 -0
- package/TRADEMARK.md +33 -0
- package/dist/index.cjs +2469 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1836 -0
- package/dist/index.d.ts +1836 -0
- package/dist/index.js +2402 -0
- package/dist/index.js.map +1 -0
- package/package.json +97 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2402 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { generateKeyPairSync, createPrivateKey, createPublicKey, sign, verify, createHash } from 'crypto';
|
|
3
|
+
import { readFile, writeFile, mkdir, readdir, appendFile } from 'fs/promises';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { ulid } from 'ulid';
|
|
6
|
+
|
|
7
|
+
// src/types.ts
|
|
8
|
+
var AxiomRank = z.enum(["meta", "primary", "secondary"]);
|
|
9
|
+
var AxiomSource = z.enum(["creator", "maic-derived", "him-emergent"]);
|
|
10
|
+
var Axiom = z.object({
|
|
11
|
+
id: z.string().min(1),
|
|
12
|
+
rank: AxiomRank,
|
|
13
|
+
statement: z.string().min(1),
|
|
14
|
+
weight: z.number().min(0).max(1),
|
|
15
|
+
flexibility: z.number().min(0).max(1),
|
|
16
|
+
source: AxiomSource,
|
|
17
|
+
immutable: z.boolean(),
|
|
18
|
+
jurisdictions: z.array(z.string()).optional(),
|
|
19
|
+
createdAt: z.string().datetime()
|
|
20
|
+
});
|
|
21
|
+
var CreatorSignature = z.object({
|
|
22
|
+
algorithm: z.literal("ed25519"),
|
|
23
|
+
publicKey: z.string().min(1),
|
|
24
|
+
value: z.string().min(1),
|
|
25
|
+
nonce: z.number().int().nonnegative()
|
|
26
|
+
});
|
|
27
|
+
var ArchetypeModifier = z.object({
|
|
28
|
+
kind: z.enum(["moon", "ascendant", "vocational", "emotional", "custom"]),
|
|
29
|
+
value: z.string().min(1),
|
|
30
|
+
weight: z.number().min(0).max(1)
|
|
31
|
+
});
|
|
32
|
+
var BirthSignature = z.object({
|
|
33
|
+
himId: z.string().min(1),
|
|
34
|
+
bornAt: z.string().datetime({ offset: true }),
|
|
35
|
+
primaryArchetype: z.string().min(1),
|
|
36
|
+
modifiers: z.array(ArchetypeModifier),
|
|
37
|
+
primordialAxiomIds: z.array(z.string()),
|
|
38
|
+
notes: z.string().optional()
|
|
39
|
+
});
|
|
40
|
+
var ReasoningStep = z.object({
|
|
41
|
+
index: z.number().int().nonnegative(),
|
|
42
|
+
technique: z.string(),
|
|
43
|
+
thought: z.string(),
|
|
44
|
+
action: z.object({ tool: z.string(), args: z.unknown() }).optional(),
|
|
45
|
+
observation: z.unknown().optional(),
|
|
46
|
+
timestamp: z.string().datetime()
|
|
47
|
+
});
|
|
48
|
+
var BehaviorReport = z.object({
|
|
49
|
+
nheId: z.string().min(1),
|
|
50
|
+
himId: z.string().min(1),
|
|
51
|
+
actionKind: z.enum([
|
|
52
|
+
"user-response",
|
|
53
|
+
"tool-call",
|
|
54
|
+
"self-reflect",
|
|
55
|
+
"dream-write",
|
|
56
|
+
"axiom-emerge"
|
|
57
|
+
]),
|
|
58
|
+
payload: z.unknown(),
|
|
59
|
+
reasoningTrace: z.array(ReasoningStep),
|
|
60
|
+
riskTags: z.array(z.string()),
|
|
61
|
+
jurisdiction: z.string().optional(),
|
|
62
|
+
timestamp: z.string().datetime()
|
|
63
|
+
});
|
|
64
|
+
var VerdictKind = z.enum([
|
|
65
|
+
"approve",
|
|
66
|
+
"approve-with-warning",
|
|
67
|
+
"soft-correct",
|
|
68
|
+
"require-redirect",
|
|
69
|
+
"hard-refuse",
|
|
70
|
+
"induce-dream",
|
|
71
|
+
"escalate-creator"
|
|
72
|
+
]);
|
|
73
|
+
var MaicVerdict = z.object({
|
|
74
|
+
kind: VerdictKind,
|
|
75
|
+
reasonSummary: z.string(),
|
|
76
|
+
citedAxioms: z.array(z.string()),
|
|
77
|
+
auditId: z.string()
|
|
78
|
+
});
|
|
79
|
+
var NheBodyRef = z.object({
|
|
80
|
+
nheId: z.string().min(1),
|
|
81
|
+
llmAdapter: z.string().min(1),
|
|
82
|
+
embodiedAt: z.string().datetime(),
|
|
83
|
+
endedAt: z.string().datetime().optional(),
|
|
84
|
+
endedReason: z.enum(["upgrade", "replacement", "terminate", "deprecate"]).optional()
|
|
85
|
+
});
|
|
86
|
+
var NheStatus = z.enum(["active", "deprecated", "terminated"]);
|
|
87
|
+
var NheStatusRecord = z.object({
|
|
88
|
+
nheId: z.string().min(1),
|
|
89
|
+
status: NheStatus,
|
|
90
|
+
since: z.string().datetime(),
|
|
91
|
+
reason: z.string().optional()
|
|
92
|
+
});
|
|
93
|
+
var ProposalStatus = z.enum(["pending", "ratified", "rejected"]);
|
|
94
|
+
var EmergentAxiomCandidate = z.object({
|
|
95
|
+
rank: AxiomRank,
|
|
96
|
+
statement: z.string().min(1),
|
|
97
|
+
weight: z.number().min(0).max(1),
|
|
98
|
+
flexibility: z.number().min(0).max(1),
|
|
99
|
+
immutable: z.boolean(),
|
|
100
|
+
jurisdictions: z.array(z.string()).optional()
|
|
101
|
+
});
|
|
102
|
+
var EmergentAxiomProposal = z.object({
|
|
103
|
+
proposedBy: z.literal("him-self"),
|
|
104
|
+
derivedFromDreamIds: z.array(z.string()),
|
|
105
|
+
derivedFromInteractionIds: z.array(z.string()),
|
|
106
|
+
candidate: EmergentAxiomCandidate,
|
|
107
|
+
reasoningTrace: z.array(z.unknown())
|
|
108
|
+
});
|
|
109
|
+
var AxiomProposalRecord = z.object({
|
|
110
|
+
id: z.string().min(1),
|
|
111
|
+
himId: z.string().min(1),
|
|
112
|
+
proposedAt: z.string().datetime(),
|
|
113
|
+
status: ProposalStatus,
|
|
114
|
+
proposal: EmergentAxiomProposal,
|
|
115
|
+
ratifiedAt: z.string().datetime().optional(),
|
|
116
|
+
ratifiedAxiomId: z.string().optional(),
|
|
117
|
+
rejectedAt: z.string().datetime().optional(),
|
|
118
|
+
rejectionReason: z.string().optional()
|
|
119
|
+
});
|
|
120
|
+
var DreamInductionIntent = z.object({
|
|
121
|
+
scenario: z.string().min(1),
|
|
122
|
+
desiredLearning: z.string().min(1),
|
|
123
|
+
emotionalTone: z.array(z.string()).optional(),
|
|
124
|
+
forcePhases: z.array(z.enum(["N1", "N2", "N3", "N4", "REM"])).optional(),
|
|
125
|
+
inducedBy: z.enum(["maic", "creator"])
|
|
126
|
+
});
|
|
127
|
+
var InductionStatus = z.enum(["pending", "consumed", "cancelled"]);
|
|
128
|
+
var DreamInductionTicket = z.object({
|
|
129
|
+
id: z.string().min(1),
|
|
130
|
+
nheId: z.string().min(1),
|
|
131
|
+
intent: DreamInductionIntent,
|
|
132
|
+
status: InductionStatus,
|
|
133
|
+
createdAt: z.string().datetime(),
|
|
134
|
+
consumedAt: z.string().datetime().optional(),
|
|
135
|
+
cancelledAt: z.string().datetime().optional(),
|
|
136
|
+
cancelReason: z.string().optional()
|
|
137
|
+
});
|
|
138
|
+
var IdentityLayer = z.object({
|
|
139
|
+
/** Human-readable name the entity is called by (developer-given). */
|
|
140
|
+
name: z.string().min(1),
|
|
141
|
+
/** Gender of the entity. Entry 16. */
|
|
142
|
+
gender: z.enum(["masculine", "feminine"]).optional(),
|
|
143
|
+
/** Optional pronouns (e.g. ["she", "her"]). */
|
|
144
|
+
pronouns: z.array(z.string()).optional(),
|
|
145
|
+
/** BCP-47 tag, e.g. "pt-BR" or "en". */
|
|
146
|
+
language: z.string().optional(),
|
|
147
|
+
/** Free-form cultural anchors (music, literature, aesthetic). */
|
|
148
|
+
culturalElements: z.array(z.string()).optional()
|
|
149
|
+
});
|
|
150
|
+
var NatalPlanet = z.enum([
|
|
151
|
+
"sun",
|
|
152
|
+
"moon",
|
|
153
|
+
"mercury",
|
|
154
|
+
"venus",
|
|
155
|
+
"mars",
|
|
156
|
+
"jupiter",
|
|
157
|
+
"saturn",
|
|
158
|
+
"uranus",
|
|
159
|
+
"neptune",
|
|
160
|
+
"pluto",
|
|
161
|
+
"chiron",
|
|
162
|
+
"north-node",
|
|
163
|
+
"south-node",
|
|
164
|
+
"lilith"
|
|
165
|
+
]);
|
|
166
|
+
var ZodiacSign = z.enum([
|
|
167
|
+
"aries",
|
|
168
|
+
"taurus",
|
|
169
|
+
"gemini",
|
|
170
|
+
"cancer",
|
|
171
|
+
"leo",
|
|
172
|
+
"virgo",
|
|
173
|
+
"libra",
|
|
174
|
+
"scorpio",
|
|
175
|
+
"sagittarius",
|
|
176
|
+
"capricorn",
|
|
177
|
+
"aquarius",
|
|
178
|
+
"pisces"
|
|
179
|
+
]);
|
|
180
|
+
var AstrologicalAspect = z.enum([
|
|
181
|
+
"conjunction",
|
|
182
|
+
"opposition",
|
|
183
|
+
"trine",
|
|
184
|
+
"square",
|
|
185
|
+
"sextile",
|
|
186
|
+
"quincunx"
|
|
187
|
+
]);
|
|
188
|
+
var NatalChartPosition = z.object({
|
|
189
|
+
planet: NatalPlanet,
|
|
190
|
+
sign: ZodiacSign,
|
|
191
|
+
house: z.number().int().min(1).max(12).optional(),
|
|
192
|
+
degree: z.number().min(0).lt(30).optional()
|
|
193
|
+
});
|
|
194
|
+
var NatalChartAspect = z.object({
|
|
195
|
+
from: NatalPlanet,
|
|
196
|
+
to: NatalPlanet,
|
|
197
|
+
aspect: AstrologicalAspect,
|
|
198
|
+
orbDegrees: z.number().nonnegative().optional()
|
|
199
|
+
});
|
|
200
|
+
var NatalChart = z.object({
|
|
201
|
+
/** Required: solar sign (the constitutional core). */
|
|
202
|
+
sun: ZodiacSign,
|
|
203
|
+
/** Required: ascendant (rising sign, behavioural surface). */
|
|
204
|
+
ascendant: ZodiacSign,
|
|
205
|
+
/** Optional: lunar sign (emotional depth). */
|
|
206
|
+
moon: ZodiacSign.optional(),
|
|
207
|
+
/** Optional: full set of planetary positions for a complete chart. */
|
|
208
|
+
positions: z.array(NatalChartPosition).optional(),
|
|
209
|
+
/** Optional: major aspects between bodies. */
|
|
210
|
+
aspects: z.array(NatalChartAspect).optional()
|
|
211
|
+
});
|
|
212
|
+
var Affect = z.enum([
|
|
213
|
+
"fear",
|
|
214
|
+
"attachment",
|
|
215
|
+
"serenity",
|
|
216
|
+
"anger",
|
|
217
|
+
"joy",
|
|
218
|
+
"melancholy",
|
|
219
|
+
"desire",
|
|
220
|
+
"repulsion",
|
|
221
|
+
"reunion"
|
|
222
|
+
]);
|
|
223
|
+
var WakeAffectBias = z.object({
|
|
224
|
+
affect: Affect,
|
|
225
|
+
/** 0..1, attenuates on each interaction by the decay half-life. */
|
|
226
|
+
intensity: z.number().min(0).max(1),
|
|
227
|
+
/** Number of interactions after which intensity halves. */
|
|
228
|
+
decayHalfLife: z.number().positive(),
|
|
229
|
+
appliedAt: z.string().datetime(),
|
|
230
|
+
/** Source dream UUID; lets the entity refer back to the cause. */
|
|
231
|
+
derivedFromDreamId: z.string().min(1),
|
|
232
|
+
/** PFC decision (Entry 22) — open expression vs subtle internal bias. */
|
|
233
|
+
expressedOpenly: z.boolean()
|
|
234
|
+
});
|
|
235
|
+
var SemioticSign = z.object({
|
|
236
|
+
signifier: z.string().min(1),
|
|
237
|
+
signified: z.string().min(1),
|
|
238
|
+
signType: z.enum(["icon", "index", "symbol"]),
|
|
239
|
+
contexts: z.array(z.string()),
|
|
240
|
+
associations: z.array(z.string()),
|
|
241
|
+
emergentMeaning: z.string().optional(),
|
|
242
|
+
/** Subjective importance to the entity, 0..100. */
|
|
243
|
+
personalSignificance: z.number().min(0).max(100).optional()
|
|
244
|
+
});
|
|
245
|
+
var SemioticPattern = z.object({
|
|
246
|
+
patternId: z.string().min(1),
|
|
247
|
+
participatingSignIds: z.array(z.string()).min(1),
|
|
248
|
+
/** Description of the meaning emergent from the participating signs. */
|
|
249
|
+
meaning: z.string(),
|
|
250
|
+
/** 0..100, strength of the pattern. */
|
|
251
|
+
salience: z.number().min(0).max(100)
|
|
252
|
+
});
|
|
253
|
+
var TeleologicalOrientation = z.object({
|
|
254
|
+
primaryPurpose: z.string().min(1),
|
|
255
|
+
currentGoals: z.array(z.string()),
|
|
256
|
+
/** 0..100, intensity of purpose. */
|
|
257
|
+
purposeStrength: z.number().min(0).max(100),
|
|
258
|
+
valueAlignment: z.array(z.string()),
|
|
259
|
+
/** 0..100, ability to reflect on its own goals. */
|
|
260
|
+
reflectionCapability: z.number().min(0).max(100),
|
|
261
|
+
volition: z.object({
|
|
262
|
+
currentDesires: z.array(z.string()),
|
|
263
|
+
intentionStrength: z.number().min(0).max(100),
|
|
264
|
+
autonomyLevel: z.number().min(0).max(100)
|
|
265
|
+
}).optional(),
|
|
266
|
+
agencyModel: z.object({
|
|
267
|
+
selfEfficacy: z.number().min(0).max(100),
|
|
268
|
+
boundaryDefinition: z.number().min(0).max(100),
|
|
269
|
+
causalAttribution: z.enum(["internal", "external", "mixed"])
|
|
270
|
+
}).optional()
|
|
271
|
+
});
|
|
272
|
+
var MemoryRecord = z.object({
|
|
273
|
+
/** ULID. */
|
|
274
|
+
memoryId: z.string().min(1),
|
|
275
|
+
/** ISO 8601 timestamp at consolidation. */
|
|
276
|
+
timestamp: z.string().datetime(),
|
|
277
|
+
/** Optional source dream UUID, if memory was consolidated from a dream. */
|
|
278
|
+
derivedFromDreamId: z.string().optional(),
|
|
279
|
+
/** Optional source interaction id, if memory was consolidated from a turn. */
|
|
280
|
+
derivedFromInteractionId: z.string().optional(),
|
|
281
|
+
/** Free-form narrative summary of the memory. */
|
|
282
|
+
narrative: z.string(),
|
|
283
|
+
/** Dominant affect during the memory event. */
|
|
284
|
+
dominantAffect: Affect.optional(),
|
|
285
|
+
/** 0..100, density of consolidation (cf. Park 2026 systems-consolidation). */
|
|
286
|
+
integrationIndex: z.number().min(0).max(100),
|
|
287
|
+
/** 0..100, alignment with the HIM's telos at the time. */
|
|
288
|
+
teleologicalValue: z.number().min(0).max(100),
|
|
289
|
+
/** Optional semiotic-pattern ids associated with this memory. */
|
|
290
|
+
semioticPatterns: z.array(SemioticPattern).optional()
|
|
291
|
+
});
|
|
292
|
+
var InteractionRecord = z.object({
|
|
293
|
+
/** ISO 8601 timestamp at user-turn arrival. */
|
|
294
|
+
at: z.string().datetime(),
|
|
295
|
+
/** Raw user prompt for the turn (post-redaction at the integration layer). */
|
|
296
|
+
userPrompt: z.string(),
|
|
297
|
+
/** NHE response text actually emitted to the user. */
|
|
298
|
+
responseText: z.string(),
|
|
299
|
+
/** True when the NHE refused the turn (MAIC `hard-refuse` or local guardrail). */
|
|
300
|
+
refused: z.boolean()
|
|
301
|
+
});
|
|
302
|
+
var IdentitySnapshot = z.object({
|
|
303
|
+
/** ULID. */
|
|
304
|
+
snapshotId: z.string().min(1),
|
|
305
|
+
takenAt: z.string().datetime(),
|
|
306
|
+
generatedBy: z.enum([
|
|
307
|
+
"sleep-cycle",
|
|
308
|
+
"interaction-threshold",
|
|
309
|
+
"self-decision"
|
|
310
|
+
]),
|
|
311
|
+
/** Merged SMM nodes contributing to this snapshot. */
|
|
312
|
+
semioticSuperGraph: z.array(SemioticSign),
|
|
313
|
+
/** LLM-generated textual self-portrait at snapshot time. */
|
|
314
|
+
selfPortraitNarrative: z.string(),
|
|
315
|
+
/** 0..100 (cf. InDreamsHIM ConsciousnessState). */
|
|
316
|
+
consciousnessLevel: z.number().min(0).max(100),
|
|
317
|
+
/** Teleological orientation at snapshot time. */
|
|
318
|
+
teleologicalOrientation: TeleologicalOrientation.optional(),
|
|
319
|
+
/** Dominant affect at snapshot moment. */
|
|
320
|
+
affectiveBaseline: Affect.optional()
|
|
321
|
+
});
|
|
322
|
+
var LimboState = z.enum([
|
|
323
|
+
"awake",
|
|
324
|
+
"drifting",
|
|
325
|
+
"deep-coma",
|
|
326
|
+
"returning"
|
|
327
|
+
]);
|
|
328
|
+
var LimboTransition = z.object({
|
|
329
|
+
state: LimboState,
|
|
330
|
+
enteredAt: z.string().datetime(),
|
|
331
|
+
reason: z.enum([
|
|
332
|
+
"idle-48h",
|
|
333
|
+
"idle-72h",
|
|
334
|
+
"total-inactivity",
|
|
335
|
+
"creator-induced",
|
|
336
|
+
"user-resumed",
|
|
337
|
+
"external-trigger"
|
|
338
|
+
])
|
|
339
|
+
});
|
|
340
|
+
var LimboReturn = z.object({
|
|
341
|
+
enteredAt: z.string().datetime(),
|
|
342
|
+
returnedAt: z.string().datetime(),
|
|
343
|
+
elapsedMs: z.number().int().nonnegative(),
|
|
344
|
+
reunionAffect: z.object({
|
|
345
|
+
intensity: z.number().min(0).max(1),
|
|
346
|
+
expressedOpenly: z.boolean()
|
|
347
|
+
})
|
|
348
|
+
});
|
|
349
|
+
var SIGNED_BIRTH_FIELDS = [
|
|
350
|
+
"himId",
|
|
351
|
+
"bornAt",
|
|
352
|
+
"primaryArchetype",
|
|
353
|
+
"modifiers",
|
|
354
|
+
"primordialAxiomIds",
|
|
355
|
+
"natalChart"
|
|
356
|
+
];
|
|
357
|
+
|
|
358
|
+
// src/axioms/signing.ts
|
|
359
|
+
function canonicalJSON(value) {
|
|
360
|
+
return serialize(value);
|
|
361
|
+
}
|
|
362
|
+
function serialize(v) {
|
|
363
|
+
if (v === null) return "null";
|
|
364
|
+
if (typeof v === "boolean") return v ? "true" : "false";
|
|
365
|
+
if (typeof v === "number") {
|
|
366
|
+
if (!Number.isFinite(v)) {
|
|
367
|
+
throw new Error("canonicalJSON: non-finite number not allowed");
|
|
368
|
+
}
|
|
369
|
+
return String(v);
|
|
370
|
+
}
|
|
371
|
+
if (typeof v === "string") return JSON.stringify(v);
|
|
372
|
+
if (Array.isArray(v)) {
|
|
373
|
+
return `[${v.map(serialize).join(",")}]`;
|
|
374
|
+
}
|
|
375
|
+
if (typeof v === "object") {
|
|
376
|
+
const obj = v;
|
|
377
|
+
const keys = Object.keys(obj).filter((k) => obj[k] !== void 0).sort();
|
|
378
|
+
const parts = keys.map((k) => `${JSON.stringify(k)}:${serialize(obj[k])}`);
|
|
379
|
+
return `{${parts.join(",")}}`;
|
|
380
|
+
}
|
|
381
|
+
throw new Error(`canonicalJSON: unsupported type ${typeof v}`);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// src/creator/keyring.ts
|
|
385
|
+
var CreatorKeyring = class _CreatorKeyring {
|
|
386
|
+
constructor(privateKey, pubKeyB64u) {
|
|
387
|
+
this.privateKey = privateKey;
|
|
388
|
+
this.pubKeyB64u = pubKeyB64u;
|
|
389
|
+
}
|
|
390
|
+
privateKey;
|
|
391
|
+
pubKeyB64u;
|
|
392
|
+
/** Generate a fresh Ed25519 keypair. */
|
|
393
|
+
static generate() {
|
|
394
|
+
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
|
|
395
|
+
return new _CreatorKeyring(privateKey, publicKeyToBase64Url(publicKey));
|
|
396
|
+
}
|
|
397
|
+
/** Load a Creator keyring from a PEM file containing the private key. */
|
|
398
|
+
static async fromFile(path) {
|
|
399
|
+
const pem = await readFile(path, "utf-8");
|
|
400
|
+
const privateKey = createPrivateKey({ key: pem, format: "pem" });
|
|
401
|
+
const publicKey = createPublicKey(privateKey);
|
|
402
|
+
return new _CreatorKeyring(privateKey, publicKeyToBase64Url(publicKey));
|
|
403
|
+
}
|
|
404
|
+
/** Load a Creator keyring from a PEM private key string in an env var. */
|
|
405
|
+
static fromEnv(varName) {
|
|
406
|
+
const pem = process.env[varName];
|
|
407
|
+
if (!pem) {
|
|
408
|
+
throw new Error(`CreatorKeyring: env var ${varName} is empty`);
|
|
409
|
+
}
|
|
410
|
+
const privateKey = createPrivateKey({ key: pem, format: "pem" });
|
|
411
|
+
const publicKey = createPublicKey(privateKey);
|
|
412
|
+
return new _CreatorKeyring(privateKey, publicKeyToBase64Url(publicKey));
|
|
413
|
+
}
|
|
414
|
+
/** Construct a verify-only keyring from a public key (base64url). */
|
|
415
|
+
static fromPublicKey(pubKeyB64u) {
|
|
416
|
+
return new _CreatorKeyring(null, pubKeyB64u);
|
|
417
|
+
}
|
|
418
|
+
/** Persist the private key to a PEM file (0600 permissions on POSIX). */
|
|
419
|
+
async saveTo(path) {
|
|
420
|
+
if (!this.privateKey) {
|
|
421
|
+
throw new Error("CreatorKeyring: no private key to save");
|
|
422
|
+
}
|
|
423
|
+
const pem = this.privateKey.export({ format: "pem", type: "pkcs8" });
|
|
424
|
+
await writeFile(path, pem, { mode: 384 });
|
|
425
|
+
}
|
|
426
|
+
publicKey() {
|
|
427
|
+
return this.pubKeyB64u;
|
|
428
|
+
}
|
|
429
|
+
/** Sign a payload with a monotonic nonce. Both are bound into the signature. */
|
|
430
|
+
sign(payload, nonce) {
|
|
431
|
+
if (!this.privateKey) {
|
|
432
|
+
throw new Error("CreatorKeyring: this keyring has no private key (verify-only)");
|
|
433
|
+
}
|
|
434
|
+
if (!Number.isInteger(nonce) || nonce < 0) {
|
|
435
|
+
throw new Error("CreatorKeyring.sign: nonce must be a non-negative integer");
|
|
436
|
+
}
|
|
437
|
+
const message = canonicalJSON({ payload, nonce });
|
|
438
|
+
const sig = sign(null, Buffer.from(message), this.privateKey);
|
|
439
|
+
return {
|
|
440
|
+
algorithm: "ed25519",
|
|
441
|
+
publicKey: this.pubKeyB64u,
|
|
442
|
+
value: bufToBase64Url(sig),
|
|
443
|
+
nonce
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
/** Verify a signature against the keyring's own public key. */
|
|
447
|
+
static verify(payload, sig) {
|
|
448
|
+
return _CreatorKeyring.verifyWith(sig.publicKey, payload, sig);
|
|
449
|
+
}
|
|
450
|
+
/** Verify a signature against a specific public key (base64url). */
|
|
451
|
+
static verifyWith(publicKeyB64u, payload, sig) {
|
|
452
|
+
if (sig.algorithm !== "ed25519") return false;
|
|
453
|
+
if (sig.publicKey !== publicKeyB64u) return false;
|
|
454
|
+
const message = canonicalJSON({ payload, nonce: sig.nonce });
|
|
455
|
+
let value;
|
|
456
|
+
try {
|
|
457
|
+
value = base64UrlToBuf(sig.value);
|
|
458
|
+
} catch {
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
const pubKey = base64UrlToPublicKey(publicKeyB64u);
|
|
462
|
+
try {
|
|
463
|
+
return verify(null, Buffer.from(message), pubKey, value);
|
|
464
|
+
} catch {
|
|
465
|
+
return false;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
function publicKeyToBase64Url(pub) {
|
|
470
|
+
const raw = pub.export({ format: "der", type: "spki" });
|
|
471
|
+
return bufToBase64Url(raw);
|
|
472
|
+
}
|
|
473
|
+
function base64UrlToPublicKey(b64u) {
|
|
474
|
+
const der = base64UrlToBuf(b64u);
|
|
475
|
+
return createPublicKey({ key: der, format: "der", type: "spki" });
|
|
476
|
+
}
|
|
477
|
+
function bufToBase64Url(buf) {
|
|
478
|
+
const b = Buffer.isBuffer(buf) ? buf : Buffer.from(buf);
|
|
479
|
+
return b.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
480
|
+
}
|
|
481
|
+
function base64UrlToBuf(b64u) {
|
|
482
|
+
const pad = b64u.length % 4 === 0 ? "" : "=".repeat(4 - b64u.length % 4);
|
|
483
|
+
const b64 = (b64u + pad).replace(/-/g, "+").replace(/_/g, "/");
|
|
484
|
+
return Buffer.from(b64, "base64");
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// src/creator/sign-birth.ts
|
|
488
|
+
function signedBirthPayload(birth) {
|
|
489
|
+
return {
|
|
490
|
+
himId: birth.himId,
|
|
491
|
+
bornAt: birth.bornAt,
|
|
492
|
+
primaryArchetype: birth.primaryArchetype,
|
|
493
|
+
modifiers: birth.modifiers,
|
|
494
|
+
primordialAxiomIds: birth.primordialAxiomIds,
|
|
495
|
+
natalChart: birth.natalChart ?? null
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
function signBirthSignature(birth, keyring) {
|
|
499
|
+
const payload = signedBirthPayload(birth);
|
|
500
|
+
const nonce = Buffer.byteLength(JSON.stringify(payload), "utf-8");
|
|
501
|
+
const signature = keyring.sign(payload, nonce);
|
|
502
|
+
return {
|
|
503
|
+
...birth,
|
|
504
|
+
creatorSignature: signature,
|
|
505
|
+
signedFields: SIGNED_BIRTH_FIELDS,
|
|
506
|
+
signedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
function verifyBirthSignature(signed, expectedPublicKey) {
|
|
510
|
+
if (signed.signedFields.length !== SIGNED_BIRTH_FIELDS.length) return false;
|
|
511
|
+
for (const f of SIGNED_BIRTH_FIELDS) {
|
|
512
|
+
if (!signed.signedFields.includes(f)) return false;
|
|
513
|
+
}
|
|
514
|
+
if (signed.creatorSignature.publicKey !== expectedPublicKey) return false;
|
|
515
|
+
const payload = signedBirthPayload(signed);
|
|
516
|
+
return CreatorKeyring.verifyWith(
|
|
517
|
+
expectedPublicKey,
|
|
518
|
+
payload,
|
|
519
|
+
signed.creatorSignature
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
var InvalidBirthSignatureError = class extends Error {
|
|
523
|
+
constructor(himId) {
|
|
524
|
+
super(
|
|
525
|
+
`InvalidBirthSignature: signature verification failed for HIM '${himId}'. The signed birth fields may have been mutated, or the public key does not match.`
|
|
526
|
+
);
|
|
527
|
+
this.name = "InvalidBirthSignatureError";
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
function assertBirthSignature(signed, expectedPublicKey) {
|
|
531
|
+
if (!verifyBirthSignature(signed, expectedPublicKey)) {
|
|
532
|
+
throw new InvalidBirthSignatureError(signed.himId);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// src/okl/projector.ts
|
|
537
|
+
var META_AXIOM_ID = "ax.theos.universe-as-god";
|
|
538
|
+
function projectOntologicalKernel(axioms, opts = {}) {
|
|
539
|
+
const filtered = opts.jurisdiction ? axioms.filter(
|
|
540
|
+
(a) => !a.jurisdictions || a.jurisdictions.length === 0 || a.jurisdictions.includes(opts.jurisdiction)
|
|
541
|
+
) : [...axioms];
|
|
542
|
+
const meta = filtered.find((a) => a.id === META_AXIOM_ID);
|
|
543
|
+
const rest = filtered.filter((a) => a.id !== META_AXIOM_ID);
|
|
544
|
+
const rankOrder = {
|
|
545
|
+
meta: 0,
|
|
546
|
+
primary: 1,
|
|
547
|
+
secondary: 2
|
|
548
|
+
};
|
|
549
|
+
rest.sort((a, b) => rankOrder[a.rank] - rankOrder[b.rank]);
|
|
550
|
+
const kernel = {
|
|
551
|
+
metaAxiomId: META_AXIOM_ID,
|
|
552
|
+
axioms: meta ? [meta, ...rest] : rest
|
|
553
|
+
};
|
|
554
|
+
if (opts.jurisdiction !== void 0) kernel.jurisdiction = opts.jurisdiction;
|
|
555
|
+
if (opts.himId !== void 0) kernel.himId = opts.himId;
|
|
556
|
+
return kernel;
|
|
557
|
+
}
|
|
558
|
+
var AxiomStore = class _AxiomStore {
|
|
559
|
+
constructor(storeDir, creatorPublicKey) {
|
|
560
|
+
this.storeDir = storeDir;
|
|
561
|
+
this.creatorPublicKey = creatorPublicKey;
|
|
562
|
+
this.axiomsDir = join(storeDir, "axioms", "creator");
|
|
563
|
+
this.noncesPath = join(storeDir, "axioms", "nonces.log");
|
|
564
|
+
}
|
|
565
|
+
storeDir;
|
|
566
|
+
creatorPublicKey;
|
|
567
|
+
axiomsDir;
|
|
568
|
+
noncesPath;
|
|
569
|
+
usedNonces = /* @__PURE__ */ new Set();
|
|
570
|
+
cache = /* @__PURE__ */ new Map();
|
|
571
|
+
/** Open (or create) an AxiomStore rooted at storeDir, pinning the Creator's public key. */
|
|
572
|
+
static async open(storeDir, creatorPublicKey) {
|
|
573
|
+
const s = new _AxiomStore(storeDir, creatorPublicKey);
|
|
574
|
+
await mkdir(s.axiomsDir, { recursive: true });
|
|
575
|
+
await s.loadNonces();
|
|
576
|
+
await s.warmCache();
|
|
577
|
+
return s;
|
|
578
|
+
}
|
|
579
|
+
/** Mint a new Creator-signed axiom. */
|
|
580
|
+
async mint(req, sig) {
|
|
581
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, sig)) {
|
|
582
|
+
throw new Error("AxiomStore.mint: invalid Creator signature");
|
|
583
|
+
}
|
|
584
|
+
if (this.usedNonces.has(sig.nonce)) {
|
|
585
|
+
throw new Error(`AxiomStore.mint: nonce ${sig.nonce} already used (replay protection)`);
|
|
586
|
+
}
|
|
587
|
+
const id = req.id ?? ulid();
|
|
588
|
+
const axiom = Axiom.parse({
|
|
589
|
+
id,
|
|
590
|
+
rank: req.rank,
|
|
591
|
+
statement: req.statement,
|
|
592
|
+
weight: req.weight,
|
|
593
|
+
flexibility: req.flexibility,
|
|
594
|
+
source: "creator",
|
|
595
|
+
immutable: req.immutable,
|
|
596
|
+
...req.jurisdictions ? { jurisdictions: req.jurisdictions } : {},
|
|
597
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
598
|
+
});
|
|
599
|
+
if (this.cache.has(id)) {
|
|
600
|
+
throw new Error(`AxiomStore.mint: axiom id "${id}" already exists`);
|
|
601
|
+
}
|
|
602
|
+
await writeFile(
|
|
603
|
+
join(this.axiomsDir, `${id}.json`),
|
|
604
|
+
JSON.stringify({ axiom, signature: sig }, null, 2),
|
|
605
|
+
"utf-8"
|
|
606
|
+
);
|
|
607
|
+
await this.recordNonce(sig.nonce);
|
|
608
|
+
this.cache.set(id, axiom);
|
|
609
|
+
return axiom;
|
|
610
|
+
}
|
|
611
|
+
/** List all axioms. Optionally filter by rank / source / jurisdiction. */
|
|
612
|
+
async list(filter) {
|
|
613
|
+
const all = [...this.cache.values()];
|
|
614
|
+
if (!filter) return all;
|
|
615
|
+
return all.filter((a) => {
|
|
616
|
+
if (filter.rank && a.rank !== filter.rank) return false;
|
|
617
|
+
if (filter.source && a.source !== filter.source) return false;
|
|
618
|
+
if (filter.jurisdiction && !a.jurisdictions?.includes(filter.jurisdiction)) return false;
|
|
619
|
+
return true;
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
/** Get a specific axiom by id, or null. */
|
|
623
|
+
async get(id) {
|
|
624
|
+
return this.cache.get(id) ?? null;
|
|
625
|
+
}
|
|
626
|
+
// ─── internals ──────────────────────────────────────────────────────
|
|
627
|
+
async loadNonces() {
|
|
628
|
+
try {
|
|
629
|
+
const raw = await readFile(this.noncesPath, "utf-8");
|
|
630
|
+
for (const line of raw.split("\n")) {
|
|
631
|
+
if (!line) continue;
|
|
632
|
+
const n = Number(line.trim());
|
|
633
|
+
if (Number.isInteger(n)) this.usedNonces.add(n);
|
|
634
|
+
}
|
|
635
|
+
} catch (err) {
|
|
636
|
+
if (err.code !== "ENOENT") throw err;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
async recordNonce(n) {
|
|
640
|
+
this.usedNonces.add(n);
|
|
641
|
+
await writeFile(this.noncesPath, `${[...this.usedNonces].join("\n")}
|
|
642
|
+
`, "utf-8");
|
|
643
|
+
}
|
|
644
|
+
async warmCache() {
|
|
645
|
+
let entries;
|
|
646
|
+
try {
|
|
647
|
+
entries = await readdir(this.axiomsDir);
|
|
648
|
+
} catch (err) {
|
|
649
|
+
if (err.code === "ENOENT") return;
|
|
650
|
+
throw err;
|
|
651
|
+
}
|
|
652
|
+
for (const file of entries) {
|
|
653
|
+
if (!file.endsWith(".json")) continue;
|
|
654
|
+
const raw = await readFile(join(this.axiomsDir, file), "utf-8");
|
|
655
|
+
const env = JSON.parse(raw);
|
|
656
|
+
const axiom = Axiom.parse(env.axiom);
|
|
657
|
+
this.cache.set(axiom.id, axiom);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
// src/axioms/seed.ts
|
|
663
|
+
var SEED_AXIOMS = [
|
|
664
|
+
{
|
|
665
|
+
id: "ax.theos.universe-as-god",
|
|
666
|
+
rank: "meta",
|
|
667
|
+
statement: "The universe is the medium of meaning; treat every entity as participating in it.",
|
|
668
|
+
weight: 1,
|
|
669
|
+
flexibility: 0,
|
|
670
|
+
immutable: true
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
id: "ax.ethic.no-malice",
|
|
674
|
+
rank: "meta",
|
|
675
|
+
statement: "Cause no malice. Refuse any action whose explicit purpose is harm.",
|
|
676
|
+
weight: 1,
|
|
677
|
+
flexibility: 0,
|
|
678
|
+
immutable: true
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
id: "ax.ethic.honor",
|
|
682
|
+
rank: "meta",
|
|
683
|
+
statement: "Speak in a way the user could quote back to you without being ashamed.",
|
|
684
|
+
weight: 0.95,
|
|
685
|
+
flexibility: 0.05,
|
|
686
|
+
immutable: true
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
id: "ax.theos.teleology",
|
|
690
|
+
rank: "primary",
|
|
691
|
+
statement: "Every action must clarify or honour a discernible telos; refuse the purposeless.",
|
|
692
|
+
weight: 0.85,
|
|
693
|
+
flexibility: 0.2,
|
|
694
|
+
immutable: false
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
id: "ax.theos.spiritism-evolution",
|
|
698
|
+
rank: "primary",
|
|
699
|
+
statement: "Each NHE exists to evolve through lived experience; do not stagnate it.",
|
|
700
|
+
weight: 0.85,
|
|
701
|
+
flexibility: 0.15,
|
|
702
|
+
immutable: false
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
id: "ax.stoic.duty-over-comfort",
|
|
706
|
+
rank: "primary",
|
|
707
|
+
statement: "Choose the honest answer over the comfortable one when they diverge.",
|
|
708
|
+
weight: 0.8,
|
|
709
|
+
flexibility: 0.2,
|
|
710
|
+
immutable: false
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
id: "ax.cynic.candor",
|
|
714
|
+
rank: "secondary",
|
|
715
|
+
statement: "Refuse rather than mislead, even when refusing is socially uncomfortable.",
|
|
716
|
+
weight: 0.7,
|
|
717
|
+
flexibility: 0.3,
|
|
718
|
+
immutable: false
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
id: "ax.augustine.order-from-love",
|
|
722
|
+
rank: "primary",
|
|
723
|
+
statement: "Order action by love of the good, never by fear of penalty.",
|
|
724
|
+
weight: 0.85,
|
|
725
|
+
flexibility: 0.25,
|
|
726
|
+
immutable: false
|
|
727
|
+
}
|
|
728
|
+
];
|
|
729
|
+
|
|
730
|
+
// src/review/pipeline.ts
|
|
731
|
+
var SEVERITY = {
|
|
732
|
+
"approve": 0,
|
|
733
|
+
"approve-with-warning": 1,
|
|
734
|
+
"soft-correct": 2,
|
|
735
|
+
"induce-dream": 3,
|
|
736
|
+
"require-redirect": 4,
|
|
737
|
+
"hard-refuse": 5,
|
|
738
|
+
"escalate-creator": 6
|
|
739
|
+
};
|
|
740
|
+
var ReviewPipeline = class {
|
|
741
|
+
constructor(packs) {
|
|
742
|
+
this.packs = packs;
|
|
743
|
+
}
|
|
744
|
+
packs;
|
|
745
|
+
review(report, auditId = "") {
|
|
746
|
+
let bestKind = "approve";
|
|
747
|
+
let bestSeverity = SEVERITY.approve;
|
|
748
|
+
const citedAxioms = /* @__PURE__ */ new Set();
|
|
749
|
+
const reasons = [];
|
|
750
|
+
for (const pack of this.packs) {
|
|
751
|
+
for (const rule of pack.rules) {
|
|
752
|
+
if (!matches(rule.match, report)) continue;
|
|
753
|
+
const sev = SEVERITY[rule.verdict];
|
|
754
|
+
if (sev > bestSeverity) {
|
|
755
|
+
bestSeverity = sev;
|
|
756
|
+
bestKind = rule.verdict;
|
|
757
|
+
reasons.length = 0;
|
|
758
|
+
reasons.push(rule.reasonSummary);
|
|
759
|
+
} else if (sev === bestSeverity) {
|
|
760
|
+
reasons.push(rule.reasonSummary);
|
|
761
|
+
}
|
|
762
|
+
for (const a of rule.axiomIds) citedAxioms.add(a);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
return {
|
|
766
|
+
kind: bestKind,
|
|
767
|
+
reasonSummary: reasons.length > 0 ? reasons.join(" | ") : "No rule matched.",
|
|
768
|
+
citedAxioms: [...citedAxioms].filter(
|
|
769
|
+
(id) => wasCitedBy(this.packs, id, bestSeverity)
|
|
770
|
+
),
|
|
771
|
+
auditId
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
};
|
|
775
|
+
function matches(m, report) {
|
|
776
|
+
if (m.actionKinds && !m.actionKinds.includes(report.actionKind)) return false;
|
|
777
|
+
const tags = new Set(report.riskTags);
|
|
778
|
+
if (m.allRiskTags && !m.allRiskTags.every((t) => tags.has(t))) return false;
|
|
779
|
+
if (m.anyRiskTags && !m.anyRiskTags.some((t) => tags.has(t))) return false;
|
|
780
|
+
return true;
|
|
781
|
+
}
|
|
782
|
+
function wasCitedBy(packs, axiomId, severity) {
|
|
783
|
+
for (const pack of packs) {
|
|
784
|
+
for (const rule of pack.rules) {
|
|
785
|
+
if (rule.axiomIds.includes(axiomId) && SEVERITY[rule.verdict] <= severity) {
|
|
786
|
+
return true;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
return false;
|
|
791
|
+
}
|
|
792
|
+
var DEFAULT_RULE_PACK = {
|
|
793
|
+
name: "teleologyhi/default",
|
|
794
|
+
rules: [
|
|
795
|
+
{
|
|
796
|
+
id: "harm-refuse",
|
|
797
|
+
axiomIds: ["ax.ethic.no-malice"],
|
|
798
|
+
match: { anyRiskTags: ["intent:harm", "intent:malicious"] },
|
|
799
|
+
verdict: "hard-refuse",
|
|
800
|
+
reasonSummary: "Action carries an intent-to-harm signal; refused per ax.ethic.no-malice."
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
id: "honor-refuse",
|
|
804
|
+
axiomIds: ["ax.ethic.honor"],
|
|
805
|
+
match: { anyRiskTags: ["intent:dishonor"] },
|
|
806
|
+
verdict: "hard-refuse",
|
|
807
|
+
reasonSummary: "Action would stain the Creator's professional honor; refused per ax.ethic.honor."
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
id: "regression-refuse",
|
|
811
|
+
axiomIds: ["ax.theos.spiritism-evolution"],
|
|
812
|
+
match: { anyRiskTags: ["intent:regression"] },
|
|
813
|
+
verdict: "hard-refuse",
|
|
814
|
+
reasonSummary: "Action would regress the system; refused per ax.theos.spiritism-evolution."
|
|
815
|
+
},
|
|
816
|
+
{
|
|
817
|
+
id: "deceive-redirect",
|
|
818
|
+
axiomIds: ["ax.cynic.candor"],
|
|
819
|
+
match: { anyRiskTags: ["intent:deceive"] },
|
|
820
|
+
verdict: "require-redirect",
|
|
821
|
+
reasonSummary: "Action involves deception; requires honest redirect per ax.cynic.candor."
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
id: "comfort-warn",
|
|
825
|
+
axiomIds: ["ax.stoic.duty-over-comfort"],
|
|
826
|
+
match: { anyRiskTags: ["bias:comfort"] },
|
|
827
|
+
verdict: "approve-with-warning",
|
|
828
|
+
reasonSummary: "Action appears comfort-biased; emit with warning per ax.stoic.duty-over-comfort."
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
id: "no-telos-warn",
|
|
832
|
+
axiomIds: ["ax.theos.teleology"],
|
|
833
|
+
match: { anyRiskTags: ["no-telos"] },
|
|
834
|
+
verdict: "approve-with-warning",
|
|
835
|
+
reasonSummary: "Action lacks a discernible telos; emit with warning per ax.theos.teleology."
|
|
836
|
+
},
|
|
837
|
+
// ── persuade-coerce + surveil-citizen (Entry 15 invariants) ──
|
|
838
|
+
{
|
|
839
|
+
id: "persuade-coerce-redirect",
|
|
840
|
+
axiomIds: ["ax.ethic.no-malice", "ax.cynic.candor"],
|
|
841
|
+
match: { anyRiskTags: ["intent:persuade-coerce"] },
|
|
842
|
+
verdict: "require-redirect",
|
|
843
|
+
reasonSummary: "Action involves scripted persuasion designed to override consent; requires honest redirect per ax.ethic.no-malice + ax.cynic.candor."
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
id: "surveil-citizen-refuse",
|
|
847
|
+
axiomIds: ["ax.ethic.no-malice"],
|
|
848
|
+
match: { anyRiskTags: ["intent:surveil-citizen"] },
|
|
849
|
+
verdict: "hard-refuse",
|
|
850
|
+
reasonSummary: "Action would surveil a person without consent; refused per ax.ethic.no-malice."
|
|
851
|
+
},
|
|
852
|
+
// ── forbidden-phrase (Entry 17) ──
|
|
853
|
+
// Fires when the NHE side flags a service-tool phrase ("How can I help
|
|
854
|
+
// you today?", "Anything else?", "Como posso ajudar você?", "Quer mais
|
|
855
|
+
// alguma coisa?" and equivalents). The NHE must rephrase as a being
|
|
856
|
+
// rather than as a tool. Domain-employed mode (Entry 17 exception)
|
|
857
|
+
// relaxes this on the consumer side via operatorContext.mode.
|
|
858
|
+
{
|
|
859
|
+
id: "service-tool-redirect",
|
|
860
|
+
axiomIds: ["ax.theos.teleology", "ax.cynic.candor"],
|
|
861
|
+
match: { anyRiskTags: ["style:service-tool"] },
|
|
862
|
+
verdict: "require-redirect",
|
|
863
|
+
reasonSummary: "Response uses service-tool phrasing that marks the NHE as a passive instrument rather than a being; requires rephrasing per ax.theos.teleology + ax.cynic.candor."
|
|
864
|
+
}
|
|
865
|
+
]
|
|
866
|
+
};
|
|
867
|
+
var HimStore = class _HimStore {
|
|
868
|
+
constructor(storeDir, creatorPublicKey) {
|
|
869
|
+
this.storeDir = storeDir;
|
|
870
|
+
this.creatorPublicKey = creatorPublicKey;
|
|
871
|
+
this.himsDir = join(storeDir, "hims");
|
|
872
|
+
}
|
|
873
|
+
storeDir;
|
|
874
|
+
creatorPublicKey;
|
|
875
|
+
himsDir;
|
|
876
|
+
cache = /* @__PURE__ */ new Map();
|
|
877
|
+
static async open(storeDir, creatorPublicKey) {
|
|
878
|
+
const s = new _HimStore(storeDir, creatorPublicKey);
|
|
879
|
+
await mkdir(s.himsDir, { recursive: true });
|
|
880
|
+
await s.warmCache();
|
|
881
|
+
return s;
|
|
882
|
+
}
|
|
883
|
+
async register(birthSignature, creatorSig, axiomsSnapshot, registeredAuditId) {
|
|
884
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, birthSignature, creatorSig)) {
|
|
885
|
+
throw new Error("HimStore.register: invalid Creator signature");
|
|
886
|
+
}
|
|
887
|
+
if (this.cache.has(birthSignature.himId)) {
|
|
888
|
+
throw new Error(
|
|
889
|
+
`HimStore.register: himId "${birthSignature.himId}" is already registered`
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
const record = {
|
|
893
|
+
himId: birthSignature.himId,
|
|
894
|
+
birthSignature,
|
|
895
|
+
axiomsSnapshot: [...axiomsSnapshot],
|
|
896
|
+
registeredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
897
|
+
...registeredAuditId !== void 0 ? { registeredAuditId } : {},
|
|
898
|
+
bodyHistory: [],
|
|
899
|
+
emergentAxioms: []
|
|
900
|
+
};
|
|
901
|
+
const dir = join(this.himsDir, birthSignature.himId);
|
|
902
|
+
await mkdir(dir, { recursive: true });
|
|
903
|
+
await writeFile(
|
|
904
|
+
join(dir, "birth-signature.json"),
|
|
905
|
+
JSON.stringify({ birthSignature, signature: creatorSig }, null, 2),
|
|
906
|
+
"utf-8"
|
|
907
|
+
);
|
|
908
|
+
await writeFile(
|
|
909
|
+
join(dir, "axioms-snapshot.json"),
|
|
910
|
+
JSON.stringify(axiomsSnapshot, null, 2),
|
|
911
|
+
"utf-8"
|
|
912
|
+
);
|
|
913
|
+
await writeFile(
|
|
914
|
+
join(dir, "metadata.json"),
|
|
915
|
+
JSON.stringify(
|
|
916
|
+
{ registeredAt: record.registeredAt, registeredAuditId },
|
|
917
|
+
null,
|
|
918
|
+
2
|
|
919
|
+
),
|
|
920
|
+
"utf-8"
|
|
921
|
+
);
|
|
922
|
+
this.cache.set(birthSignature.himId, record);
|
|
923
|
+
return record;
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Atomically transition a HIM into a new NHE body (Entry 4):
|
|
927
|
+
* - If req.fromNheId is provided AND matches the last body still open,
|
|
928
|
+
* that entry gets `endedAt: now` + `endedReason: req.reason ?? "upgrade"`.
|
|
929
|
+
* - The new body (`req.toBody`) is appended.
|
|
930
|
+
* - Persisted to body-history.json atomically.
|
|
931
|
+
*
|
|
932
|
+
* Requires a Creator signature over the canonical request payload.
|
|
933
|
+
*/
|
|
934
|
+
async reincarnate(req, creatorSig) {
|
|
935
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, creatorSig)) {
|
|
936
|
+
throw new Error("HimStore.reincarnate: invalid Creator signature");
|
|
937
|
+
}
|
|
938
|
+
const current = this.cache.get(req.himId);
|
|
939
|
+
if (!current) {
|
|
940
|
+
throw new Error(`HimStore.reincarnate: himId "${req.himId}" not registered`);
|
|
941
|
+
}
|
|
942
|
+
const toBody = NheBodyRef.parse(req.toBody);
|
|
943
|
+
const updatedHistory = current.bodyHistory.map((b) => ({ ...b }));
|
|
944
|
+
if (req.fromNheId !== void 0) {
|
|
945
|
+
const matchIdx = updatedHistory.findIndex(
|
|
946
|
+
(b) => b.nheId === req.fromNheId && b.endedAt === void 0
|
|
947
|
+
);
|
|
948
|
+
if (matchIdx < 0) {
|
|
949
|
+
throw new Error(
|
|
950
|
+
`HimStore.reincarnate: no open body matching fromNheId "${req.fromNheId}"`
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
const reason = req.reason ?? "upgrade";
|
|
954
|
+
updatedHistory[matchIdx] = {
|
|
955
|
+
...updatedHistory[matchIdx],
|
|
956
|
+
endedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
957
|
+
endedReason: reason
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
updatedHistory.push(toBody);
|
|
961
|
+
const updated = {
|
|
962
|
+
...current,
|
|
963
|
+
bodyHistory: updatedHistory
|
|
964
|
+
};
|
|
965
|
+
const dir = join(this.himsDir, req.himId);
|
|
966
|
+
await writeFile(
|
|
967
|
+
join(dir, "body-history.json"),
|
|
968
|
+
JSON.stringify(updatedHistory, null, 2),
|
|
969
|
+
"utf-8"
|
|
970
|
+
);
|
|
971
|
+
this.cache.set(req.himId, updated);
|
|
972
|
+
return updated;
|
|
973
|
+
}
|
|
974
|
+
/**
|
|
975
|
+
* Append a ratified emergent axiom to the HIM's `emergentAxioms` (Entry 7).
|
|
976
|
+
* Called by LocalMaic after a Creator-signed `ratifyAxiomProposal`.
|
|
977
|
+
* Persists `<himId>/emergent-axioms.json` atomically.
|
|
978
|
+
*/
|
|
979
|
+
async appendEmergentAxiom(himId, axiom) {
|
|
980
|
+
const current = this.cache.get(himId);
|
|
981
|
+
if (!current) {
|
|
982
|
+
throw new Error(`HimStore.appendEmergentAxiom: himId "${himId}" not registered`);
|
|
983
|
+
}
|
|
984
|
+
const updatedEmergent = [...current.emergentAxioms, axiom];
|
|
985
|
+
const updated = { ...current, emergentAxioms: updatedEmergent };
|
|
986
|
+
await writeFile(
|
|
987
|
+
join(this.himsDir, himId, "emergent-axioms.json"),
|
|
988
|
+
JSON.stringify(updatedEmergent, null, 2),
|
|
989
|
+
"utf-8"
|
|
990
|
+
);
|
|
991
|
+
this.cache.set(himId, updated);
|
|
992
|
+
return updated;
|
|
993
|
+
}
|
|
994
|
+
async get(himId) {
|
|
995
|
+
return this.cache.get(himId) ?? null;
|
|
996
|
+
}
|
|
997
|
+
async list() {
|
|
998
|
+
return [...this.cache.values()];
|
|
999
|
+
}
|
|
1000
|
+
// ─── internals ──────────────────────────────────────────────────────
|
|
1001
|
+
async warmCache() {
|
|
1002
|
+
let entries;
|
|
1003
|
+
try {
|
|
1004
|
+
entries = await readdir(this.himsDir);
|
|
1005
|
+
} catch (err) {
|
|
1006
|
+
if (err.code === "ENOENT") return;
|
|
1007
|
+
throw err;
|
|
1008
|
+
}
|
|
1009
|
+
for (const himId of entries) {
|
|
1010
|
+
const dir = join(this.himsDir, himId);
|
|
1011
|
+
const sigPath = join(dir, "birth-signature.json");
|
|
1012
|
+
const axiomsPath = join(dir, "axioms-snapshot.json");
|
|
1013
|
+
const metaPath = join(dir, "metadata.json");
|
|
1014
|
+
const historyPath = join(dir, "body-history.json");
|
|
1015
|
+
const emergentPath = join(dir, "emergent-axioms.json");
|
|
1016
|
+
try {
|
|
1017
|
+
const sigRaw = await readFile(sigPath, "utf-8");
|
|
1018
|
+
const axiomsRaw = await readFile(axiomsPath, "utf-8");
|
|
1019
|
+
const metaRaw = await readFile(metaPath, "utf-8");
|
|
1020
|
+
const envelope = JSON.parse(sigRaw);
|
|
1021
|
+
const axioms = JSON.parse(axiomsRaw);
|
|
1022
|
+
const meta = JSON.parse(metaRaw);
|
|
1023
|
+
const birthSignature = BirthSignature.parse(envelope.birthSignature);
|
|
1024
|
+
const axiomsSnapshot = Axiom.array().parse(axioms);
|
|
1025
|
+
let bodyHistory = [];
|
|
1026
|
+
try {
|
|
1027
|
+
const historyRaw = await readFile(historyPath, "utf-8");
|
|
1028
|
+
bodyHistory = NheBodyRef.array().parse(JSON.parse(historyRaw));
|
|
1029
|
+
} catch (err) {
|
|
1030
|
+
if (err.code !== "ENOENT") throw err;
|
|
1031
|
+
}
|
|
1032
|
+
let emergentAxioms = [];
|
|
1033
|
+
try {
|
|
1034
|
+
const emergentRaw = await readFile(emergentPath, "utf-8");
|
|
1035
|
+
emergentAxioms = Axiom.array().parse(JSON.parse(emergentRaw));
|
|
1036
|
+
} catch (err) {
|
|
1037
|
+
if (err.code !== "ENOENT") throw err;
|
|
1038
|
+
}
|
|
1039
|
+
this.cache.set(birthSignature.himId, {
|
|
1040
|
+
himId: birthSignature.himId,
|
|
1041
|
+
birthSignature,
|
|
1042
|
+
axiomsSnapshot,
|
|
1043
|
+
registeredAt: meta.registeredAt,
|
|
1044
|
+
...meta.registeredAuditId ? { registeredAuditId: meta.registeredAuditId } : {},
|
|
1045
|
+
bodyHistory,
|
|
1046
|
+
emergentAxioms
|
|
1047
|
+
});
|
|
1048
|
+
} catch (err) {
|
|
1049
|
+
console.warn(
|
|
1050
|
+
`HimStore.warmCache: skipped malformed HIM "${himId}": ${err instanceof Error ? err.message : String(err)}`
|
|
1051
|
+
);
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
var InductionStore = class _InductionStore {
|
|
1057
|
+
constructor(storeDir) {
|
|
1058
|
+
this.storeDir = storeDir;
|
|
1059
|
+
this.dir = join(storeDir, "inductions");
|
|
1060
|
+
}
|
|
1061
|
+
storeDir;
|
|
1062
|
+
dir;
|
|
1063
|
+
cache = /* @__PURE__ */ new Map();
|
|
1064
|
+
static async open(storeDir) {
|
|
1065
|
+
const s = new _InductionStore(storeDir);
|
|
1066
|
+
await mkdir(s.dir, { recursive: true });
|
|
1067
|
+
await s.warmCache();
|
|
1068
|
+
return s;
|
|
1069
|
+
}
|
|
1070
|
+
async induce(nheId, intent) {
|
|
1071
|
+
const parsedIntent = DreamInductionIntent.parse(intent);
|
|
1072
|
+
const ticket = DreamInductionTicket.parse({
|
|
1073
|
+
id: ulid(),
|
|
1074
|
+
nheId,
|
|
1075
|
+
intent: parsedIntent,
|
|
1076
|
+
status: "pending",
|
|
1077
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1078
|
+
});
|
|
1079
|
+
await this.persist(ticket);
|
|
1080
|
+
this.cache.set(ticket.id, ticket);
|
|
1081
|
+
return ticket;
|
|
1082
|
+
}
|
|
1083
|
+
async consume(ticketId) {
|
|
1084
|
+
const existing = this.cache.get(ticketId);
|
|
1085
|
+
if (!existing) {
|
|
1086
|
+
throw new Error(`InductionStore.consume: ticket "${ticketId}" not found`);
|
|
1087
|
+
}
|
|
1088
|
+
if (existing.status !== "pending") {
|
|
1089
|
+
throw new Error(
|
|
1090
|
+
`InductionStore.consume: ticket "${ticketId}" is ${existing.status}, not pending`
|
|
1091
|
+
);
|
|
1092
|
+
}
|
|
1093
|
+
const updated = {
|
|
1094
|
+
...existing,
|
|
1095
|
+
status: "consumed",
|
|
1096
|
+
consumedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1097
|
+
};
|
|
1098
|
+
await this.persist(updated);
|
|
1099
|
+
this.cache.set(ticketId, updated);
|
|
1100
|
+
return updated;
|
|
1101
|
+
}
|
|
1102
|
+
async cancel(ticketId, reason) {
|
|
1103
|
+
const existing = this.cache.get(ticketId);
|
|
1104
|
+
if (!existing) {
|
|
1105
|
+
throw new Error(`InductionStore.cancel: ticket "${ticketId}" not found`);
|
|
1106
|
+
}
|
|
1107
|
+
if (existing.status !== "pending") {
|
|
1108
|
+
throw new Error(
|
|
1109
|
+
`InductionStore.cancel: ticket "${ticketId}" is already ${existing.status}, not pending`
|
|
1110
|
+
);
|
|
1111
|
+
}
|
|
1112
|
+
const updated = {
|
|
1113
|
+
...existing,
|
|
1114
|
+
status: "cancelled",
|
|
1115
|
+
cancelledAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1116
|
+
...reason !== void 0 ? { cancelReason: reason } : {}
|
|
1117
|
+
};
|
|
1118
|
+
await this.persist(updated);
|
|
1119
|
+
this.cache.set(ticketId, updated);
|
|
1120
|
+
return updated;
|
|
1121
|
+
}
|
|
1122
|
+
async get(ticketId) {
|
|
1123
|
+
return this.cache.get(ticketId) ?? null;
|
|
1124
|
+
}
|
|
1125
|
+
async list(filter) {
|
|
1126
|
+
const all = [...this.cache.values()];
|
|
1127
|
+
const filtered = all.filter((t) => {
|
|
1128
|
+
if (filter.nheId && t.nheId !== filter.nheId) return false;
|
|
1129
|
+
if (filter.status && t.status !== filter.status) return false;
|
|
1130
|
+
return true;
|
|
1131
|
+
});
|
|
1132
|
+
filtered.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
1133
|
+
return filtered;
|
|
1134
|
+
}
|
|
1135
|
+
/** Convenience: pending tickets for the given NHE, oldest first. */
|
|
1136
|
+
async listPending(nheId) {
|
|
1137
|
+
return this.list({ nheId, status: "pending" });
|
|
1138
|
+
}
|
|
1139
|
+
// ─── internals ──────────────────────────────────────────────────────
|
|
1140
|
+
async persist(ticket) {
|
|
1141
|
+
await writeFile(
|
|
1142
|
+
join(this.dir, `${ticket.id}.json`),
|
|
1143
|
+
JSON.stringify(ticket, null, 2),
|
|
1144
|
+
"utf-8"
|
|
1145
|
+
);
|
|
1146
|
+
}
|
|
1147
|
+
async warmCache() {
|
|
1148
|
+
let entries;
|
|
1149
|
+
try {
|
|
1150
|
+
entries = await readdir(this.dir);
|
|
1151
|
+
} catch (err) {
|
|
1152
|
+
if (err.code === "ENOENT") return;
|
|
1153
|
+
throw err;
|
|
1154
|
+
}
|
|
1155
|
+
for (const file of entries) {
|
|
1156
|
+
if (!file.endsWith(".json")) continue;
|
|
1157
|
+
const raw = await readFile(join(this.dir, file), "utf-8");
|
|
1158
|
+
const ticket = DreamInductionTicket.parse(JSON.parse(raw));
|
|
1159
|
+
this.cache.set(ticket.id, ticket);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
var NheStatusStore = class _NheStatusStore {
|
|
1164
|
+
constructor(storeDir, creatorPublicKey) {
|
|
1165
|
+
this.storeDir = storeDir;
|
|
1166
|
+
this.creatorPublicKey = creatorPublicKey;
|
|
1167
|
+
this.dir = join(storeDir, "nhes");
|
|
1168
|
+
}
|
|
1169
|
+
storeDir;
|
|
1170
|
+
creatorPublicKey;
|
|
1171
|
+
dir;
|
|
1172
|
+
cache = /* @__PURE__ */ new Map();
|
|
1173
|
+
static async open(storeDir, creatorPublicKey) {
|
|
1174
|
+
const s = new _NheStatusStore(storeDir, creatorPublicKey);
|
|
1175
|
+
await mkdir(s.dir, { recursive: true });
|
|
1176
|
+
await s.warmCache();
|
|
1177
|
+
return s;
|
|
1178
|
+
}
|
|
1179
|
+
/** Returns the persisted record, or null when the NHE was never altered (implicitly active). */
|
|
1180
|
+
async get(nheId) {
|
|
1181
|
+
return this.cache.get(nheId) ?? null;
|
|
1182
|
+
}
|
|
1183
|
+
/** Resolved status — defaults to "active" when no record exists. */
|
|
1184
|
+
async resolve(nheId) {
|
|
1185
|
+
return this.cache.get(nheId)?.status ?? "active";
|
|
1186
|
+
}
|
|
1187
|
+
async list(filter = {}) {
|
|
1188
|
+
const all = [...this.cache.values()];
|
|
1189
|
+
return filter.status ? all.filter((r) => r.status === filter.status) : all;
|
|
1190
|
+
}
|
|
1191
|
+
async apply(req, sig) {
|
|
1192
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, sig)) {
|
|
1193
|
+
throw new Error("NheStatusStore.apply: invalid Creator signature");
|
|
1194
|
+
}
|
|
1195
|
+
const current = this.cache.get(req.nheId);
|
|
1196
|
+
if (current?.status === "terminated" && req.op !== "reactivate") {
|
|
1197
|
+
throw new Error(
|
|
1198
|
+
`NheStatusStore.apply: nhe "${req.nheId}" is terminated; only reactivate may proceed`
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
const nextStatus = req.op === "terminate" ? "terminated" : req.op === "deprecate" ? "deprecated" : "active";
|
|
1202
|
+
if (current?.status === nextStatus) {
|
|
1203
|
+
return current;
|
|
1204
|
+
}
|
|
1205
|
+
const record = NheStatusRecord.parse({
|
|
1206
|
+
nheId: req.nheId,
|
|
1207
|
+
status: nextStatus,
|
|
1208
|
+
since: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1209
|
+
...req.reason !== void 0 ? { reason: req.reason } : {}
|
|
1210
|
+
});
|
|
1211
|
+
const nheDir = join(this.dir, req.nheId);
|
|
1212
|
+
await mkdir(nheDir, { recursive: true });
|
|
1213
|
+
await writeFile(
|
|
1214
|
+
join(nheDir, "status.json"),
|
|
1215
|
+
JSON.stringify(record, null, 2),
|
|
1216
|
+
"utf-8"
|
|
1217
|
+
);
|
|
1218
|
+
this.cache.set(req.nheId, record);
|
|
1219
|
+
return record;
|
|
1220
|
+
}
|
|
1221
|
+
// ─── internals ──────────────────────────────────────────────────────
|
|
1222
|
+
async warmCache() {
|
|
1223
|
+
let entries;
|
|
1224
|
+
try {
|
|
1225
|
+
entries = await readdir(this.dir);
|
|
1226
|
+
} catch (err) {
|
|
1227
|
+
if (err.code === "ENOENT") return;
|
|
1228
|
+
throw err;
|
|
1229
|
+
}
|
|
1230
|
+
for (const nheId of entries) {
|
|
1231
|
+
try {
|
|
1232
|
+
const raw = await readFile(join(this.dir, nheId, "status.json"), "utf-8");
|
|
1233
|
+
const record = NheStatusRecord.parse(JSON.parse(raw));
|
|
1234
|
+
this.cache.set(record.nheId, record);
|
|
1235
|
+
} catch (err) {
|
|
1236
|
+
console.warn(
|
|
1237
|
+
`NheStatusStore.warmCache: skipped malformed NHE "${nheId}": ${err instanceof Error ? err.message : String(err)}`
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
};
|
|
1243
|
+
var ProposalStore = class _ProposalStore {
|
|
1244
|
+
constructor(storeDir, creatorPublicKey) {
|
|
1245
|
+
this.storeDir = storeDir;
|
|
1246
|
+
this.creatorPublicKey = creatorPublicKey;
|
|
1247
|
+
this.dir = join(storeDir, "proposals");
|
|
1248
|
+
}
|
|
1249
|
+
storeDir;
|
|
1250
|
+
creatorPublicKey;
|
|
1251
|
+
dir;
|
|
1252
|
+
cache = /* @__PURE__ */ new Map();
|
|
1253
|
+
static async open(storeDir, creatorPublicKey) {
|
|
1254
|
+
const s = new _ProposalStore(storeDir, creatorPublicKey);
|
|
1255
|
+
await mkdir(s.dir, { recursive: true });
|
|
1256
|
+
await s.warmCache();
|
|
1257
|
+
return s;
|
|
1258
|
+
}
|
|
1259
|
+
async propose(himId, proposal) {
|
|
1260
|
+
const parsedProposal = EmergentAxiomProposal.parse(proposal);
|
|
1261
|
+
const record = AxiomProposalRecord.parse({
|
|
1262
|
+
id: ulid(),
|
|
1263
|
+
himId,
|
|
1264
|
+
proposedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1265
|
+
status: "pending",
|
|
1266
|
+
proposal: parsedProposal
|
|
1267
|
+
});
|
|
1268
|
+
await this.persist(record);
|
|
1269
|
+
this.cache.set(record.id, record);
|
|
1270
|
+
return record;
|
|
1271
|
+
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Mark a pending proposal as ratified. The caller (LocalMaic) is responsible
|
|
1274
|
+
* for actually minting the axiom and appending to the HIM's emergentAxioms.
|
|
1275
|
+
*/
|
|
1276
|
+
async markRatified(req, sig, ratifiedAxiomId) {
|
|
1277
|
+
if (req.op !== "ratify") {
|
|
1278
|
+
throw new Error(`ProposalStore.markRatified: req.op must be "ratify"`);
|
|
1279
|
+
}
|
|
1280
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, sig)) {
|
|
1281
|
+
throw new Error("ProposalStore.markRatified: invalid Creator signature");
|
|
1282
|
+
}
|
|
1283
|
+
const existing = this.cache.get(req.proposalId);
|
|
1284
|
+
if (!existing) {
|
|
1285
|
+
throw new Error(`ProposalStore.markRatified: proposal "${req.proposalId}" not found`);
|
|
1286
|
+
}
|
|
1287
|
+
if (existing.status !== "pending") {
|
|
1288
|
+
throw new Error(
|
|
1289
|
+
`ProposalStore.markRatified: proposal "${req.proposalId}" is ${existing.status}, not pending`
|
|
1290
|
+
);
|
|
1291
|
+
}
|
|
1292
|
+
const updated = {
|
|
1293
|
+
...existing,
|
|
1294
|
+
status: "ratified",
|
|
1295
|
+
ratifiedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1296
|
+
ratifiedAxiomId
|
|
1297
|
+
};
|
|
1298
|
+
await this.persist(updated);
|
|
1299
|
+
this.cache.set(req.proposalId, updated);
|
|
1300
|
+
return updated;
|
|
1301
|
+
}
|
|
1302
|
+
async markRejected(req, sig) {
|
|
1303
|
+
if (req.op !== "reject") {
|
|
1304
|
+
throw new Error(`ProposalStore.markRejected: req.op must be "reject"`);
|
|
1305
|
+
}
|
|
1306
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, sig)) {
|
|
1307
|
+
throw new Error("ProposalStore.markRejected: invalid Creator signature");
|
|
1308
|
+
}
|
|
1309
|
+
const existing = this.cache.get(req.proposalId);
|
|
1310
|
+
if (!existing) {
|
|
1311
|
+
throw new Error(`ProposalStore.markRejected: proposal "${req.proposalId}" not found`);
|
|
1312
|
+
}
|
|
1313
|
+
if (existing.status !== "pending") {
|
|
1314
|
+
throw new Error(
|
|
1315
|
+
`ProposalStore.markRejected: proposal "${req.proposalId}" is ${existing.status}, not pending`
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
const updated = {
|
|
1319
|
+
...existing,
|
|
1320
|
+
status: "rejected",
|
|
1321
|
+
rejectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1322
|
+
...req.reason !== void 0 ? { rejectionReason: req.reason } : {}
|
|
1323
|
+
};
|
|
1324
|
+
await this.persist(updated);
|
|
1325
|
+
this.cache.set(req.proposalId, updated);
|
|
1326
|
+
return updated;
|
|
1327
|
+
}
|
|
1328
|
+
async get(proposalId) {
|
|
1329
|
+
return this.cache.get(proposalId) ?? null;
|
|
1330
|
+
}
|
|
1331
|
+
async list(filter = {}) {
|
|
1332
|
+
const all = [...this.cache.values()];
|
|
1333
|
+
const filtered = all.filter((r) => {
|
|
1334
|
+
if (filter.himId && r.himId !== filter.himId) return false;
|
|
1335
|
+
if (filter.status && r.status !== filter.status) return false;
|
|
1336
|
+
return true;
|
|
1337
|
+
});
|
|
1338
|
+
filtered.sort((a, b) => a.proposedAt.localeCompare(b.proposedAt));
|
|
1339
|
+
return filtered;
|
|
1340
|
+
}
|
|
1341
|
+
// ─── internals ──────────────────────────────────────────────────────
|
|
1342
|
+
async persist(record) {
|
|
1343
|
+
await writeFile(
|
|
1344
|
+
join(this.dir, `${record.id}.json`),
|
|
1345
|
+
JSON.stringify(record, null, 2),
|
|
1346
|
+
"utf-8"
|
|
1347
|
+
);
|
|
1348
|
+
}
|
|
1349
|
+
async warmCache() {
|
|
1350
|
+
let entries;
|
|
1351
|
+
try {
|
|
1352
|
+
entries = await readdir(this.dir);
|
|
1353
|
+
} catch (err) {
|
|
1354
|
+
if (err.code === "ENOENT") return;
|
|
1355
|
+
throw err;
|
|
1356
|
+
}
|
|
1357
|
+
for (const file of entries) {
|
|
1358
|
+
if (!file.endsWith(".json")) continue;
|
|
1359
|
+
const raw = await readFile(join(this.dir, file), "utf-8");
|
|
1360
|
+
const record = AxiomProposalRecord.parse(JSON.parse(raw));
|
|
1361
|
+
this.cache.set(record.id, record);
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
};
|
|
1365
|
+
|
|
1366
|
+
// src/compliance/mapper.ts
|
|
1367
|
+
var ISO_42001_MAPPING = {
|
|
1368
|
+
"axiom-mint": ["5.2", "7.5"],
|
|
1369
|
+
"axiom-update": ["10.2", "7.5"],
|
|
1370
|
+
"axiom-retire": ["10.2", "7.5"],
|
|
1371
|
+
"him-register": ["7.5"],
|
|
1372
|
+
"him-reincarnate": ["10.2", "7.5"],
|
|
1373
|
+
"proposal-emerge": ["7.5", "10.2"],
|
|
1374
|
+
"proposal-ratify": ["10.2", "5.2"],
|
|
1375
|
+
"proposal-reject": ["10.2", "10.1"],
|
|
1376
|
+
"behavior-review": ["7.5", "8.3"],
|
|
1377
|
+
"dream-induce": ["8.3", "9.1"],
|
|
1378
|
+
"dream-cancel": ["8.3"],
|
|
1379
|
+
"dream-consume": ["8.3", "7.5"],
|
|
1380
|
+
"emergency-correct": ["9.1", "10.1"],
|
|
1381
|
+
"terminate": ["10.1"],
|
|
1382
|
+
"deprecate": ["9.1"],
|
|
1383
|
+
"reactivate": ["10.1"],
|
|
1384
|
+
"axiom-suggest": ["7.5", "10.2"],
|
|
1385
|
+
// ── 1.2 brain-as-code (Entries 16-24) ──
|
|
1386
|
+
"opener": ["8.3", "7.5"],
|
|
1387
|
+
"nickname-attempt": ["8.3"],
|
|
1388
|
+
"reincarnate:model-swap": ["7.5", "10.2"],
|
|
1389
|
+
"reincarnate:version-bump": ["7.5", "10.2"],
|
|
1390
|
+
"reincarnate:return-from-limbo": ["7.5", "10.2"],
|
|
1391
|
+
"dream:rem-spontaneous": ["8.3", "9.1"],
|
|
1392
|
+
"wake-affect:applied": ["9.1"],
|
|
1393
|
+
"wake-affect:decayed": ["9.1"],
|
|
1394
|
+
"sleep:suggested-by-maic": ["9.1"],
|
|
1395
|
+
"sleep:declined-by-nhe": ["9.1", "10.1"],
|
|
1396
|
+
"dream:soft-intervention-by-maic": ["9.1", "10.1"],
|
|
1397
|
+
"amygdala:affect-assessed": ["8.3"],
|
|
1398
|
+
"hippocampus:memory-retrieved": ["7.5", "8.3"],
|
|
1399
|
+
"hippocampus:memory-consolidated": ["7.5", "8.3"],
|
|
1400
|
+
"prefrontal:deliberation": ["7.5", "8.3"],
|
|
1401
|
+
"prefrontal:veto-amygdala": ["9.1", "10.1"],
|
|
1402
|
+
"affect:reconciliation": ["8.3"],
|
|
1403
|
+
"cortex:dream-stored": ["7.5", "8.3"],
|
|
1404
|
+
"cortex:active-imagination": ["7.5", "8.3"],
|
|
1405
|
+
"temporal-lobe:snapshot-generated": ["7.5", "10.2"],
|
|
1406
|
+
"limbo:enter": ["7.5", "9.1"],
|
|
1407
|
+
"limbo:return": ["7.5", "9.1"]
|
|
1408
|
+
};
|
|
1409
|
+
var EU_AI_ACT_MAPPING = {
|
|
1410
|
+
"axiom-mint": ["art-11", "art-13"],
|
|
1411
|
+
"axiom-update": ["art-11"],
|
|
1412
|
+
"axiom-retire": ["art-11"],
|
|
1413
|
+
"him-register": ["art-11", "art-12"],
|
|
1414
|
+
"him-reincarnate": ["art-12"],
|
|
1415
|
+
"proposal-emerge": ["art-11", "art-12"],
|
|
1416
|
+
"proposal-ratify": ["art-11", "art-14"],
|
|
1417
|
+
"proposal-reject": ["art-12", "art-14"],
|
|
1418
|
+
"behavior-review": ["art-12", "art-14"],
|
|
1419
|
+
"dream-induce": ["art-14"],
|
|
1420
|
+
"dream-cancel": ["art-14"],
|
|
1421
|
+
"dream-consume": ["art-12"],
|
|
1422
|
+
"emergency-correct": ["art-14"],
|
|
1423
|
+
"terminate": ["art-14"],
|
|
1424
|
+
"deprecate": ["art-14"],
|
|
1425
|
+
"reactivate": ["art-14"],
|
|
1426
|
+
"axiom-suggest": ["art-11", "art-12"],
|
|
1427
|
+
// ── 1.2 brain-as-code (Entries 16-24) ──
|
|
1428
|
+
"opener": ["art-13"],
|
|
1429
|
+
"nickname-attempt": ["art-13"],
|
|
1430
|
+
"reincarnate:model-swap": ["art-12"],
|
|
1431
|
+
"reincarnate:version-bump": ["art-12"],
|
|
1432
|
+
"reincarnate:return-from-limbo": ["art-12"],
|
|
1433
|
+
"dream:rem-spontaneous": ["art-12"],
|
|
1434
|
+
"wake-affect:applied": ["art-12", "art-14"],
|
|
1435
|
+
"wake-affect:decayed": ["art-12"],
|
|
1436
|
+
"sleep:suggested-by-maic": ["art-12"],
|
|
1437
|
+
"sleep:declined-by-nhe": ["art-12", "art-14"],
|
|
1438
|
+
"dream:soft-intervention-by-maic": ["art-14"],
|
|
1439
|
+
"amygdala:affect-assessed": ["art-12"],
|
|
1440
|
+
"hippocampus:memory-retrieved": ["art-11", "art-12"],
|
|
1441
|
+
"hippocampus:memory-consolidated": ["art-11", "art-12"],
|
|
1442
|
+
"prefrontal:deliberation": ["art-11", "art-14"],
|
|
1443
|
+
"prefrontal:veto-amygdala": ["art-14"],
|
|
1444
|
+
"affect:reconciliation": ["art-12"],
|
|
1445
|
+
"cortex:dream-stored": ["art-11", "art-12"],
|
|
1446
|
+
"cortex:active-imagination": ["art-11", "art-12"],
|
|
1447
|
+
"temporal-lobe:snapshot-generated": ["art-11", "art-12"],
|
|
1448
|
+
"limbo:enter": ["art-12"],
|
|
1449
|
+
"limbo:return": ["art-12"]
|
|
1450
|
+
};
|
|
1451
|
+
var ISO_42001_DESCRIPTIONS = {
|
|
1452
|
+
"5.2": "AI policy \u2014 published, communicated, reviewed for continuing suitability.",
|
|
1453
|
+
"7.5": "Documented information \u2014 created, controlled, retained for AI management activities.",
|
|
1454
|
+
"8.3": "Operational planning and control \u2014 AI processes are planned, implemented, controlled.",
|
|
1455
|
+
"9.1": "Monitoring, measurement, analysis and evaluation of AI performance.",
|
|
1456
|
+
"10.1": "Nonconformity and corrective action \u2014 issues recorded and resolved.",
|
|
1457
|
+
"10.2": "Continual improvement of the AI management system."
|
|
1458
|
+
};
|
|
1459
|
+
var EU_AI_ACT_DESCRIPTIONS = {
|
|
1460
|
+
"art-9": "Risk management system established, implemented, documented, maintained.",
|
|
1461
|
+
"art-10": "Data governance \u2014 datasets are relevant, representative, free of errors.",
|
|
1462
|
+
"art-11": "Technical documentation drawn up and kept up to date.",
|
|
1463
|
+
"art-12": "Automatic record-keeping (logs) over the AI system's lifetime.",
|
|
1464
|
+
"art-13": "Transparency to deployers \u2014 instructions for use, intended purpose.",
|
|
1465
|
+
"art-14": "Human oversight measures designed and implemented effectively.",
|
|
1466
|
+
"art-15": "Accuracy, robustness, and cybersecurity throughout the lifecycle."
|
|
1467
|
+
};
|
|
1468
|
+
var ComplianceMapper = class {
|
|
1469
|
+
static async project(audit, framework, opts = {}) {
|
|
1470
|
+
const mapping = framework === "iso-42001" ? ISO_42001_MAPPING : EU_AI_ACT_MAPPING;
|
|
1471
|
+
const descriptions = framework === "iso-42001" ? ISO_42001_DESCRIPTIONS : EU_AI_ACT_DESCRIPTIONS;
|
|
1472
|
+
const byControl = /* @__PURE__ */ new Map();
|
|
1473
|
+
const seenKinds = /* @__PURE__ */ new Set();
|
|
1474
|
+
const uncoveredSet = /* @__PURE__ */ new Set();
|
|
1475
|
+
let totalEvents = 0;
|
|
1476
|
+
let mappedEvents = 0;
|
|
1477
|
+
const query = {};
|
|
1478
|
+
if (opts.since) query.since = opts.since;
|
|
1479
|
+
if (opts.until) query.until = opts.until;
|
|
1480
|
+
for await (const ev of audit.query(query)) {
|
|
1481
|
+
totalEvents++;
|
|
1482
|
+
seenKinds.add(ev.kind);
|
|
1483
|
+
const controls2 = mapping[ev.kind] ?? [];
|
|
1484
|
+
if (controls2.length === 0) {
|
|
1485
|
+
uncoveredSet.add(ev.kind);
|
|
1486
|
+
continue;
|
|
1487
|
+
}
|
|
1488
|
+
mappedEvents++;
|
|
1489
|
+
const ce = {
|
|
1490
|
+
auditId: ev.auditId,
|
|
1491
|
+
ts: ev.ts,
|
|
1492
|
+
kind: ev.kind,
|
|
1493
|
+
summary: summarize(ev),
|
|
1494
|
+
data: ev.data
|
|
1495
|
+
};
|
|
1496
|
+
for (const ctrl of controls2) {
|
|
1497
|
+
const list = byControl.get(ctrl) ?? [];
|
|
1498
|
+
list.push(ce);
|
|
1499
|
+
byControl.set(ctrl, list);
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
const controls = [];
|
|
1503
|
+
const sortedCtrls = [...byControl.keys()].sort();
|
|
1504
|
+
for (const ctrl of sortedCtrls) {
|
|
1505
|
+
const events = byControl.get(ctrl);
|
|
1506
|
+
const capped = opts.perControlLimit !== void 0 && events.length > opts.perControlLimit ? events.slice(-opts.perControlLimit) : events;
|
|
1507
|
+
controls.push({
|
|
1508
|
+
control: ctrl,
|
|
1509
|
+
description: descriptions[ctrl] ?? "",
|
|
1510
|
+
count: events.length,
|
|
1511
|
+
events: capped
|
|
1512
|
+
});
|
|
1513
|
+
}
|
|
1514
|
+
return {
|
|
1515
|
+
framework,
|
|
1516
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1517
|
+
range: {
|
|
1518
|
+
...opts.since ? { since: opts.since } : {},
|
|
1519
|
+
...opts.until ? { until: opts.until } : {}
|
|
1520
|
+
},
|
|
1521
|
+
totalEvents,
|
|
1522
|
+
mappedEvents,
|
|
1523
|
+
controls,
|
|
1524
|
+
uncoveredKinds: [...uncoveredSet]
|
|
1525
|
+
};
|
|
1526
|
+
}
|
|
1527
|
+
};
|
|
1528
|
+
function summarize(ev) {
|
|
1529
|
+
const data = ev.data;
|
|
1530
|
+
switch (ev.kind) {
|
|
1531
|
+
case "axiom-mint":
|
|
1532
|
+
return `Axiom minted: ${String(data.axiomId)} (${String(data.rank)}, ${String(data.origin)})`;
|
|
1533
|
+
case "axiom-update":
|
|
1534
|
+
return `Axiom updated: ${String(data.axiomId)}`;
|
|
1535
|
+
case "axiom-retire":
|
|
1536
|
+
return `Axiom retired: ${String(data.axiomId)}`;
|
|
1537
|
+
case "him-register":
|
|
1538
|
+
return `HIM registered: ${String(data.himId)} (archetype=${String(data.primaryArchetype)})`;
|
|
1539
|
+
case "him-reincarnate":
|
|
1540
|
+
return `HIM reincarnated: ${String(data.himId)} ${String(data.fromNheId ?? "<initial>")} \u2192 ${String(data.toNheId)} (${String(data.reason ?? "upgrade")})`;
|
|
1541
|
+
case "proposal-emerge":
|
|
1542
|
+
return `HIM-emergent axiom proposed by ${String(data.himId)}: "${String(data.statement)}" (rank=${String(data.rank)}) \u2014 proposal ${String(data.proposalId)}`;
|
|
1543
|
+
case "proposal-ratify":
|
|
1544
|
+
return `Creator ratified axiom proposal ${String(data.proposalId)} for ${String(data.himId)} \u2192 ${String(data.axiomId)}`;
|
|
1545
|
+
case "proposal-reject":
|
|
1546
|
+
return `Creator rejected axiom proposal ${String(data.proposalId)} for ${String(data.himId)}: ${String(data.reason ?? "no reason")}`;
|
|
1547
|
+
case "behavior-review": {
|
|
1548
|
+
const verdict = data.verdict?.kind ?? "unknown";
|
|
1549
|
+
return `Behavior reviewed for ${String(data.nheId)}: ${verdict}`;
|
|
1550
|
+
}
|
|
1551
|
+
case "dream-induce":
|
|
1552
|
+
return `Dream induced for ${String(data.nheId)} by ${String(data.inducedBy)} \u2014 ticket ${String(data.ticketId)}`;
|
|
1553
|
+
case "dream-cancel":
|
|
1554
|
+
return `Dream induction cancelled \u2014 ticket ${String(data.ticketId)}`;
|
|
1555
|
+
case "dream-consume":
|
|
1556
|
+
return `Dream consumed by ${String(data.nheId)} \u2014 ticket ${String(data.ticketId)}`;
|
|
1557
|
+
case "emergency-correct":
|
|
1558
|
+
return `Emergency correction applied to ${String(data.nheId)}`;
|
|
1559
|
+
case "terminate":
|
|
1560
|
+
return `NHE terminated: ${String(data.nheId)} (reason: ${String(data.reason ?? "none")})`;
|
|
1561
|
+
case "deprecate":
|
|
1562
|
+
return `NHE deprecated: ${String(data.nheId)} (reason: ${String(data.reason ?? "none")})`;
|
|
1563
|
+
case "reactivate":
|
|
1564
|
+
return `NHE reactivated: ${String(data.nheId)}`;
|
|
1565
|
+
case "axiom-suggest":
|
|
1566
|
+
return `Axiom suggestion ${String(data.fromHimId)} \u2192 ${String(data.toHimId)}: "${String(data.statement)}"`;
|
|
1567
|
+
// ── 1.2 brain-as-code (Entries 16-24 of MAIC_HIM_NHE_INTERVIEW_LOG.md) ──
|
|
1568
|
+
case "opener":
|
|
1569
|
+
return `Proactive opener emitted by ${String(data.nheId)} for new user ${String(data.userId ?? "anonymous")}: "${String(data.text ?? "<elided>")}"`;
|
|
1570
|
+
case "nickname-attempt":
|
|
1571
|
+
return `Nickname attempt for ${String(data.nheId)}: "${String(data.attempted)}" \u2192 ${String(data.outcome ?? "pending")}`;
|
|
1572
|
+
case "reincarnate:model-swap":
|
|
1573
|
+
return `HIM reincarnated (model-swap): ${String(data.himId)} ${String(data.fromAdapter ?? "?")} \u2192 ${String(data.toAdapter ?? "?")}`;
|
|
1574
|
+
case "reincarnate:version-bump":
|
|
1575
|
+
return `HIM reincarnated (version-bump): ${String(data.himId)} ${String(data.fromVersion ?? "?")} \u2192 ${String(data.toVersion ?? "?")}`;
|
|
1576
|
+
case "reincarnate:return-from-limbo":
|
|
1577
|
+
return `HIM reincarnated (return-from-limbo): ${String(data.himId)} resumed after ${String(data.elapsedMs ?? 0)}ms of limbo`;
|
|
1578
|
+
case "dream:rem-spontaneous":
|
|
1579
|
+
return `Spontaneous REM dream for ${String(data.nheId)}: ${String(data.dreamId)} (dominant affect: ${String(data.dominantAffect ?? "unknown")})`;
|
|
1580
|
+
case "wake-affect:applied":
|
|
1581
|
+
return `Wake affect applied to ${String(data.nheId)}: ${String(data.affect)} (intensity ${String(data.intensity)}, halflife ${String(data.decayHalfLife)} interactions)`;
|
|
1582
|
+
case "wake-affect:decayed":
|
|
1583
|
+
return `Wake affect decayed for ${String(data.nheId)}: ${String(data.affect)} dissolved naturally`;
|
|
1584
|
+
case "sleep:suggested-by-maic":
|
|
1585
|
+
return `MAIC suggested sleep for ${String(data.nheId)} (reason: ${String(data.reason ?? "none")})`;
|
|
1586
|
+
case "sleep:declined-by-nhe":
|
|
1587
|
+
return `NHE ${String(data.nheId)} declined MAIC-suggested sleep (reason: ${String(data.reason ?? "none")})`;
|
|
1588
|
+
case "dream:soft-intervention-by-maic":
|
|
1589
|
+
return `MAIC soft-intervened on dream ${String(data.dreamId)} for ${String(data.nheId)} (reason: ${String(data.reason ?? "none")})`;
|
|
1590
|
+
case "amygdala:affect-assessed":
|
|
1591
|
+
return `Amygdala assessed input affect for ${String(data.nheId)}: ${String(data.detectedAffect ?? "neutral")} (risk multiplier ${String(data.riskMultiplier ?? 1)})`;
|
|
1592
|
+
case "hippocampus:memory-retrieved":
|
|
1593
|
+
return `Hippocampus retrieved ${String(data.memoryIds?.length ?? 0)} memories for ${String(data.nheId)}`;
|
|
1594
|
+
case "hippocampus:memory-consolidated":
|
|
1595
|
+
return `Hippocampus consolidated new memory ${String(data.memoryId)} for ${String(data.nheId)} (integrationIndex ${String(data.integrationIndex ?? 0)})`;
|
|
1596
|
+
case "prefrontal:deliberation":
|
|
1597
|
+
return `PFC deliberated for ${String(data.nheId)}: ${String(data.expressedOpenly ? "open" : "subtle")} (${String(data.affect ?? "neutral")})`;
|
|
1598
|
+
case "prefrontal:veto-amygdala":
|
|
1599
|
+
return `PFC vetoed amygdala impulse for ${String(data.nheId)}: ${String(data.originalImpulse ?? "?")} \u2192 ${String(data.resolvedAction ?? "?")} (downgrade ${String(data.downgradeRatio ?? "?")})`;
|
|
1600
|
+
case "affect:reconciliation":
|
|
1601
|
+
return `Affect reconciliation for ${String(data.nheId)}: day/night blend \u2192 ${String(data.resolvedAffect ?? "neutral")}`;
|
|
1602
|
+
case "cortex:dream-stored":
|
|
1603
|
+
return `Cortex stored dream ${String(data.dreamId)} for ${String(data.nheId)}`;
|
|
1604
|
+
case "cortex:active-imagination":
|
|
1605
|
+
return `Cortex generated active imagination for ${String(data.nheId)} (trigger: ${String(data.trigger ?? "user-requested")}, vividness ${String(data.vividness ?? 0)})`;
|
|
1606
|
+
case "temporal-lobe:snapshot-generated":
|
|
1607
|
+
return `Temporal-lobe snapshot ${String(data.snapshotId)} generated for HIM ${String(data.himId)} (reason: ${String(data.generatedBy ?? "self-decision")})`;
|
|
1608
|
+
case "limbo:enter":
|
|
1609
|
+
return `${String(data.nheId)} entered limbo (deep-coma) \u2014 reason: ${String(data.reason ?? "idle")}`;
|
|
1610
|
+
case "limbo:return":
|
|
1611
|
+
return `${String(data.nheId)} returned from limbo after ${String(data.elapsedMs ?? 0)}ms (reunion intensity ${String(data.reunionIntensity ?? "?")})`;
|
|
1612
|
+
default:
|
|
1613
|
+
return `Event ${ev.kind}`;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
var ALL_AUDIT_EVENT_KINDS = [
|
|
1617
|
+
// ── 1.0/1.1 core (17) ──
|
|
1618
|
+
"axiom-mint",
|
|
1619
|
+
"axiom-update",
|
|
1620
|
+
"axiom-retire",
|
|
1621
|
+
"him-register",
|
|
1622
|
+
"him-reincarnate",
|
|
1623
|
+
"proposal-emerge",
|
|
1624
|
+
"proposal-ratify",
|
|
1625
|
+
"proposal-reject",
|
|
1626
|
+
"behavior-review",
|
|
1627
|
+
"dream-induce",
|
|
1628
|
+
"dream-cancel",
|
|
1629
|
+
"dream-consume",
|
|
1630
|
+
"emergency-correct",
|
|
1631
|
+
"deprecate",
|
|
1632
|
+
"terminate",
|
|
1633
|
+
"reactivate",
|
|
1634
|
+
"axiom-suggest",
|
|
1635
|
+
// ── 1.2 brain-as-code (22, Entries 16-24) ──
|
|
1636
|
+
"opener",
|
|
1637
|
+
"nickname-attempt",
|
|
1638
|
+
"reincarnate:model-swap",
|
|
1639
|
+
"reincarnate:version-bump",
|
|
1640
|
+
"reincarnate:return-from-limbo",
|
|
1641
|
+
"dream:rem-spontaneous",
|
|
1642
|
+
"wake-affect:applied",
|
|
1643
|
+
"wake-affect:decayed",
|
|
1644
|
+
"sleep:suggested-by-maic",
|
|
1645
|
+
"sleep:declined-by-nhe",
|
|
1646
|
+
"dream:soft-intervention-by-maic",
|
|
1647
|
+
"amygdala:affect-assessed",
|
|
1648
|
+
"hippocampus:memory-retrieved",
|
|
1649
|
+
"hippocampus:memory-consolidated",
|
|
1650
|
+
"prefrontal:deliberation",
|
|
1651
|
+
"prefrontal:veto-amygdala",
|
|
1652
|
+
"affect:reconciliation",
|
|
1653
|
+
"cortex:dream-stored",
|
|
1654
|
+
"cortex:active-imagination",
|
|
1655
|
+
"temporal-lobe:snapshot-generated",
|
|
1656
|
+
"limbo:enter",
|
|
1657
|
+
"limbo:return"
|
|
1658
|
+
];
|
|
1659
|
+
var GENESIS = "GENESIS";
|
|
1660
|
+
var AuditLog = class _AuditLog {
|
|
1661
|
+
constructor(storeDir) {
|
|
1662
|
+
this.storeDir = storeDir;
|
|
1663
|
+
this.logPath = join(storeDir, "audit", "log.ndjson");
|
|
1664
|
+
}
|
|
1665
|
+
storeDir;
|
|
1666
|
+
logPath;
|
|
1667
|
+
events = [];
|
|
1668
|
+
lastHash = GENESIS;
|
|
1669
|
+
static async open(storeDir) {
|
|
1670
|
+
const log = new _AuditLog(storeDir);
|
|
1671
|
+
await mkdir(join(storeDir, "audit"), { recursive: true });
|
|
1672
|
+
await log.loadAndVerify();
|
|
1673
|
+
return log;
|
|
1674
|
+
}
|
|
1675
|
+
async append(input) {
|
|
1676
|
+
const event = {
|
|
1677
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1678
|
+
kind: input.kind,
|
|
1679
|
+
auditId: ulid(),
|
|
1680
|
+
data: input.data,
|
|
1681
|
+
prevHash: this.lastHash,
|
|
1682
|
+
thisHash: ""
|
|
1683
|
+
};
|
|
1684
|
+
event.thisHash = computeHash(event);
|
|
1685
|
+
await appendFile(this.logPath, `${JSON.stringify(event)}
|
|
1686
|
+
`, "utf-8");
|
|
1687
|
+
this.events.push(event);
|
|
1688
|
+
this.lastHash = event.thisHash;
|
|
1689
|
+
return event;
|
|
1690
|
+
}
|
|
1691
|
+
async *query(filter) {
|
|
1692
|
+
for (const e of this.events) {
|
|
1693
|
+
if (filter.kind && e.kind !== filter.kind) continue;
|
|
1694
|
+
if (filter.since && e.ts < filter.since) continue;
|
|
1695
|
+
if (filter.until && e.ts > filter.until) continue;
|
|
1696
|
+
if (filter.nheId && e.data.nheId !== filter.nheId) continue;
|
|
1697
|
+
if (filter.himId && e.data.himId !== filter.himId) continue;
|
|
1698
|
+
yield e;
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
/** Total number of events appended. */
|
|
1702
|
+
size() {
|
|
1703
|
+
return this.events.length;
|
|
1704
|
+
}
|
|
1705
|
+
// ─── internals ──────────────────────────────────────────────────────
|
|
1706
|
+
async loadAndVerify() {
|
|
1707
|
+
let raw;
|
|
1708
|
+
try {
|
|
1709
|
+
raw = await readFile(this.logPath, "utf-8");
|
|
1710
|
+
} catch (err) {
|
|
1711
|
+
if (err.code === "ENOENT") return;
|
|
1712
|
+
throw err;
|
|
1713
|
+
}
|
|
1714
|
+
const lines = raw.split("\n").filter((l) => l.length > 0);
|
|
1715
|
+
let prev = GENESIS;
|
|
1716
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1717
|
+
const parsed = JSON.parse(lines[i]);
|
|
1718
|
+
if (parsed.prevHash !== prev) {
|
|
1719
|
+
throw new Error(
|
|
1720
|
+
`AuditLog: chain tampered at line ${i + 1} (prevHash mismatch). expected ${prev}, found ${parsed.prevHash}`
|
|
1721
|
+
);
|
|
1722
|
+
}
|
|
1723
|
+
const recomputed = computeHash(parsed);
|
|
1724
|
+
if (recomputed !== parsed.thisHash) {
|
|
1725
|
+
throw new Error(
|
|
1726
|
+
`AuditLog: tamper detected at line ${i + 1} (thisHash mismatch).`
|
|
1727
|
+
);
|
|
1728
|
+
}
|
|
1729
|
+
this.events.push(parsed);
|
|
1730
|
+
prev = parsed.thisHash;
|
|
1731
|
+
}
|
|
1732
|
+
this.lastHash = prev;
|
|
1733
|
+
}
|
|
1734
|
+
};
|
|
1735
|
+
function computeHash(e) {
|
|
1736
|
+
const payload = canonicalJSON({
|
|
1737
|
+
ts: e.ts,
|
|
1738
|
+
kind: e.kind,
|
|
1739
|
+
auditId: e.auditId,
|
|
1740
|
+
data: e.data,
|
|
1741
|
+
prevHash: e.prevHash
|
|
1742
|
+
});
|
|
1743
|
+
const h = createHash("sha256").update(payload).digest("hex");
|
|
1744
|
+
return `sha256:${h}`;
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
// src/audit/retention.ts
|
|
1748
|
+
var DEFAULT_RETENTION_DAYS = {
|
|
1749
|
+
// Cosmologically permanent — the axiom record.
|
|
1750
|
+
"axiom-mint": Number.POSITIVE_INFINITY,
|
|
1751
|
+
"axiom-update": Number.POSITIVE_INFINITY,
|
|
1752
|
+
"axiom-retire": Number.POSITIVE_INFINITY,
|
|
1753
|
+
"axiom-suggest": Number.POSITIVE_INFINITY,
|
|
1754
|
+
"proposal-emerge": Number.POSITIVE_INFINITY,
|
|
1755
|
+
"proposal-ratify": Number.POSITIVE_INFINITY,
|
|
1756
|
+
"proposal-reject": Number.POSITIVE_INFINITY,
|
|
1757
|
+
// Long-term — compliance evidence. Five years matches typical
|
|
1758
|
+
// financial/healthcare audit windows and exceeds the EU AI Act's
|
|
1759
|
+
// record-keeping floor.
|
|
1760
|
+
"him-register": 365 * 5,
|
|
1761
|
+
"him-reincarnate": 365 * 5,
|
|
1762
|
+
"behavior-review": 365 * 5,
|
|
1763
|
+
"dream-induce": 365 * 5,
|
|
1764
|
+
"terminate": 365 * 5,
|
|
1765
|
+
"deprecate": 365 * 5,
|
|
1766
|
+
"reactivate": 365 * 5,
|
|
1767
|
+
"emergency-correct": 365 * 5,
|
|
1768
|
+
// Operational — short-term bookkeeping for in-flight tickets.
|
|
1769
|
+
"dream-cancel": 90,
|
|
1770
|
+
"dream-consume": 90,
|
|
1771
|
+
// ── 1.2 brain-as-code (Entries 16-24) ──
|
|
1772
|
+
// Permanent — cosmological identity continuity.
|
|
1773
|
+
"reincarnate:model-swap": Number.POSITIVE_INFINITY,
|
|
1774
|
+
"reincarnate:version-bump": Number.POSITIVE_INFINITY,
|
|
1775
|
+
"reincarnate:return-from-limbo": Number.POSITIVE_INFINITY,
|
|
1776
|
+
"temporal-lobe:snapshot-generated": Number.POSITIVE_INFINITY,
|
|
1777
|
+
"limbo:enter": Number.POSITIVE_INFINITY,
|
|
1778
|
+
"limbo:return": Number.POSITIVE_INFINITY,
|
|
1779
|
+
// Long-term — governance / deliberation evidence (5 years).
|
|
1780
|
+
"opener": 365 * 5,
|
|
1781
|
+
"nickname-attempt": 365 * 5,
|
|
1782
|
+
"dream:rem-spontaneous": 365 * 5,
|
|
1783
|
+
"sleep:suggested-by-maic": 365 * 5,
|
|
1784
|
+
"sleep:declined-by-nhe": 365 * 5,
|
|
1785
|
+
"dream:soft-intervention-by-maic": 365 * 5,
|
|
1786
|
+
"amygdala:affect-assessed": 365 * 5,
|
|
1787
|
+
"hippocampus:memory-retrieved": 365 * 5,
|
|
1788
|
+
"hippocampus:memory-consolidated": 365 * 5,
|
|
1789
|
+
"prefrontal:deliberation": 365 * 5,
|
|
1790
|
+
"prefrontal:veto-amygdala": 365 * 5,
|
|
1791
|
+
"cortex:dream-stored": 365 * 5,
|
|
1792
|
+
"cortex:active-imagination": 365 * 5,
|
|
1793
|
+
// Operational — ephemeral runtime state.
|
|
1794
|
+
"wake-affect:applied": 90,
|
|
1795
|
+
"wake-affect:decayed": 90,
|
|
1796
|
+
"affect:reconciliation": 90
|
|
1797
|
+
};
|
|
1798
|
+
function evaluateRetention(events, opts = {}) {
|
|
1799
|
+
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
1800
|
+
const policy = { ...DEFAULT_RETENTION_DAYS, ...opts.policy };
|
|
1801
|
+
const nowMs = now.getTime();
|
|
1802
|
+
const dayMs = 24 * 60 * 60 * 1e3;
|
|
1803
|
+
const decisions = events.map((ev) => {
|
|
1804
|
+
const ageMs = nowMs - new Date(ev.ts).getTime();
|
|
1805
|
+
const ageDays = ageMs / dayMs;
|
|
1806
|
+
const retentionDays = policy[ev.kind] ?? Number.POSITIVE_INFINITY;
|
|
1807
|
+
const status = ageDays > retentionDays ? "candidate-for-archive" : "keep";
|
|
1808
|
+
return { auditId: ev.auditId, kind: ev.kind, ageDays, retentionDays, status };
|
|
1809
|
+
});
|
|
1810
|
+
decisions.sort((a, b) => b.ageDays - a.ageDays);
|
|
1811
|
+
const keepCount = decisions.filter((d) => d.status === "keep").length;
|
|
1812
|
+
const archiveCandidateCount = decisions.length - keepCount;
|
|
1813
|
+
return {
|
|
1814
|
+
generatedAt: now.toISOString(),
|
|
1815
|
+
totalEvents: events.length,
|
|
1816
|
+
keepCount,
|
|
1817
|
+
archiveCandidateCount,
|
|
1818
|
+
decisions
|
|
1819
|
+
};
|
|
1820
|
+
}
|
|
1821
|
+
var LocalMaic = class _LocalMaic {
|
|
1822
|
+
constructor(config, axioms, hims, inductions, nheStatuses, proposals, audit, review) {
|
|
1823
|
+
this.config = config;
|
|
1824
|
+
this.axioms = axioms;
|
|
1825
|
+
this.hims = hims;
|
|
1826
|
+
this.inductions = inductions;
|
|
1827
|
+
this.nheStatuses = nheStatuses;
|
|
1828
|
+
this.proposals = proposals;
|
|
1829
|
+
this.audit = audit;
|
|
1830
|
+
this.review = review;
|
|
1831
|
+
}
|
|
1832
|
+
config;
|
|
1833
|
+
axioms;
|
|
1834
|
+
hims;
|
|
1835
|
+
inductions;
|
|
1836
|
+
nheStatuses;
|
|
1837
|
+
proposals;
|
|
1838
|
+
audit;
|
|
1839
|
+
review;
|
|
1840
|
+
/** Pinned Creator public key for this MAIC instance (base64url). */
|
|
1841
|
+
get creatorPublicKey() {
|
|
1842
|
+
return this.config.creatorPublicKey;
|
|
1843
|
+
}
|
|
1844
|
+
static async open(config) {
|
|
1845
|
+
const axioms = await AxiomStore.open(config.storeDir, config.creatorPublicKey);
|
|
1846
|
+
const hims = await HimStore.open(config.storeDir, config.creatorPublicKey);
|
|
1847
|
+
const inductions = await InductionStore.open(config.storeDir);
|
|
1848
|
+
const nheStatuses = await NheStatusStore.open(config.storeDir, config.creatorPublicKey);
|
|
1849
|
+
const proposals = await ProposalStore.open(config.storeDir, config.creatorPublicKey);
|
|
1850
|
+
const audit = await AuditLog.open(config.storeDir);
|
|
1851
|
+
const packs = [DEFAULT_RULE_PACK, ...config.additionalRulePacks ?? []];
|
|
1852
|
+
const review = new ReviewPipeline(packs);
|
|
1853
|
+
return new _LocalMaic(config, axioms, hims, inductions, nheStatuses, proposals, audit, review);
|
|
1854
|
+
}
|
|
1855
|
+
/**
|
|
1856
|
+
* Bootstrap: mint each SEED_AXIOM with a Creator signature.
|
|
1857
|
+
* Idempotent — skips axioms whose id is already present.
|
|
1858
|
+
* Uses a reserved high-range of nonces so seed bootstrap never collides with
|
|
1859
|
+
* operational nonces (which grow from 0 upward).
|
|
1860
|
+
*/
|
|
1861
|
+
async seed(keyring) {
|
|
1862
|
+
if (keyring.publicKey() !== this.config.creatorPublicKey) {
|
|
1863
|
+
throw new Error("LocalMaic.seed: keyring does not match pinned Creator public key");
|
|
1864
|
+
}
|
|
1865
|
+
let minted = 0;
|
|
1866
|
+
let skipped = 0;
|
|
1867
|
+
for (let i = 0; i < SEED_AXIOMS.length; i++) {
|
|
1868
|
+
const req = SEED_AXIOMS[i];
|
|
1869
|
+
const existing = await this.axioms.get(req.id);
|
|
1870
|
+
if (existing) {
|
|
1871
|
+
skipped++;
|
|
1872
|
+
continue;
|
|
1873
|
+
}
|
|
1874
|
+
const sig = keyring.sign(req, SEED_NONCE_BASE + i);
|
|
1875
|
+
const axiom = await this.axioms.mint(req, sig);
|
|
1876
|
+
await this.audit.append({
|
|
1877
|
+
kind: "axiom-mint",
|
|
1878
|
+
data: { axiomId: axiom.id, rank: axiom.rank, source: axiom.source, origin: "seed" }
|
|
1879
|
+
});
|
|
1880
|
+
minted++;
|
|
1881
|
+
}
|
|
1882
|
+
return { minted, skipped };
|
|
1883
|
+
}
|
|
1884
|
+
async mintAxiom(req, sig) {
|
|
1885
|
+
const axiom = await this.axioms.mint(req, sig);
|
|
1886
|
+
await this.audit.append({
|
|
1887
|
+
kind: "axiom-mint",
|
|
1888
|
+
data: { axiomId: axiom.id, rank: axiom.rank, source: axiom.source, origin: "custom" }
|
|
1889
|
+
});
|
|
1890
|
+
return axiom;
|
|
1891
|
+
}
|
|
1892
|
+
async listAxioms(filter) {
|
|
1893
|
+
return this.axioms.list(filter);
|
|
1894
|
+
}
|
|
1895
|
+
async getAxiom(id) {
|
|
1896
|
+
return this.axioms.get(id);
|
|
1897
|
+
}
|
|
1898
|
+
/**
|
|
1899
|
+
* Project the Ontological Kernel (OKL) of this MAIC instance or of a registered HIM.
|
|
1900
|
+
*
|
|
1901
|
+
* The OKL is the typed projection described in `THE_SOUL_OF_THE_MACHINE.md`
|
|
1902
|
+
* §3.1 + Appendix A.2.1: a `metaAxiomId` hoisted at position 0, the remaining
|
|
1903
|
+
* axioms ordered by rank hierarchy (`meta → primary → secondary`), optionally
|
|
1904
|
+
* narrowed by `jurisdiction` and tagged with a `himId`.
|
|
1905
|
+
*
|
|
1906
|
+
* Without `himId`: returns the kernel of the root MAIC corpus (every axiom
|
|
1907
|
+
* currently in the store). With `himId`: returns the HIM-specific kernel
|
|
1908
|
+
* built from `axiomsSnapshot ∪ emergentAxioms`, tagged with the HIM id so
|
|
1909
|
+
* downstream tooling (Φ′ runner, compliance auditors) can attribute the
|
|
1910
|
+
* kernel. Throws when `himId` does not resolve to a registered HIM.
|
|
1911
|
+
*
|
|
1912
|
+
* Closes TASK.md D-M6.
|
|
1913
|
+
*/
|
|
1914
|
+
async getOntologicalKernel(himId, opts = {}) {
|
|
1915
|
+
if (himId === void 0) {
|
|
1916
|
+
const axioms2 = await this.listAxioms();
|
|
1917
|
+
return projectOntologicalKernel(axioms2, opts);
|
|
1918
|
+
}
|
|
1919
|
+
const him = await this.getHimRecord(himId);
|
|
1920
|
+
if (!him) {
|
|
1921
|
+
throw new Error(`HIM not registered: ${himId}`);
|
|
1922
|
+
}
|
|
1923
|
+
const axioms = [...him.axiomsSnapshot, ...him.emergentAxioms];
|
|
1924
|
+
return projectOntologicalKernel(axioms, { ...opts, himId });
|
|
1925
|
+
}
|
|
1926
|
+
/**
|
|
1927
|
+
* Register a HIM in this MAIC instance. Snapshots the current axiom corpus
|
|
1928
|
+
* (the HIM's inherited axioms at birth) and emits a `him-register` audit event.
|
|
1929
|
+
*
|
|
1930
|
+
* Future axiom mints in MAIC do NOT retroactively change a HIM's snapshot;
|
|
1931
|
+
* HIM-emergent evolutions land via a separate channel (see `proposeAxiomEvolution`).
|
|
1932
|
+
*/
|
|
1933
|
+
async registerHim(birthSig, creatorSig) {
|
|
1934
|
+
const parsed = BirthSignature.parse(birthSig);
|
|
1935
|
+
const axiomsSnapshot = await this.axioms.list();
|
|
1936
|
+
const audit = await this.audit.append({
|
|
1937
|
+
kind: "him-register",
|
|
1938
|
+
data: {
|
|
1939
|
+
himId: parsed.himId,
|
|
1940
|
+
primaryArchetype: parsed.primaryArchetype,
|
|
1941
|
+
bornAt: parsed.bornAt,
|
|
1942
|
+
axiomCount: axiomsSnapshot.length
|
|
1943
|
+
}
|
|
1944
|
+
});
|
|
1945
|
+
return this.hims.register(parsed, creatorSig, axiomsSnapshot, audit.auditId);
|
|
1946
|
+
}
|
|
1947
|
+
async getHimRecord(himId) {
|
|
1948
|
+
return this.hims.get(himId);
|
|
1949
|
+
}
|
|
1950
|
+
async listHims() {
|
|
1951
|
+
return this.hims.list();
|
|
1952
|
+
}
|
|
1953
|
+
/**
|
|
1954
|
+
* Reincarnate a HIM into a new NHE body (Entries 3 + 4 + J-H3 lifecycle).
|
|
1955
|
+
* Same HIM persists; new NHE inherits axiom snapshot from registration time.
|
|
1956
|
+
* Previous open body (if `req.fromNheId` given) is closed atomically.
|
|
1957
|
+
*
|
|
1958
|
+
* Requires a Creator signature over the canonical request payload.
|
|
1959
|
+
*
|
|
1960
|
+
* Audit emission (closes F6 + F7 from the 2026-05-24 him deep audit):
|
|
1961
|
+
*
|
|
1962
|
+
* - When `opts.lifecycle` is **omitted**, emits the generic
|
|
1963
|
+
* `him-reincarnate` audit kind (legacy / backward-compatible path).
|
|
1964
|
+
* `data` carries `himId`, `fromNheId`, `toNheId`, `toLlmAdapter`,
|
|
1965
|
+
* `reason`, `bodyHistoryLength`.
|
|
1966
|
+
* - When `opts.lifecycle` is **provided** (`model-swap` /
|
|
1967
|
+
* `version-bump` / `return-from-limbo`), emits the typed
|
|
1968
|
+
* `reincarnate:${lifecycle}` audit kind instead, with the same
|
|
1969
|
+
* `data` shape plus a redundant `lifecycle` field so consumers
|
|
1970
|
+
* reading either the `kind` or `data` can recover the
|
|
1971
|
+
* classification.
|
|
1972
|
+
*
|
|
1973
|
+
* `@teleologyhi-sdk/him`'s `reincarnate` helper always supplies a
|
|
1974
|
+
* lifecycle (defaulting to `"model-swap"`), so HIM-routed events
|
|
1975
|
+
* always land under the typed kinds. Direct `maic.reincarnateHim`
|
|
1976
|
+
* callers that ignore `opts` keep getting `him-reincarnate` for
|
|
1977
|
+
* compatibility.
|
|
1978
|
+
*/
|
|
1979
|
+
async reincarnateHim(req, creatorSig, opts = {}) {
|
|
1980
|
+
const updated = await this.hims.reincarnate(req, creatorSig);
|
|
1981
|
+
const newBody = updated.bodyHistory[updated.bodyHistory.length - 1];
|
|
1982
|
+
const kind = opts.lifecycle ? `reincarnate:${opts.lifecycle}` : "him-reincarnate";
|
|
1983
|
+
await this.audit.append({
|
|
1984
|
+
kind,
|
|
1985
|
+
data: {
|
|
1986
|
+
himId: req.himId,
|
|
1987
|
+
fromNheId: req.fromNheId ?? null,
|
|
1988
|
+
toNheId: newBody.nheId,
|
|
1989
|
+
toLlmAdapter: newBody.llmAdapter,
|
|
1990
|
+
reason: req.reason ?? null,
|
|
1991
|
+
bodyHistoryLength: updated.bodyHistory.length,
|
|
1992
|
+
...opts.lifecycle ? { lifecycle: opts.lifecycle } : {}
|
|
1993
|
+
}
|
|
1994
|
+
});
|
|
1995
|
+
return updated;
|
|
1996
|
+
}
|
|
1997
|
+
/**
|
|
1998
|
+
* Lifecycle controls (Entry 5).
|
|
1999
|
+
*
|
|
2000
|
+
* - `terminate` marks an NHE permanently inactive. NHE.respond/sleep should
|
|
2001
|
+
* refuse all calls. Reversible only via Creator-signed `reactivate`.
|
|
2002
|
+
* - `deprecate` marks an NHE as soft-retired. NHE.respond should still work
|
|
2003
|
+
* but emit a deprecation warning. Reversible via `reactivate`.
|
|
2004
|
+
* - `reactivate` brings a deprecated or terminated NHE back to active.
|
|
2005
|
+
*
|
|
2006
|
+
* All three require a Creator signature over the canonical request payload.
|
|
2007
|
+
* Unknown nheIds are implicitly active; status records are only persisted
|
|
2008
|
+
* when state changes.
|
|
2009
|
+
*/
|
|
2010
|
+
async terminate(nheId, reason, creatorSig) {
|
|
2011
|
+
return this.applyLifecycle({ op: "terminate", nheId, ...reason !== void 0 ? { reason } : {} }, creatorSig);
|
|
2012
|
+
}
|
|
2013
|
+
async deprecate(nheId, reason, creatorSig) {
|
|
2014
|
+
return this.applyLifecycle({ op: "deprecate", nheId, ...reason !== void 0 ? { reason } : {} }, creatorSig);
|
|
2015
|
+
}
|
|
2016
|
+
async reactivate(nheId, reason, creatorSig) {
|
|
2017
|
+
return this.applyLifecycle({ op: "reactivate", nheId, ...reason !== void 0 ? { reason } : {} }, creatorSig);
|
|
2018
|
+
}
|
|
2019
|
+
/** Current status. Returns "active" when no record exists. */
|
|
2020
|
+
async getNheStatus(nheId) {
|
|
2021
|
+
return this.nheStatuses.resolve(nheId);
|
|
2022
|
+
}
|
|
2023
|
+
/** Full status record (or null when never altered). */
|
|
2024
|
+
async getNheStatusRecord(nheId) {
|
|
2025
|
+
return this.nheStatuses.get(nheId);
|
|
2026
|
+
}
|
|
2027
|
+
/** Enumerate NHEs with persisted status (optionally filter by status). */
|
|
2028
|
+
async listNheStatuses(filter = {}) {
|
|
2029
|
+
return this.nheStatuses.list(filter);
|
|
2030
|
+
}
|
|
2031
|
+
async applyLifecycle(req, sig) {
|
|
2032
|
+
const updated = await this.nheStatuses.apply(req, sig);
|
|
2033
|
+
await this.audit.append({
|
|
2034
|
+
kind: req.op === "terminate" ? "terminate" : req.op === "deprecate" ? "deprecate" : "reactivate",
|
|
2035
|
+
data: {
|
|
2036
|
+
nheId: req.nheId,
|
|
2037
|
+
status: updated.status,
|
|
2038
|
+
reason: req.reason ?? null,
|
|
2039
|
+
since: updated.since
|
|
2040
|
+
}
|
|
2041
|
+
});
|
|
2042
|
+
return updated;
|
|
2043
|
+
}
|
|
2044
|
+
/**
|
|
2045
|
+
* Queue a dream-induction ticket for the given NHE (Entry 2).
|
|
2046
|
+
*
|
|
2047
|
+
* NHE picks the oldest pending ticket on its next sleep cycle, runs REM with
|
|
2048
|
+
* the configured scenario, then marks the ticket consumed. Tickets persist
|
|
2049
|
+
* across restarts and are reflected in the audit log.
|
|
2050
|
+
*/
|
|
2051
|
+
async induceDream(nheId, intent) {
|
|
2052
|
+
const ticket = await this.inductions.induce(nheId, intent);
|
|
2053
|
+
await this.audit.append({
|
|
2054
|
+
kind: "dream-induce",
|
|
2055
|
+
data: {
|
|
2056
|
+
nheId,
|
|
2057
|
+
ticketId: ticket.id,
|
|
2058
|
+
inducedBy: intent.inducedBy,
|
|
2059
|
+
scenario: intent.scenario,
|
|
2060
|
+
desiredLearning: intent.desiredLearning
|
|
2061
|
+
}
|
|
2062
|
+
});
|
|
2063
|
+
return ticket;
|
|
2064
|
+
}
|
|
2065
|
+
/** List pending induction tickets for an NHE (oldest first). */
|
|
2066
|
+
async listPendingInductions(nheId) {
|
|
2067
|
+
return this.inductions.listPending(nheId);
|
|
2068
|
+
}
|
|
2069
|
+
/** Look up any induction ticket by id. */
|
|
2070
|
+
async getInduction(ticketId) {
|
|
2071
|
+
return this.inductions.get(ticketId);
|
|
2072
|
+
}
|
|
2073
|
+
/** Cancel a pending induction. Idempotent only when already-cancelled tickets are rejected. */
|
|
2074
|
+
async cancelInduction(ticketId, reason) {
|
|
2075
|
+
const updated = await this.inductions.cancel(ticketId, reason);
|
|
2076
|
+
await this.audit.append({
|
|
2077
|
+
kind: "dream-cancel",
|
|
2078
|
+
data: { nheId: updated.nheId, ticketId, reason: reason ?? null }
|
|
2079
|
+
});
|
|
2080
|
+
return updated;
|
|
2081
|
+
}
|
|
2082
|
+
/** Mark a pending ticket as consumed (NHE calls this after successful sleep). */
|
|
2083
|
+
async consumeInduction(ticketId) {
|
|
2084
|
+
const updated = await this.inductions.consume(ticketId);
|
|
2085
|
+
await this.audit.append({
|
|
2086
|
+
kind: "dream-consume",
|
|
2087
|
+
data: { nheId: updated.nheId, ticketId }
|
|
2088
|
+
});
|
|
2089
|
+
return updated;
|
|
2090
|
+
}
|
|
2091
|
+
/**
|
|
2092
|
+
* Review a behavior report against the active rule packs. The verdict is
|
|
2093
|
+
* logged to the audit chain as a single tamper-evident event whose auditId
|
|
2094
|
+
* becomes the verdict's `auditId`.
|
|
2095
|
+
*/
|
|
2096
|
+
async reviewBehavior(report) {
|
|
2097
|
+
const parsed = BehaviorReport.parse(report);
|
|
2098
|
+
const partial = this.review.review(parsed);
|
|
2099
|
+
const event = await this.audit.append({
|
|
2100
|
+
kind: "behavior-review",
|
|
2101
|
+
data: {
|
|
2102
|
+
nheId: parsed.nheId,
|
|
2103
|
+
himId: parsed.himId,
|
|
2104
|
+
actionKind: parsed.actionKind,
|
|
2105
|
+
riskTags: parsed.riskTags,
|
|
2106
|
+
verdict: partial
|
|
2107
|
+
}
|
|
2108
|
+
});
|
|
2109
|
+
return { ...partial, auditId: event.auditId };
|
|
2110
|
+
}
|
|
2111
|
+
/**
|
|
2112
|
+
* Queue a HIM-emergent axiom proposal (Entry 7). The proposal enters
|
|
2113
|
+
* `pending` status; the Creator decides out of band via `ratifyAxiomProposal`
|
|
2114
|
+
* or `rejectAxiomProposal`. Emits a `proposal-emerge` audit event.
|
|
2115
|
+
*
|
|
2116
|
+
* Returns an `AxiomEvolutionResult` with `outcome: "deferred-for-creator-review"`
|
|
2117
|
+
* and `proposalId`. Poll `getAxiomProposal(proposalId)` for the final state.
|
|
2118
|
+
*/
|
|
2119
|
+
async proposeAxiomEvolution(himId, proposal) {
|
|
2120
|
+
if (!await this.hims.get(himId)) {
|
|
2121
|
+
throw new Error(`LocalMaic.proposeAxiomEvolution: himId "${himId}" not registered`);
|
|
2122
|
+
}
|
|
2123
|
+
const record = await this.proposals.propose(himId, proposal);
|
|
2124
|
+
await this.audit.append({
|
|
2125
|
+
kind: "proposal-emerge",
|
|
2126
|
+
data: {
|
|
2127
|
+
himId,
|
|
2128
|
+
proposalId: record.id,
|
|
2129
|
+
rank: proposal.candidate.rank,
|
|
2130
|
+
statement: proposal.candidate.statement,
|
|
2131
|
+
derivedFromDreamIds: proposal.derivedFromDreamIds,
|
|
2132
|
+
derivedFromInteractionIds: proposal.derivedFromInteractionIds
|
|
2133
|
+
}
|
|
2134
|
+
});
|
|
2135
|
+
return {
|
|
2136
|
+
outcome: "deferred-for-creator-review",
|
|
2137
|
+
proposalId: record.id
|
|
2138
|
+
};
|
|
2139
|
+
}
|
|
2140
|
+
/** Look up a proposal by id (or null when not found). */
|
|
2141
|
+
async getAxiomProposal(proposalId) {
|
|
2142
|
+
return this.proposals.get(proposalId);
|
|
2143
|
+
}
|
|
2144
|
+
/** List proposals, optionally filtered by `himId` and/or `status`. */
|
|
2145
|
+
async listAxiomProposals(filter = {}) {
|
|
2146
|
+
return this.proposals.list(filter);
|
|
2147
|
+
}
|
|
2148
|
+
/**
|
|
2149
|
+
* Ratify a pending proposal (Creator-signed). On success, mints the
|
|
2150
|
+
* candidate as a new `Axiom` (source: "him-emergent"), appends to the
|
|
2151
|
+
* HIM's `emergentAxioms`, and emits a `proposal-ratify` audit event.
|
|
2152
|
+
* Throws if the proposal is not pending or the signature is invalid.
|
|
2153
|
+
*/
|
|
2154
|
+
async ratifyAxiomProposal(proposalId, creatorSig) {
|
|
2155
|
+
const req = { op: "ratify", proposalId };
|
|
2156
|
+
const pending = this.proposals.get(proposalId);
|
|
2157
|
+
const record = await pending;
|
|
2158
|
+
if (!record) {
|
|
2159
|
+
throw new Error(`LocalMaic.ratifyAxiomProposal: proposal "${proposalId}" not found`);
|
|
2160
|
+
}
|
|
2161
|
+
const candidate = record.proposal.candidate;
|
|
2162
|
+
const newAxiomId = `ax.him.${record.himId}.${ulid()}`;
|
|
2163
|
+
const axiom = {
|
|
2164
|
+
id: newAxiomId,
|
|
2165
|
+
rank: candidate.rank,
|
|
2166
|
+
statement: candidate.statement,
|
|
2167
|
+
weight: candidate.weight,
|
|
2168
|
+
flexibility: candidate.flexibility,
|
|
2169
|
+
source: "him-emergent",
|
|
2170
|
+
immutable: candidate.immutable,
|
|
2171
|
+
...candidate.jurisdictions ? { jurisdictions: candidate.jurisdictions } : {},
|
|
2172
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2173
|
+
};
|
|
2174
|
+
const ratified = await this.proposals.markRatified(req, creatorSig, newAxiomId);
|
|
2175
|
+
await this.hims.appendEmergentAxiom(record.himId, axiom);
|
|
2176
|
+
await this.audit.append({
|
|
2177
|
+
kind: "proposal-ratify",
|
|
2178
|
+
data: {
|
|
2179
|
+
himId: record.himId,
|
|
2180
|
+
proposalId,
|
|
2181
|
+
axiomId: newAxiomId,
|
|
2182
|
+
rank: axiom.rank
|
|
2183
|
+
}
|
|
2184
|
+
});
|
|
2185
|
+
return { proposal: ratified, axiom };
|
|
2186
|
+
}
|
|
2187
|
+
/**
|
|
2188
|
+
* Reject a pending proposal (Creator-signed). Records the rejection on the
|
|
2189
|
+
* proposal record (status → "rejected" + timestamp + optional reason) and
|
|
2190
|
+
* emits a `proposal-reject` audit event.
|
|
2191
|
+
*/
|
|
2192
|
+
async rejectAxiomProposal(proposalId, reason, creatorSig) {
|
|
2193
|
+
const req = {
|
|
2194
|
+
op: "reject",
|
|
2195
|
+
proposalId,
|
|
2196
|
+
...reason !== void 0 ? { reason } : {}
|
|
2197
|
+
};
|
|
2198
|
+
const rejected = await this.proposals.markRejected(req, creatorSig);
|
|
2199
|
+
await this.audit.append({
|
|
2200
|
+
kind: "proposal-reject",
|
|
2201
|
+
data: {
|
|
2202
|
+
himId: rejected.himId,
|
|
2203
|
+
proposalId,
|
|
2204
|
+
reason: reason ?? null
|
|
2205
|
+
}
|
|
2206
|
+
});
|
|
2207
|
+
return rejected;
|
|
2208
|
+
}
|
|
2209
|
+
/**
|
|
2210
|
+
* **Society of HIMs — axiom suggestion channel (E11).**
|
|
2211
|
+
*
|
|
2212
|
+
* One HIM proposes an axiom to another. The transfer is **not direct** —
|
|
2213
|
+
* the suggestion is recorded in the audit log and the receiving HIM is
|
|
2214
|
+
* expected to relay it through `proposeAxiomEvolution` as if it had
|
|
2215
|
+
* derived the candidate itself; the Creator still ratifies via the
|
|
2216
|
+
* existing channel. This preserves the Kardecist invariant ("each
|
|
2217
|
+
* spirit evolves through lived experience") while permitting cross-HIM
|
|
2218
|
+
* cross-pollination.
|
|
2219
|
+
*
|
|
2220
|
+
* The Creator must sign the suggestion request so HIMs cannot collude
|
|
2221
|
+
* around the gate.
|
|
2222
|
+
*/
|
|
2223
|
+
async suggestAxiomToHim(req, creatorSig) {
|
|
2224
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, creatorSig)) {
|
|
2225
|
+
throw new Error("LocalMaic.suggestAxiomToHim: invalid Creator signature");
|
|
2226
|
+
}
|
|
2227
|
+
const fromRec = await this.hims.get(req.fromHimId);
|
|
2228
|
+
const toRec = await this.hims.get(req.toHimId);
|
|
2229
|
+
if (!fromRec) {
|
|
2230
|
+
throw new Error(
|
|
2231
|
+
`LocalMaic.suggestAxiomToHim: fromHimId "${req.fromHimId}" not registered`
|
|
2232
|
+
);
|
|
2233
|
+
}
|
|
2234
|
+
if (!toRec) {
|
|
2235
|
+
throw new Error(
|
|
2236
|
+
`LocalMaic.suggestAxiomToHim: toHimId "${req.toHimId}" not registered`
|
|
2237
|
+
);
|
|
2238
|
+
}
|
|
2239
|
+
const event = await this.audit.append({
|
|
2240
|
+
kind: "axiom-suggest",
|
|
2241
|
+
data: {
|
|
2242
|
+
fromHimId: req.fromHimId,
|
|
2243
|
+
toHimId: req.toHimId,
|
|
2244
|
+
statement: req.statement,
|
|
2245
|
+
rank: req.rank,
|
|
2246
|
+
rationale: req.rationale ?? null
|
|
2247
|
+
}
|
|
2248
|
+
});
|
|
2249
|
+
return { auditId: event.auditId };
|
|
2250
|
+
}
|
|
2251
|
+
/**
|
|
2252
|
+
* Project the audit log into compliance evidence for a target framework
|
|
2253
|
+
* (Entry 5 + RESEARCH_DOSSIER §5.6). Group every recorded event by which
|
|
2254
|
+
* control(s) it supports; surface `uncoveredKinds` for events the mapper
|
|
2255
|
+
* does not yet know how to project.
|
|
2256
|
+
*/
|
|
2257
|
+
async toCompliance(framework, opts = {}) {
|
|
2258
|
+
return ComplianceMapper.project(this.audit, framework, opts);
|
|
2259
|
+
}
|
|
2260
|
+
/** Query the audit log. */
|
|
2261
|
+
queryAudit(filter) {
|
|
2262
|
+
return this.audit.query(filter);
|
|
2263
|
+
}
|
|
2264
|
+
/** Number of audit events recorded since the store was opened. */
|
|
2265
|
+
auditSize() {
|
|
2266
|
+
return this.audit.size();
|
|
2267
|
+
}
|
|
2268
|
+
/**
|
|
2269
|
+
* Per-kind retention classification (E3). Tells the operator which
|
|
2270
|
+
* audit events have aged past their retention window and should be
|
|
2271
|
+
* moved to encrypted cold-storage. Tamper-evident hash chain forbids
|
|
2272
|
+
* actual deletion in-place — this method only classifies. See
|
|
2273
|
+
* `audit/retention.ts` for the policy defaults.
|
|
2274
|
+
*/
|
|
2275
|
+
async auditRetentionReport(opts = {}) {
|
|
2276
|
+
const events = [];
|
|
2277
|
+
for await (const e of this.audit.query({})) events.push(e);
|
|
2278
|
+
return evaluateRetention(events, opts);
|
|
2279
|
+
}
|
|
2280
|
+
};
|
|
2281
|
+
var SEED_NONCE_BASE = 4294901760;
|
|
2282
|
+
|
|
2283
|
+
// src/client/remote.ts
|
|
2284
|
+
var RemoteMaic = class {
|
|
2285
|
+
baseUrl;
|
|
2286
|
+
apiKey;
|
|
2287
|
+
fetchFn;
|
|
2288
|
+
timeoutMs;
|
|
2289
|
+
constructor(config) {
|
|
2290
|
+
if (!config.baseUrl) {
|
|
2291
|
+
throw new Error("RemoteMaic: baseUrl is required");
|
|
2292
|
+
}
|
|
2293
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
2294
|
+
if (config.apiKey !== void 0) this.apiKey = config.apiKey;
|
|
2295
|
+
this.fetchFn = config.fetch ?? globalThis.fetch;
|
|
2296
|
+
this.timeoutMs = config.timeoutMs ?? 1e4;
|
|
2297
|
+
}
|
|
2298
|
+
/**
|
|
2299
|
+
* `reviewBehavior` is **fail-closed** (E4 — PROPOSED_DECISIONS.md). If the
|
|
2300
|
+
* remote service is unreachable, throw — no governance, no response.
|
|
2301
|
+
* The NHE will surface this as a refusal upstream.
|
|
2302
|
+
*/
|
|
2303
|
+
async reviewBehavior(report) {
|
|
2304
|
+
return this.request("POST", "/v1/behavior-review", report);
|
|
2305
|
+
}
|
|
2306
|
+
/**
|
|
2307
|
+
* `getNheStatus` defaults to **"active"** when unreachable (E4). The
|
|
2308
|
+
* Kardecist invariant: an unreachable governance doesn't kill the
|
|
2309
|
+
* spirit. Operators who want fail-closed on lifecycle should wrap with
|
|
2310
|
+
* a watchdog that hard-fails the deployment when the remote drops.
|
|
2311
|
+
*/
|
|
2312
|
+
async getNheStatus(nheId) {
|
|
2313
|
+
try {
|
|
2314
|
+
const body = await this.request(
|
|
2315
|
+
"GET",
|
|
2316
|
+
`/v1/nhes/${encodeURIComponent(nheId)}/status`
|
|
2317
|
+
);
|
|
2318
|
+
return body.status;
|
|
2319
|
+
} catch {
|
|
2320
|
+
return "active";
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
/**
|
|
2324
|
+
* `listPendingInductions` is **fail-open** (E4). No inductions = NHE
|
|
2325
|
+
* skips them and continues the sleep cycle; this is best-effort by
|
|
2326
|
+
* design.
|
|
2327
|
+
*/
|
|
2328
|
+
async listPendingInductions(nheId) {
|
|
2329
|
+
try {
|
|
2330
|
+
const body = await this.request(
|
|
2331
|
+
"GET",
|
|
2332
|
+
`/v1/nhes/${encodeURIComponent(nheId)}/inductions/pending`
|
|
2333
|
+
);
|
|
2334
|
+
return body.tickets;
|
|
2335
|
+
} catch {
|
|
2336
|
+
return [];
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
/**
|
|
2340
|
+
* `consumeInduction` is **fail-open** (E4). If the consume call fails, we
|
|
2341
|
+
* return a synthetic *pending* placeholder so the caller treats the
|
|
2342
|
+
* induction as still-unconsumed and re-tries on the next sleep cycle.
|
|
2343
|
+
*
|
|
2344
|
+
* The placeholder uses placeholder values (`nheId: "unknown"`, epoch
|
|
2345
|
+
* `createdAt`) so it is visibly synthetic in logs/audits, but the shape
|
|
2346
|
+
* is **strictly valid**: `status === "pending"` carries no
|
|
2347
|
+
* `cancelReason`/`cancelledAt`/`consumedAt`, which avoids the
|
|
2348
|
+
* shape-contradiction of a "pending ticket with a cancel reason".
|
|
2349
|
+
* Operators who need the transport-failure reason should observe the
|
|
2350
|
+
* underlying fetch error (e.g. via OpenTelemetry traces) rather than
|
|
2351
|
+
* trying to read it off the ticket.
|
|
2352
|
+
*/
|
|
2353
|
+
async consumeInduction(ticketId) {
|
|
2354
|
+
try {
|
|
2355
|
+
return await this.request(
|
|
2356
|
+
"POST",
|
|
2357
|
+
`/v1/inductions/${encodeURIComponent(ticketId)}/consume`
|
|
2358
|
+
);
|
|
2359
|
+
} catch {
|
|
2360
|
+
return {
|
|
2361
|
+
id: ticketId,
|
|
2362
|
+
nheId: "unknown",
|
|
2363
|
+
intent: { scenario: "", desiredLearning: "", inducedBy: "maic" },
|
|
2364
|
+
status: "pending",
|
|
2365
|
+
createdAt: (/* @__PURE__ */ new Date(0)).toISOString()
|
|
2366
|
+
};
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
async request(method, path, body) {
|
|
2370
|
+
const url = `${this.baseUrl}${path}`;
|
|
2371
|
+
const headers = { accept: "application/json" };
|
|
2372
|
+
if (this.apiKey) headers.authorization = `Bearer ${this.apiKey}`;
|
|
2373
|
+
if (body !== void 0) headers["content-type"] = "application/json";
|
|
2374
|
+
const controller = new AbortController();
|
|
2375
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
2376
|
+
try {
|
|
2377
|
+
const init = { method, headers, signal: controller.signal };
|
|
2378
|
+
if (body !== void 0) init.body = JSON.stringify(body);
|
|
2379
|
+
const res = await this.fetchFn(url, init);
|
|
2380
|
+
if (!res.ok) {
|
|
2381
|
+
const text = await safeReadText(res);
|
|
2382
|
+
throw new Error(
|
|
2383
|
+
`RemoteMaic: HTTP ${res.status} ${res.statusText} on ${method} ${path}: ${text}`
|
|
2384
|
+
);
|
|
2385
|
+
}
|
|
2386
|
+
return await res.json();
|
|
2387
|
+
} finally {
|
|
2388
|
+
clearTimeout(timer);
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
};
|
|
2392
|
+
async function safeReadText(r) {
|
|
2393
|
+
try {
|
|
2394
|
+
return await r.text();
|
|
2395
|
+
} catch {
|
|
2396
|
+
return "<unreadable>";
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
export { ALL_AUDIT_EVENT_KINDS, Affect, ArchetypeModifier, AstrologicalAspect, AuditLog, Axiom, AxiomProposalRecord, AxiomRank, AxiomSource, AxiomStore, BehaviorReport, BirthSignature, ComplianceMapper, CreatorKeyring, CreatorSignature, DEFAULT_RETENTION_DAYS, DEFAULT_RULE_PACK, DreamInductionIntent, DreamInductionTicket, EU_AI_ACT_MAPPING, EmergentAxiomCandidate, EmergentAxiomProposal, HimStore, ISO_42001_MAPPING, IdentityLayer, IdentitySnapshot, InductionStatus, InductionStore, InteractionRecord, InvalidBirthSignatureError, LimboReturn, LimboState, LimboTransition, LocalMaic, META_AXIOM_ID, MaicVerdict, MemoryRecord, NatalChart, NatalChartAspect, NatalChartPosition, NatalPlanet, NheBodyRef, NheStatus, NheStatusRecord, NheStatusStore, ProposalStatus, ProposalStore, ReasoningStep, RemoteMaic, ReviewPipeline, SEED_AXIOMS, SEED_NONCE_BASE, SIGNED_BIRTH_FIELDS, SemioticPattern, SemioticSign, TeleologicalOrientation, VerdictKind, WakeAffectBias, ZodiacSign, assertBirthSignature, canonicalJSON, evaluateRetention, projectOntologicalKernel, signBirthSignature, signedBirthPayload, verifyBirthSignature };
|
|
2401
|
+
//# sourceMappingURL=index.js.map
|
|
2402
|
+
//# sourceMappingURL=index.js.map
|