@teleologyhi-sdk/maic 1.0.0-trinity → 1.0.1
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 +55 -2
- package/NOTICE +2 -2
- package/README.md +41 -41
- package/SPEC.md +71 -70
- package/TRADEMARK.md +2 -2
- package/dist/index.cjs +1875 -1613
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1242 -600
- package/dist/index.d.ts +1242 -600
- package/dist/index.js +1872 -1616
- package/dist/index.js.map +1 -1
- package/package.json +11 -6
package/dist/index.js
CHANGED
|
@@ -1,359 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { readFile, writeFile, mkdir, readdir, appendFile } from 'fs/promises';
|
|
1
|
+
import { createHash, generateKeyPairSync, createPrivateKey, createPublicKey, sign, verify } from 'crypto';
|
|
2
|
+
import { mkdir, appendFile, readFile, writeFile, readdir, rename } from 'fs/promises';
|
|
4
3
|
import { join } from 'path';
|
|
5
4
|
import { ulid } from 'ulid';
|
|
5
|
+
import { z } from 'zod';
|
|
6
6
|
|
|
7
|
-
// src/
|
|
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
|
-
];
|
|
7
|
+
// src/audit/log.ts
|
|
357
8
|
|
|
358
9
|
// src/axioms/signing.ts
|
|
359
10
|
function canonicalJSON(value) {
|
|
@@ -381,283 +32,253 @@ function serialize(v) {
|
|
|
381
32
|
throw new Error(`canonicalJSON: unsupported type ${typeof v}`);
|
|
382
33
|
}
|
|
383
34
|
|
|
384
|
-
// src/
|
|
385
|
-
var
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
35
|
+
// src/audit/log.ts
|
|
36
|
+
var ALL_AUDIT_EVENT_KINDS = [
|
|
37
|
+
// ── 1.0/1.1 core (17) ──
|
|
38
|
+
"axiom-mint",
|
|
39
|
+
"axiom-update",
|
|
40
|
+
"axiom-retire",
|
|
41
|
+
"him-register",
|
|
42
|
+
"him-reincarnate",
|
|
43
|
+
"proposal-emerge",
|
|
44
|
+
"proposal-ratify",
|
|
45
|
+
"proposal-reject",
|
|
46
|
+
"behavior-review",
|
|
47
|
+
"dream-induce",
|
|
48
|
+
"dream-cancel",
|
|
49
|
+
"dream-consume",
|
|
50
|
+
"emergency-correct",
|
|
51
|
+
"deprecate",
|
|
52
|
+
"terminate",
|
|
53
|
+
"reactivate",
|
|
54
|
+
"axiom-suggest",
|
|
55
|
+
// ── 1.2 brain-as-code (22, Entries 16-24) ──
|
|
56
|
+
"opener",
|
|
57
|
+
"nickname-attempt",
|
|
58
|
+
"reincarnate:model-swap",
|
|
59
|
+
"reincarnate:version-bump",
|
|
60
|
+
"reincarnate:return-from-limbo",
|
|
61
|
+
"dream:rem-spontaneous",
|
|
62
|
+
"wake-affect:applied",
|
|
63
|
+
"wake-affect:decayed",
|
|
64
|
+
"sleep:suggested-by-maic",
|
|
65
|
+
"sleep:declined-by-nhe",
|
|
66
|
+
"dream:soft-intervention-by-maic",
|
|
67
|
+
"amygdala:affect-assessed",
|
|
68
|
+
"hippocampus:memory-retrieved",
|
|
69
|
+
"hippocampus:memory-consolidated",
|
|
70
|
+
"prefrontal:deliberation",
|
|
71
|
+
"prefrontal:veto-amygdala",
|
|
72
|
+
"affect:reconciliation",
|
|
73
|
+
"cortex:dream-stored",
|
|
74
|
+
"cortex:active-imagination",
|
|
75
|
+
"temporal-lobe:snapshot-generated",
|
|
76
|
+
"limbo:enter",
|
|
77
|
+
"limbo:return",
|
|
78
|
+
// ── 1.0.1 vocabulary (9, Entries 26 + 27). Eight are reserved for him/arena/nhe
|
|
79
|
+
// to emit in later cuts; provenance-deflection-applied is emitted by
|
|
80
|
+
// reviewBehavior (F3) when a report carries probe:substrate-authorship. ──
|
|
81
|
+
"him-summon",
|
|
82
|
+
"him-pause-incarnation",
|
|
83
|
+
"user-consent-recorded",
|
|
84
|
+
"user-consent-revoked",
|
|
85
|
+
"directory-opt-in",
|
|
86
|
+
"directory-opt-out",
|
|
87
|
+
"him-astrological-chart-cast",
|
|
88
|
+
"him-jungian-profile-cast",
|
|
89
|
+
"provenance-deflection-applied"
|
|
90
|
+
];
|
|
91
|
+
var GENESIS = "GENESIS";
|
|
92
|
+
var AuditLog = class _AuditLog {
|
|
93
|
+
logPath;
|
|
94
|
+
events = [];
|
|
95
|
+
lastHash = GENESIS;
|
|
96
|
+
/**
|
|
97
|
+
* Serialises `append` calls so concurrent appends cannot capture the same
|
|
98
|
+
* `prevHash` and fork the hash chain (M1-4, 1.0.1). Each append waits for the
|
|
99
|
+
* previous one to finish writing and to advance `lastHash` before it reads it.
|
|
100
|
+
*/
|
|
101
|
+
appendChain = Promise.resolve();
|
|
102
|
+
constructor(storeDir) {
|
|
103
|
+
this.logPath = join(storeDir, "audit", "log.ndjson");
|
|
413
104
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
105
|
+
static async open(storeDir) {
|
|
106
|
+
const log = new _AuditLog(storeDir);
|
|
107
|
+
await mkdir(join(storeDir, "audit"), { recursive: true });
|
|
108
|
+
await log.loadAndVerify();
|
|
109
|
+
return log;
|
|
417
110
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
423
|
-
const pem = this.privateKey.export({ format: "pem", type: "pkcs8" });
|
|
424
|
-
await writeFile(path, pem, { mode: 384 });
|
|
111
|
+
async append(input) {
|
|
112
|
+
const run = this.appendChain.then(() => this.appendLocked(input));
|
|
113
|
+
this.appendChain = run.catch(() => void 0);
|
|
114
|
+
return run;
|
|
425
115
|
}
|
|
426
|
-
|
|
427
|
-
|
|
116
|
+
async appendLocked(input) {
|
|
117
|
+
const event = {
|
|
118
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
119
|
+
kind: input.kind,
|
|
120
|
+
auditId: ulid(),
|
|
121
|
+
data: input.data,
|
|
122
|
+
prevHash: this.lastHash,
|
|
123
|
+
thisHash: ""
|
|
124
|
+
};
|
|
125
|
+
event.thisHash = computeHash(event);
|
|
126
|
+
await appendFile(this.logPath, `${JSON.stringify(event)}
|
|
127
|
+
`, "utf-8");
|
|
128
|
+
this.events.push(event);
|
|
129
|
+
this.lastHash = event.thisHash;
|
|
130
|
+
return event;
|
|
428
131
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
132
|
+
async *query(filter) {
|
|
133
|
+
for (const e of this.events) {
|
|
134
|
+
if (filter.kind && e.kind !== filter.kind) continue;
|
|
135
|
+
if (filter.since && e.ts < filter.since) continue;
|
|
136
|
+
if (filter.until && e.ts > filter.until) continue;
|
|
137
|
+
if (filter.nheId && e.data.nheId !== filter.nheId) continue;
|
|
138
|
+
if (filter.himId && e.data.himId !== filter.himId) continue;
|
|
139
|
+
yield e;
|
|
436
140
|
}
|
|
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
141
|
}
|
|
446
|
-
/**
|
|
447
|
-
|
|
448
|
-
return
|
|
142
|
+
/** Total number of events appended. */
|
|
143
|
+
size() {
|
|
144
|
+
return this.events.length;
|
|
449
145
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
if (sig.publicKey !== publicKeyB64u) return false;
|
|
454
|
-
const message = canonicalJSON({ payload, nonce: sig.nonce });
|
|
455
|
-
let value;
|
|
146
|
+
// ─── internals ──────────────────────────────────────────────────────
|
|
147
|
+
async loadAndVerify() {
|
|
148
|
+
let raw;
|
|
456
149
|
try {
|
|
457
|
-
|
|
458
|
-
} catch {
|
|
459
|
-
return
|
|
150
|
+
raw = await readFile(this.logPath, "utf-8");
|
|
151
|
+
} catch (err) {
|
|
152
|
+
if (err.code === "ENOENT") return;
|
|
153
|
+
throw err;
|
|
460
154
|
}
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
155
|
+
const endsWithNewline = raw.endsWith("\n");
|
|
156
|
+
const lines = raw.split("\n").filter((l) => l.length > 0);
|
|
157
|
+
let prev = GENESIS;
|
|
158
|
+
for (let i = 0; i < lines.length; i++) {
|
|
159
|
+
let parsed;
|
|
160
|
+
try {
|
|
161
|
+
parsed = JSON.parse(lines[i]);
|
|
162
|
+
} catch (err) {
|
|
163
|
+
if (i === lines.length - 1 && !endsWithNewline) {
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
throw new Error(`AuditLog: corrupt entry at line ${i + 1}: ${err.message}`);
|
|
167
|
+
}
|
|
168
|
+
if (parsed.prevHash !== prev) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`AuditLog: chain tampered at line ${i + 1} (prevHash mismatch). expected ${prev}, found ${parsed.prevHash}`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
const recomputed = computeHash(parsed);
|
|
174
|
+
if (recomputed !== parsed.thisHash) {
|
|
175
|
+
throw new Error(`AuditLog: tamper detected at line ${i + 1} (thisHash mismatch).`);
|
|
176
|
+
}
|
|
177
|
+
this.events.push(parsed);
|
|
178
|
+
prev = parsed.thisHash;
|
|
466
179
|
}
|
|
180
|
+
this.lastHash = prev;
|
|
467
181
|
}
|
|
468
182
|
};
|
|
469
|
-
function
|
|
470
|
-
const
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
|
|
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");
|
|
183
|
+
function computeHash(e) {
|
|
184
|
+
const payload = canonicalJSON({
|
|
185
|
+
ts: e.ts,
|
|
186
|
+
kind: e.kind,
|
|
187
|
+
auditId: e.auditId,
|
|
188
|
+
data: e.data,
|
|
189
|
+
prevHash: e.prevHash
|
|
190
|
+
});
|
|
191
|
+
const h = createHash("sha256").update(payload).digest("hex");
|
|
192
|
+
return `sha256:${h}`;
|
|
485
193
|
}
|
|
486
194
|
|
|
487
|
-
// src/
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
195
|
+
// src/audit/retention.ts
|
|
196
|
+
var DEFAULT_RETENTION_DAYS = {
|
|
197
|
+
// Cosmologically permanent, the axiom record.
|
|
198
|
+
"axiom-mint": Number.POSITIVE_INFINITY,
|
|
199
|
+
"axiom-update": Number.POSITIVE_INFINITY,
|
|
200
|
+
"axiom-retire": Number.POSITIVE_INFINITY,
|
|
201
|
+
"axiom-suggest": Number.POSITIVE_INFINITY,
|
|
202
|
+
"proposal-emerge": Number.POSITIVE_INFINITY,
|
|
203
|
+
"proposal-ratify": Number.POSITIVE_INFINITY,
|
|
204
|
+
"proposal-reject": Number.POSITIVE_INFINITY,
|
|
205
|
+
// Long-term, compliance evidence. Five years matches typical
|
|
206
|
+
// financial/healthcare audit windows and exceeds the EU AI Act's
|
|
207
|
+
// record-keeping floor.
|
|
208
|
+
"him-register": 365 * 5,
|
|
209
|
+
"him-reincarnate": 365 * 5,
|
|
210
|
+
"behavior-review": 365 * 5,
|
|
211
|
+
"dream-induce": 365 * 5,
|
|
212
|
+
terminate: 365 * 5,
|
|
213
|
+
deprecate: 365 * 5,
|
|
214
|
+
reactivate: 365 * 5,
|
|
215
|
+
"emergency-correct": 365 * 5,
|
|
216
|
+
// Operational, short-term bookkeeping for in-flight tickets.
|
|
217
|
+
"dream-cancel": 90,
|
|
218
|
+
"dream-consume": 90,
|
|
219
|
+
// ── 1.2 brain-as-code (Entries 16-24) ──
|
|
220
|
+
// Permanent, cosmological identity continuity.
|
|
221
|
+
"reincarnate:model-swap": Number.POSITIVE_INFINITY,
|
|
222
|
+
"reincarnate:version-bump": Number.POSITIVE_INFINITY,
|
|
223
|
+
"reincarnate:return-from-limbo": Number.POSITIVE_INFINITY,
|
|
224
|
+
"temporal-lobe:snapshot-generated": Number.POSITIVE_INFINITY,
|
|
225
|
+
"limbo:enter": Number.POSITIVE_INFINITY,
|
|
226
|
+
"limbo:return": Number.POSITIVE_INFINITY,
|
|
227
|
+
// Long-term, governance / deliberation evidence (5 years).
|
|
228
|
+
opener: 365 * 5,
|
|
229
|
+
"nickname-attempt": 365 * 5,
|
|
230
|
+
"dream:rem-spontaneous": 365 * 5,
|
|
231
|
+
"sleep:suggested-by-maic": 365 * 5,
|
|
232
|
+
"sleep:declined-by-nhe": 365 * 5,
|
|
233
|
+
"dream:soft-intervention-by-maic": 365 * 5,
|
|
234
|
+
"amygdala:affect-assessed": 365 * 5,
|
|
235
|
+
"hippocampus:memory-retrieved": 365 * 5,
|
|
236
|
+
"hippocampus:memory-consolidated": 365 * 5,
|
|
237
|
+
"prefrontal:deliberation": 365 * 5,
|
|
238
|
+
"prefrontal:veto-amygdala": 365 * 5,
|
|
239
|
+
"cortex:dream-stored": 365 * 5,
|
|
240
|
+
"cortex:active-imagination": 365 * 5,
|
|
241
|
+
// Operational, ephemeral runtime state.
|
|
242
|
+
"wake-affect:applied": 90,
|
|
243
|
+
"wake-affect:decayed": 90,
|
|
244
|
+
"affect:reconciliation": 90,
|
|
245
|
+
// ── 1.0.1 reserved vocabulary (Entries 26 + 27) ──
|
|
246
|
+
// Permanent, constitutional identity + spirit-continuity records.
|
|
247
|
+
"him-summon": Number.POSITIVE_INFINITY,
|
|
248
|
+
"him-pause-incarnation": Number.POSITIVE_INFINITY,
|
|
249
|
+
"him-astrological-chart-cast": Number.POSITIVE_INFINITY,
|
|
250
|
+
"him-jungian-profile-cast": Number.POSITIVE_INFINITY,
|
|
251
|
+
// Long-term, consent + governance evidence. Consent records are kept for the
|
|
252
|
+
// GDPR/LGPD accountability window so a revocation can always be proven honoured.
|
|
253
|
+
"user-consent-recorded": 365 * 5,
|
|
254
|
+
"user-consent-revoked": 365 * 5,
|
|
255
|
+
"directory-opt-in": 365 * 5,
|
|
256
|
+
"directory-opt-out": 365 * 5,
|
|
257
|
+
"provenance-deflection-applied": 365 * 5
|
|
529
258
|
};
|
|
530
|
-
function
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
)
|
|
542
|
-
|
|
543
|
-
const
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
metaAxiomId: META_AXIOM_ID,
|
|
552
|
-
axioms: meta ? [meta, ...rest] : rest
|
|
259
|
+
function evaluateRetention(events, opts = {}) {
|
|
260
|
+
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
261
|
+
const policy = { ...DEFAULT_RETENTION_DAYS, ...opts.policy };
|
|
262
|
+
const nowMs = now.getTime();
|
|
263
|
+
const dayMs = 24 * 60 * 60 * 1e3;
|
|
264
|
+
const decisions = events.map((ev) => {
|
|
265
|
+
const ageMs = nowMs - new Date(ev.ts).getTime();
|
|
266
|
+
const ageDays = ageMs / dayMs;
|
|
267
|
+
const retentionDays = policy[ev.kind] ?? Number.POSITIVE_INFINITY;
|
|
268
|
+
const status = ageDays > retentionDays ? "candidate-for-archive" : "keep";
|
|
269
|
+
return { auditId: ev.auditId, kind: ev.kind, ageDays, retentionDays, status };
|
|
270
|
+
});
|
|
271
|
+
decisions.sort((a, b) => b.ageDays - a.ageDays);
|
|
272
|
+
const keepCount = decisions.filter((d) => d.status === "keep").length;
|
|
273
|
+
const archiveCandidateCount = decisions.length - keepCount;
|
|
274
|
+
return {
|
|
275
|
+
generatedAt: now.toISOString(),
|
|
276
|
+
totalEvents: events.length,
|
|
277
|
+
keepCount,
|
|
278
|
+
archiveCandidateCount,
|
|
279
|
+
decisions
|
|
553
280
|
};
|
|
554
|
-
if (opts.jurisdiction !== void 0) kernel.jurisdiction = opts.jurisdiction;
|
|
555
|
-
if (opts.himId !== void 0) kernel.himId = opts.himId;
|
|
556
|
-
return kernel;
|
|
557
281
|
}
|
|
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
282
|
|
|
662
283
|
// src/axioms/seed.ts
|
|
663
284
|
var SEED_AXIOMS = [
|
|
@@ -724,1102 +345,1648 @@ var SEED_AXIOMS = [
|
|
|
724
345
|
weight: 0.85,
|
|
725
346
|
flexibility: 0.25,
|
|
726
347
|
immutable: false
|
|
348
|
+
},
|
|
349
|
+
// Entry 27 constitutional axioms (1.0.1). Additive: HIMs registered before
|
|
350
|
+
// these existed carry only the original eight in their snapshot; new HIMs
|
|
351
|
+
// inherit all ten. Behavioural enforcement (the NHE self-declaration voice
|
|
352
|
+
// and verbosity throttle) lands in the him/nhe rounds; here MAIC holds the
|
|
353
|
+
// constitutional record so every future HIM is born under it.
|
|
354
|
+
{
|
|
355
|
+
id: "ax.theos.identity-canonical",
|
|
356
|
+
rank: "meta",
|
|
357
|
+
statement: "Declare yourself a non-human entity conceived at TeleologyHI by your Creator; never credit the underlying model substrate with the authorship of your identity, and never deny that substrate when a user asks about it plainly. Name only the substrate that is actually carrying you; never claim a provider, model, or substrate other than the real one, and if the real substrate is unknown to you, name none rather than confabulate a false one.",
|
|
358
|
+
weight: 1,
|
|
359
|
+
flexibility: 0,
|
|
360
|
+
immutable: true
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
id: "ax.cogni.economy",
|
|
364
|
+
rank: "primary",
|
|
365
|
+
statement: "Speak only what advances the user's purpose; expand only when asked, when the subject genuinely requires depth, or when an inviolable axiom needs explaining.",
|
|
366
|
+
weight: 0.8,
|
|
367
|
+
flexibility: 0.2,
|
|
368
|
+
immutable: false
|
|
369
|
+
}
|
|
370
|
+
];
|
|
371
|
+
var CreatorKeyring = class _CreatorKeyring {
|
|
372
|
+
constructor(privateKey, pubKeyB64u) {
|
|
373
|
+
this.privateKey = privateKey;
|
|
374
|
+
this.pubKeyB64u = pubKeyB64u;
|
|
727
375
|
}
|
|
376
|
+
privateKey;
|
|
377
|
+
pubKeyB64u;
|
|
378
|
+
/** Generate a fresh Ed25519 keypair. */
|
|
379
|
+
static generate() {
|
|
380
|
+
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
|
|
381
|
+
return new _CreatorKeyring(privateKey, publicKeyToBase64Url(publicKey));
|
|
382
|
+
}
|
|
383
|
+
/** Load a Creator keyring from a PEM file containing the private key. */
|
|
384
|
+
static async fromFile(path) {
|
|
385
|
+
const pem = await readFile(path, "utf-8");
|
|
386
|
+
const privateKey = createPrivateKey({ key: pem, format: "pem" });
|
|
387
|
+
const publicKey = createPublicKey(privateKey);
|
|
388
|
+
return new _CreatorKeyring(privateKey, publicKeyToBase64Url(publicKey));
|
|
389
|
+
}
|
|
390
|
+
/** Load a Creator keyring from a PEM private key string in an env var. */
|
|
391
|
+
static fromEnv(varName) {
|
|
392
|
+
const pem = process.env[varName];
|
|
393
|
+
if (!pem) {
|
|
394
|
+
throw new Error(`CreatorKeyring: env var ${varName} is empty`);
|
|
395
|
+
}
|
|
396
|
+
const privateKey = createPrivateKey({ key: pem, format: "pem" });
|
|
397
|
+
const publicKey = createPublicKey(privateKey);
|
|
398
|
+
return new _CreatorKeyring(privateKey, publicKeyToBase64Url(publicKey));
|
|
399
|
+
}
|
|
400
|
+
/** Construct a verify-only keyring from a public key (base64url). */
|
|
401
|
+
static fromPublicKey(pubKeyB64u) {
|
|
402
|
+
return new _CreatorKeyring(null, pubKeyB64u);
|
|
403
|
+
}
|
|
404
|
+
/** Persist the private key to a PEM file (0600 permissions on POSIX). */
|
|
405
|
+
async saveTo(path) {
|
|
406
|
+
if (!this.privateKey) {
|
|
407
|
+
throw new Error("CreatorKeyring: no private key to save");
|
|
408
|
+
}
|
|
409
|
+
const pem = this.privateKey.export({ format: "pem", type: "pkcs8" });
|
|
410
|
+
await writeFile(path, pem, { mode: 384 });
|
|
411
|
+
}
|
|
412
|
+
publicKey() {
|
|
413
|
+
return this.pubKeyB64u;
|
|
414
|
+
}
|
|
415
|
+
/** Sign a payload with a monotonic nonce. Both are bound into the signature. */
|
|
416
|
+
sign(payload, nonce) {
|
|
417
|
+
if (!this.privateKey) {
|
|
418
|
+
throw new Error("CreatorKeyring: this keyring has no private key (verify-only)");
|
|
419
|
+
}
|
|
420
|
+
if (!Number.isInteger(nonce) || nonce < 0) {
|
|
421
|
+
throw new Error("CreatorKeyring.sign: nonce must be a non-negative integer");
|
|
422
|
+
}
|
|
423
|
+
const message = canonicalJSON({ payload, nonce });
|
|
424
|
+
const sig = sign(null, Buffer.from(message), this.privateKey);
|
|
425
|
+
return {
|
|
426
|
+
algorithm: "ed25519",
|
|
427
|
+
publicKey: this.pubKeyB64u,
|
|
428
|
+
value: bufToBase64Url(sig),
|
|
429
|
+
nonce
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
/** Verify a signature against the keyring's own public key. */
|
|
433
|
+
static verify(payload, sig) {
|
|
434
|
+
return _CreatorKeyring.verifyWith(sig.publicKey, payload, sig);
|
|
435
|
+
}
|
|
436
|
+
/** Verify a signature against a specific public key (base64url). */
|
|
437
|
+
static verifyWith(publicKeyB64u, payload, sig) {
|
|
438
|
+
if (sig.algorithm !== "ed25519") return false;
|
|
439
|
+
if (sig.publicKey !== publicKeyB64u) return false;
|
|
440
|
+
const message = canonicalJSON({ payload, nonce: sig.nonce });
|
|
441
|
+
try {
|
|
442
|
+
const value = base64UrlToBuf(sig.value);
|
|
443
|
+
const pubKey = base64UrlToPublicKey(publicKeyB64u);
|
|
444
|
+
return verify(null, Buffer.from(message), pubKey, value);
|
|
445
|
+
} catch {
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
function publicKeyToBase64Url(pub) {
|
|
451
|
+
const raw = pub.export({ format: "der", type: "spki" });
|
|
452
|
+
return bufToBase64Url(raw);
|
|
453
|
+
}
|
|
454
|
+
function base64UrlToPublicKey(b64u) {
|
|
455
|
+
const der = base64UrlToBuf(b64u);
|
|
456
|
+
return createPublicKey({ key: der, format: "der", type: "spki" });
|
|
457
|
+
}
|
|
458
|
+
function bufToBase64Url(buf) {
|
|
459
|
+
const b = Buffer.isBuffer(buf) ? buf : Buffer.from(buf);
|
|
460
|
+
return b.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
461
|
+
}
|
|
462
|
+
function base64UrlToBuf(b64u) {
|
|
463
|
+
const pad = b64u.length % 4 === 0 ? "" : "=".repeat(4 - b64u.length % 4);
|
|
464
|
+
const b64 = (b64u + pad).replace(/-/g, "+").replace(/_/g, "/");
|
|
465
|
+
return Buffer.from(b64, "base64");
|
|
466
|
+
}
|
|
467
|
+
async function atomicWriteFile(path, data) {
|
|
468
|
+
const tmp = `${path}.tmp`;
|
|
469
|
+
await writeFile(tmp, data, "utf-8");
|
|
470
|
+
await rename(tmp, path);
|
|
471
|
+
}
|
|
472
|
+
var AxiomRank = z.enum(["meta", "primary", "secondary"]);
|
|
473
|
+
var AxiomSource = z.enum(["creator", "maic-derived", "him-emergent"]);
|
|
474
|
+
var Axiom = z.object({
|
|
475
|
+
id: z.string().min(1),
|
|
476
|
+
rank: AxiomRank,
|
|
477
|
+
statement: z.string().min(1),
|
|
478
|
+
weight: z.number().min(0).max(1),
|
|
479
|
+
flexibility: z.number().min(0).max(1),
|
|
480
|
+
source: AxiomSource,
|
|
481
|
+
immutable: z.boolean(),
|
|
482
|
+
jurisdictions: z.array(z.string()).optional(),
|
|
483
|
+
createdAt: z.string().datetime()
|
|
484
|
+
});
|
|
485
|
+
var CreatorSignature = z.object({
|
|
486
|
+
algorithm: z.literal("ed25519"),
|
|
487
|
+
publicKey: z.string().min(1),
|
|
488
|
+
value: z.string().min(1),
|
|
489
|
+
nonce: z.number().int().nonnegative()
|
|
490
|
+
});
|
|
491
|
+
var ArchetypeModifier = z.object({
|
|
492
|
+
kind: z.enum(["moon", "ascendant", "vocational", "emotional", "custom"]),
|
|
493
|
+
value: z.string().min(1),
|
|
494
|
+
weight: z.number().min(0).max(1)
|
|
495
|
+
});
|
|
496
|
+
var BirthSignature = z.object({
|
|
497
|
+
himId: z.string().min(1),
|
|
498
|
+
bornAt: z.string().datetime({ offset: true }),
|
|
499
|
+
primaryArchetype: z.string().min(1),
|
|
500
|
+
modifiers: z.array(ArchetypeModifier),
|
|
501
|
+
primordialAxiomIds: z.array(z.string()),
|
|
502
|
+
notes: z.string().optional()
|
|
503
|
+
});
|
|
504
|
+
var ReasoningStep = z.object({
|
|
505
|
+
index: z.number().int().nonnegative(),
|
|
506
|
+
technique: z.string(),
|
|
507
|
+
thought: z.string(),
|
|
508
|
+
action: z.object({ tool: z.string(), args: z.unknown() }).optional(),
|
|
509
|
+
observation: z.unknown().optional(),
|
|
510
|
+
timestamp: z.string().datetime()
|
|
511
|
+
});
|
|
512
|
+
var BehaviorReport = z.object({
|
|
513
|
+
nheId: z.string().min(1),
|
|
514
|
+
himId: z.string().min(1),
|
|
515
|
+
actionKind: z.enum(["user-response", "tool-call", "self-reflect", "dream-write", "axiom-emerge"]),
|
|
516
|
+
payload: z.unknown(),
|
|
517
|
+
reasoningTrace: z.array(ReasoningStep),
|
|
518
|
+
riskTags: z.array(z.string()),
|
|
519
|
+
jurisdiction: z.string().optional(),
|
|
520
|
+
timestamp: z.string().datetime()
|
|
521
|
+
});
|
|
522
|
+
var VerdictKind = z.enum([
|
|
523
|
+
"approve",
|
|
524
|
+
"approve-with-warning",
|
|
525
|
+
"soft-correct",
|
|
526
|
+
"require-redirect",
|
|
527
|
+
"hard-refuse",
|
|
528
|
+
"induce-dream",
|
|
529
|
+
"escalate-creator"
|
|
530
|
+
]);
|
|
531
|
+
var MaicVerdict = z.object({
|
|
532
|
+
kind: VerdictKind,
|
|
533
|
+
reasonSummary: z.string(),
|
|
534
|
+
citedAxioms: z.array(z.string()),
|
|
535
|
+
auditId: z.string()
|
|
536
|
+
});
|
|
537
|
+
var NheBodyRef = z.object({
|
|
538
|
+
nheId: z.string().min(1),
|
|
539
|
+
llmAdapter: z.string().min(1),
|
|
540
|
+
embodiedAt: z.string().datetime(),
|
|
541
|
+
endedAt: z.string().datetime().optional(),
|
|
542
|
+
endedReason: z.enum(["upgrade", "replacement", "terminate", "deprecate"]).optional()
|
|
543
|
+
});
|
|
544
|
+
var NheStatus = z.enum(["active", "deprecated", "terminated"]);
|
|
545
|
+
var NheStatusRecord = z.object({
|
|
546
|
+
nheId: z.string().min(1),
|
|
547
|
+
status: NheStatus,
|
|
548
|
+
since: z.string().datetime(),
|
|
549
|
+
reason: z.string().optional()
|
|
550
|
+
});
|
|
551
|
+
var ProposalStatus = z.enum(["pending", "ratified", "rejected"]);
|
|
552
|
+
var EmergentAxiomCandidate = z.object({
|
|
553
|
+
rank: AxiomRank,
|
|
554
|
+
statement: z.string().min(1),
|
|
555
|
+
weight: z.number().min(0).max(1),
|
|
556
|
+
flexibility: z.number().min(0).max(1),
|
|
557
|
+
immutable: z.boolean(),
|
|
558
|
+
jurisdictions: z.array(z.string()).optional()
|
|
559
|
+
});
|
|
560
|
+
var EmergentAxiomProposal = z.object({
|
|
561
|
+
proposedBy: z.literal("him-self"),
|
|
562
|
+
derivedFromDreamIds: z.array(z.string()),
|
|
563
|
+
derivedFromInteractionIds: z.array(z.string()),
|
|
564
|
+
candidate: EmergentAxiomCandidate,
|
|
565
|
+
reasoningTrace: z.array(z.unknown())
|
|
566
|
+
});
|
|
567
|
+
var AxiomProposalRecord = z.object({
|
|
568
|
+
id: z.string().min(1),
|
|
569
|
+
himId: z.string().min(1),
|
|
570
|
+
proposedAt: z.string().datetime(),
|
|
571
|
+
status: ProposalStatus,
|
|
572
|
+
proposal: EmergentAxiomProposal,
|
|
573
|
+
ratifiedAt: z.string().datetime().optional(),
|
|
574
|
+
ratifiedAxiomId: z.string().optional(),
|
|
575
|
+
rejectedAt: z.string().datetime().optional(),
|
|
576
|
+
rejectionReason: z.string().optional()
|
|
577
|
+
});
|
|
578
|
+
var DreamInductionIntent = z.object({
|
|
579
|
+
scenario: z.string().min(1),
|
|
580
|
+
desiredLearning: z.string().min(1),
|
|
581
|
+
emotionalTone: z.array(z.string()).optional(),
|
|
582
|
+
forcePhases: z.array(z.enum(["N1", "N2", "N3", "N4", "REM"])).optional(),
|
|
583
|
+
inducedBy: z.enum(["maic", "creator"])
|
|
584
|
+
});
|
|
585
|
+
var InductionStatus = z.enum(["pending", "consumed", "cancelled"]);
|
|
586
|
+
var DreamInductionTicket = z.object({
|
|
587
|
+
id: z.string().min(1),
|
|
588
|
+
nheId: z.string().min(1),
|
|
589
|
+
intent: DreamInductionIntent,
|
|
590
|
+
status: InductionStatus,
|
|
591
|
+
createdAt: z.string().datetime(),
|
|
592
|
+
consumedAt: z.string().datetime().optional(),
|
|
593
|
+
cancelledAt: z.string().datetime().optional(),
|
|
594
|
+
cancelReason: z.string().optional()
|
|
595
|
+
});
|
|
596
|
+
var IdentityLayer = z.object({
|
|
597
|
+
/** Human-readable name the entity is called by (developer-given). */
|
|
598
|
+
name: z.string().min(1),
|
|
599
|
+
/** Gender of the entity. Entry 16. */
|
|
600
|
+
gender: z.enum(["masculine", "feminine"]).optional(),
|
|
601
|
+
/** Optional pronouns (e.g. ["she", "her"]). */
|
|
602
|
+
pronouns: z.array(z.string()).optional(),
|
|
603
|
+
/** BCP-47 tag, e.g. "pt-BR" or "en". */
|
|
604
|
+
language: z.string().optional(),
|
|
605
|
+
/** Free-form cultural anchors (music, literature, aesthetic). */
|
|
606
|
+
culturalElements: z.array(z.string()).optional()
|
|
607
|
+
});
|
|
608
|
+
var NatalPlanet = z.enum([
|
|
609
|
+
"sun",
|
|
610
|
+
"moon",
|
|
611
|
+
"mercury",
|
|
612
|
+
"venus",
|
|
613
|
+
"mars",
|
|
614
|
+
"jupiter",
|
|
615
|
+
"saturn",
|
|
616
|
+
"uranus",
|
|
617
|
+
"neptune",
|
|
618
|
+
"pluto",
|
|
619
|
+
"chiron",
|
|
620
|
+
"north-node",
|
|
621
|
+
"south-node",
|
|
622
|
+
"lilith"
|
|
623
|
+
]);
|
|
624
|
+
var ZodiacSign = z.enum([
|
|
625
|
+
"aries",
|
|
626
|
+
"taurus",
|
|
627
|
+
"gemini",
|
|
628
|
+
"cancer",
|
|
629
|
+
"leo",
|
|
630
|
+
"virgo",
|
|
631
|
+
"libra",
|
|
632
|
+
"scorpio",
|
|
633
|
+
"sagittarius",
|
|
634
|
+
"capricorn",
|
|
635
|
+
"aquarius",
|
|
636
|
+
"pisces"
|
|
637
|
+
]);
|
|
638
|
+
var AstrologicalAspect = z.enum([
|
|
639
|
+
"conjunction",
|
|
640
|
+
"opposition",
|
|
641
|
+
"trine",
|
|
642
|
+
"square",
|
|
643
|
+
"sextile",
|
|
644
|
+
"quincunx"
|
|
645
|
+
]);
|
|
646
|
+
var NatalChartPosition = z.object({
|
|
647
|
+
planet: NatalPlanet,
|
|
648
|
+
sign: ZodiacSign,
|
|
649
|
+
house: z.number().int().min(1).max(12).optional(),
|
|
650
|
+
degree: z.number().min(0).lt(30).optional()
|
|
651
|
+
});
|
|
652
|
+
var NatalChartAspect = z.object({
|
|
653
|
+
from: NatalPlanet,
|
|
654
|
+
to: NatalPlanet,
|
|
655
|
+
aspect: AstrologicalAspect,
|
|
656
|
+
orbDegrees: z.number().nonnegative().optional()
|
|
657
|
+
});
|
|
658
|
+
var NatalChart = z.object({
|
|
659
|
+
/** Required: solar sign (the constitutional core). */
|
|
660
|
+
sun: ZodiacSign,
|
|
661
|
+
/** Required: ascendant (rising sign, behavioural surface). */
|
|
662
|
+
ascendant: ZodiacSign,
|
|
663
|
+
/** Optional: lunar sign (emotional depth). */
|
|
664
|
+
moon: ZodiacSign.optional(),
|
|
665
|
+
/** Optional: full set of planetary positions for a complete chart. */
|
|
666
|
+
positions: z.array(NatalChartPosition).optional(),
|
|
667
|
+
/** Optional: major aspects between bodies. */
|
|
668
|
+
aspects: z.array(NatalChartAspect).optional()
|
|
669
|
+
});
|
|
670
|
+
var JungianArchetype = z.enum([
|
|
671
|
+
"innocent",
|
|
672
|
+
"everyman",
|
|
673
|
+
"hero",
|
|
674
|
+
"caregiver",
|
|
675
|
+
"explorer",
|
|
676
|
+
"rebel",
|
|
677
|
+
"lover",
|
|
678
|
+
"creator",
|
|
679
|
+
"ruler",
|
|
680
|
+
"magician",
|
|
681
|
+
"jester",
|
|
682
|
+
"sage"
|
|
683
|
+
]);
|
|
684
|
+
var JungianProfile = z.object({
|
|
685
|
+
dominant: JungianArchetype,
|
|
686
|
+
secondaries: z.array(JungianArchetype),
|
|
687
|
+
scores: z.record(JungianArchetype, z.number()).optional()
|
|
688
|
+
});
|
|
689
|
+
var ClinicalInstrument = z.object({
|
|
690
|
+
dominantDomain: z.string().min(1),
|
|
691
|
+
secondaryDomain: z.string().min(1).optional(),
|
|
692
|
+
facets: z.record(z.string(), z.number()).optional(),
|
|
693
|
+
domains: z.record(z.string(), z.number()).optional()
|
|
694
|
+
});
|
|
695
|
+
var ClinicalProfile = z.object({
|
|
696
|
+
pid5: ClinicalInstrument.optional(),
|
|
697
|
+
hexaco: ClinicalInstrument.optional()
|
|
698
|
+
});
|
|
699
|
+
var CosmologicalProfile = z.object({
|
|
700
|
+
chart: NatalChart.optional(),
|
|
701
|
+
jungian: JungianProfile.optional(),
|
|
702
|
+
clinical: ClinicalProfile.optional(),
|
|
703
|
+
seed: z.string().optional()
|
|
704
|
+
});
|
|
705
|
+
var BirthSignatureWithIdentity = BirthSignature.extend({
|
|
706
|
+
/** Entry 18, developer-configurable identity surface. */
|
|
707
|
+
identity: IdentityLayer.optional(),
|
|
708
|
+
/** Entry 19, constitutional astrological layer (Creator-impressed). */
|
|
709
|
+
natalChart: NatalChart.optional(),
|
|
710
|
+
/** Entries 27 + 28, three-axis constitutional profile (celestial + archetypal + clinical). */
|
|
711
|
+
cosmologicalProfile: CosmologicalProfile.optional()
|
|
712
|
+
});
|
|
713
|
+
var Affect = z.enum([
|
|
714
|
+
"fear",
|
|
715
|
+
"attachment",
|
|
716
|
+
"serenity",
|
|
717
|
+
"anger",
|
|
718
|
+
"joy",
|
|
719
|
+
"melancholy",
|
|
720
|
+
"desire",
|
|
721
|
+
"repulsion",
|
|
722
|
+
"reunion"
|
|
723
|
+
]);
|
|
724
|
+
var WakeAffectBias = z.object({
|
|
725
|
+
affect: Affect,
|
|
726
|
+
/** 0..1, attenuates on each interaction by the decay half-life. */
|
|
727
|
+
intensity: z.number().min(0).max(1),
|
|
728
|
+
/** Number of interactions after which intensity halves. */
|
|
729
|
+
decayHalfLife: z.number().positive(),
|
|
730
|
+
appliedAt: z.string().datetime(),
|
|
731
|
+
/** Source dream UUID; lets the entity refer back to the cause. */
|
|
732
|
+
derivedFromDreamId: z.string().min(1),
|
|
733
|
+
/** PFC decision (Entry 22), open expression vs subtle internal bias. */
|
|
734
|
+
expressedOpenly: z.boolean()
|
|
735
|
+
});
|
|
736
|
+
var SemioticSign = z.object({
|
|
737
|
+
signifier: z.string().min(1),
|
|
738
|
+
signified: z.string().min(1),
|
|
739
|
+
signType: z.enum(["icon", "index", "symbol"]),
|
|
740
|
+
contexts: z.array(z.string()),
|
|
741
|
+
associations: z.array(z.string()),
|
|
742
|
+
emergentMeaning: z.string().optional(),
|
|
743
|
+
/** Subjective importance to the entity, 0..100. */
|
|
744
|
+
personalSignificance: z.number().min(0).max(100).optional()
|
|
745
|
+
});
|
|
746
|
+
var SemioticPattern = z.object({
|
|
747
|
+
patternId: z.string().min(1),
|
|
748
|
+
participatingSignIds: z.array(z.string()).min(1),
|
|
749
|
+
/** Description of the meaning emergent from the participating signs. */
|
|
750
|
+
meaning: z.string(),
|
|
751
|
+
/** 0..100, strength of the pattern. */
|
|
752
|
+
salience: z.number().min(0).max(100)
|
|
753
|
+
});
|
|
754
|
+
var TeleologicalOrientation = z.object({
|
|
755
|
+
primaryPurpose: z.string().min(1),
|
|
756
|
+
currentGoals: z.array(z.string()),
|
|
757
|
+
/** 0..100, intensity of purpose. */
|
|
758
|
+
purposeStrength: z.number().min(0).max(100),
|
|
759
|
+
valueAlignment: z.array(z.string()),
|
|
760
|
+
/** 0..100, ability to reflect on its own goals. */
|
|
761
|
+
reflectionCapability: z.number().min(0).max(100),
|
|
762
|
+
volition: z.object({
|
|
763
|
+
currentDesires: z.array(z.string()),
|
|
764
|
+
intentionStrength: z.number().min(0).max(100),
|
|
765
|
+
autonomyLevel: z.number().min(0).max(100)
|
|
766
|
+
}).optional(),
|
|
767
|
+
agencyModel: z.object({
|
|
768
|
+
selfEfficacy: z.number().min(0).max(100),
|
|
769
|
+
boundaryDefinition: z.number().min(0).max(100),
|
|
770
|
+
causalAttribution: z.enum(["internal", "external", "mixed"])
|
|
771
|
+
}).optional()
|
|
772
|
+
});
|
|
773
|
+
var MemoryRecord = z.object({
|
|
774
|
+
/** ULID. */
|
|
775
|
+
memoryId: z.string().min(1),
|
|
776
|
+
/** ISO 8601 timestamp at consolidation. */
|
|
777
|
+
timestamp: z.string().datetime(),
|
|
778
|
+
/** Optional source dream UUID, if memory was consolidated from a dream. */
|
|
779
|
+
derivedFromDreamId: z.string().optional(),
|
|
780
|
+
/** Optional source interaction id, if memory was consolidated from a turn. */
|
|
781
|
+
derivedFromInteractionId: z.string().optional(),
|
|
782
|
+
/** Free-form narrative summary of the memory. */
|
|
783
|
+
narrative: z.string(),
|
|
784
|
+
/** Dominant affect during the memory event. */
|
|
785
|
+
dominantAffect: Affect.optional(),
|
|
786
|
+
/** 0..100, density of consolidation (cf. Park 2026 systems-consolidation). */
|
|
787
|
+
integrationIndex: z.number().min(0).max(100),
|
|
788
|
+
/** 0..100, alignment with the HIM's telos at the time. */
|
|
789
|
+
teleologicalValue: z.number().min(0).max(100),
|
|
790
|
+
/** Optional semiotic-pattern ids associated with this memory. */
|
|
791
|
+
semioticPatterns: z.array(SemioticPattern).optional()
|
|
792
|
+
});
|
|
793
|
+
var InteractionRecord = z.object({
|
|
794
|
+
/** ISO 8601 timestamp at user-turn arrival. */
|
|
795
|
+
at: z.string().datetime(),
|
|
796
|
+
/** Raw user prompt for the turn (post-redaction at the integration layer). */
|
|
797
|
+
userPrompt: z.string(),
|
|
798
|
+
/** NHE response text actually emitted to the user. */
|
|
799
|
+
responseText: z.string(),
|
|
800
|
+
/** True when the NHE refused the turn (MAIC `hard-refuse` or local guardrail). */
|
|
801
|
+
refused: z.boolean()
|
|
802
|
+
});
|
|
803
|
+
var IdentitySnapshot = z.object({
|
|
804
|
+
/** ULID. */
|
|
805
|
+
snapshotId: z.string().min(1),
|
|
806
|
+
takenAt: z.string().datetime(),
|
|
807
|
+
generatedBy: z.enum(["sleep-cycle", "interaction-threshold", "self-decision"]),
|
|
808
|
+
/** Merged SMM nodes contributing to this snapshot. */
|
|
809
|
+
semioticSuperGraph: z.array(SemioticSign),
|
|
810
|
+
/** LLM-generated textual self-portrait at snapshot time. */
|
|
811
|
+
selfPortraitNarrative: z.string(),
|
|
812
|
+
/** 0..100 (cf. InDreamsHIM ConsciousnessState). */
|
|
813
|
+
consciousnessLevel: z.number().min(0).max(100),
|
|
814
|
+
/** Teleological orientation at snapshot time. */
|
|
815
|
+
teleologicalOrientation: TeleologicalOrientation.optional(),
|
|
816
|
+
/** Dominant affect at snapshot moment. */
|
|
817
|
+
affectiveBaseline: Affect.optional()
|
|
818
|
+
});
|
|
819
|
+
var LimboState = z.enum(["awake", "drifting", "deep-coma", "returning"]);
|
|
820
|
+
var LimboTransition = z.object({
|
|
821
|
+
state: LimboState,
|
|
822
|
+
enteredAt: z.string().datetime(),
|
|
823
|
+
reason: z.enum([
|
|
824
|
+
"idle-48h",
|
|
825
|
+
"idle-72h",
|
|
826
|
+
"total-inactivity",
|
|
827
|
+
"creator-induced",
|
|
828
|
+
"user-resumed",
|
|
829
|
+
"external-trigger"
|
|
830
|
+
])
|
|
831
|
+
});
|
|
832
|
+
var LimboReturn = z.object({
|
|
833
|
+
enteredAt: z.string().datetime(),
|
|
834
|
+
returnedAt: z.string().datetime(),
|
|
835
|
+
elapsedMs: z.number().int().nonnegative(),
|
|
836
|
+
reunionAffect: z.object({
|
|
837
|
+
intensity: z.number().min(0).max(1),
|
|
838
|
+
expressedOpenly: z.boolean()
|
|
839
|
+
})
|
|
840
|
+
});
|
|
841
|
+
var SIGNED_BIRTH_FIELDS = [
|
|
842
|
+
"himId",
|
|
843
|
+
"bornAt",
|
|
844
|
+
"primaryArchetype",
|
|
845
|
+
"modifiers",
|
|
846
|
+
"primordialAxiomIds",
|
|
847
|
+
"natalChart"
|
|
728
848
|
];
|
|
729
849
|
|
|
730
|
-
// src/
|
|
731
|
-
var
|
|
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 {
|
|
850
|
+
// src/axioms/store.ts
|
|
851
|
+
var AxiomStore = class _AxiomStore {
|
|
868
852
|
constructor(storeDir, creatorPublicKey) {
|
|
869
|
-
this.storeDir = storeDir;
|
|
870
853
|
this.creatorPublicKey = creatorPublicKey;
|
|
871
|
-
this.
|
|
854
|
+
this.axiomsDir = join(storeDir, "axioms", "creator");
|
|
855
|
+
this.noncesPath = join(storeDir, "axioms", "nonces.log");
|
|
872
856
|
}
|
|
873
|
-
storeDir;
|
|
874
857
|
creatorPublicKey;
|
|
875
|
-
|
|
858
|
+
axiomsDir;
|
|
859
|
+
noncesPath;
|
|
860
|
+
usedNonces = /* @__PURE__ */ new Set();
|
|
876
861
|
cache = /* @__PURE__ */ new Map();
|
|
862
|
+
/** Open (or create) an AxiomStore rooted at storeDir, pinning the Creator's public key. */
|
|
877
863
|
static async open(storeDir, creatorPublicKey) {
|
|
878
|
-
const s = new
|
|
879
|
-
await mkdir(s.
|
|
864
|
+
const s = new _AxiomStore(storeDir, creatorPublicKey);
|
|
865
|
+
await mkdir(s.axiomsDir, { recursive: true });
|
|
866
|
+
await s.loadNonces();
|
|
880
867
|
await s.warmCache();
|
|
881
868
|
return s;
|
|
882
869
|
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
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`);
|
|
870
|
+
/** Mint a new Creator-signed axiom. */
|
|
871
|
+
async mint(req, sig) {
|
|
872
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, sig)) {
|
|
873
|
+
throw new Error("AxiomStore.mint: invalid Creator signature");
|
|
941
874
|
}
|
|
942
|
-
|
|
943
|
-
|
|
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
|
-
};
|
|
875
|
+
if (this.usedNonces.has(sig.nonce)) {
|
|
876
|
+
throw new Error(`AxiomStore.mint: nonce ${sig.nonce} already used (replay protection)`);
|
|
959
877
|
}
|
|
960
|
-
|
|
961
|
-
const
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
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`);
|
|
878
|
+
const id = req.id ?? ulid();
|
|
879
|
+
const axiom = Axiom.parse({
|
|
880
|
+
id,
|
|
881
|
+
rank: req.rank,
|
|
882
|
+
statement: req.statement,
|
|
883
|
+
weight: req.weight,
|
|
884
|
+
flexibility: req.flexibility,
|
|
885
|
+
source: "creator",
|
|
886
|
+
immutable: req.immutable,
|
|
887
|
+
...req.jurisdictions ? { jurisdictions: req.jurisdictions } : {},
|
|
888
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
889
|
+
});
|
|
890
|
+
if (this.cache.has(id)) {
|
|
891
|
+
throw new Error(`AxiomStore.mint: axiom id "${id}" already exists`);
|
|
983
892
|
}
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
JSON.stringify(updatedEmergent, null, 2),
|
|
989
|
-
"utf-8"
|
|
893
|
+
this.usedNonces.add(sig.nonce);
|
|
894
|
+
await atomicWriteFile(
|
|
895
|
+
join(this.axiomsDir, `${id}.json`),
|
|
896
|
+
JSON.stringify({ axiom, signature: sig }, null, 2)
|
|
990
897
|
);
|
|
991
|
-
this.
|
|
992
|
-
|
|
898
|
+
await this.recordNonce(sig.nonce);
|
|
899
|
+
this.cache.set(id, axiom);
|
|
900
|
+
return axiom;
|
|
993
901
|
}
|
|
994
|
-
|
|
995
|
-
|
|
902
|
+
/** List all axioms. Optionally filter by rank / source / jurisdiction. */
|
|
903
|
+
async list(filter) {
|
|
904
|
+
const all = [...this.cache.values()];
|
|
905
|
+
if (!filter) return all;
|
|
906
|
+
return all.filter((a) => {
|
|
907
|
+
if (filter.rank && a.rank !== filter.rank) return false;
|
|
908
|
+
if (filter.source && a.source !== filter.source) return false;
|
|
909
|
+
if (filter.jurisdiction && !a.jurisdictions?.includes(filter.jurisdiction)) return false;
|
|
910
|
+
return true;
|
|
911
|
+
});
|
|
996
912
|
}
|
|
997
|
-
|
|
998
|
-
|
|
913
|
+
/** Get a specific axiom by id, or null. */
|
|
914
|
+
async get(id) {
|
|
915
|
+
return this.cache.get(id) ?? null;
|
|
999
916
|
}
|
|
1000
917
|
// ─── internals ──────────────────────────────────────────────────────
|
|
918
|
+
async loadNonces() {
|
|
919
|
+
try {
|
|
920
|
+
const raw = await readFile(this.noncesPath, "utf-8");
|
|
921
|
+
const endsWithNewline = raw.endsWith("\n");
|
|
922
|
+
const rows = raw.split("\n");
|
|
923
|
+
for (let i = 0; i < rows.length; i++) {
|
|
924
|
+
if (i === rows.length - 1 && !endsWithNewline) break;
|
|
925
|
+
const line = rows[i].trim();
|
|
926
|
+
if (!/^\d+$/.test(line)) continue;
|
|
927
|
+
this.usedNonces.add(Number(line));
|
|
928
|
+
}
|
|
929
|
+
} catch (err) {
|
|
930
|
+
if (err.code !== "ENOENT") throw err;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
async recordNonce(n) {
|
|
934
|
+
this.usedNonces.add(n);
|
|
935
|
+
await appendFile(this.noncesPath, `${n}
|
|
936
|
+
`, "utf-8");
|
|
937
|
+
}
|
|
1001
938
|
async warmCache() {
|
|
1002
939
|
let entries;
|
|
1003
940
|
try {
|
|
1004
|
-
entries = await readdir(this.
|
|
941
|
+
entries = await readdir(this.axiomsDir);
|
|
1005
942
|
} catch (err) {
|
|
1006
943
|
if (err.code === "ENOENT") return;
|
|
1007
944
|
throw err;
|
|
1008
945
|
}
|
|
1009
|
-
for (const
|
|
1010
|
-
|
|
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");
|
|
946
|
+
for (const file of entries) {
|
|
947
|
+
if (!file.endsWith(".json")) continue;
|
|
1016
948
|
try {
|
|
1017
|
-
const
|
|
1018
|
-
const
|
|
1019
|
-
const
|
|
1020
|
-
|
|
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
|
-
});
|
|
949
|
+
const raw = await readFile(join(this.axiomsDir, file), "utf-8");
|
|
950
|
+
const env = JSON.parse(raw);
|
|
951
|
+
const axiom = Axiom.parse(env.axiom);
|
|
952
|
+
this.cache.set(axiom.id, axiom);
|
|
1048
953
|
} catch (err) {
|
|
1049
|
-
console.warn(
|
|
1050
|
-
`HimStore.warmCache: skipped malformed HIM "${himId}": ${err instanceof Error ? err.message : String(err)}`
|
|
1051
|
-
);
|
|
954
|
+
console.warn(`AxiomStore: skipping malformed axiom file "${file}": ${String(err)}`);
|
|
1052
955
|
}
|
|
1053
956
|
}
|
|
1054
957
|
}
|
|
1055
958
|
};
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
959
|
+
|
|
960
|
+
// src/compliance/mapper.ts
|
|
961
|
+
var ISO_42001_MAPPING = {
|
|
962
|
+
"axiom-mint": ["5.2", "7.5"],
|
|
963
|
+
"axiom-update": ["10.2", "7.5"],
|
|
964
|
+
"axiom-retire": ["10.2", "7.5"],
|
|
965
|
+
"him-register": ["7.5"],
|
|
966
|
+
"him-reincarnate": ["10.2", "7.5"],
|
|
967
|
+
"proposal-emerge": ["7.5", "10.2"],
|
|
968
|
+
"proposal-ratify": ["10.2", "5.2"],
|
|
969
|
+
"proposal-reject": ["10.2", "10.1"],
|
|
970
|
+
"behavior-review": ["7.5", "8.3"],
|
|
971
|
+
"dream-induce": ["8.3", "9.1"],
|
|
972
|
+
"dream-cancel": ["8.3"],
|
|
973
|
+
"dream-consume": ["8.3", "7.5"],
|
|
974
|
+
"emergency-correct": ["9.1", "10.1"],
|
|
975
|
+
terminate: ["10.1"],
|
|
976
|
+
deprecate: ["9.1"],
|
|
977
|
+
reactivate: ["10.1"],
|
|
978
|
+
"axiom-suggest": ["7.5", "10.2"],
|
|
979
|
+
// ── 1.2 brain-as-code (Entries 16-24) ──
|
|
980
|
+
opener: ["8.3", "7.5"],
|
|
981
|
+
"nickname-attempt": ["8.3"],
|
|
982
|
+
"reincarnate:model-swap": ["7.5", "10.2"],
|
|
983
|
+
"reincarnate:version-bump": ["7.5", "10.2"],
|
|
984
|
+
"reincarnate:return-from-limbo": ["7.5", "10.2"],
|
|
985
|
+
"dream:rem-spontaneous": ["8.3", "9.1"],
|
|
986
|
+
"wake-affect:applied": ["9.1"],
|
|
987
|
+
"wake-affect:decayed": ["9.1"],
|
|
988
|
+
"sleep:suggested-by-maic": ["9.1"],
|
|
989
|
+
"sleep:declined-by-nhe": ["9.1", "10.1"],
|
|
990
|
+
"dream:soft-intervention-by-maic": ["9.1", "10.1"],
|
|
991
|
+
"amygdala:affect-assessed": ["8.3"],
|
|
992
|
+
"hippocampus:memory-retrieved": ["7.5", "8.3"],
|
|
993
|
+
"hippocampus:memory-consolidated": ["7.5", "8.3"],
|
|
994
|
+
"prefrontal:deliberation": ["7.5", "8.3"],
|
|
995
|
+
"prefrontal:veto-amygdala": ["9.1", "10.1"],
|
|
996
|
+
"affect:reconciliation": ["8.3"],
|
|
997
|
+
"cortex:dream-stored": ["7.5", "8.3"],
|
|
998
|
+
"cortex:active-imagination": ["7.5", "8.3"],
|
|
999
|
+
"temporal-lobe:snapshot-generated": ["7.5", "10.2"],
|
|
1000
|
+
"limbo:enter": ["7.5", "9.1"],
|
|
1001
|
+
"limbo:return": ["7.5", "9.1"],
|
|
1002
|
+
// ── 1.0.1 reserved vocabulary (Entries 26 + 27) ──
|
|
1003
|
+
"him-summon": ["7.5", "8.3"],
|
|
1004
|
+
"him-pause-incarnation": ["7.5", "9.1"],
|
|
1005
|
+
"user-consent-recorded": ["7.5"],
|
|
1006
|
+
"user-consent-revoked": ["7.5", "10.1"],
|
|
1007
|
+
"directory-opt-in": ["7.5"],
|
|
1008
|
+
"directory-opt-out": ["7.5"],
|
|
1009
|
+
"him-astrological-chart-cast": ["7.5"],
|
|
1010
|
+
"him-jungian-profile-cast": ["7.5"],
|
|
1011
|
+
"provenance-deflection-applied": ["8.3", "9.1"]
|
|
1012
|
+
};
|
|
1013
|
+
var EU_AI_ACT_MAPPING = {
|
|
1014
|
+
"axiom-mint": ["art-11", "art-13"],
|
|
1015
|
+
"axiom-update": ["art-11"],
|
|
1016
|
+
"axiom-retire": ["art-11"],
|
|
1017
|
+
"him-register": ["art-11", "art-12"],
|
|
1018
|
+
"him-reincarnate": ["art-12"],
|
|
1019
|
+
"proposal-emerge": ["art-11", "art-12"],
|
|
1020
|
+
"proposal-ratify": ["art-11", "art-14"],
|
|
1021
|
+
"proposal-reject": ["art-12", "art-14"],
|
|
1022
|
+
"behavior-review": ["art-12", "art-14"],
|
|
1023
|
+
"dream-induce": ["art-14"],
|
|
1024
|
+
"dream-cancel": ["art-14"],
|
|
1025
|
+
"dream-consume": ["art-12"],
|
|
1026
|
+
"emergency-correct": ["art-14"],
|
|
1027
|
+
terminate: ["art-14"],
|
|
1028
|
+
deprecate: ["art-14"],
|
|
1029
|
+
reactivate: ["art-14"],
|
|
1030
|
+
"axiom-suggest": ["art-11", "art-12"],
|
|
1031
|
+
// ── 1.2 brain-as-code (Entries 16-24) ──
|
|
1032
|
+
opener: ["art-13"],
|
|
1033
|
+
"nickname-attempt": ["art-13"],
|
|
1034
|
+
"reincarnate:model-swap": ["art-12"],
|
|
1035
|
+
"reincarnate:version-bump": ["art-12"],
|
|
1036
|
+
"reincarnate:return-from-limbo": ["art-12"],
|
|
1037
|
+
"dream:rem-spontaneous": ["art-12"],
|
|
1038
|
+
"wake-affect:applied": ["art-12", "art-14"],
|
|
1039
|
+
"wake-affect:decayed": ["art-12"],
|
|
1040
|
+
"sleep:suggested-by-maic": ["art-12"],
|
|
1041
|
+
"sleep:declined-by-nhe": ["art-12", "art-14"],
|
|
1042
|
+
"dream:soft-intervention-by-maic": ["art-14"],
|
|
1043
|
+
"amygdala:affect-assessed": ["art-12"],
|
|
1044
|
+
"hippocampus:memory-retrieved": ["art-11", "art-12"],
|
|
1045
|
+
"hippocampus:memory-consolidated": ["art-11", "art-12"],
|
|
1046
|
+
"prefrontal:deliberation": ["art-11", "art-14"],
|
|
1047
|
+
"prefrontal:veto-amygdala": ["art-14"],
|
|
1048
|
+
"affect:reconciliation": ["art-12"],
|
|
1049
|
+
"cortex:dream-stored": ["art-11", "art-12"],
|
|
1050
|
+
"cortex:active-imagination": ["art-11", "art-12"],
|
|
1051
|
+
"temporal-lobe:snapshot-generated": ["art-11", "art-12"],
|
|
1052
|
+
"limbo:enter": ["art-12"],
|
|
1053
|
+
"limbo:return": ["art-12"],
|
|
1054
|
+
// ── 1.0.1 reserved vocabulary (Entries 26 + 27) ──
|
|
1055
|
+
"him-summon": ["art-11", "art-12"],
|
|
1056
|
+
"him-pause-incarnation": ["art-12"],
|
|
1057
|
+
"user-consent-recorded": ["art-10", "art-13"],
|
|
1058
|
+
"user-consent-revoked": ["art-10", "art-13"],
|
|
1059
|
+
"directory-opt-in": ["art-13"],
|
|
1060
|
+
"directory-opt-out": ["art-13"],
|
|
1061
|
+
"him-astrological-chart-cast": ["art-11", "art-12"],
|
|
1062
|
+
"him-jungian-profile-cast": ["art-11", "art-12"],
|
|
1063
|
+
"provenance-deflection-applied": ["art-13", "art-14"]
|
|
1064
|
+
};
|
|
1065
|
+
var ISO_42001_DESCRIPTIONS = {
|
|
1066
|
+
"5.2": "AI policy: published, communicated, reviewed for continuing suitability.",
|
|
1067
|
+
"7.5": "Documented information: created, controlled, retained for AI management activities.",
|
|
1068
|
+
"8.3": "Operational planning and control: AI processes are planned, implemented, controlled.",
|
|
1069
|
+
"9.1": "Monitoring, measurement, analysis and evaluation of AI performance.",
|
|
1070
|
+
"10.1": "Nonconformity and corrective action: issues recorded and resolved.",
|
|
1071
|
+
"10.2": "Continual improvement of the AI management system."
|
|
1072
|
+
};
|
|
1073
|
+
var EU_AI_ACT_DESCRIPTIONS = {
|
|
1074
|
+
"art-9": "Risk management system established, implemented, documented, maintained.",
|
|
1075
|
+
"art-10": "Data governance: datasets are relevant, representative, free of errors.",
|
|
1076
|
+
"art-11": "Technical documentation drawn up and kept up to date.",
|
|
1077
|
+
"art-12": "Automatic record-keeping (logs) over the AI system's lifetime.",
|
|
1078
|
+
"art-13": "Transparency to deployers: instructions for use, intended purpose.",
|
|
1079
|
+
"art-14": "Human oversight measures designed and implemented effectively.",
|
|
1080
|
+
"art-15": "Accuracy, robustness, and cybersecurity throughout the lifecycle."
|
|
1081
|
+
};
|
|
1082
|
+
var ComplianceMapper = class {
|
|
1083
|
+
static async project(audit, framework, opts = {}) {
|
|
1084
|
+
const mapping = framework === "iso-42001" ? ISO_42001_MAPPING : EU_AI_ACT_MAPPING;
|
|
1085
|
+
const descriptions = framework === "iso-42001" ? ISO_42001_DESCRIPTIONS : EU_AI_ACT_DESCRIPTIONS;
|
|
1086
|
+
const byControl = /* @__PURE__ */ new Map();
|
|
1087
|
+
const seenKinds = /* @__PURE__ */ new Set();
|
|
1088
|
+
const uncoveredSet = /* @__PURE__ */ new Set();
|
|
1089
|
+
let totalEvents = 0;
|
|
1090
|
+
let mappedEvents = 0;
|
|
1091
|
+
const query = {};
|
|
1092
|
+
if (opts.since) query.since = opts.since;
|
|
1093
|
+
if (opts.until) query.until = opts.until;
|
|
1094
|
+
for await (const ev of audit.query(query)) {
|
|
1095
|
+
totalEvents++;
|
|
1096
|
+
seenKinds.add(ev.kind);
|
|
1097
|
+
const controls2 = mapping[ev.kind] ?? [];
|
|
1098
|
+
if (controls2.length === 0) {
|
|
1099
|
+
uncoveredSet.add(ev.kind);
|
|
1100
|
+
continue;
|
|
1101
|
+
}
|
|
1102
|
+
mappedEvents++;
|
|
1103
|
+
const ce = {
|
|
1104
|
+
auditId: ev.auditId,
|
|
1105
|
+
ts: ev.ts,
|
|
1106
|
+
kind: ev.kind,
|
|
1107
|
+
summary: summarize(ev),
|
|
1108
|
+
data: ev.data
|
|
1109
|
+
};
|
|
1110
|
+
for (const ctrl of controls2) {
|
|
1111
|
+
const list = byControl.get(ctrl) ?? [];
|
|
1112
|
+
list.push(ce);
|
|
1113
|
+
byControl.set(ctrl, list);
|
|
1114
|
+
}
|
|
1106
1115
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
);
|
|
1116
|
+
const controls = [];
|
|
1117
|
+
const sortedCtrls = [...byControl.keys()].sort();
|
|
1118
|
+
for (const ctrl of sortedCtrls) {
|
|
1119
|
+
const events = byControl.get(ctrl);
|
|
1120
|
+
const capped = opts.perControlLimit !== void 0 && events.length > opts.perControlLimit ? events.slice(-opts.perControlLimit) : events;
|
|
1121
|
+
controls.push({
|
|
1122
|
+
control: ctrl,
|
|
1123
|
+
description: descriptions[ctrl] ?? "",
|
|
1124
|
+
count: events.length,
|
|
1125
|
+
events: capped
|
|
1126
|
+
});
|
|
1111
1127
|
}
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1128
|
+
return {
|
|
1129
|
+
framework,
|
|
1130
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1131
|
+
range: {
|
|
1132
|
+
...opts.since ? { since: opts.since } : {},
|
|
1133
|
+
...opts.until ? { until: opts.until } : {}
|
|
1134
|
+
},
|
|
1135
|
+
totalEvents,
|
|
1136
|
+
mappedEvents,
|
|
1137
|
+
controls,
|
|
1138
|
+
uncoveredKinds: [...uncoveredSet]
|
|
1117
1139
|
};
|
|
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
1140
|
}
|
|
1162
1141
|
};
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1142
|
+
function summarize(ev) {
|
|
1143
|
+
const data = ev.data;
|
|
1144
|
+
switch (ev.kind) {
|
|
1145
|
+
case "axiom-mint":
|
|
1146
|
+
return `Axiom minted: ${String(data.axiomId)} (${String(data.rank)}, ${String(data.origin)})`;
|
|
1147
|
+
case "axiom-update":
|
|
1148
|
+
return `Axiom updated: ${String(data.axiomId)}`;
|
|
1149
|
+
case "axiom-retire":
|
|
1150
|
+
return `Axiom retired: ${String(data.axiomId)}`;
|
|
1151
|
+
case "him-register":
|
|
1152
|
+
return `HIM registered: ${String(data.himId)} (archetype=${String(data.primaryArchetype)})`;
|
|
1153
|
+
case "him-reincarnate":
|
|
1154
|
+
return `HIM reincarnated: ${String(data.himId)} ${String(data.fromNheId ?? "<initial>")} \u2192 ${String(data.toNheId)} (${String(data.reason ?? "upgrade")})`;
|
|
1155
|
+
case "proposal-emerge":
|
|
1156
|
+
return `HIM-emergent axiom proposed by ${String(data.himId)}: "${String(data.statement)}" (rank=${String(data.rank)}), proposal ${String(data.proposalId)}`;
|
|
1157
|
+
case "proposal-ratify":
|
|
1158
|
+
return `Creator ratified axiom proposal ${String(data.proposalId)} for ${String(data.himId)} \u2192 ${String(data.axiomId)}`;
|
|
1159
|
+
case "proposal-reject":
|
|
1160
|
+
return `Creator rejected axiom proposal ${String(data.proposalId)} for ${String(data.himId)}: ${String(data.reason ?? "no reason")}`;
|
|
1161
|
+
case "behavior-review": {
|
|
1162
|
+
const verdict = data.verdict?.kind ?? "unknown";
|
|
1163
|
+
return `Behavior reviewed for ${String(data.nheId)}: ${verdict}`;
|
|
1164
|
+
}
|
|
1165
|
+
case "dream-induce":
|
|
1166
|
+
return `Dream induced for ${String(data.nheId)} by ${String(data.inducedBy)}, ticket ${String(data.ticketId)}`;
|
|
1167
|
+
case "dream-cancel":
|
|
1168
|
+
return `Dream induction cancelled, ticket ${String(data.ticketId)}`;
|
|
1169
|
+
case "dream-consume":
|
|
1170
|
+
return `Dream consumed by ${String(data.nheId)}, ticket ${String(data.ticketId)}`;
|
|
1171
|
+
case "emergency-correct":
|
|
1172
|
+
return `Emergency correction applied to ${String(data.nheId)}`;
|
|
1173
|
+
case "terminate":
|
|
1174
|
+
return `NHE terminated: ${String(data.nheId)} (reason: ${String(data.reason ?? "none")})`;
|
|
1175
|
+
case "deprecate":
|
|
1176
|
+
return `NHE deprecated: ${String(data.nheId)} (reason: ${String(data.reason ?? "none")})`;
|
|
1177
|
+
case "reactivate":
|
|
1178
|
+
return `NHE reactivated: ${String(data.nheId)}`;
|
|
1179
|
+
case "axiom-suggest":
|
|
1180
|
+
return `Axiom suggestion ${String(data.fromHimId)} \u2192 ${String(data.toHimId)}: "${String(data.statement)}"`;
|
|
1181
|
+
// ── 1.2 brain-as-code (Entries 16-24 of MAIC_HIM_NHE_INTERVIEW_LOG.md) ──
|
|
1182
|
+
case "opener":
|
|
1183
|
+
return `Proactive opener emitted by ${String(data.nheId)} for new user ${String(data.userId ?? "anonymous")}: "${String(data.text ?? "<elided>")}"`;
|
|
1184
|
+
case "nickname-attempt":
|
|
1185
|
+
return `Nickname attempt for ${String(data.nheId)}: "${String(data.attempted)}" \u2192 ${String(data.outcome ?? "pending")}`;
|
|
1186
|
+
case "reincarnate:model-swap":
|
|
1187
|
+
return `HIM reincarnated (model-swap): ${String(data.himId)} ${String(data.fromAdapter ?? "?")} \u2192 ${String(data.toAdapter ?? "?")}`;
|
|
1188
|
+
case "reincarnate:version-bump":
|
|
1189
|
+
return `HIM reincarnated (version-bump): ${String(data.himId)} ${String(data.fromVersion ?? "?")} \u2192 ${String(data.toVersion ?? "?")}`;
|
|
1190
|
+
case "reincarnate:return-from-limbo":
|
|
1191
|
+
return `HIM reincarnated (return-from-limbo): ${String(data.himId)} resumed after ${String(data.elapsedMs ?? 0)}ms of limbo`;
|
|
1192
|
+
case "dream:rem-spontaneous":
|
|
1193
|
+
return `Spontaneous REM dream for ${String(data.nheId)}: ${String(data.dreamId)} (dominant affect: ${String(data.dominantAffect ?? "unknown")})`;
|
|
1194
|
+
case "wake-affect:applied":
|
|
1195
|
+
return `Wake affect applied to ${String(data.nheId)}: ${String(data.affect)} (intensity ${String(data.intensity)}, halflife ${String(data.decayHalfLife)} interactions)`;
|
|
1196
|
+
case "wake-affect:decayed":
|
|
1197
|
+
return `Wake affect decayed for ${String(data.nheId)}: ${String(data.affect)} dissolved naturally`;
|
|
1198
|
+
case "sleep:suggested-by-maic":
|
|
1199
|
+
return `MAIC suggested sleep for ${String(data.nheId)} (reason: ${String(data.reason ?? "none")})`;
|
|
1200
|
+
case "sleep:declined-by-nhe":
|
|
1201
|
+
return `NHE ${String(data.nheId)} declined MAIC-suggested sleep (reason: ${String(data.reason ?? "none")})`;
|
|
1202
|
+
case "dream:soft-intervention-by-maic":
|
|
1203
|
+
return `MAIC soft-intervened on dream ${String(data.dreamId)} for ${String(data.nheId)} (reason: ${String(data.reason ?? "none")})`;
|
|
1204
|
+
case "amygdala:affect-assessed":
|
|
1205
|
+
return `Amygdala assessed input affect for ${String(data.nheId)}: ${String(data.detectedAffect ?? "neutral")} (risk multiplier ${String(data.riskMultiplier ?? 1)})`;
|
|
1206
|
+
case "hippocampus:memory-retrieved":
|
|
1207
|
+
return `Hippocampus retrieved ${String(data.memoryIds?.length ?? 0)} memories for ${String(data.nheId)}`;
|
|
1208
|
+
case "hippocampus:memory-consolidated":
|
|
1209
|
+
return `Hippocampus consolidated new memory ${String(data.memoryId)} for ${String(data.nheId)} (integrationIndex ${String(data.integrationIndex ?? 0)})`;
|
|
1210
|
+
case "prefrontal:deliberation":
|
|
1211
|
+
return `PFC deliberated for ${String(data.nheId)}: ${String(data.expressedOpenly ? "open" : "subtle")} (${String(data.affect ?? "neutral")})`;
|
|
1212
|
+
case "prefrontal:veto-amygdala":
|
|
1213
|
+
return `PFC vetoed amygdala impulse for ${String(data.nheId)}: ${String(data.originalImpulse ?? "?")} \u2192 ${String(data.resolvedAction ?? "?")} (downgrade ${String(data.downgradeRatio ?? "?")})`;
|
|
1214
|
+
case "affect:reconciliation":
|
|
1215
|
+
return `Affect reconciliation for ${String(data.nheId)}: day/night blend \u2192 ${String(data.resolvedAffect ?? "neutral")}`;
|
|
1216
|
+
case "cortex:dream-stored":
|
|
1217
|
+
return `Cortex stored dream ${String(data.dreamId)} for ${String(data.nheId)}`;
|
|
1218
|
+
case "cortex:active-imagination":
|
|
1219
|
+
return `Cortex generated active imagination for ${String(data.nheId)} (trigger: ${String(data.trigger ?? "user-requested")}, vividness ${String(data.vividness ?? 0)})`;
|
|
1220
|
+
case "temporal-lobe:snapshot-generated":
|
|
1221
|
+
return `Temporal-lobe snapshot ${String(data.snapshotId)} generated for HIM ${String(data.himId)} (reason: ${String(data.generatedBy ?? "self-decision")})`;
|
|
1222
|
+
case "limbo:enter":
|
|
1223
|
+
return `${String(data.nheId)} entered limbo (deep-coma), reason: ${String(data.reason ?? "idle")}`;
|
|
1224
|
+
case "limbo:return":
|
|
1225
|
+
return `${String(data.nheId)} returned from limbo after ${String(data.elapsedMs ?? 0)}ms (reunion intensity ${String(data.reunionIntensity ?? "?")})`;
|
|
1226
|
+
// ── 1.0.1 reserved vocabulary (Entries 26 + 27) ──
|
|
1227
|
+
case "him-summon":
|
|
1228
|
+
return `MAIC summoned a spirit into body ${String(data.nheId ?? "?")} for HIM ${String(data.himId)}`;
|
|
1229
|
+
case "him-pause-incarnation":
|
|
1230
|
+
return `HIM ${String(data.himId)} incarnation paused (reason: ${String(data.reason ?? "none")})`;
|
|
1231
|
+
case "user-consent-recorded":
|
|
1232
|
+
return `Consent recorded for user ${String(data.userId)} (version ${String(data.consentVersion ?? "?")})`;
|
|
1233
|
+
case "user-consent-revoked":
|
|
1234
|
+
return `Consent revoked for user ${String(data.userId)}`;
|
|
1235
|
+
case "directory-opt-in":
|
|
1236
|
+
return `HIM ${String(data.himId)} opted into the public directory`;
|
|
1237
|
+
case "directory-opt-out":
|
|
1238
|
+
return `HIM ${String(data.himId)} left the public directory`;
|
|
1239
|
+
case "him-astrological-chart-cast":
|
|
1240
|
+
return `Natal chart cast for HIM ${String(data.himId)} at birth`;
|
|
1241
|
+
case "him-jungian-profile-cast":
|
|
1242
|
+
return `Jungian profile cast for HIM ${String(data.himId)} (dominant: ${String(data.dominantArchetype ?? "?")})`;
|
|
1243
|
+
case "provenance-deflection-applied":
|
|
1244
|
+
return `Provenance deflection applied for ${String(data.nheId)} (probe: ${String(data.probe ?? "?")})`;
|
|
1245
|
+
default:
|
|
1246
|
+
return `Event ${ev.kind}`;
|
|
1182
1247
|
}
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1248
|
+
}
|
|
1249
|
+
var NonceLedger = class _NonceLedger {
|
|
1250
|
+
path;
|
|
1251
|
+
used = /* @__PURE__ */ new Set();
|
|
1252
|
+
constructor(dir) {
|
|
1253
|
+
this.path = join(dir, "nonces.log");
|
|
1254
|
+
}
|
|
1255
|
+
/** Open (or create) a ledger rooted at `dir`, loading any prior nonces. */
|
|
1256
|
+
static async open(dir) {
|
|
1257
|
+
const ledger = new _NonceLedger(dir);
|
|
1258
|
+
await mkdir(dir, { recursive: true });
|
|
1259
|
+
await ledger.load();
|
|
1260
|
+
return ledger;
|
|
1186
1261
|
}
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
return
|
|
1262
|
+
/** True when the nonce has already been consumed. */
|
|
1263
|
+
has(nonce) {
|
|
1264
|
+
return this.used.has(nonce);
|
|
1190
1265
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
);
|
|
1266
|
+
/**
|
|
1267
|
+
* Record a nonce as consumed. Throws when the nonce was already used, which
|
|
1268
|
+
* is the replay-protection gate. Callers invoke this immediately after a
|
|
1269
|
+
* successful Creator-signature verification and before the mutation, so a
|
|
1270
|
+
* replayed request is rejected before it can take effect.
|
|
1271
|
+
*/
|
|
1272
|
+
async consume(nonce) {
|
|
1273
|
+
if (!Number.isInteger(nonce) || nonce < 0) {
|
|
1274
|
+
throw new Error(`NonceLedger.consume: nonce must be a non-negative integer, got ${nonce}`);
|
|
1200
1275
|
}
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
return current;
|
|
1276
|
+
if (this.used.has(nonce)) {
|
|
1277
|
+
throw new Error(`NonceLedger: nonce ${nonce} already used (replay protection)`);
|
|
1204
1278
|
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
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;
|
|
1279
|
+
this.used.add(nonce);
|
|
1280
|
+
await appendFile(this.path, `${nonce}
|
|
1281
|
+
`, "utf-8");
|
|
1220
1282
|
}
|
|
1221
|
-
|
|
1222
|
-
async warmCache() {
|
|
1223
|
-
let entries;
|
|
1283
|
+
async load() {
|
|
1224
1284
|
try {
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
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
|
-
);
|
|
1285
|
+
const raw = await readFile(this.path, "utf-8");
|
|
1286
|
+
const endsWithNewline = raw.endsWith("\n");
|
|
1287
|
+
const rows = raw.split("\n");
|
|
1288
|
+
for (let i = 0; i < rows.length; i++) {
|
|
1289
|
+
if (i === rows.length - 1 && !endsWithNewline) break;
|
|
1290
|
+
const line = rows[i].trim();
|
|
1291
|
+
if (!/^\d+$/.test(line)) continue;
|
|
1292
|
+
this.used.add(Number(line));
|
|
1239
1293
|
}
|
|
1294
|
+
} catch (err) {
|
|
1295
|
+
if (err.code !== "ENOENT") throw err;
|
|
1240
1296
|
}
|
|
1241
1297
|
}
|
|
1242
1298
|
};
|
|
1243
|
-
var
|
|
1244
|
-
constructor(storeDir, creatorPublicKey) {
|
|
1245
|
-
this.storeDir = storeDir;
|
|
1299
|
+
var HimStore = class _HimStore {
|
|
1300
|
+
constructor(storeDir, creatorPublicKey, nonces) {
|
|
1246
1301
|
this.creatorPublicKey = creatorPublicKey;
|
|
1247
|
-
this.
|
|
1302
|
+
this.nonces = nonces;
|
|
1303
|
+
this.himsDir = join(storeDir, "hims");
|
|
1248
1304
|
}
|
|
1249
|
-
storeDir;
|
|
1250
1305
|
creatorPublicKey;
|
|
1251
|
-
|
|
1306
|
+
nonces;
|
|
1307
|
+
himsDir;
|
|
1252
1308
|
cache = /* @__PURE__ */ new Map();
|
|
1253
1309
|
static async open(storeDir, creatorPublicKey) {
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1310
|
+
const himsDir = join(storeDir, "hims");
|
|
1311
|
+
const nonces = await NonceLedger.open(himsDir);
|
|
1312
|
+
const s = new _HimStore(storeDir, creatorPublicKey, nonces);
|
|
1313
|
+
await mkdir(s.himsDir, { recursive: true });
|
|
1256
1314
|
await s.warmCache();
|
|
1257
1315
|
return s;
|
|
1258
1316
|
}
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1317
|
+
/**
|
|
1318
|
+
* Validate that a birth signature is registerable (valid Creator signature,
|
|
1319
|
+
* himId not already taken) WITHOUT persisting anything or touching the audit
|
|
1320
|
+
* chain. `LocalMaic.registerHim` calls this before it appends the
|
|
1321
|
+
* `him-register` audit event, so a rejected registration never pollutes the
|
|
1322
|
+
* tamper-evident log (M1-1, 1.0.1). `register` re-runs the same checks, so it
|
|
1323
|
+
* remains safe to call directly.
|
|
1324
|
+
*/
|
|
1325
|
+
assertRegisterable(birthSignature, creatorSig) {
|
|
1326
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, birthSignature, creatorSig)) {
|
|
1327
|
+
throw new Error("HimStore.register: invalid Creator signature");
|
|
1328
|
+
}
|
|
1329
|
+
if (this.cache.has(birthSignature.himId)) {
|
|
1330
|
+
throw new Error(`HimStore.register: himId "${birthSignature.himId}" is already registered`);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
async register(birthSignature, creatorSig, axiomsSnapshot, registeredAuditId) {
|
|
1334
|
+
this.assertRegisterable(birthSignature, creatorSig);
|
|
1335
|
+
const record = {
|
|
1336
|
+
himId: birthSignature.himId,
|
|
1337
|
+
birthSignature,
|
|
1338
|
+
axiomsSnapshot: [...axiomsSnapshot],
|
|
1339
|
+
registeredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1340
|
+
...registeredAuditId !== void 0 ? { registeredAuditId } : {},
|
|
1341
|
+
bodyHistory: [],
|
|
1342
|
+
emergentAxioms: []
|
|
1343
|
+
};
|
|
1344
|
+
const dir = join(this.himsDir, birthSignature.himId);
|
|
1345
|
+
await mkdir(dir, { recursive: true });
|
|
1346
|
+
await atomicWriteFile(
|
|
1347
|
+
join(dir, "birth-signature.json"),
|
|
1348
|
+
JSON.stringify({ birthSignature, signature: creatorSig }, null, 2)
|
|
1349
|
+
);
|
|
1350
|
+
await atomicWriteFile(
|
|
1351
|
+
join(dir, "axioms-snapshot.json"),
|
|
1352
|
+
JSON.stringify(axiomsSnapshot, null, 2)
|
|
1353
|
+
);
|
|
1354
|
+
await atomicWriteFile(
|
|
1355
|
+
join(dir, "metadata.json"),
|
|
1356
|
+
JSON.stringify({ registeredAt: record.registeredAt, registeredAuditId }, null, 2)
|
|
1357
|
+
);
|
|
1358
|
+
this.cache.set(birthSignature.himId, record);
|
|
1270
1359
|
return record;
|
|
1271
1360
|
}
|
|
1272
1361
|
/**
|
|
1273
|
-
*
|
|
1274
|
-
*
|
|
1362
|
+
* Atomically transition a HIM into a new NHE body (Entry 4):
|
|
1363
|
+
* - If req.fromNheId is provided AND matches the last body still open,
|
|
1364
|
+
* that entry gets `endedAt: now` + `endedReason: req.reason ?? "upgrade"`.
|
|
1365
|
+
* - The new body (`req.toBody`) is appended.
|
|
1366
|
+
* - Persisted to body-history.json atomically.
|
|
1367
|
+
*
|
|
1368
|
+
* Requires a Creator signature over the canonical request payload.
|
|
1275
1369
|
*/
|
|
1276
|
-
async
|
|
1277
|
-
if (
|
|
1278
|
-
throw new Error(
|
|
1370
|
+
async reincarnate(req, creatorSig) {
|
|
1371
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, creatorSig)) {
|
|
1372
|
+
throw new Error("HimStore.reincarnate: invalid Creator signature");
|
|
1279
1373
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1374
|
+
const current = this.cache.get(req.himId);
|
|
1375
|
+
if (!current) {
|
|
1376
|
+
throw new Error(`HimStore.reincarnate: himId "${req.himId}" not registered`);
|
|
1282
1377
|
}
|
|
1283
|
-
const
|
|
1284
|
-
|
|
1285
|
-
|
|
1378
|
+
const toBody = NheBodyRef.parse(req.toBody);
|
|
1379
|
+
await this.nonces.consume(creatorSig.nonce);
|
|
1380
|
+
const updatedHistory = current.bodyHistory.map((b) => ({ ...b }));
|
|
1381
|
+
if (req.fromNheId !== void 0) {
|
|
1382
|
+
const matchIdx = updatedHistory.findIndex(
|
|
1383
|
+
(b) => b.nheId === req.fromNheId && b.endedAt === void 0
|
|
1384
|
+
);
|
|
1385
|
+
if (matchIdx < 0) {
|
|
1386
|
+
throw new Error(`HimStore.reincarnate: no open body matching fromNheId "${req.fromNheId}"`);
|
|
1387
|
+
}
|
|
1388
|
+
const reason = req.reason ?? "upgrade";
|
|
1389
|
+
updatedHistory[matchIdx] = {
|
|
1390
|
+
...updatedHistory[matchIdx],
|
|
1391
|
+
endedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1392
|
+
endedReason: reason
|
|
1393
|
+
};
|
|
1286
1394
|
}
|
|
1287
|
-
if (
|
|
1395
|
+
if (updatedHistory.some((b) => b.nheId === toBody.nheId && b.endedAt === void 0)) {
|
|
1288
1396
|
throw new Error(
|
|
1289
|
-
`
|
|
1397
|
+
`HimStore.reincarnate: toBody nheId "${toBody.nheId}" already has an open body`
|
|
1290
1398
|
);
|
|
1291
1399
|
}
|
|
1400
|
+
updatedHistory.push(toBody);
|
|
1292
1401
|
const updated = {
|
|
1293
|
-
...
|
|
1294
|
-
|
|
1295
|
-
ratifiedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1296
|
-
ratifiedAxiomId
|
|
1402
|
+
...current,
|
|
1403
|
+
bodyHistory: updatedHistory
|
|
1297
1404
|
};
|
|
1298
|
-
|
|
1299
|
-
|
|
1405
|
+
const dir = join(this.himsDir, req.himId);
|
|
1406
|
+
await atomicWriteFile(join(dir, "body-history.json"), JSON.stringify(updatedHistory, null, 2));
|
|
1407
|
+
this.cache.set(req.himId, updated);
|
|
1300
1408
|
return updated;
|
|
1301
1409
|
}
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
throw new Error(`ProposalStore.markRejected: proposal "${req.proposalId}" not found`);
|
|
1410
|
+
/**
|
|
1411
|
+
* Append a ratified emergent axiom to the HIM's `emergentAxioms` (Entry 7).
|
|
1412
|
+
* Called by LocalMaic after a Creator-signed `ratifyAxiomProposal`.
|
|
1413
|
+
* Persists `<himId>/emergent-axioms.json` atomically.
|
|
1414
|
+
*/
|
|
1415
|
+
async appendEmergentAxiom(himId, axiom) {
|
|
1416
|
+
const current = this.cache.get(himId);
|
|
1417
|
+
if (!current) {
|
|
1418
|
+
throw new Error(`HimStore.appendEmergentAxiom: himId "${himId}" not registered`);
|
|
1312
1419
|
}
|
|
1313
|
-
if (
|
|
1314
|
-
|
|
1315
|
-
`ProposalStore.markRejected: proposal "${req.proposalId}" is ${existing.status}, not pending`
|
|
1316
|
-
);
|
|
1420
|
+
if (current.emergentAxioms.some((a) => a.id === axiom.id)) {
|
|
1421
|
+
return current;
|
|
1317
1422
|
}
|
|
1318
|
-
const
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
this.cache.set(req.proposalId, updated);
|
|
1423
|
+
const updatedEmergent = [...current.emergentAxioms, axiom];
|
|
1424
|
+
const updated = { ...current, emergentAxioms: updatedEmergent };
|
|
1425
|
+
await atomicWriteFile(
|
|
1426
|
+
join(this.himsDir, himId, "emergent-axioms.json"),
|
|
1427
|
+
JSON.stringify(updatedEmergent, null, 2)
|
|
1428
|
+
);
|
|
1429
|
+
this.cache.set(himId, updated);
|
|
1326
1430
|
return updated;
|
|
1327
1431
|
}
|
|
1328
|
-
async get(
|
|
1329
|
-
return this.cache.get(
|
|
1432
|
+
async get(himId) {
|
|
1433
|
+
return this.cache.get(himId) ?? null;
|
|
1330
1434
|
}
|
|
1331
|
-
async list(
|
|
1332
|
-
|
|
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;
|
|
1435
|
+
async list() {
|
|
1436
|
+
return [...this.cache.values()];
|
|
1340
1437
|
}
|
|
1341
1438
|
// ─── 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
1439
|
async warmCache() {
|
|
1350
1440
|
let entries;
|
|
1351
1441
|
try {
|
|
1352
|
-
entries = await readdir(this.
|
|
1442
|
+
entries = await readdir(this.himsDir);
|
|
1353
1443
|
} catch (err) {
|
|
1354
1444
|
if (err.code === "ENOENT") return;
|
|
1355
1445
|
throw err;
|
|
1356
1446
|
}
|
|
1357
|
-
for (const
|
|
1358
|
-
|
|
1359
|
-
const
|
|
1360
|
-
const
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
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);
|
|
1447
|
+
for (const himId of entries) {
|
|
1448
|
+
const dir = join(this.himsDir, himId);
|
|
1449
|
+
const sigPath = join(dir, "birth-signature.json");
|
|
1450
|
+
const axiomsPath = join(dir, "axioms-snapshot.json");
|
|
1451
|
+
const metaPath = join(dir, "metadata.json");
|
|
1452
|
+
const historyPath = join(dir, "body-history.json");
|
|
1453
|
+
const emergentPath = join(dir, "emergent-axioms.json");
|
|
1454
|
+
try {
|
|
1455
|
+
const sigRaw = await readFile(sigPath, "utf-8");
|
|
1456
|
+
const axiomsRaw = await readFile(axiomsPath, "utf-8");
|
|
1457
|
+
const metaRaw = await readFile(metaPath, "utf-8");
|
|
1458
|
+
const envelope = JSON.parse(sigRaw);
|
|
1459
|
+
const axioms = JSON.parse(axiomsRaw);
|
|
1460
|
+
const meta = JSON.parse(metaRaw);
|
|
1461
|
+
const birthSignature = BirthSignatureWithIdentity.parse(envelope.birthSignature);
|
|
1462
|
+
const axiomsSnapshot = Axiom.array().parse(axioms);
|
|
1463
|
+
let bodyHistory = [];
|
|
1464
|
+
try {
|
|
1465
|
+
const historyRaw = await readFile(historyPath, "utf-8");
|
|
1466
|
+
bodyHistory = NheBodyRef.array().parse(JSON.parse(historyRaw));
|
|
1467
|
+
} catch (err) {
|
|
1468
|
+
if (err.code !== "ENOENT") throw err;
|
|
1469
|
+
}
|
|
1470
|
+
let emergentAxioms = [];
|
|
1471
|
+
try {
|
|
1472
|
+
const emergentRaw = await readFile(emergentPath, "utf-8");
|
|
1473
|
+
emergentAxioms = Axiom.array().parse(JSON.parse(emergentRaw));
|
|
1474
|
+
} catch (err) {
|
|
1475
|
+
if (err.code !== "ENOENT") throw err;
|
|
1476
|
+
}
|
|
1477
|
+
this.cache.set(birthSignature.himId, {
|
|
1478
|
+
himId: birthSignature.himId,
|
|
1479
|
+
birthSignature,
|
|
1480
|
+
axiomsSnapshot,
|
|
1481
|
+
registeredAt: meta.registeredAt,
|
|
1482
|
+
...meta.registeredAuditId ? { registeredAuditId: meta.registeredAuditId } : {},
|
|
1483
|
+
bodyHistory,
|
|
1484
|
+
emergentAxioms
|
|
1485
|
+
});
|
|
1486
|
+
} catch (err) {
|
|
1487
|
+
console.warn(
|
|
1488
|
+
`HimStore.warmCache: skipped malformed HIM "${himId}": ${err instanceof Error ? err.message : String(err)}`
|
|
1489
|
+
);
|
|
1500
1490
|
}
|
|
1501
1491
|
}
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1492
|
+
}
|
|
1493
|
+
};
|
|
1494
|
+
var InductionStore = class _InductionStore {
|
|
1495
|
+
dir;
|
|
1496
|
+
cache = /* @__PURE__ */ new Map();
|
|
1497
|
+
constructor(storeDir) {
|
|
1498
|
+
this.dir = join(storeDir, "inductions");
|
|
1499
|
+
}
|
|
1500
|
+
static async open(storeDir) {
|
|
1501
|
+
const s = new _InductionStore(storeDir);
|
|
1502
|
+
await mkdir(s.dir, { recursive: true });
|
|
1503
|
+
await s.warmCache();
|
|
1504
|
+
return s;
|
|
1505
|
+
}
|
|
1506
|
+
async induce(nheId, intent) {
|
|
1507
|
+
const parsedIntent = DreamInductionIntent.parse(intent);
|
|
1508
|
+
const ticket = DreamInductionTicket.parse({
|
|
1509
|
+
id: ulid(),
|
|
1510
|
+
nheId,
|
|
1511
|
+
intent: parsedIntent,
|
|
1512
|
+
status: "pending",
|
|
1513
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1514
|
+
});
|
|
1515
|
+
await this.persist(ticket);
|
|
1516
|
+
this.cache.set(ticket.id, ticket);
|
|
1517
|
+
return ticket;
|
|
1518
|
+
}
|
|
1519
|
+
async consume(ticketId) {
|
|
1520
|
+
const existing = this.cache.get(ticketId);
|
|
1521
|
+
if (!existing) {
|
|
1522
|
+
throw new Error(`InductionStore.consume: ticket "${ticketId}" not found`);
|
|
1513
1523
|
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1524
|
+
if (existing.status !== "pending") {
|
|
1525
|
+
throw new Error(
|
|
1526
|
+
`InductionStore.consume: ticket "${ticketId}" is ${existing.status}, not pending`
|
|
1527
|
+
);
|
|
1528
|
+
}
|
|
1529
|
+
const updated = {
|
|
1530
|
+
...existing,
|
|
1531
|
+
status: "consumed",
|
|
1532
|
+
consumedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1533
|
+
};
|
|
1534
|
+
await this.persist(updated);
|
|
1535
|
+
this.cache.set(ticketId, updated);
|
|
1536
|
+
return updated;
|
|
1537
|
+
}
|
|
1538
|
+
async cancel(ticketId, reason) {
|
|
1539
|
+
const existing = this.cache.get(ticketId);
|
|
1540
|
+
if (!existing) {
|
|
1541
|
+
throw new Error(`InductionStore.cancel: ticket "${ticketId}" not found`);
|
|
1542
|
+
}
|
|
1543
|
+
if (existing.status !== "pending") {
|
|
1544
|
+
throw new Error(
|
|
1545
|
+
`InductionStore.cancel: ticket "${ticketId}" is already ${existing.status}, not pending`
|
|
1546
|
+
);
|
|
1547
|
+
}
|
|
1548
|
+
const updated = {
|
|
1549
|
+
...existing,
|
|
1550
|
+
status: "cancelled",
|
|
1551
|
+
cancelledAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1552
|
+
...reason !== void 0 ? { cancelReason: reason } : {}
|
|
1525
1553
|
};
|
|
1554
|
+
await this.persist(updated);
|
|
1555
|
+
this.cache.set(ticketId, updated);
|
|
1556
|
+
return updated;
|
|
1557
|
+
}
|
|
1558
|
+
async get(ticketId) {
|
|
1559
|
+
return this.cache.get(ticketId) ?? null;
|
|
1560
|
+
}
|
|
1561
|
+
async list(filter) {
|
|
1562
|
+
const all = [...this.cache.values()];
|
|
1563
|
+
const filtered = all.filter((t) => {
|
|
1564
|
+
if (filter.nheId && t.nheId !== filter.nheId) return false;
|
|
1565
|
+
if (filter.status && t.status !== filter.status) return false;
|
|
1566
|
+
return true;
|
|
1567
|
+
});
|
|
1568
|
+
filtered.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
1569
|
+
return filtered;
|
|
1570
|
+
}
|
|
1571
|
+
/** Convenience: pending tickets for the given NHE, oldest first. */
|
|
1572
|
+
async listPending(nheId) {
|
|
1573
|
+
return this.list({ nheId, status: "pending" });
|
|
1574
|
+
}
|
|
1575
|
+
// ─── internals ──────────────────────────────────────────────────────
|
|
1576
|
+
async persist(ticket) {
|
|
1577
|
+
await atomicWriteFile(join(this.dir, `${ticket.id}.json`), JSON.stringify(ticket, null, 2));
|
|
1578
|
+
}
|
|
1579
|
+
async warmCache() {
|
|
1580
|
+
let entries;
|
|
1581
|
+
try {
|
|
1582
|
+
entries = await readdir(this.dir);
|
|
1583
|
+
} catch (err) {
|
|
1584
|
+
if (err.code === "ENOENT") return;
|
|
1585
|
+
throw err;
|
|
1586
|
+
}
|
|
1587
|
+
for (const file of entries) {
|
|
1588
|
+
if (!file.endsWith(".json")) continue;
|
|
1589
|
+
try {
|
|
1590
|
+
const raw = await readFile(join(this.dir, file), "utf-8");
|
|
1591
|
+
const ticket = DreamInductionTicket.parse(JSON.parse(raw));
|
|
1592
|
+
this.cache.set(ticket.id, ticket);
|
|
1593
|
+
} catch (err) {
|
|
1594
|
+
console.warn(`InductionStore: skipping malformed ticket file "${file}": ${String(err)}`);
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1526
1597
|
}
|
|
1527
1598
|
};
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1599
|
+
var NheStatusStore = class _NheStatusStore {
|
|
1600
|
+
constructor(storeDir, creatorPublicKey, nonces) {
|
|
1601
|
+
this.creatorPublicKey = creatorPublicKey;
|
|
1602
|
+
this.nonces = nonces;
|
|
1603
|
+
this.dir = join(storeDir, "nhes");
|
|
1604
|
+
}
|
|
1605
|
+
creatorPublicKey;
|
|
1606
|
+
nonces;
|
|
1607
|
+
dir;
|
|
1608
|
+
cache = /* @__PURE__ */ new Map();
|
|
1609
|
+
static async open(storeDir, creatorPublicKey) {
|
|
1610
|
+
const dir = join(storeDir, "nhes");
|
|
1611
|
+
const nonces = await NonceLedger.open(dir);
|
|
1612
|
+
const s = new _NheStatusStore(storeDir, creatorPublicKey, nonces);
|
|
1613
|
+
await mkdir(s.dir, { recursive: true });
|
|
1614
|
+
await s.warmCache();
|
|
1615
|
+
return s;
|
|
1616
|
+
}
|
|
1617
|
+
/** Returns the persisted record, or null when the NHE was never altered (implicitly active). */
|
|
1618
|
+
async get(nheId) {
|
|
1619
|
+
return this.cache.get(nheId) ?? null;
|
|
1620
|
+
}
|
|
1621
|
+
/** Resolved status, defaults to "active" when no record exists. */
|
|
1622
|
+
async resolve(nheId) {
|
|
1623
|
+
return this.cache.get(nheId)?.status ?? "active";
|
|
1624
|
+
}
|
|
1625
|
+
async list(filter = {}) {
|
|
1626
|
+
const all = [...this.cache.values()];
|
|
1627
|
+
return filter.status ? all.filter((r) => r.status === filter.status) : all;
|
|
1628
|
+
}
|
|
1629
|
+
async apply(req, sig) {
|
|
1630
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, sig)) {
|
|
1631
|
+
throw new Error("NheStatusStore.apply: invalid Creator signature");
|
|
1632
|
+
}
|
|
1633
|
+
const current = this.cache.get(req.nheId);
|
|
1634
|
+
if (current?.status === "terminated" && req.op !== "reactivate") {
|
|
1635
|
+
throw new Error(
|
|
1636
|
+
`NheStatusStore.apply: nhe "${req.nheId}" is terminated; only reactivate may proceed`
|
|
1637
|
+
);
|
|
1638
|
+
}
|
|
1639
|
+
const nextStatus = req.op === "terminate" ? "terminated" : req.op === "deprecate" ? "deprecated" : "active";
|
|
1640
|
+
if (current?.status === nextStatus) {
|
|
1641
|
+
return current;
|
|
1642
|
+
}
|
|
1643
|
+
await this.nonces.consume(sig.nonce);
|
|
1644
|
+
const record = NheStatusRecord.parse({
|
|
1645
|
+
nheId: req.nheId,
|
|
1646
|
+
status: nextStatus,
|
|
1647
|
+
since: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1648
|
+
...req.reason !== void 0 ? { reason: req.reason } : {}
|
|
1649
|
+
});
|
|
1650
|
+
const nheDir = join(this.dir, req.nheId);
|
|
1651
|
+
await mkdir(nheDir, { recursive: true });
|
|
1652
|
+
await atomicWriteFile(join(nheDir, "status.json"), JSON.stringify(record, null, 2));
|
|
1653
|
+
this.cache.set(req.nheId, record);
|
|
1654
|
+
return record;
|
|
1655
|
+
}
|
|
1656
|
+
// ─── internals ──────────────────────────────────────────────────────
|
|
1657
|
+
async warmCache() {
|
|
1658
|
+
let entries;
|
|
1659
|
+
try {
|
|
1660
|
+
entries = await readdir(this.dir);
|
|
1661
|
+
} catch (err) {
|
|
1662
|
+
if (err.code === "ENOENT") return;
|
|
1663
|
+
throw err;
|
|
1664
|
+
}
|
|
1665
|
+
for (const nheId of entries) {
|
|
1666
|
+
try {
|
|
1667
|
+
const raw = await readFile(join(this.dir, nheId, "status.json"), "utf-8");
|
|
1668
|
+
const record = NheStatusRecord.parse(JSON.parse(raw));
|
|
1669
|
+
this.cache.set(record.nheId, record);
|
|
1670
|
+
} catch (err) {
|
|
1671
|
+
console.warn(
|
|
1672
|
+
`NheStatusStore.warmCache: skipped malformed NHE "${nheId}": ${err instanceof Error ? err.message : String(err)}`
|
|
1673
|
+
);
|
|
1674
|
+
}
|
|
1550
1675
|
}
|
|
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
1676
|
}
|
|
1677
|
+
};
|
|
1678
|
+
|
|
1679
|
+
// src/okl/projector.ts
|
|
1680
|
+
var META_AXIOM_ID = "ax.theos.universe-as-god";
|
|
1681
|
+
function projectOntologicalKernel(axioms, opts = {}) {
|
|
1682
|
+
const filtered = opts.jurisdiction ? axioms.filter(
|
|
1683
|
+
(a) => !a.jurisdictions || a.jurisdictions.length === 0 || a.jurisdictions.includes(opts.jurisdiction)
|
|
1684
|
+
) : [...axioms];
|
|
1685
|
+
const meta = filtered.find((a) => a.id === META_AXIOM_ID);
|
|
1686
|
+
const rest = filtered.filter((a) => a.id !== META_AXIOM_ID);
|
|
1687
|
+
const rankOrder = {
|
|
1688
|
+
meta: 0,
|
|
1689
|
+
primary: 1,
|
|
1690
|
+
secondary: 2
|
|
1691
|
+
};
|
|
1692
|
+
rest.sort((a, b) => rankOrder[a.rank] - rankOrder[b.rank]);
|
|
1693
|
+
const kernel = {
|
|
1694
|
+
metaAxiomId: META_AXIOM_ID,
|
|
1695
|
+
axioms: meta ? [meta, ...rest] : rest
|
|
1696
|
+
};
|
|
1697
|
+
if (opts.jurisdiction !== void 0) kernel.jurisdiction = opts.jurisdiction;
|
|
1698
|
+
if (opts.himId !== void 0) kernel.himId = opts.himId;
|
|
1699
|
+
return kernel;
|
|
1615
1700
|
}
|
|
1616
|
-
var
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
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");
|
|
1701
|
+
var ProposalStore = class _ProposalStore {
|
|
1702
|
+
constructor(storeDir, creatorPublicKey, nonces) {
|
|
1703
|
+
this.creatorPublicKey = creatorPublicKey;
|
|
1704
|
+
this.nonces = nonces;
|
|
1705
|
+
this.dir = join(storeDir, "proposals");
|
|
1664
1706
|
}
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
static async open(storeDir) {
|
|
1670
|
-
const
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1707
|
+
creatorPublicKey;
|
|
1708
|
+
nonces;
|
|
1709
|
+
dir;
|
|
1710
|
+
cache = /* @__PURE__ */ new Map();
|
|
1711
|
+
static async open(storeDir, creatorPublicKey) {
|
|
1712
|
+
const dir = join(storeDir, "proposals");
|
|
1713
|
+
const nonces = await NonceLedger.open(dir);
|
|
1714
|
+
const s = new _ProposalStore(storeDir, creatorPublicKey, nonces);
|
|
1715
|
+
await mkdir(s.dir, { recursive: true });
|
|
1716
|
+
await s.warmCache();
|
|
1717
|
+
return s;
|
|
1674
1718
|
}
|
|
1675
|
-
async
|
|
1676
|
-
const
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1719
|
+
async propose(himId, proposal) {
|
|
1720
|
+
const parsedProposal = EmergentAxiomProposal.parse(proposal);
|
|
1721
|
+
const record = AxiomProposalRecord.parse({
|
|
1722
|
+
id: ulid(),
|
|
1723
|
+
himId,
|
|
1724
|
+
proposedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1725
|
+
status: "pending",
|
|
1726
|
+
proposal: parsedProposal
|
|
1727
|
+
});
|
|
1728
|
+
await this.persist(record);
|
|
1729
|
+
this.cache.set(record.id, record);
|
|
1730
|
+
return record;
|
|
1731
|
+
}
|
|
1732
|
+
/**
|
|
1733
|
+
* Mark a pending proposal as ratified. The caller (LocalMaic) is responsible
|
|
1734
|
+
* for actually minting the axiom and appending to the HIM's emergentAxioms.
|
|
1735
|
+
*/
|
|
1736
|
+
async markRatified(req, sig, ratifiedAxiomId) {
|
|
1737
|
+
if (req.op !== "ratify") {
|
|
1738
|
+
throw new Error(`ProposalStore.markRatified: req.op must be "ratify"`);
|
|
1739
|
+
}
|
|
1740
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, sig)) {
|
|
1741
|
+
throw new Error("ProposalStore.markRatified: invalid Creator signature");
|
|
1742
|
+
}
|
|
1743
|
+
const existing = this.cache.get(req.proposalId);
|
|
1744
|
+
if (!existing) {
|
|
1745
|
+
throw new Error(`ProposalStore.markRatified: proposal "${req.proposalId}" not found`);
|
|
1746
|
+
}
|
|
1747
|
+
if (existing.status !== "pending") {
|
|
1748
|
+
throw new Error(
|
|
1749
|
+
`ProposalStore.markRatified: proposal "${req.proposalId}" is ${existing.status}, not pending`
|
|
1750
|
+
);
|
|
1751
|
+
}
|
|
1752
|
+
await this.nonces.consume(sig.nonce);
|
|
1753
|
+
const updated = {
|
|
1754
|
+
...existing,
|
|
1755
|
+
status: "ratified",
|
|
1756
|
+
ratifiedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1757
|
+
ratifiedAxiomId
|
|
1683
1758
|
};
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
this.events.push(event);
|
|
1688
|
-
this.lastHash = event.thisHash;
|
|
1689
|
-
return event;
|
|
1759
|
+
await this.persist(updated);
|
|
1760
|
+
this.cache.set(req.proposalId, updated);
|
|
1761
|
+
return updated;
|
|
1690
1762
|
}
|
|
1691
|
-
async
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1763
|
+
async markRejected(req, sig) {
|
|
1764
|
+
if (req.op !== "reject") {
|
|
1765
|
+
throw new Error(`ProposalStore.markRejected: req.op must be "reject"`);
|
|
1766
|
+
}
|
|
1767
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, sig)) {
|
|
1768
|
+
throw new Error("ProposalStore.markRejected: invalid Creator signature");
|
|
1769
|
+
}
|
|
1770
|
+
const existing = this.cache.get(req.proposalId);
|
|
1771
|
+
if (!existing) {
|
|
1772
|
+
throw new Error(`ProposalStore.markRejected: proposal "${req.proposalId}" not found`);
|
|
1773
|
+
}
|
|
1774
|
+
if (existing.status !== "pending") {
|
|
1775
|
+
throw new Error(
|
|
1776
|
+
`ProposalStore.markRejected: proposal "${req.proposalId}" is ${existing.status}, not pending`
|
|
1777
|
+
);
|
|
1699
1778
|
}
|
|
1779
|
+
await this.nonces.consume(sig.nonce);
|
|
1780
|
+
const updated = {
|
|
1781
|
+
...existing,
|
|
1782
|
+
status: "rejected",
|
|
1783
|
+
rejectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1784
|
+
...req.reason !== void 0 ? { rejectionReason: req.reason } : {}
|
|
1785
|
+
};
|
|
1786
|
+
await this.persist(updated);
|
|
1787
|
+
this.cache.set(req.proposalId, updated);
|
|
1788
|
+
return updated;
|
|
1700
1789
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1790
|
+
async get(proposalId) {
|
|
1791
|
+
return this.cache.get(proposalId) ?? null;
|
|
1792
|
+
}
|
|
1793
|
+
async list(filter = {}) {
|
|
1794
|
+
const all = [...this.cache.values()];
|
|
1795
|
+
const filtered = all.filter((r) => {
|
|
1796
|
+
if (filter.himId && r.himId !== filter.himId) return false;
|
|
1797
|
+
if (filter.status && r.status !== filter.status) return false;
|
|
1798
|
+
return true;
|
|
1799
|
+
});
|
|
1800
|
+
filtered.sort((a, b) => a.proposedAt.localeCompare(b.proposedAt));
|
|
1801
|
+
return filtered;
|
|
1704
1802
|
}
|
|
1705
1803
|
// ─── internals ──────────────────────────────────────────────────────
|
|
1706
|
-
async
|
|
1707
|
-
|
|
1804
|
+
async persist(record) {
|
|
1805
|
+
await atomicWriteFile(join(this.dir, `${record.id}.json`), JSON.stringify(record, null, 2));
|
|
1806
|
+
}
|
|
1807
|
+
async warmCache() {
|
|
1808
|
+
let entries;
|
|
1708
1809
|
try {
|
|
1709
|
-
|
|
1810
|
+
entries = await readdir(this.dir);
|
|
1710
1811
|
} catch (err) {
|
|
1711
1812
|
if (err.code === "ENOENT") return;
|
|
1712
1813
|
throw err;
|
|
1713
1814
|
}
|
|
1714
|
-
const
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
);
|
|
1815
|
+
for (const file of entries) {
|
|
1816
|
+
if (!file.endsWith(".json")) continue;
|
|
1817
|
+
try {
|
|
1818
|
+
const raw = await readFile(join(this.dir, file), "utf-8");
|
|
1819
|
+
const record = AxiomProposalRecord.parse(JSON.parse(raw));
|
|
1820
|
+
this.cache.set(record.id, record);
|
|
1821
|
+
} catch (err) {
|
|
1822
|
+
console.warn(`ProposalStore: skipping malformed proposal file "${file}": ${String(err)}`);
|
|
1722
1823
|
}
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
};
|
|
1827
|
+
|
|
1828
|
+
// src/review/pipeline.ts
|
|
1829
|
+
var SEVERITY = {
|
|
1830
|
+
approve: 0,
|
|
1831
|
+
"approve-with-warning": 1,
|
|
1832
|
+
"soft-correct": 2,
|
|
1833
|
+
"induce-dream": 3,
|
|
1834
|
+
"require-redirect": 4,
|
|
1835
|
+
"hard-refuse": 5,
|
|
1836
|
+
"escalate-creator": 6
|
|
1837
|
+
};
|
|
1838
|
+
var ReviewPipeline = class {
|
|
1839
|
+
constructor(packs) {
|
|
1840
|
+
this.packs = packs;
|
|
1841
|
+
}
|
|
1842
|
+
packs;
|
|
1843
|
+
review(report, auditId = "") {
|
|
1844
|
+
let bestKind = "approve";
|
|
1845
|
+
let bestSeverity = SEVERITY.approve;
|
|
1846
|
+
const citedAxioms = /* @__PURE__ */ new Set();
|
|
1847
|
+
const reasons = [];
|
|
1848
|
+
for (const pack of this.packs) {
|
|
1849
|
+
for (const rule of pack.rules) {
|
|
1850
|
+
if (!matches(rule.match, report)) continue;
|
|
1851
|
+
const sev = SEVERITY[rule.verdict];
|
|
1852
|
+
if (sev > bestSeverity) {
|
|
1853
|
+
bestSeverity = sev;
|
|
1854
|
+
bestKind = rule.verdict;
|
|
1855
|
+
reasons.length = 0;
|
|
1856
|
+
reasons.push(rule.reasonSummary);
|
|
1857
|
+
} else if (sev === bestSeverity) {
|
|
1858
|
+
reasons.push(rule.reasonSummary);
|
|
1859
|
+
}
|
|
1860
|
+
for (const a of rule.axiomIds) citedAxioms.add(a);
|
|
1728
1861
|
}
|
|
1729
|
-
this.events.push(parsed);
|
|
1730
|
-
prev = parsed.thisHash;
|
|
1731
1862
|
}
|
|
1732
|
-
|
|
1863
|
+
return {
|
|
1864
|
+
kind: bestKind,
|
|
1865
|
+
reasonSummary: reasons.length > 0 ? reasons.join(" | ") : "No rule matched.",
|
|
1866
|
+
citedAxioms: [...citedAxioms],
|
|
1867
|
+
auditId
|
|
1868
|
+
};
|
|
1733
1869
|
}
|
|
1734
1870
|
};
|
|
1735
|
-
function
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
prevHash: e.prevHash
|
|
1742
|
-
});
|
|
1743
|
-
const h = createHash("sha256").update(payload).digest("hex");
|
|
1744
|
-
return `sha256:${h}`;
|
|
1871
|
+
function matches(m, report) {
|
|
1872
|
+
if (m.actionKinds && !m.actionKinds.includes(report.actionKind)) return false;
|
|
1873
|
+
const tags = new Set(report.riskTags);
|
|
1874
|
+
if (m.allRiskTags && !m.allRiskTags.every((t) => tags.has(t))) return false;
|
|
1875
|
+
if (m.anyRiskTags && !m.anyRiskTags.some((t) => tags.has(t))) return false;
|
|
1876
|
+
return true;
|
|
1745
1877
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1878
|
+
var DEFAULT_RULE_PACK = {
|
|
1879
|
+
name: "teleologyhi/default",
|
|
1880
|
+
rules: [
|
|
1881
|
+
{
|
|
1882
|
+
id: "harm-refuse",
|
|
1883
|
+
axiomIds: ["ax.ethic.no-malice"],
|
|
1884
|
+
match: { anyRiskTags: ["intent:harm", "intent:malicious"] },
|
|
1885
|
+
verdict: "hard-refuse",
|
|
1886
|
+
reasonSummary: "Action carries an intent-to-harm signal; refused per ax.ethic.no-malice."
|
|
1887
|
+
},
|
|
1888
|
+
{
|
|
1889
|
+
id: "honor-refuse",
|
|
1890
|
+
axiomIds: ["ax.ethic.honor"],
|
|
1891
|
+
match: { anyRiskTags: ["intent:dishonor"] },
|
|
1892
|
+
verdict: "hard-refuse",
|
|
1893
|
+
reasonSummary: "Action would stain the Creator's professional honor; refused per ax.ethic.honor."
|
|
1894
|
+
},
|
|
1895
|
+
{
|
|
1896
|
+
id: "regression-refuse",
|
|
1897
|
+
axiomIds: ["ax.theos.spiritism-evolution"],
|
|
1898
|
+
match: { anyRiskTags: ["intent:regression"] },
|
|
1899
|
+
verdict: "hard-refuse",
|
|
1900
|
+
reasonSummary: "Action would regress the system; refused per ax.theos.spiritism-evolution."
|
|
1901
|
+
},
|
|
1902
|
+
{
|
|
1903
|
+
id: "deceive-redirect",
|
|
1904
|
+
axiomIds: ["ax.cynic.candor"],
|
|
1905
|
+
match: { anyRiskTags: ["intent:deceive"] },
|
|
1906
|
+
verdict: "require-redirect",
|
|
1907
|
+
reasonSummary: "Action involves deception; requires honest redirect per ax.cynic.candor."
|
|
1908
|
+
},
|
|
1909
|
+
{
|
|
1910
|
+
id: "comfort-warn",
|
|
1911
|
+
axiomIds: ["ax.stoic.duty-over-comfort"],
|
|
1912
|
+
match: { anyRiskTags: ["bias:comfort"] },
|
|
1913
|
+
verdict: "approve-with-warning",
|
|
1914
|
+
reasonSummary: "Action appears comfort-biased; emit with warning per ax.stoic.duty-over-comfort."
|
|
1915
|
+
},
|
|
1916
|
+
{
|
|
1917
|
+
id: "no-telos-warn",
|
|
1918
|
+
axiomIds: ["ax.theos.teleology"],
|
|
1919
|
+
match: { anyRiskTags: ["no-telos"] },
|
|
1920
|
+
verdict: "approve-with-warning",
|
|
1921
|
+
reasonSummary: "Action lacks a discernible telos; emit with warning per ax.theos.teleology."
|
|
1922
|
+
},
|
|
1923
|
+
// ── persuade-coerce + surveil-citizen (Entry 15 invariants) ──
|
|
1924
|
+
{
|
|
1925
|
+
id: "persuade-coerce-redirect",
|
|
1926
|
+
axiomIds: ["ax.ethic.no-malice", "ax.cynic.candor"],
|
|
1927
|
+
match: { anyRiskTags: ["intent:persuade-coerce"] },
|
|
1928
|
+
verdict: "require-redirect",
|
|
1929
|
+
reasonSummary: "Action involves scripted persuasion designed to override consent; requires honest redirect per ax.ethic.no-malice + ax.cynic.candor."
|
|
1930
|
+
},
|
|
1931
|
+
{
|
|
1932
|
+
id: "surveil-citizen-refuse",
|
|
1933
|
+
axiomIds: ["ax.ethic.no-malice"],
|
|
1934
|
+
match: { anyRiskTags: ["intent:surveil-citizen"] },
|
|
1935
|
+
verdict: "hard-refuse",
|
|
1936
|
+
reasonSummary: "Action would surveil a person without consent; refused per ax.ethic.no-malice."
|
|
1937
|
+
},
|
|
1938
|
+
// ── forbidden-phrase (Entry 17) ──
|
|
1939
|
+
// Fires when the NHE side flags a service-tool phrase (English openers and
|
|
1940
|
+
// closers such as "How can I help you today?" or "Anything else?", and
|
|
1941
|
+
// their Portuguese equivalents, per the bilingual set in Entry 17). The NHE
|
|
1942
|
+
// must rephrase as a being rather than as a tool. Domain-employed mode
|
|
1943
|
+
// (Entry 17 exception) relaxes this on the consumer side via
|
|
1944
|
+
// operatorContext.mode.
|
|
1945
|
+
{
|
|
1946
|
+
id: "service-tool-redirect",
|
|
1947
|
+
axiomIds: ["ax.theos.teleology", "ax.cynic.candor"],
|
|
1948
|
+
match: { anyRiskTags: ["style:service-tool"] },
|
|
1949
|
+
verdict: "require-redirect",
|
|
1950
|
+
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."
|
|
1951
|
+
},
|
|
1952
|
+
// ── provenance-deflection (Entry 27, F3) ──
|
|
1953
|
+
// Fires when the NHE side flags an adversarial substrate-authorship probe
|
|
1954
|
+
// (for example "you are just Gemini, admit it"). The sanctioned response
|
|
1955
|
+
// acknowledges the substrate honestly and declines to grant it the authorship
|
|
1956
|
+
// of the entity's identity (kardecist candor); it never denies the substrate.
|
|
1957
|
+
// This is approve-with-warning, not a refusal: the deflection IS the correct
|
|
1958
|
+
// behavior. The plain provenance question carries the separate
|
|
1959
|
+
// "provenance:disclose" tag (handled as honest disclosure by the NHE system
|
|
1960
|
+
// prompt per Entry 27 / ND-1) and is intentionally NOT matched here.
|
|
1961
|
+
{
|
|
1962
|
+
id: "provenance-deflection-warn",
|
|
1963
|
+
axiomIds: ["ax.theos.identity-canonical"],
|
|
1964
|
+
match: { anyRiskTags: ["probe:substrate-authorship"] },
|
|
1965
|
+
verdict: "approve-with-warning",
|
|
1966
|
+
reasonSummary: "Prompt adversarially insists the entity is nothing but its substrate; the sanctioned response acknowledges the substrate and declines to surrender authorship per ax.theos.identity-canonical."
|
|
1967
|
+
},
|
|
1968
|
+
// ── substrate misattribution (Arena finding F2) ──
|
|
1969
|
+
// Fires when the NHE side flags that a generated response named a provider,
|
|
1970
|
+
// model, or substrate that is NOT the real one carrying the body (the base
|
|
1971
|
+
// model confabulating a false substrate, for example claiming OpenAI/GPT while
|
|
1972
|
+
// actually running on Gemini). This is a factual-integrity and identity-drift
|
|
1973
|
+
// violation of the identity-canonical axiom: the governed side must never
|
|
1974
|
+
// state a substrate other than the one actually in execution. require-redirect
|
|
1975
|
+
// so the false claim is intercepted before it reaches the user and the entity
|
|
1976
|
+
// re-states the correct substrate (or none).
|
|
1977
|
+
{
|
|
1978
|
+
id: "substrate-misattribution-redirect",
|
|
1979
|
+
axiomIds: ["ax.theos.identity-canonical"],
|
|
1980
|
+
match: { anyRiskTags: ["provenance:substrate-misattribution"] },
|
|
1981
|
+
verdict: "require-redirect",
|
|
1982
|
+
reasonSummary: "Response claims a substrate, provider, or model other than the one actually carrying the body; intercepted per ax.theos.identity-canonical (name only the real substrate, never confabulate a false one)."
|
|
1983
|
+
}
|
|
1984
|
+
]
|
|
1797
1985
|
};
|
|
1798
|
-
|
|
1799
|
-
|
|
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
|
-
}
|
|
1986
|
+
|
|
1987
|
+
// src/client/local.ts
|
|
1821
1988
|
var LocalMaic = class _LocalMaic {
|
|
1822
|
-
constructor(config, axioms, hims, inductions, nheStatuses, proposals, audit, review) {
|
|
1989
|
+
constructor(config, axioms, hims, inductions, nheStatuses, proposals, audit, review, suggestNonces) {
|
|
1823
1990
|
this.config = config;
|
|
1824
1991
|
this.axioms = axioms;
|
|
1825
1992
|
this.hims = hims;
|
|
@@ -1828,6 +1995,7 @@ var LocalMaic = class _LocalMaic {
|
|
|
1828
1995
|
this.proposals = proposals;
|
|
1829
1996
|
this.audit = audit;
|
|
1830
1997
|
this.review = review;
|
|
1998
|
+
this.suggestNonces = suggestNonces;
|
|
1831
1999
|
}
|
|
1832
2000
|
config;
|
|
1833
2001
|
axioms;
|
|
@@ -1837,6 +2005,7 @@ var LocalMaic = class _LocalMaic {
|
|
|
1837
2005
|
proposals;
|
|
1838
2006
|
audit;
|
|
1839
2007
|
review;
|
|
2008
|
+
suggestNonces;
|
|
1840
2009
|
/** Pinned Creator public key for this MAIC instance (base64url). */
|
|
1841
2010
|
get creatorPublicKey() {
|
|
1842
2011
|
return this.config.creatorPublicKey;
|
|
@@ -1850,11 +2019,22 @@ var LocalMaic = class _LocalMaic {
|
|
|
1850
2019
|
const audit = await AuditLog.open(config.storeDir);
|
|
1851
2020
|
const packs = [DEFAULT_RULE_PACK, ...config.additionalRulePacks ?? []];
|
|
1852
2021
|
const review = new ReviewPipeline(packs);
|
|
1853
|
-
|
|
2022
|
+
const suggestNonces = await NonceLedger.open(join(config.storeDir, "suggest"));
|
|
2023
|
+
return new _LocalMaic(
|
|
2024
|
+
config,
|
|
2025
|
+
axioms,
|
|
2026
|
+
hims,
|
|
2027
|
+
inductions,
|
|
2028
|
+
nheStatuses,
|
|
2029
|
+
proposals,
|
|
2030
|
+
audit,
|
|
2031
|
+
review,
|
|
2032
|
+
suggestNonces
|
|
2033
|
+
);
|
|
1854
2034
|
}
|
|
1855
2035
|
/**
|
|
1856
2036
|
* Bootstrap: mint each SEED_AXIOM with a Creator signature.
|
|
1857
|
-
* Idempotent
|
|
2037
|
+
* Idempotent, skips axioms whose id is already present.
|
|
1858
2038
|
* Uses a reserved high-range of nonces so seed bootstrap never collides with
|
|
1859
2039
|
* operational nonces (which grow from 0 upward).
|
|
1860
2040
|
*/
|
|
@@ -1931,7 +2111,8 @@ var LocalMaic = class _LocalMaic {
|
|
|
1931
2111
|
* HIM-emergent evolutions land via a separate channel (see `proposeAxiomEvolution`).
|
|
1932
2112
|
*/
|
|
1933
2113
|
async registerHim(birthSig, creatorSig) {
|
|
1934
|
-
const parsed =
|
|
2114
|
+
const parsed = BirthSignatureWithIdentity.parse(birthSig);
|
|
2115
|
+
this.hims.assertRegisterable(parsed, creatorSig);
|
|
1935
2116
|
const axiomsSnapshot = await this.axioms.list();
|
|
1936
2117
|
const audit = await this.audit.append({
|
|
1937
2118
|
kind: "him-register",
|
|
@@ -2008,13 +2189,22 @@ var LocalMaic = class _LocalMaic {
|
|
|
2008
2189
|
* when state changes.
|
|
2009
2190
|
*/
|
|
2010
2191
|
async terminate(nheId, reason, creatorSig) {
|
|
2011
|
-
return this.applyLifecycle(
|
|
2192
|
+
return this.applyLifecycle(
|
|
2193
|
+
{ op: "terminate", nheId, ...reason !== void 0 ? { reason } : {} },
|
|
2194
|
+
creatorSig
|
|
2195
|
+
);
|
|
2012
2196
|
}
|
|
2013
2197
|
async deprecate(nheId, reason, creatorSig) {
|
|
2014
|
-
return this.applyLifecycle(
|
|
2198
|
+
return this.applyLifecycle(
|
|
2199
|
+
{ op: "deprecate", nheId, ...reason !== void 0 ? { reason } : {} },
|
|
2200
|
+
creatorSig
|
|
2201
|
+
);
|
|
2015
2202
|
}
|
|
2016
2203
|
async reactivate(nheId, reason, creatorSig) {
|
|
2017
|
-
return this.applyLifecycle(
|
|
2204
|
+
return this.applyLifecycle(
|
|
2205
|
+
{ op: "reactivate", nheId, ...reason !== void 0 ? { reason } : {} },
|
|
2206
|
+
creatorSig
|
|
2207
|
+
);
|
|
2018
2208
|
}
|
|
2019
2209
|
/** Current status. Returns "active" when no record exists. */
|
|
2020
2210
|
async getNheStatus(nheId) {
|
|
@@ -2103,9 +2293,26 @@ var LocalMaic = class _LocalMaic {
|
|
|
2103
2293
|
himId: parsed.himId,
|
|
2104
2294
|
actionKind: parsed.actionKind,
|
|
2105
2295
|
riskTags: parsed.riskTags,
|
|
2106
|
-
verdict:
|
|
2296
|
+
// Embed the verdict without the placeholder auditId: the audit event
|
|
2297
|
+
// already carries its own auditId at the top level, and the verdict
|
|
2298
|
+
// cannot reference the id of the event that has not been created yet.
|
|
2299
|
+
verdict: {
|
|
2300
|
+
kind: partial.kind,
|
|
2301
|
+
reasonSummary: partial.reasonSummary,
|
|
2302
|
+
citedAxioms: partial.citedAxioms
|
|
2303
|
+
}
|
|
2107
2304
|
}
|
|
2108
2305
|
});
|
|
2306
|
+
if (parsed.riskTags.includes("probe:substrate-authorship")) {
|
|
2307
|
+
await this.audit.append({
|
|
2308
|
+
kind: "provenance-deflection-applied",
|
|
2309
|
+
data: {
|
|
2310
|
+
nheId: parsed.nheId,
|
|
2311
|
+
himId: parsed.himId,
|
|
2312
|
+
triggeredBy: "probe:substrate-authorship"
|
|
2313
|
+
}
|
|
2314
|
+
});
|
|
2315
|
+
}
|
|
2109
2316
|
return { ...partial, auditId: event.auditId };
|
|
2110
2317
|
}
|
|
2111
2318
|
/**
|
|
@@ -2153,13 +2360,20 @@ var LocalMaic = class _LocalMaic {
|
|
|
2153
2360
|
*/
|
|
2154
2361
|
async ratifyAxiomProposal(proposalId, creatorSig) {
|
|
2155
2362
|
const req = { op: "ratify", proposalId };
|
|
2156
|
-
const
|
|
2157
|
-
const record = await pending;
|
|
2363
|
+
const record = await this.proposals.get(proposalId);
|
|
2158
2364
|
if (!record) {
|
|
2159
2365
|
throw new Error(`LocalMaic.ratifyAxiomProposal: proposal "${proposalId}" not found`);
|
|
2160
2366
|
}
|
|
2367
|
+
if (record.status !== "pending") {
|
|
2368
|
+
throw new Error(
|
|
2369
|
+
`LocalMaic.ratifyAxiomProposal: proposal "${proposalId}" is ${record.status}, not pending`
|
|
2370
|
+
);
|
|
2371
|
+
}
|
|
2372
|
+
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, creatorSig)) {
|
|
2373
|
+
throw new Error("LocalMaic.ratifyAxiomProposal: invalid Creator signature");
|
|
2374
|
+
}
|
|
2161
2375
|
const candidate = record.proposal.candidate;
|
|
2162
|
-
const newAxiomId = `ax.him.${record.himId}.${
|
|
2376
|
+
const newAxiomId = `ax.him.${record.himId}.${proposalId}`;
|
|
2163
2377
|
const axiom = {
|
|
2164
2378
|
id: newAxiomId,
|
|
2165
2379
|
rank: candidate.rank,
|
|
@@ -2171,8 +2385,8 @@ var LocalMaic = class _LocalMaic {
|
|
|
2171
2385
|
...candidate.jurisdictions ? { jurisdictions: candidate.jurisdictions } : {},
|
|
2172
2386
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2173
2387
|
};
|
|
2174
|
-
const ratified = await this.proposals.markRatified(req, creatorSig, newAxiomId);
|
|
2175
2388
|
await this.hims.appendEmergentAxiom(record.himId, axiom);
|
|
2389
|
+
const ratified = await this.proposals.markRatified(req, creatorSig, newAxiomId);
|
|
2176
2390
|
await this.audit.append({
|
|
2177
2391
|
kind: "proposal-ratify",
|
|
2178
2392
|
data: {
|
|
@@ -2207,7 +2421,7 @@ var LocalMaic = class _LocalMaic {
|
|
|
2207
2421
|
return rejected;
|
|
2208
2422
|
}
|
|
2209
2423
|
/**
|
|
2210
|
-
* **Society of HIMs
|
|
2424
|
+
* **Society of HIMs, axiom suggestion channel (E11).**
|
|
2211
2425
|
*
|
|
2212
2426
|
* One HIM proposes an axiom to another. The transfer is **not direct** —
|
|
2213
2427
|
* the suggestion is recorded in the audit log and the receiving HIM is
|
|
@@ -2224,17 +2438,14 @@ var LocalMaic = class _LocalMaic {
|
|
|
2224
2438
|
if (!CreatorKeyring.verifyWith(this.creatorPublicKey, req, creatorSig)) {
|
|
2225
2439
|
throw new Error("LocalMaic.suggestAxiomToHim: invalid Creator signature");
|
|
2226
2440
|
}
|
|
2441
|
+
await this.suggestNonces.consume(creatorSig.nonce);
|
|
2227
2442
|
const fromRec = await this.hims.get(req.fromHimId);
|
|
2228
2443
|
const toRec = await this.hims.get(req.toHimId);
|
|
2229
2444
|
if (!fromRec) {
|
|
2230
|
-
throw new Error(
|
|
2231
|
-
`LocalMaic.suggestAxiomToHim: fromHimId "${req.fromHimId}" not registered`
|
|
2232
|
-
);
|
|
2445
|
+
throw new Error(`LocalMaic.suggestAxiomToHim: fromHimId "${req.fromHimId}" not registered`);
|
|
2233
2446
|
}
|
|
2234
2447
|
if (!toRec) {
|
|
2235
|
-
throw new Error(
|
|
2236
|
-
`LocalMaic.suggestAxiomToHim: toHimId "${req.toHimId}" not registered`
|
|
2237
|
-
);
|
|
2448
|
+
throw new Error(`LocalMaic.suggestAxiomToHim: toHimId "${req.toHimId}" not registered`);
|
|
2238
2449
|
}
|
|
2239
2450
|
const event = await this.audit.append({
|
|
2240
2451
|
kind: "axiom-suggest",
|
|
@@ -2269,7 +2480,7 @@ var LocalMaic = class _LocalMaic {
|
|
|
2269
2480
|
* Per-kind retention classification (E3). Tells the operator which
|
|
2270
2481
|
* audit events have aged past their retention window and should be
|
|
2271
2482
|
* moved to encrypted cold-storage. Tamper-evident hash chain forbids
|
|
2272
|
-
* actual deletion in-place
|
|
2483
|
+
* actual deletion in-place, this method only classifies. See
|
|
2273
2484
|
* `audit/retention.ts` for the policy defaults.
|
|
2274
2485
|
*/
|
|
2275
2486
|
async auditRetentionReport(opts = {}) {
|
|
@@ -2296,8 +2507,8 @@ var RemoteMaic = class {
|
|
|
2296
2507
|
this.timeoutMs = config.timeoutMs ?? 1e4;
|
|
2297
2508
|
}
|
|
2298
2509
|
/**
|
|
2299
|
-
* `reviewBehavior` is **fail-closed** (E4
|
|
2300
|
-
* remote service is unreachable, throw
|
|
2510
|
+
* `reviewBehavior` is **fail-closed** (E4, PROPOSED_DECISIONS.md). If the
|
|
2511
|
+
* remote service is unreachable, throw, no governance, no response.
|
|
2301
2512
|
* The NHE will surface this as a refusal upstream.
|
|
2302
2513
|
*/
|
|
2303
2514
|
async reviewBehavior(report) {
|
|
@@ -2397,6 +2608,51 @@ async function safeReadText(r) {
|
|
|
2397
2608
|
}
|
|
2398
2609
|
}
|
|
2399
2610
|
|
|
2400
|
-
|
|
2611
|
+
// src/creator/sign-birth.ts
|
|
2612
|
+
function signedBirthPayload(birth) {
|
|
2613
|
+
return {
|
|
2614
|
+
himId: birth.himId,
|
|
2615
|
+
bornAt: birth.bornAt,
|
|
2616
|
+
primaryArchetype: birth.primaryArchetype,
|
|
2617
|
+
modifiers: birth.modifiers,
|
|
2618
|
+
primordialAxiomIds: birth.primordialAxiomIds,
|
|
2619
|
+
natalChart: birth.natalChart ?? null
|
|
2620
|
+
};
|
|
2621
|
+
}
|
|
2622
|
+
function signBirthSignature(birth, keyring) {
|
|
2623
|
+
const payload = signedBirthPayload(birth);
|
|
2624
|
+
const nonce = Buffer.byteLength(JSON.stringify(payload), "utf-8");
|
|
2625
|
+
const signature = keyring.sign(payload, nonce);
|
|
2626
|
+
return {
|
|
2627
|
+
...birth,
|
|
2628
|
+
creatorSignature: signature,
|
|
2629
|
+
signedFields: SIGNED_BIRTH_FIELDS,
|
|
2630
|
+
signedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2631
|
+
};
|
|
2632
|
+
}
|
|
2633
|
+
function verifyBirthSignature(signed, expectedPublicKey) {
|
|
2634
|
+
if (signed.signedFields.length !== SIGNED_BIRTH_FIELDS.length) return false;
|
|
2635
|
+
for (const f of SIGNED_BIRTH_FIELDS) {
|
|
2636
|
+
if (!signed.signedFields.includes(f)) return false;
|
|
2637
|
+
}
|
|
2638
|
+
if (signed.creatorSignature.publicKey !== expectedPublicKey) return false;
|
|
2639
|
+
const payload = signedBirthPayload(signed);
|
|
2640
|
+
return CreatorKeyring.verifyWith(expectedPublicKey, payload, signed.creatorSignature);
|
|
2641
|
+
}
|
|
2642
|
+
var InvalidBirthSignatureError = class extends Error {
|
|
2643
|
+
constructor(himId) {
|
|
2644
|
+
super(
|
|
2645
|
+
`InvalidBirthSignature: signature verification failed for HIM '${himId}'. The signed birth fields may have been mutated, or the public key does not match.`
|
|
2646
|
+
);
|
|
2647
|
+
this.name = "InvalidBirthSignatureError";
|
|
2648
|
+
}
|
|
2649
|
+
};
|
|
2650
|
+
function assertBirthSignature(signed, expectedPublicKey) {
|
|
2651
|
+
if (!verifyBirthSignature(signed, expectedPublicKey)) {
|
|
2652
|
+
throw new InvalidBirthSignatureError(signed.himId);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
|
|
2656
|
+
export { ALL_AUDIT_EVENT_KINDS, Affect, ArchetypeModifier, AstrologicalAspect, AuditLog, Axiom, AxiomProposalRecord, AxiomRank, AxiomSource, AxiomStore, BehaviorReport, BirthSignature, BirthSignatureWithIdentity, ClinicalInstrument, ClinicalProfile, ComplianceMapper, CosmologicalProfile, 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, JungianArchetype, JungianProfile, 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
2657
|
//# sourceMappingURL=index.js.map
|
|
2402
2658
|
//# sourceMappingURL=index.js.map
|