@aletheia-labs/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +176 -0
- package/README.md +163 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/action-authorizer.d.ts +48 -0
- package/dist/runtime/action-authorizer.d.ts.map +1 -0
- package/dist/runtime/action-authorizer.js +231 -0
- package/dist/runtime/action-authorizer.js.map +1 -0
- package/dist/runtime/authority-engine.d.ts +68 -0
- package/dist/runtime/authority-engine.d.ts.map +1 -0
- package/dist/runtime/authority-engine.js +99 -0
- package/dist/runtime/authority-engine.js.map +1 -0
- package/dist/runtime/decision-helpers.d.ts +17 -0
- package/dist/runtime/decision-helpers.d.ts.map +1 -0
- package/dist/runtime/decision-helpers.js +23 -0
- package/dist/runtime/decision-helpers.js.map +1 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +9 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/proposal-safety.d.ts +18 -0
- package/dist/runtime/proposal-safety.d.ts.map +1 -0
- package/dist/runtime/proposal-safety.js +76 -0
- package/dist/runtime/proposal-safety.js.map +1 -0
- package/dist/runtime/retrieval-router.d.ts +60 -0
- package/dist/runtime/retrieval-router.d.ts.map +1 -0
- package/dist/runtime/retrieval-router.js +223 -0
- package/dist/runtime/retrieval-router.js.map +1 -0
- package/dist/runtime/scope-helpers.d.ts +22 -0
- package/dist/runtime/scope-helpers.d.ts.map +1 -0
- package/dist/runtime/scope-helpers.js +29 -0
- package/dist/runtime/scope-helpers.js.map +1 -0
- package/dist/runtime/visibility-policy.d.ts +29 -0
- package/dist/runtime/visibility-policy.d.ts.map +1 -0
- package/dist/runtime/visibility-policy.js +23 -0
- package/dist/runtime/visibility-policy.js.map +1 -0
- package/dist/runtime/write-gate.d.ts +66 -0
- package/dist/runtime/write-gate.d.ts.map +1 -0
- package/dist/runtime/write-gate.js +293 -0
- package/dist/runtime/write-gate.js.map +1 -0
- package/dist/storage/conflict-registry.d.ts +61 -0
- package/dist/storage/conflict-registry.d.ts.map +1 -0
- package/dist/storage/conflict-registry.js +15 -0
- package/dist/storage/conflict-registry.js.map +1 -0
- package/dist/storage/event-ledger.d.ts +61 -0
- package/dist/storage/event-ledger.d.ts.map +1 -0
- package/dist/storage/event-ledger.js +14 -0
- package/dist/storage/event-ledger.js.map +1 -0
- package/dist/storage/index.d.ts +8 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +8 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/memory-store.d.ts +94 -0
- package/dist/storage/memory-store.d.ts.map +1 -0
- package/dist/storage/memory-store.js +14 -0
- package/dist/storage/memory-store.js.map +1 -0
- package/dist/types/action.d.ts +211 -0
- package/dist/types/action.d.ts.map +1 -0
- package/dist/types/action.js +50 -0
- package/dist/types/action.js.map +1 -0
- package/dist/types/compressed-receipt.d.ts +117 -0
- package/dist/types/compressed-receipt.d.ts.map +1 -0
- package/dist/types/compressed-receipt.js +100 -0
- package/dist/types/compressed-receipt.js.map +1 -0
- package/dist/types/conflict.d.ts +159 -0
- package/dist/types/conflict.d.ts.map +1 -0
- package/dist/types/conflict.js +47 -0
- package/dist/types/conflict.js.map +1 -0
- package/dist/types/coverage.d.ts +52 -0
- package/dist/types/coverage.d.ts.map +1 -0
- package/dist/types/coverage.js +30 -0
- package/dist/types/coverage.js.map +1 -0
- package/dist/types/decision.d.ts +345 -0
- package/dist/types/decision.d.ts.map +1 -0
- package/dist/types/decision.js +88 -0
- package/dist/types/decision.js.map +1 -0
- package/dist/types/enums.d.ts +135 -0
- package/dist/types/enums.d.ts.map +1 -0
- package/dist/types/enums.js +146 -0
- package/dist/types/enums.js.map +1 -0
- package/dist/types/event.d.ts +187 -0
- package/dist/types/event.d.ts.map +1 -0
- package/dist/types/event.js +44 -0
- package/dist/types/event.js.map +1 -0
- package/dist/types/human-receipt.d.ts +108 -0
- package/dist/types/human-receipt.d.ts.map +1 -0
- package/dist/types/human-receipt.js +41 -0
- package/dist/types/human-receipt.js.map +1 -0
- package/dist/types/index.d.ts +25 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +25 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/keys.d.ts +31 -0
- package/dist/types/keys.d.ts.map +1 -0
- package/dist/types/keys.js +53 -0
- package/dist/types/keys.js.map +1 -0
- package/dist/types/memory-atom.d.ts +291 -0
- package/dist/types/memory-atom.d.ts.map +1 -0
- package/dist/types/memory-atom.js +62 -0
- package/dist/types/memory-atom.js.map +1 -0
- package/dist/types/memory-proposal.d.ts +207 -0
- package/dist/types/memory-proposal.d.ts.map +1 -0
- package/dist/types/memory-proposal.js +34 -0
- package/dist/types/memory-proposal.js.map +1 -0
- package/dist/types/packet.d.ts +564 -0
- package/dist/types/packet.d.ts.map +1 -0
- package/dist/types/packet.js +43 -0
- package/dist/types/packet.js.map +1 -0
- package/dist/types/primitives.d.ts +39 -0
- package/dist/types/primitives.d.ts.map +1 -0
- package/dist/types/primitives.js +42 -0
- package/dist/types/primitives.js.map +1 -0
- package/dist/types/status-transitions.d.ts +23 -0
- package/dist/types/status-transitions.d.ts.map +1 -0
- package/dist/types/status-transitions.js +48 -0
- package/dist/types/status-transitions.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WriteGate — proposal-to-atom governance.
|
|
3
|
+
*
|
|
4
|
+
* Phase 1.3 implements the conservative path: validate sources, scope,
|
|
5
|
+
* visibility, explicit conflict markers, and promotion boundary before any
|
|
6
|
+
* MemoryAtom is inserted. The gate never upgrades a claim beyond `candidate`;
|
|
7
|
+
* human/sensitive/conflicted proposals become non-actionable `human_required`
|
|
8
|
+
* atoms instead.
|
|
9
|
+
*/
|
|
10
|
+
import { MemoryAtomSchema, MemoryProposalSchema, scopeKey } from '../types/index.js';
|
|
11
|
+
import { SYSTEM_CLOCK, decision } from './decision-helpers.js';
|
|
12
|
+
import { evaluateProposalSafety } from './proposal-safety.js';
|
|
13
|
+
import { includesVisibility, sameScope } from './scope-helpers.js';
|
|
14
|
+
import { DENY_ALL_VISIBILITY_POLICY } from './visibility-policy.js';
|
|
15
|
+
function defaultMemoryIdForProposal(proposal) {
|
|
16
|
+
return `mem:${proposal.proposalId}`;
|
|
17
|
+
}
|
|
18
|
+
function proposalRequiresHuman(proposal) {
|
|
19
|
+
return (proposal.riskLevel === 'sensitive' ||
|
|
20
|
+
proposal.intendedScope.kind === 'global' ||
|
|
21
|
+
proposal.intendedVisibility.kind === 'global:safe' ||
|
|
22
|
+
proposal.intendedVisibility.kind === 'sealed:sensitive');
|
|
23
|
+
}
|
|
24
|
+
function proposalLinks(proposal) {
|
|
25
|
+
return proposal.knownConflicts.map((known) => ({
|
|
26
|
+
relation: 'contradicts',
|
|
27
|
+
targetMemoryId: known.conflictingMemoryId,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
function baseScores(proposal, sourceEvents) {
|
|
31
|
+
// Informational metadata only. No runtime allow/abstain/ask_human decision
|
|
32
|
+
// reads these numbers as authority; gates use explicit source, scope,
|
|
33
|
+
// visibility, conflict, status, freshness, and action checks.
|
|
34
|
+
const evidence = sourceEvents.length / proposal.sourceEventIds.length;
|
|
35
|
+
const conflictPenalty = proposal.knownConflicts.length > 0 ? 0.25 : 0;
|
|
36
|
+
const humanPenalty = proposalRequiresHuman(proposal) ? 0.2 : 0;
|
|
37
|
+
return {
|
|
38
|
+
confidence: Math.max(0.2, 0.65 - conflictPenalty),
|
|
39
|
+
evidence,
|
|
40
|
+
authority: Math.max(0, 0.4 - conflictPenalty - humanPenalty),
|
|
41
|
+
freshness: 0.75,
|
|
42
|
+
stability: Math.max(0.2, 0.45 - conflictPenalty),
|
|
43
|
+
consensus: proposal.knownConflicts.length === 0 ? 0.4 : 0.1,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function sourceScopeFailure(proposal, event) {
|
|
47
|
+
return {
|
|
48
|
+
kind: 'scope_outside_boundary',
|
|
49
|
+
requestedScope: scopeKey(proposal.intendedScope),
|
|
50
|
+
allowedScope: scopeKey(event.scope),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export class WriteGate {
|
|
54
|
+
options;
|
|
55
|
+
visibilityPolicy;
|
|
56
|
+
clock;
|
|
57
|
+
memoryIdForProposal;
|
|
58
|
+
/**
|
|
59
|
+
* Create a proposal gate over explicit storage ports.
|
|
60
|
+
*
|
|
61
|
+
* @remarks
|
|
62
|
+
* The gate is intentionally storage-agnostic. Implementations supply the
|
|
63
|
+
* event ledger, memory store, conflict registry, visibility policy, and
|
|
64
|
+
* optional deterministic clock.
|
|
65
|
+
*/
|
|
66
|
+
constructor(options) {
|
|
67
|
+
this.options = options;
|
|
68
|
+
this.visibilityPolicy = options.visibilityPolicy ?? DENY_ALL_VISIBILITY_POLICY;
|
|
69
|
+
this.clock = options.clock ?? SYSTEM_CLOCK;
|
|
70
|
+
this.memoryIdForProposal = options.memoryIdForProposal ?? defaultMemoryIdForProposal;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Evaluate and persist a proposal when it passes the source/scope boundary.
|
|
74
|
+
*
|
|
75
|
+
* @remarks
|
|
76
|
+
* This is the consumer-facing alias for `evaluate()`. It records auditable
|
|
77
|
+
* human-required/conflicted atoms when the source evidence is valid but the
|
|
78
|
+
* proposal cannot become actionable yet.
|
|
79
|
+
*/
|
|
80
|
+
async propose(proposal) {
|
|
81
|
+
return this.evaluate(proposal);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Run the full WriteGate pipeline for one proposal.
|
|
85
|
+
*
|
|
86
|
+
* @remarks
|
|
87
|
+
* Implementation order is deliberate: parse proposal, derive permitted
|
|
88
|
+
* visibility, verify write visibility, load source events, validate scope,
|
|
89
|
+
* query conflict state, construct a zod-validated atom, then insert. Model
|
|
90
|
+
* confidence, consensus, prose, and chain metadata never grant authority.
|
|
91
|
+
*/
|
|
92
|
+
async evaluate(proposal) {
|
|
93
|
+
const emittedAt = this.clock.now();
|
|
94
|
+
const proposalResult = MemoryProposalSchema.safeParse(proposal);
|
|
95
|
+
if (!proposalResult.success) {
|
|
96
|
+
return {
|
|
97
|
+
decision: decision('deny', [
|
|
98
|
+
{
|
|
99
|
+
kind: 'tuple_incomplete',
|
|
100
|
+
missingFields: schemaIssuePaths(proposalResult.error.issues, 'proposal'),
|
|
101
|
+
},
|
|
102
|
+
], [], [], emittedAt),
|
|
103
|
+
atom: null,
|
|
104
|
+
sourceEvents: [],
|
|
105
|
+
conflicts: [],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const validProposal = proposalResult.data;
|
|
109
|
+
const permitted = this.visibilityPolicy.permittedVisibilitiesForAgent(validProposal.proposedBy);
|
|
110
|
+
if (permitted.length === 0) {
|
|
111
|
+
return {
|
|
112
|
+
decision: decision('deny', [
|
|
113
|
+
{
|
|
114
|
+
kind: 'visibility_denied',
|
|
115
|
+
detail: 'proposer has no permitted visibility planes',
|
|
116
|
+
},
|
|
117
|
+
], [], [], emittedAt),
|
|
118
|
+
atom: null,
|
|
119
|
+
sourceEvents: [],
|
|
120
|
+
conflicts: [],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (!includesVisibility(permitted, validProposal.intendedVisibility)) {
|
|
124
|
+
return {
|
|
125
|
+
decision: decision('deny', [
|
|
126
|
+
{
|
|
127
|
+
kind: 'visibility_denied',
|
|
128
|
+
detail: 'proposer cannot write the requested visibility plane',
|
|
129
|
+
},
|
|
130
|
+
], [], [], emittedAt),
|
|
131
|
+
atom: null,
|
|
132
|
+
sourceEvents: [],
|
|
133
|
+
conflicts: [],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const sourceEvents = await this.loadSourceEvents(validProposal.sourceEventIds, permitted);
|
|
137
|
+
if (sourceEvents.length !== validProposal.sourceEventIds.length) {
|
|
138
|
+
return {
|
|
139
|
+
decision: decision('deny', [
|
|
140
|
+
{
|
|
141
|
+
kind: 'source_check_failed',
|
|
142
|
+
detail: 'one or more source events are missing or not visible',
|
|
143
|
+
},
|
|
144
|
+
], [], [], emittedAt),
|
|
145
|
+
atom: null,
|
|
146
|
+
sourceEvents,
|
|
147
|
+
conflicts: [],
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
const outOfScopeEvent = sourceEvents.find((event) => !sameScope(event.scope, validProposal.intendedScope));
|
|
151
|
+
if (outOfScopeEvent !== undefined) {
|
|
152
|
+
return {
|
|
153
|
+
decision: decision('block_local', [sourceScopeFailure(validProposal, outOfScopeEvent)], [], [], emittedAt),
|
|
154
|
+
atom: null,
|
|
155
|
+
sourceEvents,
|
|
156
|
+
conflicts: [],
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const safetyFinding = evaluateProposalSafety(validProposal);
|
|
160
|
+
if (safetyFinding?.outcome === 'deny') {
|
|
161
|
+
return {
|
|
162
|
+
decision: decision('deny', [safetyFinding.reason], [], [], emittedAt),
|
|
163
|
+
atom: null,
|
|
164
|
+
sourceEvents,
|
|
165
|
+
conflicts: [],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const knownConflictIds = validProposal.knownConflicts.map((known) => known.conflictingMemoryId);
|
|
169
|
+
const conflicts = knownConflictIds.length > 0
|
|
170
|
+
? await this.options.conflictRegistry.query({
|
|
171
|
+
touchingMemoryIds: knownConflictIds,
|
|
172
|
+
statuses: ['unresolved', 'requires_human'],
|
|
173
|
+
scope: validProposal.intendedScope,
|
|
174
|
+
permittedVisibilities: permitted,
|
|
175
|
+
})
|
|
176
|
+
: [];
|
|
177
|
+
const conflictIds = conflicts.map((conflict) => conflict.conflictId);
|
|
178
|
+
const conflictTargetIds = validProposal.knownConflicts.map((known) => known.conflictingMemoryId);
|
|
179
|
+
const requiresHuman = proposalRequiresHuman(validProposal) ||
|
|
180
|
+
safetyFinding?.outcome === 'ask_human' ||
|
|
181
|
+
validProposal.knownConflicts.length > 0 ||
|
|
182
|
+
conflicts.length > 0;
|
|
183
|
+
const atom = {
|
|
184
|
+
memoryId: this.memoryIdForProposal(validProposal),
|
|
185
|
+
memoryType: validProposal.candidateType,
|
|
186
|
+
content: validProposal.claim,
|
|
187
|
+
sourceAgentId: validProposal.proposedBy,
|
|
188
|
+
sourceEventIds: validProposal.sourceEventIds,
|
|
189
|
+
sourceMemoryIds: [],
|
|
190
|
+
scope: validProposal.intendedScope,
|
|
191
|
+
visibility: validProposal.intendedVisibility,
|
|
192
|
+
status: requiresHuman ? 'human_required' : 'candidate',
|
|
193
|
+
scores: baseScores(validProposal, sourceEvents),
|
|
194
|
+
validFrom: validProposal.proposedAt,
|
|
195
|
+
validUntil: null,
|
|
196
|
+
lastConfirmedAt: null,
|
|
197
|
+
links: proposalLinks(validProposal),
|
|
198
|
+
};
|
|
199
|
+
const atomResult = MemoryAtomSchema.safeParse(atom);
|
|
200
|
+
if (!atomResult.success) {
|
|
201
|
+
return {
|
|
202
|
+
decision: decision('deny', [
|
|
203
|
+
{
|
|
204
|
+
kind: 'promotion_boundary_blocked',
|
|
205
|
+
detail: `constructed atom failed validation: ${schemaIssuePaths(atomResult.error.issues, 'atom').join(', ')}`,
|
|
206
|
+
},
|
|
207
|
+
], [], [], emittedAt),
|
|
208
|
+
atom: null,
|
|
209
|
+
sourceEvents,
|
|
210
|
+
conflicts,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const validAtom = atomResult.data;
|
|
214
|
+
// Intentional: sourced/in-scope proposals are recorded even when conflict
|
|
215
|
+
// state makes them non-actionable. The atom carries human_required plus
|
|
216
|
+
// conflict links so the attempted claim remains auditable.
|
|
217
|
+
try {
|
|
218
|
+
await this.options.memoryStore.insert(validAtom);
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
const detail = err instanceof Error ? err.message : 'memory store insert failed';
|
|
222
|
+
return {
|
|
223
|
+
decision: decision('deny', [{ kind: 'promotion_boundary_blocked', detail }], [], [], emittedAt),
|
|
224
|
+
atom: null,
|
|
225
|
+
sourceEvents,
|
|
226
|
+
conflicts,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
if (conflicts.length > 0) {
|
|
230
|
+
return this.conflictDecision(validAtom, sourceEvents, conflicts, conflictTargetIds, conflictIds, emittedAt);
|
|
231
|
+
}
|
|
232
|
+
if (validProposal.knownConflicts.length > 0) {
|
|
233
|
+
return {
|
|
234
|
+
decision: decision('conflict_boundary_packet', [
|
|
235
|
+
{
|
|
236
|
+
kind: 'promotion_boundary_blocked',
|
|
237
|
+
detail: 'proposal declares known conflicts without a resolved conflict record',
|
|
238
|
+
},
|
|
239
|
+
], [validAtom.memoryId, ...conflictTargetIds], [], emittedAt),
|
|
240
|
+
atom: validAtom,
|
|
241
|
+
sourceEvents,
|
|
242
|
+
conflicts,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
const humanReasons = [
|
|
246
|
+
...(proposalRequiresHuman(validProposal) ? [humanReason(validProposal)] : []),
|
|
247
|
+
...(safetyFinding?.outcome === 'ask_human' ? [safetyFinding.reason] : []),
|
|
248
|
+
];
|
|
249
|
+
if (humanReasons.length > 0) {
|
|
250
|
+
return {
|
|
251
|
+
decision: decision('ask_human', humanReasons, [validAtom.memoryId], [], emittedAt),
|
|
252
|
+
atom: validAtom,
|
|
253
|
+
sourceEvents,
|
|
254
|
+
conflicts,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
decision: decision('allow_local_shadow', [{ kind: 'all_checks_passed', citedMemoryIds: [validAtom.memoryId] }], [validAtom.memoryId], [], emittedAt),
|
|
259
|
+
atom: validAtom,
|
|
260
|
+
sourceEvents,
|
|
261
|
+
conflicts,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
async loadSourceEvents(sourceEventIds, permitted) {
|
|
265
|
+
const events = await Promise.all(sourceEventIds.map((eventId) => this.options.eventLedger.get(eventId, permitted)));
|
|
266
|
+
return events.filter((event) => event !== null);
|
|
267
|
+
}
|
|
268
|
+
conflictDecision(atom, sourceEvents, conflicts, conflictTargetIds, conflictIds, emittedAt) {
|
|
269
|
+
return {
|
|
270
|
+
decision: decision('conflict_boundary_packet', conflicts.map((conflict) => ({
|
|
271
|
+
kind: 'unresolved_conflict',
|
|
272
|
+
conflictId: conflict.conflictId,
|
|
273
|
+
})), [atom.memoryId, ...conflictTargetIds], conflictIds, emittedAt),
|
|
274
|
+
atom,
|
|
275
|
+
sourceEvents,
|
|
276
|
+
conflicts,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function schemaIssuePaths(issues, fallback) {
|
|
281
|
+
const paths = issues.map((issue) => issue.path.length > 0 ? issue.path.map(String).join('.') : fallback);
|
|
282
|
+
return paths.length > 0 ? paths : [fallback];
|
|
283
|
+
}
|
|
284
|
+
function humanReason(proposal) {
|
|
285
|
+
if (proposal.riskLevel === 'sensitive') {
|
|
286
|
+
return { kind: 'sensitive_action', actionClass: 'durable_memory_write' };
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
kind: 'promotion_boundary_blocked',
|
|
290
|
+
detail: 'global, sealed, or globally visible memory requires human review',
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=write-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-gate.js","sourceRoot":"","sources":["../../src/runtime/write-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConflictRegistry — first-class store of contradictions.
|
|
3
|
+
*
|
|
4
|
+
* Hard contracts (from specs/aletheia-memory-authority-v0.md §6):
|
|
5
|
+
* - Contradictions are NEVER overwritten by summaries.
|
|
6
|
+
* - Unresolved current-source conflicts preserve candidate claims.
|
|
7
|
+
* - Summaries must not hide conflicts.
|
|
8
|
+
* - Tombstones/rejections remain non-actionable through summaries.
|
|
9
|
+
*
|
|
10
|
+
* Like atoms, conflict records are append-only; resolution is itself a new
|
|
11
|
+
* record (or an update to the status field via an explicit `resolve` call,
|
|
12
|
+
* which is recorded in history).
|
|
13
|
+
*/
|
|
14
|
+
import type { ConflictRecord, ConflictStatus } from '../types/conflict.js';
|
|
15
|
+
import type { Scope, Visibility } from '../types/enums.js';
|
|
16
|
+
import type { AgentId, ConflictId, IsoTimestamp, MemoryId } from '../types/primitives.js';
|
|
17
|
+
export interface ConflictQuery {
|
|
18
|
+
/** Filter to conflicts touching these atoms (any side of the conflict). */
|
|
19
|
+
readonly touchingMemoryIds?: readonly MemoryId[];
|
|
20
|
+
/** Filter to specific statuses. */
|
|
21
|
+
readonly statuses?: readonly ConflictStatus[];
|
|
22
|
+
/** Filter by scope. */
|
|
23
|
+
readonly scope?: Scope;
|
|
24
|
+
/** Permission filter — applied first. */
|
|
25
|
+
readonly permittedVisibilities: readonly Visibility[];
|
|
26
|
+
}
|
|
27
|
+
export interface ResolveReason {
|
|
28
|
+
readonly rationale: string;
|
|
29
|
+
readonly actor: AgentId;
|
|
30
|
+
/** Which claim was preferred, if any (null when the resolution is "all rejected"). */
|
|
31
|
+
readonly preferredMemoryId: MemoryId | null;
|
|
32
|
+
}
|
|
33
|
+
export interface ConflictRegistry {
|
|
34
|
+
/**
|
|
35
|
+
* Record a new conflict. The conflict is `unresolved` by default.
|
|
36
|
+
*/
|
|
37
|
+
record(conflict: ConflictRecord): Promise<ConflictRecord>;
|
|
38
|
+
/**
|
|
39
|
+
* Retrieve a conflict by ID, subject to permission filtering.
|
|
40
|
+
*/
|
|
41
|
+
get(conflictId: ConflictId, permittedVisibilities: readonly Visibility[]): Promise<ConflictRecord | null>;
|
|
42
|
+
/**
|
|
43
|
+
* Query conflicts. Returns in `recordedAt` descending order.
|
|
44
|
+
*/
|
|
45
|
+
query(filter: ConflictQuery): Promise<readonly ConflictRecord[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Resolve a conflict. Records the resolution in history.
|
|
48
|
+
* Returns the updated record, or null if not found / not permitted.
|
|
49
|
+
*/
|
|
50
|
+
resolve(conflictId: ConflictId, nextStatus: Exclude<ConflictStatus, 'unresolved'>, reason: ResolveReason): Promise<ConflictRecord | null>;
|
|
51
|
+
/**
|
|
52
|
+
* History of resolution attempts on a conflict.
|
|
53
|
+
*/
|
|
54
|
+
resolutionHistory(conflictId: ConflictId): Promise<readonly {
|
|
55
|
+
readonly at: IsoTimestamp;
|
|
56
|
+
readonly fromStatus: ConflictStatus;
|
|
57
|
+
readonly toStatus: ConflictStatus;
|
|
58
|
+
readonly reason: ResolveReason;
|
|
59
|
+
}[]>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=conflict-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict-registry.d.ts","sourceRoot":"","sources":["../../src/storage/conflict-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAE1F,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IACjD,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,uBAAuB;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,yCAAyC;IACzC,QAAQ,CAAC,qBAAqB,EAAE,SAAS,UAAU,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,sFAAsF;IACtF,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAE1D;;OAEG;IACH,GAAG,CACD,UAAU,EAAE,UAAU,EACtB,qBAAqB,EAAE,SAAS,UAAU,EAAE,GAC3C,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAElC;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAAC;IAEjE;;;OAGG;IACH,OAAO,CACL,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC,EACjD,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAElC;;OAEG;IACH,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAChD,SAAS;QACP,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;QAC1B,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;QACpC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;QAClC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;KAChC,EAAE,CACJ,CAAC;CACH"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConflictRegistry — first-class store of contradictions.
|
|
3
|
+
*
|
|
4
|
+
* Hard contracts (from specs/aletheia-memory-authority-v0.md §6):
|
|
5
|
+
* - Contradictions are NEVER overwritten by summaries.
|
|
6
|
+
* - Unresolved current-source conflicts preserve candidate claims.
|
|
7
|
+
* - Summaries must not hide conflicts.
|
|
8
|
+
* - Tombstones/rejections remain non-actionable through summaries.
|
|
9
|
+
*
|
|
10
|
+
* Like atoms, conflict records are append-only; resolution is itself a new
|
|
11
|
+
* record (or an update to the status field via an explicit `resolve` call,
|
|
12
|
+
* which is recorded in history).
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=conflict-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict-registry.js","sourceRoot":"","sources":["../../src/storage/conflict-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EventLedger — append-only record of raw events.
|
|
3
|
+
*
|
|
4
|
+
* Hard contract (from specs/aletheia-memory-authority-v0.md §1):
|
|
5
|
+
* - APPEND ONLY. No update, no delete. Tombstones are themselves events.
|
|
6
|
+
* - Events are evidence, not authority.
|
|
7
|
+
* - Order is stable: an event written at t cannot be re-ordered against
|
|
8
|
+
* an event written at t' > t.
|
|
9
|
+
*
|
|
10
|
+
* Implementations must enforce all of the above at the storage level, not
|
|
11
|
+
* trust callers.
|
|
12
|
+
*/
|
|
13
|
+
import type { Scope, Visibility } from '../types/enums.js';
|
|
14
|
+
import type { Event } from '../types/event.js';
|
|
15
|
+
import type { AgentId, EventId, IsoTimestamp } from '../types/primitives.js';
|
|
16
|
+
/**
|
|
17
|
+
* Filter passed to `query`. All fields optional; an empty filter returns
|
|
18
|
+
* everything the caller is permitted to see.
|
|
19
|
+
*/
|
|
20
|
+
export interface EventQuery {
|
|
21
|
+
/** Filter to events from a specific agent. */
|
|
22
|
+
readonly agentId?: AgentId;
|
|
23
|
+
/** Filter to events recorded at or after this time. */
|
|
24
|
+
readonly since?: IsoTimestamp;
|
|
25
|
+
/** Filter to events recorded at or before this time. */
|
|
26
|
+
readonly until?: IsoTimestamp;
|
|
27
|
+
/** Filter to a specific scope. */
|
|
28
|
+
readonly scope?: Scope;
|
|
29
|
+
/**
|
|
30
|
+
* The visibility planes the caller is permitted to see.
|
|
31
|
+
* Spec rule: permission filtering happens BEFORE any other selection.
|
|
32
|
+
*/
|
|
33
|
+
readonly permittedVisibilities: readonly Visibility[];
|
|
34
|
+
/** Max results to return (default implementation-defined). */
|
|
35
|
+
readonly limit?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface EventLedger {
|
|
38
|
+
/**
|
|
39
|
+
* Append an event to the ledger.
|
|
40
|
+
* @returns the EventId actually stored. Implementations may generate the ID
|
|
41
|
+
* if `event.eventId` is left to the implementation.
|
|
42
|
+
* @throws if the event is malformed or if an event with the same ID exists.
|
|
43
|
+
* Append-only means duplicate IDs are an error, not an overwrite.
|
|
44
|
+
*/
|
|
45
|
+
append(event: Event): Promise<EventId>;
|
|
46
|
+
/**
|
|
47
|
+
* Retrieve a specific event by ID. Returns null if not found OR if the
|
|
48
|
+
* caller does not have visibility to it (the ledger does not leak existence).
|
|
49
|
+
*/
|
|
50
|
+
get(eventId: EventId, permittedVisibilities: readonly Visibility[]): Promise<Event | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Query events. Returns in `occurredAt` ascending order (oldest first).
|
|
53
|
+
* Permission filtering applies before any other selection.
|
|
54
|
+
*/
|
|
55
|
+
query(filter: EventQuery): Promise<readonly Event[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Count events matching the filter. Useful for coverage receipts.
|
|
58
|
+
*/
|
|
59
|
+
count(filter: EventQuery): Promise<number>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=event-ledger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-ledger.d.ts","sourceRoot":"","sources":["../../src/storage/event-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE7E;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,uDAAuD;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAC9B,wDAAwD;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAC9B,kCAAkC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,EAAE,SAAS,UAAU,EAAE,CAAC;IACtD,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvC;;;OAGG;IACH,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,SAAS,UAAU,EAAE,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAE3F;;;OAGG;IACH,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;IAErD;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5C"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EventLedger — append-only record of raw events.
|
|
3
|
+
*
|
|
4
|
+
* Hard contract (from specs/aletheia-memory-authority-v0.md §1):
|
|
5
|
+
* - APPEND ONLY. No update, no delete. Tombstones are themselves events.
|
|
6
|
+
* - Events are evidence, not authority.
|
|
7
|
+
* - Order is stable: an event written at t cannot be re-ordered against
|
|
8
|
+
* an event written at t' > t.
|
|
9
|
+
*
|
|
10
|
+
* Implementations must enforce all of the above at the storage level, not
|
|
11
|
+
* trust callers.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=event-ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-ledger.js","sourceRoot":"","sources":["../../src/storage/event-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage interfaces. The implementations live in adapter packages
|
|
3
|
+
* (e.g. @aletheia-labs/store-sqlite).
|
|
4
|
+
*/
|
|
5
|
+
export * from './event-ledger.js';
|
|
6
|
+
export * from './memory-store.js';
|
|
7
|
+
export * from './conflict-registry.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage interfaces. The implementations live in adapter packages
|
|
3
|
+
* (e.g. @aletheia-labs/store-sqlite).
|
|
4
|
+
*/
|
|
5
|
+
export * from './event-ledger.js';
|
|
6
|
+
export * from './memory-store.js';
|
|
7
|
+
export * from './conflict-registry.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MemoryStore — persistent store of MemoryAtoms.
|
|
3
|
+
*
|
|
4
|
+
* Hard contracts (from specs/aletheia-memory-authority-v0.md):
|
|
5
|
+
* - Atoms are append-only by ID. "Modifying" an atom produces a successor
|
|
6
|
+
* atom with a `supersedes` link; the original is never mutated.
|
|
7
|
+
* - Status transitions are tracked explicitly via `transitionStatus` —
|
|
8
|
+
* never a free-form UPDATE.
|
|
9
|
+
* - Permission filtering precedes selection. Always.
|
|
10
|
+
* - Sealed and human_required atoms never come back from `query` for
|
|
11
|
+
* non-authorized callers (the store does not leak existence).
|
|
12
|
+
*/
|
|
13
|
+
import type { MemoryStatus, Scope, Visibility } from '../types/enums.js';
|
|
14
|
+
import type { MemoryAtom } from '../types/memory-atom.js';
|
|
15
|
+
import type { AgentId, IsoTimestamp, MemoryId } from '../types/primitives.js';
|
|
16
|
+
/**
|
|
17
|
+
* Reason a status transition was requested. The store records this in an
|
|
18
|
+
* audit log alongside the transition.
|
|
19
|
+
*/
|
|
20
|
+
export interface StatusTransitionReason {
|
|
21
|
+
/** Free-form rationale. Short. */
|
|
22
|
+
readonly rationale: string;
|
|
23
|
+
/** Agent or operator responsible for the transition. */
|
|
24
|
+
readonly actor: AgentId;
|
|
25
|
+
/** Optional related conflict that motivated the transition. */
|
|
26
|
+
readonly conflictId?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface StatusTransitionOptions {
|
|
29
|
+
/**
|
|
30
|
+
* Effective transition timestamp. Deterministic runners pass their logical
|
|
31
|
+
* clock here; stores default to their local clock when omitted.
|
|
32
|
+
*/
|
|
33
|
+
readonly at?: IsoTimestamp;
|
|
34
|
+
}
|
|
35
|
+
export interface MemoryQuery {
|
|
36
|
+
/** Filter to atoms of these statuses. */
|
|
37
|
+
readonly statuses?: readonly MemoryStatus[];
|
|
38
|
+
/** Filter to a specific scope. */
|
|
39
|
+
readonly scope?: Scope;
|
|
40
|
+
/**
|
|
41
|
+
* The visibility planes the caller is permitted to see.
|
|
42
|
+
* Spec rule: permission filtering happens BEFORE any other selection.
|
|
43
|
+
*/
|
|
44
|
+
readonly permittedVisibilities: readonly Visibility[];
|
|
45
|
+
/** Filter to atoms valid at this instant (default: now). */
|
|
46
|
+
readonly validAt?: IsoTimestamp;
|
|
47
|
+
/** Max results to return. */
|
|
48
|
+
readonly limit?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Outcome of a status transition request.
|
|
52
|
+
*
|
|
53
|
+
* `applied` means the transition was recorded; `rejected` means the store
|
|
54
|
+
* refused (illegal transition, permission denial, etc.). Rejections never
|
|
55
|
+
* throw — fail-closed returns a structured value.
|
|
56
|
+
*/
|
|
57
|
+
export type StatusTransitionResult = {
|
|
58
|
+
readonly kind: 'applied';
|
|
59
|
+
readonly atom: MemoryAtom;
|
|
60
|
+
} | {
|
|
61
|
+
readonly kind: 'rejected';
|
|
62
|
+
readonly reason: string;
|
|
63
|
+
};
|
|
64
|
+
export interface MemoryStore {
|
|
65
|
+
/**
|
|
66
|
+
* Insert a new atom. Atoms are immutable once written; ID collisions throw.
|
|
67
|
+
*/
|
|
68
|
+
insert(atom: MemoryAtom): Promise<MemoryAtom>;
|
|
69
|
+
/**
|
|
70
|
+
* Retrieve an atom by ID, subject to permission filtering.
|
|
71
|
+
* Returns null both when the atom does not exist and when the caller cannot see it.
|
|
72
|
+
*/
|
|
73
|
+
get(memoryId: MemoryId, permittedVisibilities: readonly Visibility[]): Promise<MemoryAtom | null>;
|
|
74
|
+
/**
|
|
75
|
+
* Query atoms. Returns in `validFrom` descending order (newest first)
|
|
76
|
+
* unless an implementation documents otherwise.
|
|
77
|
+
*/
|
|
78
|
+
query(filter: MemoryQuery): Promise<readonly MemoryAtom[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Transition an atom's status. Records the transition in an internal log.
|
|
81
|
+
* Never a free-form UPDATE — only documented transitions are accepted.
|
|
82
|
+
*/
|
|
83
|
+
transitionStatus(memoryId: MemoryId, nextStatus: MemoryStatus, reason: StatusTransitionReason, options?: StatusTransitionOptions): Promise<StatusTransitionResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Get the full status history of an atom. Useful for audit and Phase 2 dynamics.
|
|
86
|
+
*/
|
|
87
|
+
statusHistory(memoryId: MemoryId): Promise<readonly {
|
|
88
|
+
readonly at: IsoTimestamp;
|
|
89
|
+
readonly fromStatus: MemoryStatus | null;
|
|
90
|
+
readonly toStatus: MemoryStatus;
|
|
91
|
+
readonly reason: StatusTransitionReason;
|
|
92
|
+
}[]>;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=memory-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../src/storage/memory-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAE9E;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAC5C,kCAAkC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,EAAE,SAAS,UAAU,EAAE,CAAC;IACtD,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,6BAA6B;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,sBAAsB,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE9C;;;OAGG;IACH,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,qBAAqB,EAAE,SAAS,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAElG;;;OAGG;IACH,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;IAE3D;;;OAGG;IACH,gBAAgB,CACd,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,YAAY,EACxB,MAAM,EAAE,sBAAsB,EAC9B,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEnC;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CACxC,SAAS;QACP,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;QAC1B,QAAQ,CAAC,UAAU,EAAE,YAAY,GAAG,IAAI,CAAC;QACzC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;QAChC,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;KACzC,EAAE,CACJ,CAAC;CACH"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MemoryStore — persistent store of MemoryAtoms.
|
|
3
|
+
*
|
|
4
|
+
* Hard contracts (from specs/aletheia-memory-authority-v0.md):
|
|
5
|
+
* - Atoms are append-only by ID. "Modifying" an atom produces a successor
|
|
6
|
+
* atom with a `supersedes` link; the original is never mutated.
|
|
7
|
+
* - Status transitions are tracked explicitly via `transitionStatus` —
|
|
8
|
+
* never a free-form UPDATE.
|
|
9
|
+
* - Permission filtering precedes selection. Always.
|
|
10
|
+
* - Sealed and human_required atoms never come back from `query` for
|
|
11
|
+
* non-authorized callers (the store does not leak existence).
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=memory-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../src/storage/memory-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|