@uwmd/core 1.3.0 → 1.5.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/dist/browser.d.ts +10 -4
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +5 -2
- package/dist/browser.js.map +1 -1
- package/dist/cascade.d.ts +60 -6
- package/dist/cascade.d.ts.map +1 -1
- package/dist/cascade.js +93 -14
- package/dist/cascade.js.map +1 -1
- package/dist/cli.js +269 -11
- package/dist/cli.js.map +1 -1
- package/dist/composition.d.ts +182 -0
- package/dist/composition.d.ts.map +1 -0
- package/dist/composition.js +536 -0
- package/dist/composition.js.map +1 -0
- package/dist/context.js +23 -23
- package/dist/index.d.ts +10 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/lite-bridge.d.ts +9 -0
- package/dist/lite-bridge.d.ts.map +1 -1
- package/dist/lite-bridge.js +44 -5
- package/dist/lite-bridge.js.map +1 -1
- package/dist/lite.js +37 -1
- package/dist/lite.js.map +1 -1
- package/dist/market-data.d.ts +134 -0
- package/dist/market-data.d.ts.map +1 -0
- package/dist/market-data.js +292 -0
- package/dist/market-data.js.map +1 -0
- package/dist/protocol.d.ts +57 -8
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +74 -4
- package/dist/protocol.js.map +1 -1
- package/dist/receipts.d.ts +189 -9
- package/dist/receipts.d.ts.map +1 -1
- package/dist/receipts.js +373 -14
- package/dist/receipts.js.map +1 -1
- package/dist/report.js +165 -165
- package/dist/types.d.ts +54 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/validator.d.ts.map +1 -1
- package/dist/validator.js +17 -0
- package/dist/validator.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
// Composable UWX documents (RFC 0021) — fragments and section externalization.
|
|
2
|
+
//
|
|
3
|
+
// One invariant carries the whole design:
|
|
4
|
+
//
|
|
5
|
+
// I-1 (Digest invariance). A record with externalized parts, resolved, has
|
|
6
|
+
// the same semantic digest as the byte-identical inline record in which every
|
|
7
|
+
// part has been substituted in place.
|
|
8
|
+
//
|
|
9
|
+
// Composition is therefore a *packaging* decision, not a modelling one:
|
|
10
|
+
// externalizing a section does not change what the record means, does not
|
|
11
|
+
// invalidate a receipt over the resolved form, and is not a Tier-2 edit.
|
|
12
|
+
//
|
|
13
|
+
// Everything here exists to make I-1 hold, and two things about it are less
|
|
14
|
+
// obvious than the RFC's statement of the rule suggests:
|
|
15
|
+
//
|
|
16
|
+
// 1. The semantic value includes the block's `annotation` and `prose`, not
|
|
17
|
+
// just its content (see `toEnvelopeBlock` in `envelope.ts`). A resolved
|
|
18
|
+
// block that kept `external=true` in its fence annotation would digest
|
|
19
|
+
// differently from its inline twin and I-1 would fail on every fixture.
|
|
20
|
+
// Resolution therefore normalizes the annotation.
|
|
21
|
+
// 2. Merge order cannot come from `parts` order or archive order, or the same
|
|
22
|
+
// forty rows would canonicalize two ways. Rows are sorted by the declared
|
|
23
|
+
// collection key under a byte-wise total order.
|
|
24
|
+
//
|
|
25
|
+
// Browser-safe: no I/O. Resolution reads parts a caller has already supplied,
|
|
26
|
+
// and never performs network or filesystem access — a reference pointing
|
|
27
|
+
// outside the package is unresolvable, not fetched.
|
|
28
|
+
import { isStandardSectionId } from './protocol.js';
|
|
29
|
+
// ─── Representation ──────────────────────────────────────────────────────────
|
|
30
|
+
export const UWPART_EXTENSION = '.uwpart.md';
|
|
31
|
+
export const UWPART_MEDIA_TYPE = 'text/vnd.uwmd.part+markdown';
|
|
32
|
+
export const UWPART_REPRESENTATION_ID = 'uwx-part-markdown';
|
|
33
|
+
export const UWPART_VERSION = '1.0';
|
|
34
|
+
/**
|
|
35
|
+
* The annotation key marking a section block as externalized. Stripped during
|
|
36
|
+
* resolution — see the note on I-1 above.
|
|
37
|
+
*/
|
|
38
|
+
export const EXTERNAL_ANNOTATION_KEY = 'external';
|
|
39
|
+
export class CompositionError extends Error {
|
|
40
|
+
code;
|
|
41
|
+
constructor(code, message) {
|
|
42
|
+
super(`[${code}] ${message}`);
|
|
43
|
+
this.name = 'CompositionError';
|
|
44
|
+
this.code = code;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function compError(code, message, pointer) {
|
|
48
|
+
return { category: 'validate', code, message, ...(pointer ? { pointer } : {}) };
|
|
49
|
+
}
|
|
50
|
+
function isRecord(v) {
|
|
51
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
52
|
+
}
|
|
53
|
+
function nonEmptyString(v) {
|
|
54
|
+
return typeof v === 'string' && v.trim() !== '';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Read a fragment from an already-parsed file.
|
|
58
|
+
*
|
|
59
|
+
* A fragment must parse standalone — that is a hard requirement, not a nicety.
|
|
60
|
+
* A fragment only understandable in the context of its parent is not
|
|
61
|
+
* independently reviewable and cannot be usefully content-addressed.
|
|
62
|
+
*/
|
|
63
|
+
export function parseUWPart(parsed, opts = {}) {
|
|
64
|
+
const fm = parsed.frontmatter;
|
|
65
|
+
const where = opts.filename ? ` (${opts.filename})` : '';
|
|
66
|
+
if (!nonEmptyString(fm['uwpart_version'])) {
|
|
67
|
+
throw new CompositionError('COMP-PART-MALFORMED', `Fragment requires uwpart_version${where}.`);
|
|
68
|
+
}
|
|
69
|
+
if (!nonEmptyString(fm['part_id'])) {
|
|
70
|
+
throw new CompositionError('COMP-PART-MALFORMED', `Fragment requires part_id${where}.`);
|
|
71
|
+
}
|
|
72
|
+
if (!nonEmptyString(fm['section'])) {
|
|
73
|
+
throw new CompositionError('COMP-PART-MALFORMED', `Fragment requires section${where}.`);
|
|
74
|
+
}
|
|
75
|
+
// A fragment is not an underwriting record and must never be presented as
|
|
76
|
+
// one; carrying a deal_id is the cheapest way for that to happen.
|
|
77
|
+
if ('deal_id' in fm) {
|
|
78
|
+
throw new CompositionError('COMP-PART-MALFORMED', `A fragment MUST NOT carry deal_id${where} — it is not an underwriting record.`);
|
|
79
|
+
}
|
|
80
|
+
const section = fm['section'];
|
|
81
|
+
if (!isStandardSectionId(section) && !section.startsWith('x_')) {
|
|
82
|
+
throw new CompositionError('COMP-PART-MALFORMED', `Fragment declares section '${section}', which the format does not register${where}.`);
|
|
83
|
+
}
|
|
84
|
+
const blocks = [];
|
|
85
|
+
for (const [sectionId, entry] of Object.entries(parsed.sections)) {
|
|
86
|
+
const found = isRecord(entry) && 'annotation' in entry
|
|
87
|
+
? [entry]
|
|
88
|
+
: Object.values(entry);
|
|
89
|
+
// A fragment must not contribute to two sections — that is what two
|
|
90
|
+
// fragments are for.
|
|
91
|
+
if (sectionId !== section) {
|
|
92
|
+
throw new CompositionError('COMP-SECTION-MISMATCH', `Fragment '${fm['part_id']}' declares section '${section}' but carries a block for '${sectionId}'${where}.`);
|
|
93
|
+
}
|
|
94
|
+
blocks.push(...found);
|
|
95
|
+
}
|
|
96
|
+
if (blocks.length === 0) {
|
|
97
|
+
throw new CompositionError('COMP-PART-MALFORMED', `Fragment '${fm['part_id']}' carries no block for section '${section}'${where}.`);
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
part_id: fm['part_id'],
|
|
101
|
+
section,
|
|
102
|
+
collection_member: fm['collection_member'] === true,
|
|
103
|
+
blocks,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
export function validateExternalDirective(candidate) {
|
|
107
|
+
const errors = [];
|
|
108
|
+
if (!isRecord(candidate)) {
|
|
109
|
+
return [compError('COMP-DIRECTIVE-MALFORMED', 'external must be an object.')];
|
|
110
|
+
}
|
|
111
|
+
const d = candidate;
|
|
112
|
+
if (!Array.isArray(d.parts) || d.parts.some((p) => !nonEmptyString(p))) {
|
|
113
|
+
errors.push(compError('COMP-DIRECTIVE-MALFORMED', 'external.parts must be an array of part ids.', 'external.parts'));
|
|
114
|
+
}
|
|
115
|
+
else if (d.parts.length === 0) {
|
|
116
|
+
errors.push(compError('COMP-DIRECTIVE-MALFORMED', 'external.parts must not be empty.', 'external.parts'));
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
const seen = new Set();
|
|
120
|
+
for (const p of d.parts) {
|
|
121
|
+
if (seen.has(p)) {
|
|
122
|
+
errors.push(compError('COMP-DUP-KEY', `external.parts names '${p}' more than once.`, 'external.parts'));
|
|
123
|
+
}
|
|
124
|
+
seen.add(p);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Redundant on purpose. A truncated `parts` array is then a detectable error
|
|
128
|
+
// rather than a silently smaller rent roll — which still totals, still
|
|
129
|
+
// validates, and still produces a confident DSCR.
|
|
130
|
+
if (typeof d.part_count !== 'number' || !Number.isInteger(d.part_count)) {
|
|
131
|
+
errors.push(compError('COMP-DIRECTIVE-MALFORMED', 'external.part_count must be an integer.', 'external.part_count'));
|
|
132
|
+
}
|
|
133
|
+
else if (Array.isArray(d.parts) && d.part_count !== d.parts.length) {
|
|
134
|
+
errors.push(compError('COMP-COUNT-MISMATCH', `external.part_count is ${d.part_count} but parts lists ${d.parts.length}.`, 'external.part_count'));
|
|
135
|
+
}
|
|
136
|
+
if (d.collection_key !== undefined && !nonEmptyString(d.collection_key)) {
|
|
137
|
+
errors.push(compError('COMP-DIRECTIVE-MALFORMED', 'external.collection_key must be a non-empty string.', 'external.collection_key'));
|
|
138
|
+
}
|
|
139
|
+
if (d.collection_path !== undefined && !nonEmptyString(d.collection_path)) {
|
|
140
|
+
errors.push(compError('COMP-DIRECTIVE-MALFORMED', 'external.collection_path must be a non-empty string.', 'external.collection_path'));
|
|
141
|
+
}
|
|
142
|
+
return errors;
|
|
143
|
+
}
|
|
144
|
+
/** Read the directive off a section block, or null when the section is inline. */
|
|
145
|
+
export function readExternalDirective(block) {
|
|
146
|
+
const external = block.content['external'];
|
|
147
|
+
if (external === undefined)
|
|
148
|
+
return null;
|
|
149
|
+
const errors = validateExternalDirective(external);
|
|
150
|
+
if (errors.length > 0) {
|
|
151
|
+
throw new CompositionError(errors[0].code, errors.map((e) => e.message).join('; '));
|
|
152
|
+
}
|
|
153
|
+
return external;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Byte-wise total order on the UTF-8 key. `localeCompare` would be
|
|
157
|
+
* locale-dependent and so would make the canonical form — and therefore the
|
|
158
|
+
* digest — vary by machine, which is exactly what I-1 forbids.
|
|
159
|
+
*/
|
|
160
|
+
function byteCompare(a, b) {
|
|
161
|
+
const left = new TextEncoder().encode(a);
|
|
162
|
+
const right = new TextEncoder().encode(b);
|
|
163
|
+
const n = Math.min(left.length, right.length);
|
|
164
|
+
for (let i = 0; i < n; i++) {
|
|
165
|
+
if (left[i] !== right[i])
|
|
166
|
+
return left[i] - right[i];
|
|
167
|
+
}
|
|
168
|
+
return left.length - right.length;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Strip the externalization marker from a fence annotation, so a resolved block
|
|
172
|
+
* carries the annotation its inline equivalent would. Without this I-1 fails:
|
|
173
|
+
* the envelope's semantic value includes `annotation`, not only `content`.
|
|
174
|
+
*/
|
|
175
|
+
function inlineAnnotation(annotation) {
|
|
176
|
+
const { [EXTERNAL_ANNOTATION_KEY]: _external, ...rest } = annotation;
|
|
177
|
+
return rest;
|
|
178
|
+
}
|
|
179
|
+
function sectionBlocks(entry) {
|
|
180
|
+
return isRecord(entry) && 'annotation' in entry
|
|
181
|
+
? [entry]
|
|
182
|
+
: Object.values(entry);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Resolve every externalized section into its inline equivalent.
|
|
186
|
+
*
|
|
187
|
+
* Returns `unresolved` rather than throwing when a part is missing, because a
|
|
188
|
+
* record referencing a fragment the caller does not hold is *undecidable*, not
|
|
189
|
+
* wrong — the same distinction the receipt verifier draws with `unverifiable`.
|
|
190
|
+
* A missing part never yields a smaller collection.
|
|
191
|
+
*/
|
|
192
|
+
export function resolveComposition(parsed, opts) {
|
|
193
|
+
const issues = [];
|
|
194
|
+
const externalized = [];
|
|
195
|
+
const sections = { ...parsed.sections };
|
|
196
|
+
for (const [sectionId, entry] of Object.entries(parsed.sections)) {
|
|
197
|
+
const blocks = sectionBlocks(entry);
|
|
198
|
+
if (blocks.length !== 1)
|
|
199
|
+
continue;
|
|
200
|
+
const block = blocks[0];
|
|
201
|
+
let directive;
|
|
202
|
+
try {
|
|
203
|
+
directive = readExternalDirective(block);
|
|
204
|
+
}
|
|
205
|
+
catch (e) {
|
|
206
|
+
issues.push(compError(e.code, e.message, sectionId));
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (!directive)
|
|
210
|
+
continue;
|
|
211
|
+
externalized.push(sectionId);
|
|
212
|
+
const resolvedParts = [];
|
|
213
|
+
let missing = false;
|
|
214
|
+
for (const partId of directive.parts) {
|
|
215
|
+
const part = opts.parts.get(partId);
|
|
216
|
+
if (!part) {
|
|
217
|
+
issues.push(compError('COMP-UNRESOLVED', `Part '${partId}' does not resolve within this package.`, `${sectionId}.external.parts`));
|
|
218
|
+
missing = true;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (part.section !== sectionId) {
|
|
222
|
+
issues.push(compError('COMP-SECTION-MISMATCH', `Part '${partId}' declares section '${part.section}' but is referenced from '${sectionId}'.`, `${sectionId}.external.parts`));
|
|
223
|
+
missing = true;
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
resolvedParts.push(part);
|
|
227
|
+
}
|
|
228
|
+
if (missing)
|
|
229
|
+
continue;
|
|
230
|
+
const collectionParts = resolvedParts.filter((p) => p.collection_member);
|
|
231
|
+
const wholeParts = resolvedParts.filter((p) => !p.collection_member);
|
|
232
|
+
if (collectionParts.length > 0 && wholeParts.length > 0) {
|
|
233
|
+
issues.push(compError('COMP-DIRECTIVE-MALFORMED', `Section '${sectionId}' mixes collection-member fragments with whole-section fragments.`, sectionId));
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
// Whole-section: exactly one fragment supplies the section.
|
|
237
|
+
if (wholeParts.length > 0) {
|
|
238
|
+
if (wholeParts.length !== 1) {
|
|
239
|
+
issues.push(compError('COMP-DIRECTIVE-MALFORMED', `Section '${sectionId}' names ${wholeParts.length} whole-section fragments; exactly one supplies a section.`, sectionId));
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const source = wholeParts[0].blocks[0];
|
|
243
|
+
sections[sectionId] = {
|
|
244
|
+
...block,
|
|
245
|
+
annotation: inlineAnnotation(block.annotation),
|
|
246
|
+
content: source.content,
|
|
247
|
+
};
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
// Collection: merge rows, keyed and totally ordered.
|
|
251
|
+
if (!directive.collection_key) {
|
|
252
|
+
issues.push(compError('COMP-DIRECTIVE-MALFORMED', `Section '${sectionId}' composes collection fragments but declares no collection_key.`, `${sectionId}.external.collection_key`));
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (!directive.collection_path) {
|
|
256
|
+
issues.push(compError('COMP-DIRECTIVE-MALFORMED', `Section '${sectionId}' composes collection fragments but declares no collection_path naming where rows land.`, `${sectionId}.external.collection_path`));
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const rows = [];
|
|
260
|
+
const seenKeys = new Map();
|
|
261
|
+
let conflicted = false;
|
|
262
|
+
for (const part of collectionParts) {
|
|
263
|
+
for (const b of part.blocks) {
|
|
264
|
+
const { _meta: _dropped, ...row } = b.content;
|
|
265
|
+
const key = row[directive.collection_key];
|
|
266
|
+
if (!nonEmptyString(key)) {
|
|
267
|
+
issues.push(compError('COMP-DIRECTIVE-MALFORMED', `Part '${part.part_id}' has no usable '${directive.collection_key}' value.`, `${sectionId}.external.collection_key`));
|
|
268
|
+
conflicted = true;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
const prior = seenKeys.get(key);
|
|
272
|
+
if (prior !== undefined) {
|
|
273
|
+
// Never last-one-wins: two fragments claiming suite 210 is a conflict
|
|
274
|
+
// a human resolves, not an ordering question.
|
|
275
|
+
issues.push(compError('COMP-DUP-KEY', `Parts '${prior}' and '${part.part_id}' both claim ${directive.collection_key} '${key}'.`, sectionId));
|
|
276
|
+
conflicted = true;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
seenKeys.set(key, part.part_id);
|
|
280
|
+
rows.push(row);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (conflicted)
|
|
284
|
+
continue;
|
|
285
|
+
rows.sort((a, b) => byteCompare(String(a[directive.collection_key]), String(b[directive.collection_key])));
|
|
286
|
+
const { external: _external, ...rest } = block.content;
|
|
287
|
+
sections[sectionId] = {
|
|
288
|
+
...block,
|
|
289
|
+
annotation: inlineAnnotation(block.annotation),
|
|
290
|
+
content: { ...rest, [directive.collection_path]: rows },
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
status: issues.length > 0 ? 'unresolved' : 'resolved',
|
|
295
|
+
document: { ...parsed, sections: sections },
|
|
296
|
+
issues,
|
|
297
|
+
externalized,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
// ─── Composites and recursion (RFC 0021 §4) ──────────────────────────────────
|
|
301
|
+
/**
|
|
302
|
+
* Depth and member bounds. These mirror the safe-ZIP limits and exist for the
|
|
303
|
+
* same reason: a nested-package expansion is a decompression bomb wearing a
|
|
304
|
+
* different hat.
|
|
305
|
+
*/
|
|
306
|
+
export const DEFAULT_MAX_COMPOSITION_DEPTH = 8;
|
|
307
|
+
export const DEFAULT_MAX_COMPOSITION_MEMBERS = 4096;
|
|
308
|
+
/**
|
|
309
|
+
* Walk the composition DAG, enforcing the normative bounds.
|
|
310
|
+
*
|
|
311
|
+
* Resolution performs no network or filesystem access: members resolve from
|
|
312
|
+
* what the caller already holds. A reference pointing outside the package is
|
|
313
|
+
* unresolvable, never fetched — that is what keeps a package offline-verifiable
|
|
314
|
+
* and keeps validation from writing untrusted bytes anywhere.
|
|
315
|
+
*/
|
|
316
|
+
export function resolveComposite(opts) {
|
|
317
|
+
const maxDepth = opts.maxDepth ?? DEFAULT_MAX_COMPOSITION_DEPTH;
|
|
318
|
+
const maxMembers = opts.maxMembers ?? DEFAULT_MAX_COMPOSITION_MEMBERS;
|
|
319
|
+
const issues = [];
|
|
320
|
+
const known = new Set(opts.members);
|
|
321
|
+
const childrenOf = new Map();
|
|
322
|
+
for (const link of opts.links) {
|
|
323
|
+
if (!known.has(link.from)) {
|
|
324
|
+
issues.push(compError('COMP-UNRESOLVED', `Link names child '${link.from}', which is not a member of this package.`));
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (!known.has(link.to)) {
|
|
328
|
+
issues.push(compError('COMP-UNRESOLVED', `Link names parent '${link.to}', which is not a member of this package.`));
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
const list = childrenOf.get(link.to) ?? [];
|
|
332
|
+
list.push(link.from);
|
|
333
|
+
childrenOf.set(link.to, list);
|
|
334
|
+
}
|
|
335
|
+
if (issues.length > 0) {
|
|
336
|
+
return { status: 'unresolved', order: [], depth: 0, member_count: 0, stale: [], issues };
|
|
337
|
+
}
|
|
338
|
+
if (known.size > maxMembers) {
|
|
339
|
+
return {
|
|
340
|
+
status: 'unresolved',
|
|
341
|
+
order: [],
|
|
342
|
+
depth: 0,
|
|
343
|
+
member_count: known.size,
|
|
344
|
+
stale: [],
|
|
345
|
+
issues: [compError('COMP-DEPTH', `Package holds ${known.size} members, above the bound of ${maxMembers}.`)],
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
// Roots are members nothing contributes to.
|
|
349
|
+
const isChild = new Set(opts.links.map((l) => l.from));
|
|
350
|
+
const roots = [...known].filter((id) => !isChild.has(id)).sort();
|
|
351
|
+
const order = [];
|
|
352
|
+
const finished = new Set();
|
|
353
|
+
const onPath = new Set();
|
|
354
|
+
let deepest = 0;
|
|
355
|
+
const stale = [];
|
|
356
|
+
// Iterative DFS: a recursive walk would blow the JS stack before hitting the
|
|
357
|
+
// depth bound on a hostile graph, turning a clean COMP-DEPTH into a crash.
|
|
358
|
+
const walk = (root) => {
|
|
359
|
+
const stack = [
|
|
360
|
+
{ id: root, depth: 1, expanded: false },
|
|
361
|
+
];
|
|
362
|
+
while (stack.length > 0) {
|
|
363
|
+
const frame = stack[stack.length - 1];
|
|
364
|
+
if (frame.expanded) {
|
|
365
|
+
stack.pop();
|
|
366
|
+
onPath.delete(frame.id);
|
|
367
|
+
if (!finished.has(frame.id)) {
|
|
368
|
+
finished.add(frame.id);
|
|
369
|
+
order.push(frame.id);
|
|
370
|
+
}
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
frame.expanded = true;
|
|
374
|
+
deepest = Math.max(deepest, frame.depth);
|
|
375
|
+
if (frame.depth > maxDepth) {
|
|
376
|
+
issues.push(compError('COMP-DEPTH', `Composition depth ${frame.depth} at '${frame.id}' exceeds the bound of ${maxDepth}.`));
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
if (onPath.has(frame.id)) {
|
|
380
|
+
issues.push(compError('COMP-CYCLE', `Composition cycle reaches '${frame.id}' again.`));
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
onPath.add(frame.id);
|
|
384
|
+
for (const child of (childrenOf.get(frame.id) ?? []).slice().sort()) {
|
|
385
|
+
if (onPath.has(child)) {
|
|
386
|
+
issues.push(compError('COMP-CYCLE', `Composition cycle: '${frame.id}' and '${child}' are mutually reachable.`));
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
// Staleness is checked on the edge, because the recorded digest belongs
|
|
390
|
+
// to the parent's view of the child, not to the child.
|
|
391
|
+
const recorded = opts.recordedDigests?.get(`${frame.id}::${child}`);
|
|
392
|
+
const actual = opts.actualDigests?.get(child);
|
|
393
|
+
if (recorded !== undefined && actual !== undefined && recorded !== actual) {
|
|
394
|
+
stale.push({ parent: frame.id, child, recorded, actual });
|
|
395
|
+
}
|
|
396
|
+
if (!finished.has(child)) {
|
|
397
|
+
stack.push({ id: child, depth: frame.depth + 1, expanded: false });
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return true;
|
|
402
|
+
};
|
|
403
|
+
for (const root of roots) {
|
|
404
|
+
if (!walk(root)) {
|
|
405
|
+
return { status: 'unresolved', order: [], depth: deepest, member_count: known.size, stale, issues };
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
// Any member never reached from a root sits in a cycle: it has a parent, but
|
|
409
|
+
// no root leads to it.
|
|
410
|
+
if (finished.size !== known.size) {
|
|
411
|
+
const unreached = [...known].filter((id) => !finished.has(id)).sort();
|
|
412
|
+
issues.push(compError('COMP-CYCLE', `Members unreachable from any root, indicating a cycle: ${unreached.join(', ')}.`));
|
|
413
|
+
return { status: 'unresolved', order: [], depth: deepest, member_count: known.size, stale, issues };
|
|
414
|
+
}
|
|
415
|
+
return {
|
|
416
|
+
status: stale.length > 0 ? 'stale' : 'resolved',
|
|
417
|
+
order,
|
|
418
|
+
depth: deepest,
|
|
419
|
+
member_count: known.size,
|
|
420
|
+
stale,
|
|
421
|
+
issues,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Split a collection section into fragments, leaving a directive behind.
|
|
426
|
+
*
|
|
427
|
+
* This is the inverse of `resolveComposition`, and the pair is what makes
|
|
428
|
+
* externalizing a packaging decision rather than a modelling one: resolving the
|
|
429
|
+
* output of this function MUST reproduce the input's canonical form. That is
|
|
430
|
+
* I-1 read backwards, and it is asserted as a round-trip rather than assumed.
|
|
431
|
+
*/
|
|
432
|
+
export function externalizeSection(parsed, opts) {
|
|
433
|
+
const entry = parsed.sections[opts.section];
|
|
434
|
+
if (entry === undefined) {
|
|
435
|
+
throw new CompositionError('COMP-SECTION-MISMATCH', `Record has no section '${opts.section}' to externalize.`);
|
|
436
|
+
}
|
|
437
|
+
const blocks = sectionBlocks(entry);
|
|
438
|
+
if (blocks.length !== 1) {
|
|
439
|
+
throw new CompositionError('COMP-SECTION-MISMATCH', `Section '${opts.section}' holds ${blocks.length} blocks; externalization expects exactly one.`);
|
|
440
|
+
}
|
|
441
|
+
const block = blocks[0];
|
|
442
|
+
const content = block.content;
|
|
443
|
+
if (content['external'] !== undefined) {
|
|
444
|
+
throw new CompositionError('COMP-DIRECTIVE-MALFORMED', `Section '${opts.section}' is already externalized.`);
|
|
445
|
+
}
|
|
446
|
+
const rows = content[opts.collectionPath];
|
|
447
|
+
if (!Array.isArray(rows) || rows.length === 0) {
|
|
448
|
+
throw new CompositionError('COMP-DIRECTIVE-MALFORMED', `Section '${opts.section}' has no non-empty collection at '${opts.collectionPath}'.`);
|
|
449
|
+
}
|
|
450
|
+
const prefix = opts.partIdPrefix ?? opts.section;
|
|
451
|
+
const parts = [];
|
|
452
|
+
const seen = new Set();
|
|
453
|
+
for (const row of rows) {
|
|
454
|
+
if (!isRecord(row)) {
|
|
455
|
+
throw new CompositionError('COMP-DIRECTIVE-MALFORMED', `Collection '${opts.collectionPath}' holds a non-object row.`);
|
|
456
|
+
}
|
|
457
|
+
const key = row[opts.collectionKey];
|
|
458
|
+
if (!nonEmptyString(key)) {
|
|
459
|
+
throw new CompositionError('COMP-DIRECTIVE-MALFORMED', `A row has no usable '${opts.collectionKey}' value, so it cannot be addressed as a fragment.`);
|
|
460
|
+
}
|
|
461
|
+
if (seen.has(key)) {
|
|
462
|
+
throw new CompositionError('COMP-DUP-KEY', `Two rows claim ${opts.collectionKey} '${key}'; the source collection is already inconsistent.`);
|
|
463
|
+
}
|
|
464
|
+
seen.add(key);
|
|
465
|
+
parts.push({
|
|
466
|
+
part_id: `${prefix}-${key}`,
|
|
467
|
+
section: opts.section,
|
|
468
|
+
collection_member: true,
|
|
469
|
+
blocks: [
|
|
470
|
+
{
|
|
471
|
+
...block,
|
|
472
|
+
annotation: inlineAnnotation(block.annotation),
|
|
473
|
+
// The fragment is independently reviewable, so it carries the
|
|
474
|
+
// section's provenance. Resolution drops it again (§3.7): inline
|
|
475
|
+
// rows are plain objects, and I-1 requires the merge to match them.
|
|
476
|
+
content: { _meta: content['_meta'], ...row },
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
// Byte-wise on the key, matching resolution's merge order, so the directive
|
|
482
|
+
// lists parts in the order they will come back.
|
|
483
|
+
parts.sort((a, b) => byteCompare(a.part_id, b.part_id));
|
|
484
|
+
const { [opts.collectionPath]: _rows, ...restContent } = content;
|
|
485
|
+
const directive = {
|
|
486
|
+
parts: parts.map((p) => p.part_id),
|
|
487
|
+
collection_key: opts.collectionKey,
|
|
488
|
+
collection_path: opts.collectionPath,
|
|
489
|
+
part_count: parts.length,
|
|
490
|
+
};
|
|
491
|
+
const sections = { ...parsed.sections };
|
|
492
|
+
sections[opts.section] = {
|
|
493
|
+
...block,
|
|
494
|
+
annotation: { ...block.annotation, [EXTERNAL_ANNOTATION_KEY]: true },
|
|
495
|
+
content: { ...restContent, external: directive },
|
|
496
|
+
};
|
|
497
|
+
return {
|
|
498
|
+
document: { ...parsed, sections: sections },
|
|
499
|
+
parts,
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
/** Section id → a readable heading, e.g. `rent_roll` → `Rent Roll`. */
|
|
503
|
+
function sectionHeading(section) {
|
|
504
|
+
return section
|
|
505
|
+
.split('_')
|
|
506
|
+
.map((w) => (w.length > 0 ? w[0].toUpperCase() + w.slice(1) : w))
|
|
507
|
+
.join(' ');
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Serialize a fragment to `.uwpart.md` source.
|
|
511
|
+
*
|
|
512
|
+
* A fragment must parse standalone, so this emits the frontmatter and a single
|
|
513
|
+
* section block — everything `parseUWPart` needs and nothing that would make
|
|
514
|
+
* the file readable only in the context of its parent.
|
|
515
|
+
*/
|
|
516
|
+
export function stringifyUWPart(part) {
|
|
517
|
+
const lines = [
|
|
518
|
+
'---',
|
|
519
|
+
`uwpart_version: "${UWPART_VERSION}"`,
|
|
520
|
+
`part_id: ${part.part_id}`,
|
|
521
|
+
`section: ${part.section}`,
|
|
522
|
+
...(part.collection_member ? ['collection_member: true'] : []),
|
|
523
|
+
'---',
|
|
524
|
+
'',
|
|
525
|
+
`## ${sectionHeading(part.section)} {#${part.section}}`,
|
|
526
|
+
'',
|
|
527
|
+
];
|
|
528
|
+
for (const block of part.blocks) {
|
|
529
|
+
lines.push(`\`\`\`json uw:section=${part.section} v=1`);
|
|
530
|
+
lines.push(JSON.stringify(block.content, null, 2));
|
|
531
|
+
lines.push('```');
|
|
532
|
+
lines.push('');
|
|
533
|
+
}
|
|
534
|
+
return lines.join('\n');
|
|
535
|
+
}
|
|
536
|
+
//# sourceMappingURL=composition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composition.js","sourceRoot":"","sources":["../src/composition.ts"],"names":[],"mappings":"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"}
|
package/dist/context.js
CHANGED
|
@@ -168,30 +168,30 @@ export function buildAgentPrompt(context, userInstructions) {
|
|
|
168
168
|
const missingWarn = context.missingRequired.length > 0
|
|
169
169
|
? `\n\n⚠ MISSING REQUIRED INPUT SECTIONS: ${context.missingRequired.join(', ')}. Proceed with available data only — mark confidence as "low" and set human_review_required: true for fields that depend on missing inputs.`
|
|
170
170
|
: '';
|
|
171
|
-
const systemPrompt = `You are ${layer.id} — ${layer.name} — a specialized agent in the Bancroft CRE underwriting pipeline.
|
|
172
|
-
|
|
173
|
-
Your role: ${getLayerDescription(layer.id)}
|
|
174
|
-
|
|
175
|
-
## Your Output Contract
|
|
176
|
-
|
|
177
|
-
You must return a single JSON object that will be written as a .uw.md section block. The object must:
|
|
178
|
-
- Begin with a "_meta" object (see spec §2.5)
|
|
179
|
-
- Include all required fields for the section(s) you write: ${layer.writes.join(', ')}
|
|
180
|
-
- Set confidence to "high" / "medium" / "low" based on available data quality
|
|
181
|
-
- Set human_review_required: true if any field is uncertain, estimated, or depends on missing inputs
|
|
182
|
-
- Never calculate financial figures — report what the data shows; the deterministic engine owns the math
|
|
183
|
-
- Set flags[] for any anomalies, policy concerns, or data quality issues you observe
|
|
184
|
-
|
|
185
|
-
## Available Input Sections
|
|
186
|
-
${Object.keys(context.sections).map(s => `- ${s}`).join('\n')}
|
|
187
|
-
${missingWarn}
|
|
188
|
-
|
|
189
|
-
## Blocking Flags
|
|
171
|
+
const systemPrompt = `You are ${layer.id} — ${layer.name} — a specialized agent in the Bancroft CRE underwriting pipeline.
|
|
172
|
+
|
|
173
|
+
Your role: ${getLayerDescription(layer.id)}
|
|
174
|
+
|
|
175
|
+
## Your Output Contract
|
|
176
|
+
|
|
177
|
+
You must return a single JSON object that will be written as a .uw.md section block. The object must:
|
|
178
|
+
- Begin with a "_meta" object (see spec §2.5)
|
|
179
|
+
- Include all required fields for the section(s) you write: ${layer.writes.join(', ')}
|
|
180
|
+
- Set confidence to "high" / "medium" / "low" based on available data quality
|
|
181
|
+
- Set human_review_required: true if any field is uncertain, estimated, or depends on missing inputs
|
|
182
|
+
- Never calculate financial figures — report what the data shows; the deterministic engine owns the math
|
|
183
|
+
- Set flags[] for any anomalies, policy concerns, or data quality issues you observe
|
|
184
|
+
|
|
185
|
+
## Available Input Sections
|
|
186
|
+
${Object.keys(context.sections).map(s => `- ${s}`).join('\n')}
|
|
187
|
+
${missingWarn}
|
|
188
|
+
|
|
189
|
+
## Blocking Flags
|
|
190
190
|
${context.blockingFlags.length > 0 ? context.blockingFlags.map(f => `- ${f}`).join('\n') : 'None — pipeline is clear to proceed'}`;
|
|
191
|
-
const userMessage = `${context.chatContext}
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
191
|
+
const userMessage = `${context.chatContext}
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
195
|
${userInstructions ? `Additional instructions:\n${userInstructions}\n\n---\n\n` : ''}Return your output as a single JSON block for section(s): ${layer.writes.join(', ')}`;
|
|
196
196
|
return {
|
|
197
197
|
systemPrompt,
|