@unson/brainbase-mcp 0.6.0 → 0.8.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/contracts/foundation/graph-history.sql +634 -0
- package/contracts/judgment-value-proof/schema.json +43 -1
- package/dist/canonical-task-contract.d.ts +9 -0
- package/dist/canonical-task-contract.js +39 -0
- package/dist/canonical-task-principal.d.ts +16 -0
- package/dist/canonical-task-principal.js +36 -0
- package/dist/canonical-task-service.d.ts +251 -0
- package/dist/canonical-task-service.js +820 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +107 -0
- package/dist/company-os-evaluation.d.ts +193 -0
- package/dist/company-os-evaluation.js +1150 -0
- package/dist/company-os-impact-review.d.ts +248 -0
- package/dist/company-os-impact-review.js +663 -0
- package/dist/company-os-learning-adoption.d.ts +288 -0
- package/dist/company-os-learning-adoption.js +944 -0
- package/dist/company-os-objectives.d.ts +63 -0
- package/dist/company-os-objectives.js +234 -0
- package/dist/company-os-receipt-adapter.d.ts +109 -0
- package/dist/company-os-receipt-adapter.js +636 -0
- package/dist/constraint-exception-store.d.ts +23 -0
- package/dist/constraint-exception-store.js +108 -0
- package/dist/constraint-resolution.d.ts +175 -0
- package/dist/constraint-resolution.js +922 -0
- package/dist/decision-adapter.d.ts +145 -0
- package/dist/decision-adapter.js +586 -0
- package/dist/durable-wait-http.d.ts +51 -0
- package/dist/durable-wait-http.js +497 -0
- package/dist/durable-waits.d.ts +234 -0
- package/dist/durable-waits.js +944 -0
- package/dist/execution-authority-http.d.ts +28 -0
- package/dist/execution-authority-http.js +359 -0
- package/dist/execution-authority.d.ts +201 -0
- package/dist/execution-authority.js +634 -0
- package/dist/foundation-authenticated-tools.d.ts +56 -0
- package/dist/foundation-authenticated-tools.js +347 -0
- package/dist/foundation-catalog.d.ts +26 -0
- package/dist/foundation-catalog.js +206 -0
- package/dist/foundation-constraint-store.d.ts +50 -0
- package/dist/foundation-constraint-store.js +215 -0
- package/dist/foundation-graph-http.d.ts +43 -0
- package/dist/foundation-graph-http.js +243 -0
- package/dist/foundation-graph-write.d.ts +90 -0
- package/dist/foundation-graph-write.js +447 -0
- package/dist/foundation-http.d.ts +90 -0
- package/dist/foundation-http.js +439 -0
- package/dist/foundation-public-provider.d.ts +140 -0
- package/dist/foundation-public-provider.js +192 -0
- package/dist/foundation-store.d.ts +132 -0
- package/dist/foundation-store.js +654 -0
- package/dist/graph-corrections.d.ts +157 -0
- package/dist/graph-corrections.js +620 -0
- package/dist/graph-foundation-reader.d.ts +60 -0
- package/dist/graph-foundation-reader.js +494 -0
- package/dist/graph-retrieval.d.ts +6 -1
- package/dist/graph-revision-reader.d.ts +80 -0
- package/dist/graph-revision-reader.js +246 -0
- package/dist/graph-web-http.d.ts +26 -0
- package/dist/graph-web-http.js +215 -0
- package/dist/graph-web.d.ts +364 -0
- package/dist/graph-web.js +639 -0
- package/dist/judgment-dag-composition.d.ts +224 -0
- package/dist/judgment-dag-composition.js +731 -0
- package/dist/judgment-dag.d.ts +2 -0
- package/dist/judgment-dag.js +1 -0
- package/dist/judgment-problem-snapshot.d.ts +213 -0
- package/dist/judgment-problem-snapshot.js +1073 -0
- package/dist/judgment-value-proof-review.d.ts +166 -0
- package/dist/judgment-value-proof-review.js +437 -0
- package/dist/judgment-value-proof.d.ts +28 -1
- package/dist/judgment-value-proof.js +53 -8
- package/dist/judgment-view-http.d.ts +22 -0
- package/dist/judgment-view-http.js +128 -0
- package/dist/judgment-view.d.ts +222 -0
- package/dist/judgment-view.js +627 -0
- package/dist/knowledge-adapter.d.ts +112 -0
- package/dist/knowledge-adapter.js +691 -0
- package/dist/knowledge-continuation.d.ts +127 -0
- package/dist/knowledge-continuation.js +446 -0
- package/dist/knowledge-lookup.d.ts +178 -0
- package/dist/knowledge-lookup.js +758 -0
- package/dist/local-web-fetch-bridge.d.ts +5 -0
- package/dist/local-web-fetch-bridge.js +37 -0
- package/dist/local-web-host.d.ts +109 -0
- package/dist/local-web-host.js +688 -0
- package/dist/local-web-security.d.ts +25 -0
- package/dist/local-web-security.js +95 -0
- package/dist/ontology-foundation.d.ts +209 -0
- package/dist/ontology-foundation.js +1000 -0
- package/dist/ontology.d.ts +13 -0
- package/dist/ontology.js +14 -0
- package/dist/organization-connection.d.ts +164 -0
- package/dist/organization-connection.js +428 -0
- package/dist/organization-graph.d.ts +15 -0
- package/dist/organization-graph.js +24 -4
- package/dist/personal-knowledge.d.ts +132 -0
- package/dist/personal-knowledge.js +779 -0
- package/dist/personal-memory-handover.d.ts +108 -0
- package/dist/personal-memory-handover.js +369 -0
- package/dist/philosophy-revision-reader.d.ts +85 -0
- package/dist/philosophy-revision-reader.js +241 -0
- package/dist/portable-graph.d.ts +24 -0
- package/dist/portable-graph.js +77 -0
- package/dist/problem-candidates.d.ts +149 -0
- package/dist/problem-candidates.js +898 -0
- package/dist/problem-selection.d.ts +238 -0
- package/dist/problem-selection.js +995 -0
- package/dist/resource-reservation-http.d.ts +31 -0
- package/dist/resource-reservation-http.js +371 -0
- package/dist/resource-reservations.d.ts +221 -0
- package/dist/resource-reservations.js +577 -0
- package/dist/server.d.ts +104 -2
- package/dist/server.js +186 -4
- package/dist/ssot.d.ts +6 -1
- package/dist/ssot.js +63 -5
- package/dist/streamable-http.d.ts +42 -0
- package/dist/streamable-http.js +288 -0
- package/dist/types.d.ts +20 -0
- package/dist/value-proof-review-http.d.ts +25 -0
- package/dist/value-proof-review-http.js +185 -0
- package/dist/world-model.d.ts +199 -0
- package/dist/world-model.js +955 -0
- package/package.json +230 -3
- package/ui/brainbase-tokens.css +56 -0
- package/ui/graph-own-share.js +367 -0
- package/ui/graph-projects-view.css +23 -0
- package/ui/graph-projects-view.js +730 -0
- package/ui/graph-registry-view.css +101 -0
- package/ui/graph-registry-view.js +804 -0
- package/ui/graph-view-shared.css +522 -0
- package/ui/graph-view-shared.js +1227 -0
- package/ui/judgment-view.css +312 -0
- package/ui/judgment-view.js +508 -0
- package/ui/local-web-shell.css +396 -0
- package/ui/local-web-shell.js +378 -0
- package/ui/objective-editor-http-port.js +154 -0
- package/ui/objective-editor.css +286 -0
- package/ui/objective-editor.js +1586 -0
- package/ui/outcome-knowledge.css +50 -14
- package/ui/outcome-knowledge.js +15 -1
- package/ui/outcome-mana.css +91 -14
- package/ui/outcome-mana.js +958 -61
- package/ui/value-proof-review.css +504 -0
- package/ui/value-proof-review.js +1104 -0
- package/ui/workspace-kit.css +485 -0
- package/ui/workspace-kit.js +229 -0
- package/ui/world-model-view.css +188 -0
- package/ui/world-model-view.js +486 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createJudgmentProblemPhilosophyReferenceResolver } from './philosophy-revision-reader.js';
|
|
3
|
+
import { judgmentFoundationContract } from './ontology-foundation.js';
|
|
4
|
+
import { digestFoundationDefinition } from './foundation-catalog.js';
|
|
5
|
+
import { createJudgmentProblemFoundationReferenceProvider, validateJudgmentProblemSnapshot, JudgmentProblemSnapshotError } from './judgment-problem-snapshot.js';
|
|
6
|
+
export const FOUNDATION_PUBLIC_CONTRACT_VERSION = 'foundation-public.v1';
|
|
7
|
+
const revision = z.string().regex(/^[1-9]\d*$/u);
|
|
8
|
+
const digest = z.string().regex(/^sha256:[0-9a-f]{64}$/u).transform((value) => value);
|
|
9
|
+
const readSchema = z.object({
|
|
10
|
+
type: z.enum(['objective', 'variable', 'model', 'constraint', 'philosophy']),
|
|
11
|
+
id: z.string().min(1), revision, digest: digest.optional()
|
|
12
|
+
}).strict();
|
|
13
|
+
const referenceSchema = z.object({
|
|
14
|
+
kind: z.enum(['objective', 'variable', 'model', 'constraint', 'philosophy']),
|
|
15
|
+
id: z.string().min(1), revision, digest,
|
|
16
|
+
scope: z.object({ type: z.enum(['personal', 'project', 'organization']), id: z.string().min(1) }).strict(),
|
|
17
|
+
valid_from: z.string().datetime({ offset: true }),
|
|
18
|
+
valid_to: z.string().datetime({ offset: true }).nullable().optional()
|
|
19
|
+
}).strict();
|
|
20
|
+
const problemSchema = z.object({ snapshot: z.unknown() }).strict();
|
|
21
|
+
const validateSchema = z.object({
|
|
22
|
+
reference: referenceSchema,
|
|
23
|
+
phase: z.enum(['read', 'historical_read']).default('read')
|
|
24
|
+
}).strict();
|
|
25
|
+
/** The host owns canonical storage and authentication. No body can supply either. */
|
|
26
|
+
export function createFoundationPublicProvider(options) {
|
|
27
|
+
const resolvePhilosophy = options.philosophyReader
|
|
28
|
+
? createJudgmentProblemPhilosophyReferenceResolver({ reader: options.philosophyReader })
|
|
29
|
+
: undefined;
|
|
30
|
+
function assertContext(context) {
|
|
31
|
+
if (!context || typeof context.principal !== 'string' || !context.principal.trim()) {
|
|
32
|
+
throw new Error('foundation_trusted_context_required');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function referenceProvider(context) {
|
|
36
|
+
const provider = createJudgmentProblemFoundationReferenceProvider({
|
|
37
|
+
store: { read: (reference) => options.store.read(reference, context) },
|
|
38
|
+
resolveOther: (input) => input.reference.kind === 'philosophy'
|
|
39
|
+
? resolvePhilosophy?.(input) ?? { status: 'unresolved', message: 'Philosophy reader is not connected' }
|
|
40
|
+
: options.resolveOther?.(input) ?? { status: 'unresolved', message: `No provider is registered for ${input.reference.kind}` }
|
|
41
|
+
});
|
|
42
|
+
return { resolve(input) {
|
|
43
|
+
if (context.scope && !context.scope.subjectIds.includes(input.reference.scope.id)) {
|
|
44
|
+
return { status: 'unauthorized', message: 'Reference is outside the trusted scope' };
|
|
45
|
+
}
|
|
46
|
+
return provider.resolve(input);
|
|
47
|
+
} };
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
describe() {
|
|
51
|
+
return {
|
|
52
|
+
contractVersion: FOUNDATION_PUBLIC_CONTRACT_VERSION,
|
|
53
|
+
foundation: judgmentFoundationContract,
|
|
54
|
+
connection: 'configured',
|
|
55
|
+
storage: 'canonical-provider',
|
|
56
|
+
philosophy: { kind: 'philosophy', canonicalSource: 'host-provider', connected: Boolean(options.philosophyReader), immutableRevisionRequired: true },
|
|
57
|
+
historicalRead: 'current-acl-and-exact-digest',
|
|
58
|
+
executionPermission: 'none'
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
async read(raw, context) {
|
|
62
|
+
assertContext(context);
|
|
63
|
+
const args = readSchema.parse(raw);
|
|
64
|
+
if (args.type === 'philosophy') {
|
|
65
|
+
if (!options.philosophyReader?.readCanonical)
|
|
66
|
+
throw new Error('foundation_provider_unconfigured');
|
|
67
|
+
const result = await options.philosophyReader.readCanonical({ id: args.id, revision: args.revision, context });
|
|
68
|
+
if (result.status !== 'resolved') {
|
|
69
|
+
throw new Error(result.status === 'unauthorized' ? 'authorization_denied' : result.status === 'missing' ? 'foundation_revision_missing' : 'foundation_digest_or_identity_mismatch');
|
|
70
|
+
}
|
|
71
|
+
const record = result.record;
|
|
72
|
+
if (record.id !== args.id || record.revision !== args.revision || (args.digest && args.digest !== record.digest)) {
|
|
73
|
+
throw new Error('foundation_digest_or_identity_mismatch');
|
|
74
|
+
}
|
|
75
|
+
if (context.scope && !context.scope.subjectIds.includes(record.applicability.scope.id))
|
|
76
|
+
throw new Error('scope_violation');
|
|
77
|
+
const resolved = await createJudgmentProblemPhilosophyReferenceResolver({ reader: { read: () => result } })({
|
|
78
|
+
reference: { kind: 'philosophy', id: record.id, revision: record.revision, digest: record.digest,
|
|
79
|
+
scope: record.applicability.scope, valid_from: record.applicability.validFrom,
|
|
80
|
+
...(record.applicability.validUntil ? { valid_to: record.applicability.validUntil } : {}) },
|
|
81
|
+
phase: 'historical_read', context
|
|
82
|
+
});
|
|
83
|
+
if (resolved.status !== 'resolved')
|
|
84
|
+
throw new Error(resolved.status === 'unauthorized' ? 'authorization_denied' : 'foundation_digest_or_identity_mismatch');
|
|
85
|
+
return record;
|
|
86
|
+
}
|
|
87
|
+
const record = await options.store.read({ type: args.type, id: args.id, revision: args.revision }, context);
|
|
88
|
+
if (!record)
|
|
89
|
+
throw new Error('foundation_revision_missing');
|
|
90
|
+
if (record.definition.id !== args.id || record.definition.type !== args.type || record.definition.revision !== args.revision
|
|
91
|
+
|| digestFoundationDefinition(record.definition) !== record.digest || (args.digest && args.digest !== record.digest)) {
|
|
92
|
+
throw new Error('foundation_digest_or_identity_mismatch');
|
|
93
|
+
}
|
|
94
|
+
return record;
|
|
95
|
+
},
|
|
96
|
+
async validate(raw, context) {
|
|
97
|
+
assertContext(context);
|
|
98
|
+
const args = validateSchema.parse(raw);
|
|
99
|
+
return referenceProvider(context).resolve({ reference: args.reference, phase: args.phase, context });
|
|
100
|
+
},
|
|
101
|
+
async validateProblem(raw, context) {
|
|
102
|
+
assertContext(context);
|
|
103
|
+
const args = problemSchema.parse(raw);
|
|
104
|
+
const owner = args.snapshot?.owner_scope;
|
|
105
|
+
if (context.scope && owner && !context.scope.subjectIds.includes(owner.id)) {
|
|
106
|
+
throw new JudgmentProblemSnapshotError('unauthorized', 'Snapshot owner is outside the trusted scope');
|
|
107
|
+
}
|
|
108
|
+
await validateJudgmentProblemSnapshot({
|
|
109
|
+
snapshot: args.snapshot,
|
|
110
|
+
access: context,
|
|
111
|
+
referenceProvider: referenceProvider(context)
|
|
112
|
+
});
|
|
113
|
+
return { status: 'resolved', executionPermission: 'none' };
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
export const foundationPublicToolDefinitions = [
|
|
118
|
+
{ name: 'foundation_describe', description: 'Describe the connected versioned judgment foundation contract.', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
119
|
+
{ name: 'foundation_read', description: 'Read an exact canonical foundation revision under current access rights.', inputSchema: {
|
|
120
|
+
type: 'object', required: ['type', 'id', 'revision'], additionalProperties: false,
|
|
121
|
+
properties: { type: { type: 'string', enum: ['objective', 'variable', 'model', 'constraint', 'philosophy'] }, id: { type: 'string' }, revision: { type: 'string' }, digest: { type: 'string' } }
|
|
122
|
+
} },
|
|
123
|
+
{ name: 'foundation_validate_reference', description: 'Validate an exact foundation or philosophy reference for judgment, including its dependencies.', inputSchema: {
|
|
124
|
+
type: 'object', required: ['reference'], additionalProperties: false,
|
|
125
|
+
properties: { reference: { type: 'object', required: ['kind', 'id', 'revision', 'digest', 'scope', 'valid_from'], additionalProperties: false,
|
|
126
|
+
properties: { kind: { type: 'string', enum: ['objective', 'variable', 'model', 'constraint', 'philosophy'] }, id: { type: 'string' }, revision: { type: 'string' }, digest: { type: 'string' }, scope: { type: 'object', required: ['type', 'id'], additionalProperties: false, properties: { type: { type: 'string', enum: ['personal', 'project', 'organization'] }, id: { type: 'string' } } }, valid_from: { type: 'string' }, valid_to: { type: ['string', 'null'] } } }, phase: { type: 'string', enum: ['read', 'historical_read'] } }
|
|
127
|
+
} },
|
|
128
|
+
{ name: 'foundation_validate_problem', description: 'Validate a complete judgment snapshot and canonical observation measurement conditions. Grants no execution permission.', inputSchema: { type: 'object', required: ['snapshot'], properties: { snapshot: { type: 'object' } }, additionalProperties: false } }
|
|
129
|
+
];
|
|
130
|
+
export async function callFoundationPublicTool(name, args, connection) {
|
|
131
|
+
if (!connection)
|
|
132
|
+
throw new Error('foundation_provider_unconfigured');
|
|
133
|
+
const context = await connection.resolveContext();
|
|
134
|
+
if (!context?.principal?.trim())
|
|
135
|
+
throw new Error('foundation_trusted_context_required');
|
|
136
|
+
if (name === 'foundation_describe') {
|
|
137
|
+
z.object({}).strict().parse(args);
|
|
138
|
+
return connection.provider.describe();
|
|
139
|
+
}
|
|
140
|
+
if (name === 'foundation_read')
|
|
141
|
+
return connection.provider.read(args, context);
|
|
142
|
+
if (name === 'foundation_validate_problem')
|
|
143
|
+
return connection.provider.validateProblem(args, context);
|
|
144
|
+
if (name === 'foundation_validate_reference')
|
|
145
|
+
return connection.provider.validate(args, context);
|
|
146
|
+
throw new Error('foundation_tool_unknown');
|
|
147
|
+
}
|
|
148
|
+
/** Mounted with createFoundationHttpRouter, whose host resolves auth and CSRF. */
|
|
149
|
+
export function createFoundationPublicRoute(provider) {
|
|
150
|
+
const prefix = '/api/foundation';
|
|
151
|
+
const matches = (request) => {
|
|
152
|
+
const pathname = new URL(request.url).pathname;
|
|
153
|
+
return pathname === `${prefix}/contract` || pathname === `${prefix}/judgment-references/validate` || pathname === `${prefix}/judgment-problems/validate`
|
|
154
|
+
|| /^\/api\/foundation\/definitions\/[^/]+\/[^/]+$/u.test(pathname);
|
|
155
|
+
};
|
|
156
|
+
const json = (status, value) => new Response(JSON.stringify(value), { status, headers: { 'content-type': 'application/json' } });
|
|
157
|
+
return {
|
|
158
|
+
name: 'foundation-public', methods: ['GET', 'POST'], paths: [`${prefix}/contract`, `${prefix}/definitions/:type/:id`, `${prefix}/judgment-references/validate`, `${prefix}/judgment-problems/validate`], matches,
|
|
159
|
+
async handle(request, { context }) {
|
|
160
|
+
try {
|
|
161
|
+
const url = new URL(request.url);
|
|
162
|
+
for (const key of url.searchParams.keys())
|
|
163
|
+
if (!['scope_id', 'revision', 'digest'].includes(key))
|
|
164
|
+
return json(400, { error: { code: 'invalid_query' } });
|
|
165
|
+
if (url.pathname === `${prefix}/contract` && request.method === 'GET')
|
|
166
|
+
return json(200, provider.describe());
|
|
167
|
+
if ([`${prefix}/judgment-references/validate`, `${prefix}/judgment-problems/validate`].includes(url.pathname) && request.method === 'POST') {
|
|
168
|
+
if (Number(request.headers.get('content-length')) > 65_536)
|
|
169
|
+
return json(413, { error: { code: 'body_too_large' } });
|
|
170
|
+
const body = await request.text();
|
|
171
|
+
if (new TextEncoder().encode(body).length > 65_536)
|
|
172
|
+
return json(413, { error: { code: 'body_too_large' } });
|
|
173
|
+
const result = url.pathname.endsWith('/judgment-problems/validate')
|
|
174
|
+
? await provider.validateProblem(JSON.parse(body), context)
|
|
175
|
+
: await provider.validate(JSON.parse(body), context);
|
|
176
|
+
return json(result.status === 'resolved' ? 200 : result.status === 'unauthorized' ? 403 : 422, result);
|
|
177
|
+
}
|
|
178
|
+
const parts = /^\/api\/foundation\/definitions\/([^/]+)\/([^/]+)$/u.exec(url.pathname);
|
|
179
|
+
if (parts && request.method === 'GET')
|
|
180
|
+
return json(200, await provider.read({ type: decodeURIComponent(parts[1]), id: decodeURIComponent(parts[2]), revision: url.searchParams.get('revision'), ...(url.searchParams.has('digest') ? { digest: url.searchParams.get('digest') } : {}) }, context));
|
|
181
|
+
return json(405, { error: { code: 'method_not_allowed' } });
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
const rawCode = error instanceof Error && 'code' in error ? String(error.code) : error instanceof Error ? error.message : '';
|
|
185
|
+
const knownCodes = ['foundation_provider_unconfigured', 'authorization_denied', 'scope_violation', 'foundation_revision_missing', 'foundation_digest_or_identity_mismatch', 'foundation_trusted_context_required', 'corrupt_catalog', 'unauthorized', 'invalid_request', 'unresolved_constraint', 'integrity_mismatch', 'missing_reference', 'not_applicable'];
|
|
186
|
+
const code = knownCodes.includes(rawCode) ? rawCode : 'foundation_read_failed';
|
|
187
|
+
const status = code === 'foundation_provider_unconfigured' ? 503 : ['authorization_denied', 'scope_violation', 'unauthorized'].includes(code) ? 403 : code === 'foundation_revision_missing' ? 404 : code === 'invalid_request' || error instanceof z.ZodError || error instanceof SyntaxError || error instanceof URIError ? 400 : 422;
|
|
188
|
+
return json(status, { error: { code: status === 400 ? 'invalid_request' : code, ...(error instanceof JudgmentProblemSnapshotError && error.reference ? { reference: { kind: error.reference.kind, id: error.reference.id, revision: error.reference.revision } } : {}) } });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { FoundationDefinition, FoundationAcl, FoundationRelationEndpoint, FoundationRelationReference, FoundationRevision, FoundationScope, FoundationType } from './ontology-foundation.js';
|
|
2
|
+
import type { FoundationCatalogRecord, PersonalOs } from './types.js';
|
|
3
|
+
import type { FoundationRef } from './foundation-catalog.js';
|
|
4
|
+
export interface FoundationStoreContext {
|
|
5
|
+
/** Identity resolved by the caller's trusted auth boundary. */
|
|
6
|
+
principal: string;
|
|
7
|
+
/**
|
|
8
|
+
* Optional trusted subject scope. The request body never supplies this
|
|
9
|
+
* value; organization adapters may inject it for the default policy.
|
|
10
|
+
*/
|
|
11
|
+
scope?: FoundationScope;
|
|
12
|
+
}
|
|
13
|
+
export type FoundationStoreAction = 'create' | 'read' | 'update' | 'list' | 'link';
|
|
14
|
+
/**
|
|
15
|
+
* Metadata returned for a non-foundation relation endpoint (for example a
|
|
16
|
+
* Story). It deliberately contains no Story body or private projection.
|
|
17
|
+
* `acl` and `scope` are the current values used for authorization even when
|
|
18
|
+
* `revision` points at an older immutable revision.
|
|
19
|
+
*/
|
|
20
|
+
export interface FoundationEndpointResource {
|
|
21
|
+
id: string;
|
|
22
|
+
type: FoundationRelationEndpoint;
|
|
23
|
+
revision: string;
|
|
24
|
+
currentRevision: string;
|
|
25
|
+
acl: FoundationAcl;
|
|
26
|
+
scope: FoundationScope;
|
|
27
|
+
}
|
|
28
|
+
export type FoundationAuthorizationResource = FoundationDefinition | FoundationEndpointResource;
|
|
29
|
+
export interface FoundationEndpointResolverRequest {
|
|
30
|
+
endpoint: {
|
|
31
|
+
id: string;
|
|
32
|
+
type: FoundationRelationEndpoint;
|
|
33
|
+
revision?: string;
|
|
34
|
+
};
|
|
35
|
+
context: FoundationStoreContext;
|
|
36
|
+
/** The current aggregate loaded while the canonical SSOT lock is held. */
|
|
37
|
+
current: PersonalOs;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Trusted adapter for endpoint types that are not stored by this foundation
|
|
41
|
+
* catalog. A resolver is called only inside the canonical mutation lock and
|
|
42
|
+
* must return authorization metadata, never a private endpoint document.
|
|
43
|
+
*/
|
|
44
|
+
export interface FoundationEndpointResolver {
|
|
45
|
+
resolve(request: FoundationEndpointResolverRequest): FoundationEndpointResource | null | Promise<FoundationEndpointResource | null>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Minimal metadata record used by the OSS standalone Story resolver. This is
|
|
49
|
+
* an adapter input, not a second Story store: Story content and lifecycle stay
|
|
50
|
+
* owned by the consuming Story provider.
|
|
51
|
+
*/
|
|
52
|
+
export interface LocalStoryRevision {
|
|
53
|
+
id: string;
|
|
54
|
+
revision: string;
|
|
55
|
+
acl: FoundationAcl;
|
|
56
|
+
scope: FoundationScope;
|
|
57
|
+
}
|
|
58
|
+
export interface FoundationAuthorizationRequest {
|
|
59
|
+
action: FoundationStoreAction;
|
|
60
|
+
context: FoundationStoreContext;
|
|
61
|
+
reference?: FoundationRevision;
|
|
62
|
+
current?: FoundationDefinition;
|
|
63
|
+
next?: FoundationDefinition;
|
|
64
|
+
/**
|
|
65
|
+
* Foundation records resolved from relation endpoints while the canonical
|
|
66
|
+
* SSOT lock is held. A link must never be authorized from an ID alone.
|
|
67
|
+
*/
|
|
68
|
+
resources?: readonly FoundationAuthorizationResource[];
|
|
69
|
+
relation?: FoundationRelationReference;
|
|
70
|
+
}
|
|
71
|
+
export interface FoundationStorePolicy {
|
|
72
|
+
authorize(request: FoundationAuthorizationRequest): void | boolean | Promise<void | boolean>;
|
|
73
|
+
}
|
|
74
|
+
export interface FoundationUpdateInput {
|
|
75
|
+
reference: FoundationRevision;
|
|
76
|
+
next: FoundationDefinition;
|
|
77
|
+
/** Optional duplicate check for callers that carry an explicit CAS field. */
|
|
78
|
+
expectedRevision?: string;
|
|
79
|
+
}
|
|
80
|
+
export interface FoundationRevisionStore {
|
|
81
|
+
create(definition: FoundationDefinition, context: FoundationStoreContext): Promise<FoundationRef>;
|
|
82
|
+
read(reference: FoundationRevision, context: FoundationStoreContext): Promise<FoundationCatalogRecord | null>;
|
|
83
|
+
readLatest(type: FoundationType, id: string, context: FoundationStoreContext): Promise<FoundationCatalogRecord | null>;
|
|
84
|
+
update(input: FoundationUpdateInput, context: FoundationStoreContext): Promise<FoundationRef>;
|
|
85
|
+
list(type: FoundationType | undefined, context: FoundationStoreContext): Promise<FoundationCatalogRecord[]>;
|
|
86
|
+
addRelation(relation: FoundationRelationReference, context: FoundationStoreContext): Promise<void>;
|
|
87
|
+
}
|
|
88
|
+
export type FoundationStoreErrorCode = 'invalid_input' | 'not_found' | 'revision_conflict' | 'authorization_denied' | 'scope_violation' | 'unsupported_graph' | 'corrupt_catalog' | 'readback_mismatch';
|
|
89
|
+
export declare class FoundationStoreError extends Error {
|
|
90
|
+
readonly code: FoundationStoreErrorCode;
|
|
91
|
+
readonly currentRevision?: string;
|
|
92
|
+
constructor(code: FoundationStoreErrorCode, message: string, options?: {
|
|
93
|
+
currentRevision?: string;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
export interface FoundationRevisionStoreOptions {
|
|
97
|
+
dataDir: string;
|
|
98
|
+
policy?: FoundationStorePolicy;
|
|
99
|
+
/** Trusted resolver for Story and other external relation endpoints. */
|
|
100
|
+
endpointResolver?: FoundationEndpointResolver;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Canonical foundation persistence over the existing Graph SSOT aggregate.
|
|
104
|
+
* There is intentionally no separate objectives/world-model file or writer.
|
|
105
|
+
*/
|
|
106
|
+
export declare class GraphFoundationRevisionStore implements FoundationRevisionStore {
|
|
107
|
+
private readonly dataDir;
|
|
108
|
+
private readonly policy?;
|
|
109
|
+
private readonly endpointResolver?;
|
|
110
|
+
constructor(options: FoundationRevisionStoreOptions);
|
|
111
|
+
create(definition: FoundationDefinition, context: FoundationStoreContext): Promise<FoundationRef>;
|
|
112
|
+
read(reference: FoundationRevision, context: FoundationStoreContext): Promise<FoundationCatalogRecord | null>;
|
|
113
|
+
readLatest(type: FoundationType, id: string, context: FoundationStoreContext): Promise<FoundationCatalogRecord | null>;
|
|
114
|
+
update(input: FoundationUpdateInput, context: FoundationStoreContext): Promise<FoundationRef>;
|
|
115
|
+
list(type: FoundationType | undefined, context: FoundationStoreContext): Promise<FoundationCatalogRecord[]>;
|
|
116
|
+
addRelation(relation: FoundationRelationReference, context: FoundationStoreContext): Promise<void>;
|
|
117
|
+
private load;
|
|
118
|
+
private authorize;
|
|
119
|
+
private readback;
|
|
120
|
+
}
|
|
121
|
+
export declare function createFoundationRevisionStore(options: FoundationRevisionStoreOptions): FoundationRevisionStore;
|
|
122
|
+
export declare const createFoundationStore: typeof createFoundationRevisionStore;
|
|
123
|
+
/**
|
|
124
|
+
* Creates a concrete, in-memory Story endpoint adapter for OSS consumers.
|
|
125
|
+
* Only immutable revision/security metadata is supplied; no Story body is
|
|
126
|
+
* duplicated into the foundation catalog. Current ACL and scope are taken
|
|
127
|
+
* from the greatest registered revision while the requested revision is only
|
|
128
|
+
* checked for existence and retained in the relation.
|
|
129
|
+
*/
|
|
130
|
+
export declare function createLocalStoryResolver(records: readonly LocalStoryRevision[]): FoundationEndpointResolver;
|
|
131
|
+
/** Descriptive alias for consumers that use the generic endpoint terminology. */
|
|
132
|
+
export declare const createStoryEndpointResolver: typeof createLocalStoryResolver;
|