@orkestrel/brief 0.0.6 → 0.0.7
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/README.md +6 -6
- package/dist/src/core/index.cjs +380 -274
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +594 -485
- package/dist/src/core/index.d.ts +594 -485
- package/dist/src/core/index.js +369 -263
- package/dist/src/core/index.js.map +1 -1
- package/package.json +16 -15
package/dist/src/core/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@ let _orkestrel_interpret = require("@orkestrel/interpret");
|
|
|
4
4
|
let _orkestrel_reason = require("@orkestrel/reason");
|
|
5
5
|
let _orkestrel_emitter = require("@orkestrel/emitter");
|
|
6
6
|
//#region src/core/constants.ts
|
|
7
|
-
/**
|
|
7
|
+
/** Lists the `TaskOperation` values, frozen. */
|
|
8
8
|
var TASK_OPERATIONS = Object.freeze([
|
|
9
9
|
"create",
|
|
10
10
|
"refactor",
|
|
@@ -19,7 +19,7 @@ var TASK_OPERATIONS = Object.freeze([
|
|
|
19
19
|
"document",
|
|
20
20
|
"plan"
|
|
21
21
|
]);
|
|
22
|
-
/**
|
|
22
|
+
/** Lists the `TaskDomain` values, frozen. */
|
|
23
23
|
var TASK_DOMAINS = Object.freeze([
|
|
24
24
|
"code",
|
|
25
25
|
"writing",
|
|
@@ -30,7 +30,7 @@ var TASK_DOMAINS = Object.freeze([
|
|
|
30
30
|
"ops",
|
|
31
31
|
"other"
|
|
32
32
|
]);
|
|
33
|
-
/**
|
|
33
|
+
/** Lists the `OutputFormat` values, frozen. */
|
|
34
34
|
var OUTPUT_FORMATS = Object.freeze([
|
|
35
35
|
"markdown",
|
|
36
36
|
"json",
|
|
@@ -38,14 +38,14 @@ var OUTPUT_FORMATS = Object.freeze([
|
|
|
38
38
|
"diff",
|
|
39
39
|
"prose"
|
|
40
40
|
]);
|
|
41
|
-
/**
|
|
41
|
+
/** Lists the `RiskSeverity` values, frozen. */
|
|
42
42
|
var RISK_SEVERITIES = Object.freeze([
|
|
43
43
|
"low",
|
|
44
44
|
"medium",
|
|
45
45
|
"high"
|
|
46
46
|
]);
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
48
|
+
* Lists every published `Interpretation` member name, frozen.
|
|
49
49
|
*
|
|
50
50
|
* @remarks
|
|
51
51
|
* The capture list `BriefCompiler` hands `captureValue` at each interpret door — the borrowed
|
|
@@ -70,33 +70,32 @@ var INTERPRETATION_MEMBERS = Object.freeze([
|
|
|
70
70
|
"prompt",
|
|
71
71
|
"stages",
|
|
72
72
|
"failures",
|
|
73
|
-
"complete",
|
|
74
73
|
"confidence",
|
|
75
74
|
"digest"
|
|
76
75
|
]);
|
|
77
76
|
/**
|
|
78
|
-
* `16` — the default turn cap `briefToGoal` renders.
|
|
77
|
+
* Holds `16` — the default turn cap `briefToGoal` renders.
|
|
79
78
|
*
|
|
80
79
|
* @remarks
|
|
81
80
|
* Domain-qualified so the barrel stays collision-free as sibling modules add their own
|
|
82
81
|
* turn defaults.
|
|
83
82
|
*/
|
|
84
83
|
var DEFAULT_BRIEF_TURNS = 16;
|
|
85
|
-
/** `'gate'` — the id of the `
|
|
84
|
+
/** Holds `'gate'` — the id of the `buildGateDefinition()` logical definition. */
|
|
86
85
|
var GATE_ID = "gate";
|
|
87
86
|
/**
|
|
88
|
-
*
|
|
87
|
+
* Matches every line terminator a brief field refuses.
|
|
89
88
|
*
|
|
90
89
|
* @remarks
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
90
|
+
* Every ECMAScript line terminator, not just `\n`: a renderer that splits on any of them
|
|
91
|
+
* would let the others forge a markdown row. CRLF leads the alternation so a Windows
|
|
92
|
+
* exemplar splits as ONE break rather than two, which would insert a blank line the caller
|
|
93
|
+
* never wrote. Kept unanchored and stateless — no `g` flag — so `test` never carries
|
|
95
94
|
* `lastIndex` between calls.
|
|
96
95
|
*/
|
|
97
96
|
var LINE_BREAK_PATTERN = /\r\n|[\n\r\u2028\u2029]/;
|
|
98
97
|
/**
|
|
99
|
-
*
|
|
98
|
+
* Holds the positive form of {@link LINE_BREAK_PATTERN}, for the shape DSL.
|
|
100
99
|
*
|
|
101
100
|
* @remarks
|
|
102
101
|
* `stringShape`'s `pattern` must MATCH an accepted value, so the guard's refusal regex
|
|
@@ -105,7 +104,7 @@ var LINE_BREAK_PATTERN = /\r\n|[\n\r\u2028\u2029]/;
|
|
|
105
104
|
*/
|
|
106
105
|
var SINGLE_LINE_PATTERN = /^[^\n\r\u2028\u2029]*$/;
|
|
107
106
|
/**
|
|
108
|
-
*
|
|
107
|
+
* Matches a string of one or more spaces and nothing else.
|
|
109
108
|
*
|
|
110
109
|
* @remarks
|
|
111
110
|
* The one exemplar side `exampleToLines` must NOT pad. CommonMark strips a fully-blank code
|
|
@@ -119,7 +118,7 @@ var BLANK_PATTERN = /^ +$/;
|
|
|
119
118
|
//#endregion
|
|
120
119
|
//#region src/core/errors.ts
|
|
121
120
|
/**
|
|
122
|
-
*
|
|
121
|
+
* Represents the one error class this package throws.
|
|
123
122
|
*
|
|
124
123
|
* @remarks
|
|
125
124
|
* Throws are reserved for caller misuse: `assertBrief`, `snapshotBrief`, and `pinBrief` on
|
|
@@ -149,10 +148,10 @@ var BriefError = class extends Error {
|
|
|
149
148
|
}
|
|
150
149
|
};
|
|
151
150
|
/**
|
|
152
|
-
*
|
|
151
|
+
* Narrows a caught value to a {@link BriefError}.
|
|
153
152
|
*
|
|
154
153
|
* @param value - The caught value to inspect.
|
|
155
|
-
* @returns
|
|
154
|
+
* @returns True if `value` is a `BriefError`; false otherwise.
|
|
156
155
|
*
|
|
157
156
|
* @example
|
|
158
157
|
* ```ts
|
|
@@ -170,82 +169,82 @@ function isBriefError(value) {
|
|
|
170
169
|
}
|
|
171
170
|
//#endregion
|
|
172
171
|
//#region src/core/shapers.ts
|
|
173
|
-
/**
|
|
172
|
+
/** Describes a single-line string of any length, including empty. */
|
|
174
173
|
var textShape = (0, _orkestrel_contract.stringShape)({ pattern: SINGLE_LINE_PATTERN });
|
|
175
|
-
/**
|
|
174
|
+
/** Describes a non-empty single-line string — the shape mirror of `isLine`. */
|
|
176
175
|
var lineShape = (0, _orkestrel_contract.stringShape)({
|
|
177
176
|
min: 1,
|
|
178
177
|
pattern: SINGLE_LINE_PATTERN
|
|
179
178
|
});
|
|
180
|
-
/**
|
|
179
|
+
/** Describes the `Task` shape — closed operation and domain vocabularies plus a non-empty statement. */
|
|
181
180
|
var taskShape = (0, _orkestrel_contract.objectShape)({
|
|
182
181
|
operation: (0, _orkestrel_contract.literalShape)(TASK_OPERATIONS),
|
|
183
182
|
domain: (0, _orkestrel_contract.literalShape)(TASK_DOMAINS),
|
|
184
183
|
statement: lineShape
|
|
185
184
|
}, { description: "What the brief asks for, in one imperative sentence." });
|
|
186
|
-
/**
|
|
185
|
+
/** Describes the `Reference` shape — a path and the note that justifies listing it. */
|
|
187
186
|
var referenceShape = (0, _orkestrel_contract.objectShape)({
|
|
188
187
|
path: lineShape,
|
|
189
188
|
note: lineShape
|
|
190
189
|
}, { description: "One referenced path and why it is listed." });
|
|
191
|
-
/**
|
|
190
|
+
/** Describes the `Manifest` shape — disjoint reference partitions. */
|
|
192
191
|
var manifestShape = (0, _orkestrel_contract.objectShape)({
|
|
193
192
|
read: (0, _orkestrel_contract.arrayShape)(referenceShape),
|
|
194
193
|
edit: (0, _orkestrel_contract.arrayShape)(referenceShape),
|
|
195
194
|
locked: (0, _orkestrel_contract.arrayShape)(referenceShape),
|
|
196
195
|
forbidden: (0, _orkestrel_contract.arrayShape)(referenceShape)
|
|
197
|
-
}, { description: "The
|
|
198
|
-
/**
|
|
196
|
+
}, { description: "The disjoint file partitions of a brief." });
|
|
197
|
+
/** Describes the `Outcome` shape — a one-based rank, the result text, and whether it gates done. */
|
|
199
198
|
var outcomeShape = (0, _orkestrel_contract.objectShape)({
|
|
200
199
|
rank: (0, _orkestrel_contract.integerShape)({ min: 1 }),
|
|
201
200
|
text: lineShape,
|
|
202
201
|
required: (0, _orkestrel_contract.booleanShape)()
|
|
203
202
|
}, { description: "One ranked outcome — a result, never a step." });
|
|
204
|
-
/**
|
|
203
|
+
/** Describes the `Given` shape — one categorized context fact. */
|
|
205
204
|
var givenShape = (0, _orkestrel_contract.objectShape)({
|
|
206
205
|
category: lineShape,
|
|
207
206
|
name: lineShape,
|
|
208
207
|
value: textShape
|
|
209
208
|
}, { description: "One context fact handed to the executor." });
|
|
210
|
-
/**
|
|
209
|
+
/** Describes the `Example` shape — one input to output exemplar. */
|
|
211
210
|
var exampleShape = (0, _orkestrel_contract.objectShape)({
|
|
212
211
|
input: (0, _orkestrel_contract.stringShape)({ min: 1 }),
|
|
213
212
|
output: (0, _orkestrel_contract.stringShape)({ min: 1 }),
|
|
214
213
|
note: (0, _orkestrel_contract.optionalShape)(lineShape)
|
|
215
214
|
}, { description: "One input to output exemplar." });
|
|
216
|
-
/**
|
|
215
|
+
/** Describes the `Citation` shape — a name, a locator, and why the source is cited. */
|
|
217
216
|
var citationShape = (0, _orkestrel_contract.objectShape)({
|
|
218
217
|
name: lineShape,
|
|
219
218
|
url: lineShape,
|
|
220
219
|
note: lineShape
|
|
221
220
|
}, { description: "One external source; list order is the trust order." });
|
|
222
|
-
/**
|
|
221
|
+
/** Describes the `Gap` shape — an unknown, whether it blocks, and the candidates that would close it. */
|
|
223
222
|
var gapShape = (0, _orkestrel_contract.objectShape)({
|
|
224
223
|
field: lineShape,
|
|
225
224
|
question: lineShape,
|
|
226
225
|
blocking: (0, _orkestrel_contract.booleanShape)(),
|
|
227
226
|
candidates: (0, _orkestrel_contract.optionalShape)((0, _orkestrel_contract.arrayShape)(lineShape))
|
|
228
227
|
}, { description: "One unresolved decision; blocking means the gate fails closed." });
|
|
229
|
-
/**
|
|
228
|
+
/** Describes the `Risk` shape — a closed severity, the risk, and its mitigation. */
|
|
230
229
|
var riskShape = (0, _orkestrel_contract.objectShape)({
|
|
231
230
|
severity: (0, _orkestrel_contract.literalShape)(RISK_SEVERITIES),
|
|
232
231
|
text: lineShape,
|
|
233
232
|
mitigation: lineShape
|
|
234
233
|
}, { description: "One pre-empted risk and the mitigation that answers it." });
|
|
235
|
-
/**
|
|
234
|
+
/** Describes the `Output` shape — a closed format plus its optional refinements. */
|
|
236
235
|
var outputShape = (0, _orkestrel_contract.objectShape)({
|
|
237
236
|
format: (0, _orkestrel_contract.literalShape)(OUTPUT_FORMATS),
|
|
238
237
|
sections: (0, _orkestrel_contract.optionalShape)((0, _orkestrel_contract.arrayShape)(lineShape)),
|
|
239
238
|
include: (0, _orkestrel_contract.optionalShape)((0, _orkestrel_contract.arrayShape)(lineShape)),
|
|
240
239
|
exclude: (0, _orkestrel_contract.optionalShape)((0, _orkestrel_contract.arrayShape)(lineShape))
|
|
241
240
|
}, { description: "The closed shape of the deliverable." });
|
|
242
|
-
/**
|
|
241
|
+
/** Describes the `Proof` shape — the claim and the command that settles it. */
|
|
243
242
|
var proofShape = (0, _orkestrel_contract.objectShape)({
|
|
244
243
|
text: lineShape,
|
|
245
244
|
command: lineShape
|
|
246
245
|
}, { description: "One mechanical, transcript-provable check." });
|
|
247
246
|
/**
|
|
248
|
-
*
|
|
247
|
+
* Describes the whole `Brief` shape, section shapes composed.
|
|
249
248
|
*
|
|
250
249
|
* @remarks
|
|
251
250
|
* `trace` and `hash` are optional because `pinBrief` fills them; an unpinned draft is
|
|
@@ -272,40 +271,82 @@ var briefShape = (0, _orkestrel_contract.objectShape)({
|
|
|
272
271
|
//#endregion
|
|
273
272
|
//#region src/core/validators.ts
|
|
274
273
|
/**
|
|
275
|
-
*
|
|
274
|
+
* Checks whether the value is a string holding no line terminator, empty included.
|
|
276
275
|
*
|
|
277
276
|
* @remarks
|
|
278
277
|
* `briefToMarkdown` renders each brief field as ONE markdown row, so a field carrying a
|
|
279
278
|
* line break would forge a heading or an extra manifest row — which is how a rendered
|
|
280
279
|
* prompt and `briefToDispatch`'s path sets could disagree about the same brief.
|
|
280
|
+
*
|
|
281
|
+
* @param value - The value to inspect.
|
|
282
|
+
* @returns True if `value` is a string holding no line terminator, empty included; false
|
|
283
|
+
* otherwise.
|
|
281
284
|
*/
|
|
282
285
|
var isText = (value) => (0, _orkestrel_contract.isString)(value) && !LINE_BREAK_PATTERN.test(value);
|
|
283
|
-
/**
|
|
286
|
+
/**
|
|
287
|
+
* Checks whether the value is a non-empty string holding no line terminator.
|
|
288
|
+
*
|
|
289
|
+
* @param value - The value to inspect.
|
|
290
|
+
* @returns True if `value` is a non-empty string holding no line terminator; false otherwise.
|
|
291
|
+
*/
|
|
284
292
|
var isLine = (0, _orkestrel_contract.andOf)(_orkestrel_contract.isNonEmptyString, isText);
|
|
285
|
-
/**
|
|
293
|
+
/**
|
|
294
|
+
* Checks whether the value is one of the `TaskOperation` literals.
|
|
295
|
+
*
|
|
296
|
+
* @param value - The value to inspect.
|
|
297
|
+
* @returns True if `value` is one of the `TaskOperation` literals; false otherwise.
|
|
298
|
+
*/
|
|
286
299
|
var isTaskOperation = (0, _orkestrel_contract.literalOf)(TASK_OPERATIONS);
|
|
287
|
-
/**
|
|
300
|
+
/**
|
|
301
|
+
* Checks whether the value is one of the `TaskDomain` literals.
|
|
302
|
+
*
|
|
303
|
+
* @param value - The value to inspect.
|
|
304
|
+
* @returns True if `value` is one of the `TaskDomain` literals; false otherwise.
|
|
305
|
+
*/
|
|
288
306
|
var isTaskDomain = (0, _orkestrel_contract.literalOf)(TASK_DOMAINS);
|
|
289
|
-
/**
|
|
307
|
+
/**
|
|
308
|
+
* Checks whether the value is one of the `OutputFormat` literals.
|
|
309
|
+
*
|
|
310
|
+
* @param value - The value to inspect.
|
|
311
|
+
* @returns True if `value` is one of the `OutputFormat` literals; false otherwise.
|
|
312
|
+
*/
|
|
290
313
|
var isOutputFormat = (0, _orkestrel_contract.literalOf)(OUTPUT_FORMATS);
|
|
291
|
-
/**
|
|
314
|
+
/**
|
|
315
|
+
* Checks whether the value is one of the `RiskSeverity` literals.
|
|
316
|
+
*
|
|
317
|
+
* @param value - The value to inspect.
|
|
318
|
+
* @returns True if `value` is one of the `RiskSeverity` literals; false otherwise.
|
|
319
|
+
*/
|
|
292
320
|
var isRiskSeverity = (0, _orkestrel_contract.literalOf)(RISK_SEVERITIES);
|
|
293
|
-
/**
|
|
321
|
+
/**
|
|
322
|
+
* Checks whether the value is a well-formed `Task` — both vocabularies closed, statement one line.
|
|
323
|
+
*
|
|
324
|
+
* @param value - The value to inspect.
|
|
325
|
+
* @returns True if `value` is a well-formed `Task`; false otherwise.
|
|
326
|
+
*/
|
|
294
327
|
var isTask = (0, _orkestrel_contract.recordOf)({
|
|
295
328
|
operation: isTaskOperation,
|
|
296
329
|
domain: isTaskDomain,
|
|
297
330
|
statement: isLine
|
|
298
331
|
});
|
|
299
|
-
/**
|
|
332
|
+
/**
|
|
333
|
+
* Checks whether the value is a well-formed `Reference` — both members required, both single-line.
|
|
334
|
+
*
|
|
335
|
+
* @param value - The value to inspect.
|
|
336
|
+
* @returns True if `value` is a well-formed `Reference`; false otherwise.
|
|
337
|
+
*/
|
|
300
338
|
var isReference = (0, _orkestrel_contract.recordOf)({
|
|
301
339
|
path: isLine,
|
|
302
340
|
note: isLine
|
|
303
341
|
});
|
|
304
342
|
/**
|
|
305
|
-
*
|
|
343
|
+
* Checks whether the value is a well-formed `Manifest`.
|
|
306
344
|
*
|
|
307
345
|
* @remarks
|
|
308
346
|
* Partition presence only — disjointness is `validateBrief`'s semantic pass.
|
|
347
|
+
*
|
|
348
|
+
* @param value - The value to inspect.
|
|
349
|
+
* @returns True if `value` is a well-formed `Manifest`; false otherwise.
|
|
309
350
|
*/
|
|
310
351
|
var isManifest = (0, _orkestrel_contract.recordOf)({
|
|
311
352
|
read: (0, _orkestrel_contract.arrayOf)(isReference),
|
|
@@ -313,50 +354,83 @@ var isManifest = (0, _orkestrel_contract.recordOf)({
|
|
|
313
354
|
locked: (0, _orkestrel_contract.arrayOf)(isReference),
|
|
314
355
|
forbidden: (0, _orkestrel_contract.arrayOf)(isReference)
|
|
315
356
|
});
|
|
316
|
-
/**
|
|
357
|
+
/**
|
|
358
|
+
* Checks whether the value is a well-formed `Outcome` — `rank` a positive integer.
|
|
359
|
+
*
|
|
360
|
+
* @param value - The value to inspect.
|
|
361
|
+
* @returns True if `value` is a well-formed `Outcome`; false otherwise.
|
|
362
|
+
*/
|
|
317
363
|
var isOutcome = (0, _orkestrel_contract.recordOf)({
|
|
318
364
|
rank: (0, _orkestrel_contract.andOf)(_orkestrel_contract.isInteger, (0, _orkestrel_contract.boundsOf)(1)),
|
|
319
365
|
text: isLine,
|
|
320
366
|
required: _orkestrel_contract.isBoolean
|
|
321
367
|
});
|
|
322
|
-
/**
|
|
368
|
+
/**
|
|
369
|
+
* Checks whether the value is a well-formed `Given` — its `value` may be empty but stays one line.
|
|
370
|
+
*
|
|
371
|
+
* @param value - The value to inspect.
|
|
372
|
+
* @returns True if `value` is a well-formed `Given`; false otherwise.
|
|
373
|
+
*/
|
|
323
374
|
var isGiven = (0, _orkestrel_contract.recordOf)({
|
|
324
375
|
category: isLine,
|
|
325
376
|
name: isLine,
|
|
326
377
|
value: isText
|
|
327
378
|
});
|
|
328
379
|
/**
|
|
329
|
-
*
|
|
380
|
+
* Checks whether the value is a well-formed `Example`.
|
|
330
381
|
*
|
|
331
382
|
* @remarks
|
|
332
383
|
* An exemplar's two sides are the ONLY members a brief lets span lines, because they
|
|
333
384
|
* carry code. `briefToMarkdown` fences them rather than rendering them as a row.
|
|
385
|
+
*
|
|
386
|
+
* @param value - The value to inspect.
|
|
387
|
+
* @returns True if `value` is a well-formed `Example`; false otherwise.
|
|
334
388
|
*/
|
|
335
389
|
var isExample = (0, _orkestrel_contract.recordOf)({
|
|
336
390
|
input: _orkestrel_contract.isNonEmptyString,
|
|
337
391
|
output: _orkestrel_contract.isNonEmptyString,
|
|
338
392
|
note: isLine
|
|
339
393
|
}, ["note"]);
|
|
340
|
-
/**
|
|
394
|
+
/**
|
|
395
|
+
* Checks whether the value is a well-formed `Citation` — every member single-line.
|
|
396
|
+
*
|
|
397
|
+
* @param value - The value to inspect.
|
|
398
|
+
* @returns True if `value` is a well-formed `Citation`; false otherwise.
|
|
399
|
+
*/
|
|
341
400
|
var isCitation = (0, _orkestrel_contract.recordOf)({
|
|
342
401
|
name: isLine,
|
|
343
402
|
url: isLine,
|
|
344
403
|
note: isLine
|
|
345
404
|
});
|
|
346
|
-
/**
|
|
405
|
+
/**
|
|
406
|
+
* Checks whether the value is a well-formed `Gap`.
|
|
407
|
+
*
|
|
408
|
+
* @param value - The value to inspect.
|
|
409
|
+
* @returns True if `value` is a well-formed `Gap`; false otherwise.
|
|
410
|
+
*/
|
|
347
411
|
var isGap = (0, _orkestrel_contract.recordOf)({
|
|
348
412
|
field: isLine,
|
|
349
413
|
question: isLine,
|
|
350
414
|
blocking: _orkestrel_contract.isBoolean,
|
|
351
415
|
candidates: (0, _orkestrel_contract.arrayOf)(isLine)
|
|
352
416
|
}, ["candidates"]);
|
|
353
|
-
/**
|
|
417
|
+
/**
|
|
418
|
+
* Checks whether the value is a well-formed `Risk` — `severity` on the closed vocabulary.
|
|
419
|
+
*
|
|
420
|
+
* @param value - The value to inspect.
|
|
421
|
+
* @returns True if `value` is a well-formed `Risk`; false otherwise.
|
|
422
|
+
*/
|
|
354
423
|
var isRisk = (0, _orkestrel_contract.recordOf)({
|
|
355
424
|
severity: isRiskSeverity,
|
|
356
425
|
text: isLine,
|
|
357
426
|
mitigation: isLine
|
|
358
427
|
});
|
|
359
|
-
/**
|
|
428
|
+
/**
|
|
429
|
+
* Checks whether the value is a well-formed `Output` — `format` on the closed vocabulary.
|
|
430
|
+
*
|
|
431
|
+
* @param value - The value to inspect.
|
|
432
|
+
* @returns True if `value` is a well-formed `Output`; false otherwise.
|
|
433
|
+
*/
|
|
360
434
|
var isOutput = (0, _orkestrel_contract.recordOf)({
|
|
361
435
|
format: isOutputFormat,
|
|
362
436
|
sections: (0, _orkestrel_contract.arrayOf)(isLine),
|
|
@@ -367,17 +441,25 @@ var isOutput = (0, _orkestrel_contract.recordOf)({
|
|
|
367
441
|
"include",
|
|
368
442
|
"exclude"
|
|
369
443
|
]);
|
|
370
|
-
/**
|
|
444
|
+
/**
|
|
445
|
+
* Checks whether the value is a well-formed `Proof`.
|
|
446
|
+
*
|
|
447
|
+
* @param value - The value to inspect.
|
|
448
|
+
* @returns True if `value` is a well-formed `Proof`; false otherwise.
|
|
449
|
+
*/
|
|
371
450
|
var isProof = (0, _orkestrel_contract.recordOf)({
|
|
372
451
|
text: isLine,
|
|
373
452
|
command: isLine
|
|
374
453
|
});
|
|
375
454
|
/**
|
|
376
|
-
*
|
|
455
|
+
* Checks whether the value satisfies the whole exact-record `Brief` contract.
|
|
377
456
|
*
|
|
378
457
|
* @remarks
|
|
379
458
|
* Every section must be present; an extra key fails. `trace` and `hash` are the only
|
|
380
459
|
* optional members, because `pinBrief` rather than the author fills them.
|
|
460
|
+
*
|
|
461
|
+
* @param value - The value to inspect.
|
|
462
|
+
* @returns True if `value` satisfies the whole exact-record `Brief` contract; false otherwise.
|
|
381
463
|
*/
|
|
382
464
|
var isBrief = (0, _orkestrel_contract.recordOf)({
|
|
383
465
|
task: isTask,
|
|
@@ -478,7 +560,7 @@ function captureValue(source, members) {
|
|
|
478
560
|
return target;
|
|
479
561
|
}
|
|
480
562
|
/**
|
|
481
|
-
*
|
|
563
|
+
* Returns a deeply owned, deeply frozen copy of a brief, refusing anything off-contract.
|
|
482
564
|
*
|
|
483
565
|
* @remarks
|
|
484
566
|
* The one reading boundary this package has, used by the pin, the registry, and every
|
|
@@ -502,10 +584,10 @@ function captureValue(source, members) {
|
|
|
502
584
|
*
|
|
503
585
|
* @example
|
|
504
586
|
* ```ts
|
|
505
|
-
* import {
|
|
587
|
+
* import { buildBrief, buildOutcome, buildTask, snapshotBrief } from '@orkestrel/brief'
|
|
506
588
|
*
|
|
507
|
-
* const outcomes = [
|
|
508
|
-
* const owned = snapshotBrief(
|
|
589
|
+
* const outcomes = [buildOutcome(1, 'shipped')]
|
|
590
|
+
* const owned = snapshotBrief(buildBrief(buildTask('plan', 'ops', 'Plan the release.'), { outcomes }))
|
|
509
591
|
* owned.outcomes === outcomes // false — the alias is broken
|
|
510
592
|
* Object.isFrozen(owned.outcomes) // true
|
|
511
593
|
* ```
|
|
@@ -518,7 +600,7 @@ function snapshotBrief(source) {
|
|
|
518
600
|
//#endregion
|
|
519
601
|
//#region src/core/helpers.ts
|
|
520
602
|
/**
|
|
521
|
-
*
|
|
603
|
+
* Assembles a `Task` from an operation, a domain, and a statement.
|
|
522
604
|
*
|
|
523
605
|
* @param operation - What the brief asks for, from the closed operation vocabulary.
|
|
524
606
|
* @param domain - The subject matter, from the closed domain vocabulary.
|
|
@@ -527,12 +609,12 @@ function snapshotBrief(source) {
|
|
|
527
609
|
*
|
|
528
610
|
* @example
|
|
529
611
|
* ```ts
|
|
530
|
-
* import {
|
|
612
|
+
* import { buildTask } from '@orkestrel/brief'
|
|
531
613
|
*
|
|
532
|
-
*
|
|
614
|
+
* buildTask('refactor', 'code', 'Refactor useForm to native browser form APIs.')
|
|
533
615
|
* ```
|
|
534
616
|
*/
|
|
535
|
-
function
|
|
617
|
+
function buildTask(operation, domain, statement) {
|
|
536
618
|
return {
|
|
537
619
|
operation,
|
|
538
620
|
domain,
|
|
@@ -540,7 +622,7 @@ function task(operation, domain, statement) {
|
|
|
540
622
|
};
|
|
541
623
|
}
|
|
542
624
|
/**
|
|
543
|
-
*
|
|
625
|
+
* Assembles a `Reference` from a path and the note that justifies listing it.
|
|
544
626
|
*
|
|
545
627
|
* @param path - The referenced path or glob.
|
|
546
628
|
* @param note - Why the path is listed.
|
|
@@ -548,31 +630,31 @@ function task(operation, domain, statement) {
|
|
|
548
630
|
*
|
|
549
631
|
* @example
|
|
550
632
|
* ```ts
|
|
551
|
-
* import {
|
|
633
|
+
* import { buildReference } from '@orkestrel/brief'
|
|
552
634
|
*
|
|
553
|
-
*
|
|
635
|
+
* buildReference('AGENTS.md', 'project law') // { path: 'AGENTS.md', note: 'project law' }
|
|
554
636
|
* ```
|
|
555
637
|
*/
|
|
556
|
-
function
|
|
638
|
+
function buildReference(path, note) {
|
|
557
639
|
return {
|
|
558
640
|
path,
|
|
559
641
|
note
|
|
560
642
|
};
|
|
561
643
|
}
|
|
562
644
|
/**
|
|
563
|
-
*
|
|
645
|
+
* Assembles a `Manifest`, defaulting every absent partition to an empty list.
|
|
564
646
|
*
|
|
565
647
|
* @param partitions - The partitions to fill; a partial literal is enough.
|
|
566
|
-
* @returns A fresh `Manifest` with
|
|
648
|
+
* @returns A fresh `Manifest` with every partition present.
|
|
567
649
|
*
|
|
568
650
|
* @example
|
|
569
651
|
* ```ts
|
|
570
|
-
* import {
|
|
652
|
+
* import { buildManifest, buildReference } from '@orkestrel/brief'
|
|
571
653
|
*
|
|
572
|
-
*
|
|
654
|
+
* buildManifest({ edit: [buildReference('src/core/helpers.ts', 'implementation')] })
|
|
573
655
|
* ```
|
|
574
656
|
*/
|
|
575
|
-
function
|
|
657
|
+
function buildManifest(partitions) {
|
|
576
658
|
return {
|
|
577
659
|
read: partitions?.read ?? [],
|
|
578
660
|
edit: partitions?.edit ?? [],
|
|
@@ -581,22 +663,23 @@ function manifest(partitions) {
|
|
|
581
663
|
};
|
|
582
664
|
}
|
|
583
665
|
/**
|
|
584
|
-
*
|
|
666
|
+
* Assembles an `Outcome` from a rank and its result text.
|
|
585
667
|
*
|
|
586
668
|
* @param rank - The one-based rank; lower ranks matter more.
|
|
587
669
|
* @param text - The result, never a step.
|
|
588
|
-
* @param required -
|
|
670
|
+
* @param required - If `true`, the outcome gates "done"; if `false`, it is desirable but not
|
|
671
|
+
* blocking. Default: `true`.
|
|
589
672
|
* @returns A fresh `Outcome`.
|
|
590
673
|
*
|
|
591
674
|
* @example
|
|
592
675
|
* ```ts
|
|
593
|
-
* import {
|
|
676
|
+
* import { buildOutcome } from '@orkestrel/brief'
|
|
594
677
|
*
|
|
595
|
-
*
|
|
596
|
-
*
|
|
678
|
+
* buildOutcome(1, 'useForm uses native FormData with no behavior change') // required: true
|
|
679
|
+
* buildOutcome(2, 'the diff stays under 200 lines', false)
|
|
597
680
|
* ```
|
|
598
681
|
*/
|
|
599
|
-
function
|
|
682
|
+
function buildOutcome(rank, text, required = true) {
|
|
600
683
|
return {
|
|
601
684
|
rank,
|
|
602
685
|
text,
|
|
@@ -604,7 +687,7 @@ function outcome(rank, text, required = true) {
|
|
|
604
687
|
};
|
|
605
688
|
}
|
|
606
689
|
/**
|
|
607
|
-
*
|
|
690
|
+
* Assembles a `Given` from a category, a name, and a value.
|
|
608
691
|
*
|
|
609
692
|
* @param category - The kind of fact — a convention, a version, a constraint.
|
|
610
693
|
* @param name - The fact's name.
|
|
@@ -613,12 +696,12 @@ function outcome(rank, text, required = true) {
|
|
|
613
696
|
*
|
|
614
697
|
* @example
|
|
615
698
|
* ```ts
|
|
616
|
-
* import {
|
|
699
|
+
* import { buildGiven } from '@orkestrel/brief'
|
|
617
700
|
*
|
|
618
|
-
*
|
|
701
|
+
* buildGiven('convention', 'indentation', 'tabs')
|
|
619
702
|
* ```
|
|
620
703
|
*/
|
|
621
|
-
function
|
|
704
|
+
function buildGiven(category, name, value) {
|
|
622
705
|
return {
|
|
623
706
|
category,
|
|
624
707
|
name,
|
|
@@ -626,32 +709,32 @@ function given(category, name, value) {
|
|
|
626
709
|
};
|
|
627
710
|
}
|
|
628
711
|
/**
|
|
629
|
-
*
|
|
712
|
+
* Assembles an `Example` from an exemplar input and its expected output.
|
|
630
713
|
*
|
|
631
714
|
* @param input - The exemplar input.
|
|
632
|
-
* @param
|
|
715
|
+
* @param output - The expected output for that input.
|
|
633
716
|
* @param note - Optional detail; the key is OMITTED when absent.
|
|
634
717
|
* @returns A fresh `Example`.
|
|
635
718
|
*
|
|
636
719
|
* @example
|
|
637
720
|
* ```ts
|
|
638
|
-
* import {
|
|
721
|
+
* import { buildExample } from '@orkestrel/brief'
|
|
639
722
|
*
|
|
640
|
-
*
|
|
723
|
+
* buildExample('<input required>', 'validity read from el.validity')
|
|
641
724
|
* ```
|
|
642
725
|
*/
|
|
643
|
-
function
|
|
726
|
+
function buildExample(input, output, note) {
|
|
644
727
|
return note === void 0 ? {
|
|
645
728
|
input,
|
|
646
|
-
output
|
|
729
|
+
output
|
|
647
730
|
} : {
|
|
648
731
|
input,
|
|
649
|
-
output
|
|
732
|
+
output,
|
|
650
733
|
note
|
|
651
734
|
};
|
|
652
735
|
}
|
|
653
736
|
/**
|
|
654
|
-
*
|
|
737
|
+
* Assembles a `Citation` from a name, a URL, and the note that justifies citing it.
|
|
655
738
|
*
|
|
656
739
|
* @param name - The source's display name.
|
|
657
740
|
* @param url - Where the source lives.
|
|
@@ -660,16 +743,16 @@ function example(input, result, note) {
|
|
|
660
743
|
*
|
|
661
744
|
* @example
|
|
662
745
|
* ```ts
|
|
663
|
-
* import {
|
|
746
|
+
* import { buildCitation } from '@orkestrel/brief'
|
|
664
747
|
*
|
|
665
|
-
*
|
|
748
|
+
* buildCitation(
|
|
666
749
|
* 'MDN Constraint Validation',
|
|
667
750
|
* 'https://developer.mozilla.org/',
|
|
668
751
|
* 'the native validity behavior being adopted',
|
|
669
752
|
* )
|
|
670
753
|
* ```
|
|
671
754
|
*/
|
|
672
|
-
function
|
|
755
|
+
function buildCitation(name, url, note) {
|
|
673
756
|
return {
|
|
674
757
|
name,
|
|
675
758
|
url,
|
|
@@ -677,23 +760,23 @@ function citation(name, url, note) {
|
|
|
677
760
|
};
|
|
678
761
|
}
|
|
679
762
|
/**
|
|
680
|
-
*
|
|
763
|
+
* Assembles a `Gap` from the section it belongs to and the question that would close it.
|
|
681
764
|
*
|
|
682
765
|
* @param field - The brief section the unknown belongs to.
|
|
683
766
|
* @param question - The question that would close it.
|
|
684
|
-
* @param overrides - Optional `blocking`
|
|
685
|
-
*
|
|
767
|
+
* @param overrides - Optional `blocking` and `candidates`; an absent `candidates` key is
|
|
768
|
+
* OMITTED entirely. Default: `blocking: false`.
|
|
686
769
|
* @returns A fresh `Gap`.
|
|
687
770
|
*
|
|
688
771
|
* @example
|
|
689
772
|
* ```ts
|
|
690
|
-
* import {
|
|
773
|
+
* import { buildGap } from '@orkestrel/brief'
|
|
691
774
|
*
|
|
692
|
-
*
|
|
693
|
-
*
|
|
775
|
+
* buildGap('rules', 'Does validation message wording need to change?') // blocking: false
|
|
776
|
+
* buildGap('output', 'Diff or full files?', { blocking: true, candidates: ['diff', 'code'] })
|
|
694
777
|
* ```
|
|
695
778
|
*/
|
|
696
|
-
function
|
|
779
|
+
function buildGap(field, question, overrides) {
|
|
697
780
|
const blocking = overrides?.blocking ?? false;
|
|
698
781
|
return overrides?.candidates === void 0 ? {
|
|
699
782
|
field,
|
|
@@ -707,7 +790,7 @@ function gap(field, question, overrides) {
|
|
|
707
790
|
};
|
|
708
791
|
}
|
|
709
792
|
/**
|
|
710
|
-
*
|
|
793
|
+
* Assembles a `Risk` from a severity, what could go wrong, and the mitigation that answers it.
|
|
711
794
|
*
|
|
712
795
|
* @param severity - The closed severity.
|
|
713
796
|
* @param text - What could go wrong.
|
|
@@ -716,12 +799,12 @@ function gap(field, question, overrides) {
|
|
|
716
799
|
*
|
|
717
800
|
* @example
|
|
718
801
|
* ```ts
|
|
719
|
-
* import {
|
|
802
|
+
* import { buildRisk } from '@orkestrel/brief'
|
|
720
803
|
*
|
|
721
|
-
*
|
|
804
|
+
* buildRisk('medium', 'native validation differs subtly', 'assert message and state in tests')
|
|
722
805
|
* ```
|
|
723
806
|
*/
|
|
724
|
-
function
|
|
807
|
+
function buildRisk(severity, text, mitigation) {
|
|
725
808
|
return {
|
|
726
809
|
severity,
|
|
727
810
|
text,
|
|
@@ -729,7 +812,7 @@ function risk(severity, text, mitigation) {
|
|
|
729
812
|
};
|
|
730
813
|
}
|
|
731
814
|
/**
|
|
732
|
-
*
|
|
815
|
+
* Assembles an `Output` from a format plus its optional refinements.
|
|
733
816
|
*
|
|
734
817
|
* @param format - The closed deliverable format.
|
|
735
818
|
* @param overrides - Optional `sections` / `include` / `exclude`; absent keys are OMITTED.
|
|
@@ -737,13 +820,13 @@ function risk(severity, text, mitigation) {
|
|
|
737
820
|
*
|
|
738
821
|
* @example
|
|
739
822
|
* ```ts
|
|
740
|
-
* import {
|
|
823
|
+
* import { buildOutput } from '@orkestrel/brief'
|
|
741
824
|
*
|
|
742
|
-
*
|
|
743
|
-
*
|
|
825
|
+
* buildOutput('markdown') // { format: 'markdown' }
|
|
826
|
+
* buildOutput('diff', { include: ['updated useForm.ts'] })
|
|
744
827
|
* ```
|
|
745
828
|
*/
|
|
746
|
-
function
|
|
829
|
+
function buildOutput(format, overrides) {
|
|
747
830
|
return {
|
|
748
831
|
format,
|
|
749
832
|
...overrides?.sections === void 0 ? {} : { sections: overrides.sections },
|
|
@@ -752,7 +835,7 @@ function output(format, overrides) {
|
|
|
752
835
|
};
|
|
753
836
|
}
|
|
754
837
|
/**
|
|
755
|
-
*
|
|
838
|
+
* Assembles a `Proof` from what the check settles and the command that settles it.
|
|
756
839
|
*
|
|
757
840
|
* @param text - What the check settles.
|
|
758
841
|
* @param command - The command whose exit signal settles it.
|
|
@@ -760,41 +843,41 @@ function output(format, overrides) {
|
|
|
760
843
|
*
|
|
761
844
|
* @example
|
|
762
845
|
* ```ts
|
|
763
|
-
* import {
|
|
846
|
+
* import { buildProof } from '@orkestrel/brief'
|
|
764
847
|
*
|
|
765
|
-
*
|
|
848
|
+
* buildProof('type-check and lint pass', 'npm run check')
|
|
766
849
|
* ```
|
|
767
850
|
*/
|
|
768
|
-
function
|
|
851
|
+
function buildProof(text, command) {
|
|
769
852
|
return {
|
|
770
853
|
text,
|
|
771
854
|
command
|
|
772
855
|
};
|
|
773
856
|
}
|
|
774
857
|
/**
|
|
775
|
-
*
|
|
858
|
+
* Assembles a `Brief` from a `Task` plus section overrides.
|
|
776
859
|
*
|
|
777
860
|
* @param subject - The task the brief is about.
|
|
778
|
-
* @param overrides - Any sections to fill;
|
|
779
|
-
* `
|
|
780
|
-
* `
|
|
861
|
+
* @param overrides - Any sections to fill; `trace` / `hash` stay OMITTED so `pinBrief` can
|
|
862
|
+
* fill them. Default: `[]` for every absent collection and `buildOutput('markdown')` for
|
|
863
|
+
* `output`.
|
|
781
864
|
* @returns A fresh, unpinned `Brief`.
|
|
782
865
|
*
|
|
783
866
|
* @example
|
|
784
867
|
* ```ts
|
|
785
|
-
* import {
|
|
868
|
+
* import { buildBrief, buildOutcome, buildProof, buildTask } from '@orkestrel/brief'
|
|
786
869
|
*
|
|
787
|
-
*
|
|
788
|
-
* outcomes: [
|
|
789
|
-
* proofs: [
|
|
870
|
+
* buildBrief(buildTask('audit', 'code', 'Audit the barrel for undocumented exports.'), {
|
|
871
|
+
* outcomes: [buildOutcome(1, 'every export appears in the guide')],
|
|
872
|
+
* proofs: [buildProof('parity passes', 'npm run test:guides')],
|
|
790
873
|
* })
|
|
791
874
|
* ```
|
|
792
875
|
*/
|
|
793
|
-
function
|
|
876
|
+
function buildBrief(subject, overrides) {
|
|
794
877
|
return {
|
|
795
878
|
task: subject,
|
|
796
879
|
authority: overrides?.authority ?? [],
|
|
797
|
-
manifest: overrides?.manifest ??
|
|
880
|
+
manifest: overrides?.manifest ?? buildManifest(),
|
|
798
881
|
outcomes: overrides?.outcomes ?? [],
|
|
799
882
|
rules: overrides?.rules ?? [],
|
|
800
883
|
invariants: overrides?.invariants ?? [],
|
|
@@ -804,17 +887,17 @@ function brief(subject, overrides) {
|
|
|
804
887
|
citations: overrides?.citations ?? [],
|
|
805
888
|
gaps: overrides?.gaps ?? [],
|
|
806
889
|
risks: overrides?.risks ?? [],
|
|
807
|
-
output: overrides?.output ??
|
|
890
|
+
output: overrides?.output ?? buildOutput("markdown"),
|
|
808
891
|
proofs: overrides?.proofs ?? []
|
|
809
892
|
};
|
|
810
893
|
}
|
|
811
894
|
/**
|
|
812
|
-
*
|
|
895
|
+
* Assembles the fail-closed readiness gate as a reasons `LogicalDefinition`.
|
|
813
896
|
*
|
|
814
897
|
* @remarks
|
|
815
|
-
*
|
|
816
|
-
*
|
|
817
|
-
*
|
|
898
|
+
* Each readiness rule derives one named fact from `briefToSubject`'s measures, and a final
|
|
899
|
+
* `ready` rule conjoins them all. Forward chaining reports the LAST rule's conclusion, so
|
|
900
|
+
* `LogicalResult.conclusion` is exactly `ready`.
|
|
818
901
|
*
|
|
819
902
|
* The gate takes NO parameters, and that is deliberate rather than unfinished. The
|
|
820
903
|
* reasoner overlays every derived fact into one flat namespace, so a caller rule named
|
|
@@ -828,50 +911,50 @@ function brief(subject, overrides) {
|
|
|
828
911
|
*
|
|
829
912
|
* @example
|
|
830
913
|
* ```ts
|
|
831
|
-
* import { briefToSubject,
|
|
914
|
+
* import { briefToSubject, buildGateDefinition } from '@orkestrel/brief'
|
|
832
915
|
* import { createLogicalReasoner, createReason } from '@orkestrel/reason'
|
|
833
916
|
*
|
|
834
917
|
* const reason = createReason({ reasoners: [createLogicalReasoner()] })
|
|
835
|
-
* const verdict = reason.reason(briefToSubject(pinned),
|
|
918
|
+
* const verdict = reason.reason(briefToSubject(pinned), buildGateDefinition())
|
|
836
919
|
* reason.destroy()
|
|
837
920
|
* ```
|
|
838
921
|
*/
|
|
839
|
-
function
|
|
922
|
+
function buildGateDefinition() {
|
|
840
923
|
const readiness = [
|
|
841
|
-
(0, _orkestrel_reason.
|
|
842
|
-
(0, _orkestrel_reason.
|
|
843
|
-
(0, _orkestrel_reason.
|
|
844
|
-
(0, _orkestrel_reason.
|
|
845
|
-
(0, _orkestrel_reason.
|
|
846
|
-
(0, _orkestrel_reason.
|
|
924
|
+
(0, _orkestrel_reason.createRule)("specified", [(0, _orkestrel_reason.createAtom)("blocking", "equals", 0)], (0, _orkestrel_reason.createAtom)("specified", "equals", true)),
|
|
925
|
+
(0, _orkestrel_reason.createRule)("aimed", [(0, _orkestrel_reason.createCompound)("and", [(0, _orkestrel_reason.createAtom)("outcomes", "above", 0), (0, _orkestrel_reason.createAtom)("required", "above", 0)])], (0, _orkestrel_reason.createAtom)("aimed", "equals", true)),
|
|
926
|
+
(0, _orkestrel_reason.createRule)("proven", [(0, _orkestrel_reason.createAtom)("proofs", "above", 0)], (0, _orkestrel_reason.createAtom)("proven", "equals", true)),
|
|
927
|
+
(0, _orkestrel_reason.createRule)("disjoint", [(0, _orkestrel_reason.createAtom)("overlaps", "equals", 0)], (0, _orkestrel_reason.createAtom)("disjoint", "equals", true)),
|
|
928
|
+
(0, _orkestrel_reason.createRule)("granted", [(0, _orkestrel_reason.createAtom)("ungranted", "equals", 0)], (0, _orkestrel_reason.createAtom)("granted", "equals", true)),
|
|
929
|
+
(0, _orkestrel_reason.createRule)("single", [(0, _orkestrel_reason.createAtom)("sentences", "equals", 1)], (0, _orkestrel_reason.createAtom)("single", "equals", true))
|
|
847
930
|
];
|
|
848
|
-
return (0, _orkestrel_reason.
|
|
931
|
+
return (0, _orkestrel_reason.createLogicalDefinition)(GATE_ID, "Brief readiness", [...readiness, (0, _orkestrel_reason.createRule)("ready", [(0, _orkestrel_reason.createCompound)("and", readiness.map((entry) => (0, _orkestrel_reason.createAtom)(entry.id, "equals", true)))], (0, _orkestrel_reason.createAtom)("ready", "equals", true))]);
|
|
849
932
|
}
|
|
850
933
|
/**
|
|
851
|
-
*
|
|
934
|
+
* Lists the readiness rules a brief fails, computed directly from its own measures.
|
|
852
935
|
*
|
|
853
936
|
* @remarks
|
|
854
|
-
* The gate's decision, in code. `
|
|
937
|
+
* The gate's decision, in code. `buildGateDefinition()` states the same rules as data for a
|
|
855
938
|
* reasoner to narrate, and a narration is not a decision: `BriefCompilerOptions.reason` lets a
|
|
856
939
|
* caller supply the engine, and an engine that answers "met" to everything would otherwise
|
|
857
940
|
* emit a brief with no proofs. `compile` refuses on THIS and keeps the verdict for its
|
|
858
941
|
* trace, so a supplied engine can add detail and never remove a refusal.
|
|
859
942
|
*
|
|
860
|
-
* The
|
|
861
|
-
* is what stops
|
|
943
|
+
* The data and the code must agree. `tests/src/core/helpers.test.ts` drives both over one
|
|
944
|
+
* value set, which is what stops them from drifting apart.
|
|
862
945
|
*
|
|
863
946
|
* @param source - The brief to measure.
|
|
864
947
|
* @returns The unmet rule ids, in gate order; empty when the brief is ready.
|
|
865
948
|
*
|
|
866
949
|
* @example
|
|
867
950
|
* ```ts
|
|
868
|
-
* import {
|
|
951
|
+
* import { buildBrief, buildOutcome, buildProof, buildTask, findUnmetRules } from '@orkestrel/brief'
|
|
869
952
|
*
|
|
870
|
-
* findUnmetRules(
|
|
953
|
+
* findUnmetRules(buildBrief(buildTask('plan', 'ops', 'Plan the release.'))) // ['aimed', 'proven']
|
|
871
954
|
* findUnmetRules(
|
|
872
|
-
*
|
|
873
|
-
* outcomes: [
|
|
874
|
-
* proofs: [
|
|
955
|
+
* buildBrief(buildTask('plan', 'ops', 'Plan the release.'), {
|
|
956
|
+
* outcomes: [buildOutcome(1, 'shipped')],
|
|
957
|
+
* proofs: [buildProof('x', 'npm test')],
|
|
875
958
|
* }),
|
|
876
959
|
* ) // []
|
|
877
960
|
* ```
|
|
@@ -887,7 +970,7 @@ function findUnmetRules(source) {
|
|
|
887
970
|
return unready;
|
|
888
971
|
}
|
|
889
972
|
/**
|
|
890
|
-
*
|
|
973
|
+
* Counts the sentences a statement holds.
|
|
891
974
|
*
|
|
892
975
|
* @remarks
|
|
893
976
|
* A terminator run (`.`, `!`, `?`) followed by whitespace or the end of the text closes one
|
|
@@ -925,17 +1008,17 @@ function countSentences(statement) {
|
|
|
925
1008
|
return /[.!?]$/u.test(text) ? matches.length : matches.length + 1;
|
|
926
1009
|
}
|
|
927
1010
|
/**
|
|
928
|
-
*
|
|
1011
|
+
* Lists the gaps that block emission.
|
|
929
1012
|
*
|
|
930
1013
|
* @param source - The brief to inspect.
|
|
931
1014
|
* @returns Every gap carrying `blocking: true`, in declaration order.
|
|
932
1015
|
*
|
|
933
1016
|
* @example
|
|
934
1017
|
* ```ts
|
|
935
|
-
* import {
|
|
1018
|
+
* import { buildBrief, buildGap, buildTask, findBlockingGaps } from '@orkestrel/brief'
|
|
936
1019
|
*
|
|
937
|
-
* const draft =
|
|
938
|
-
* gaps: [
|
|
1020
|
+
* const draft = buildBrief(buildTask('plan', 'ops', 'Plan the release.'), {
|
|
1021
|
+
* gaps: [buildGap('output', 'Diff or files?', { blocking: true })],
|
|
939
1022
|
* })
|
|
940
1023
|
* findBlockingGaps(draft).length // 1
|
|
941
1024
|
* ```
|
|
@@ -944,18 +1027,18 @@ function findBlockingGaps(source) {
|
|
|
944
1027
|
return source.gaps.filter((entry) => entry.blocking);
|
|
945
1028
|
}
|
|
946
1029
|
/**
|
|
947
|
-
*
|
|
1030
|
+
* Lists the authority paths the manifest never grants access to.
|
|
948
1031
|
*
|
|
949
1032
|
* @remarks
|
|
950
1033
|
* An authority the executor cannot open is an instruction it cannot follow, so every ranked
|
|
951
|
-
* path must appear in `read`, `edit`, or `locked`. Those
|
|
1034
|
+
* path must appear in `read`, `edit`, or `locked`. Those are the grants: `locked` is a
|
|
952
1035
|
* grant, because read-only is exactly what obeying a file requires.
|
|
953
1036
|
*
|
|
954
|
-
* This subsumes the narrower question of an authority sitting in `forbidden`. The
|
|
955
|
-
*
|
|
956
|
-
*
|
|
957
|
-
*
|
|
958
|
-
*
|
|
1037
|
+
* This subsumes the narrower question of an authority sitting in `forbidden`. The partitions
|
|
1038
|
+
* are disjoint — `findManifestOverlaps` and the `disjoint` rule enforce it — so a forbidden
|
|
1039
|
+
* path is in none of the grants and is reported here. An authority named in NO partition at
|
|
1040
|
+
* all is reported for the same reason, and that is the case a forbidden-only check misses
|
|
1041
|
+
* entirely: the brief simply never says the executor may open what it must obey.
|
|
959
1042
|
*
|
|
960
1043
|
* Paths are compared as EXACT strings, matching `findManifestOverlaps`. A glob is never
|
|
961
1044
|
* expanded, so `read: 'guides/**'` does not grant `authority: 'guides/brief.md'`. State a
|
|
@@ -966,11 +1049,17 @@ function findBlockingGaps(source) {
|
|
|
966
1049
|
*
|
|
967
1050
|
* @example
|
|
968
1051
|
* ```ts
|
|
969
|
-
* import {
|
|
970
|
-
*
|
|
971
|
-
*
|
|
972
|
-
*
|
|
973
|
-
*
|
|
1052
|
+
* import {
|
|
1053
|
+
* buildBrief,
|
|
1054
|
+
* buildManifest,
|
|
1055
|
+
* buildReference,
|
|
1056
|
+
* buildTask,
|
|
1057
|
+
* findUngrantedAuthority,
|
|
1058
|
+
* } from '@orkestrel/brief'
|
|
1059
|
+
*
|
|
1060
|
+
* const draft = buildBrief(buildTask('debug', 'code', 'Fix the leak.'), {
|
|
1061
|
+
* authority: [buildReference('AGENTS.md', 'project law')],
|
|
1062
|
+
* manifest: buildManifest(),
|
|
974
1063
|
* })
|
|
975
1064
|
* findUngrantedAuthority(draft) // ['AGENTS.md'] — ranked, but no partition opens it
|
|
976
1065
|
* ```
|
|
@@ -986,10 +1075,10 @@ function findUngrantedAuthority(source) {
|
|
|
986
1075
|
return ungranted;
|
|
987
1076
|
}
|
|
988
1077
|
/**
|
|
989
|
-
*
|
|
1078
|
+
* Lists the paths appearing in more than one manifest partition.
|
|
990
1079
|
*
|
|
991
1080
|
* @remarks
|
|
992
|
-
* Duplicates WITHIN one partition are not an overlap; the
|
|
1081
|
+
* Duplicates WITHIN one partition are not an overlap; the partitions must be
|
|
993
1082
|
* mutually disjoint, which is what `validateBrief` errors on.
|
|
994
1083
|
*
|
|
995
1084
|
* Paths are compared as EXACT strings. A glob is never expanded, so `edit: 'app/file.ts'`
|
|
@@ -1001,12 +1090,18 @@ function findUngrantedAuthority(source) {
|
|
|
1001
1090
|
*
|
|
1002
1091
|
* @example
|
|
1003
1092
|
* ```ts
|
|
1004
|
-
* import {
|
|
1005
|
-
*
|
|
1006
|
-
*
|
|
1007
|
-
*
|
|
1008
|
-
*
|
|
1009
|
-
*
|
|
1093
|
+
* import {
|
|
1094
|
+
* buildBrief,
|
|
1095
|
+
* buildManifest,
|
|
1096
|
+
* buildReference,
|
|
1097
|
+
* buildTask,
|
|
1098
|
+
* findManifestOverlaps,
|
|
1099
|
+
* } from '@orkestrel/brief'
|
|
1100
|
+
*
|
|
1101
|
+
* const draft = buildBrief(buildTask('debug', 'code', 'Fix the leak.'), {
|
|
1102
|
+
* manifest: buildManifest({
|
|
1103
|
+
* edit: [buildReference('src/core/BriefCompiler.ts', 'the leaking pipeline')],
|
|
1104
|
+
* locked: [buildReference('src/core/BriefCompiler.ts', 'the published contract')],
|
|
1010
1105
|
* }),
|
|
1011
1106
|
* })
|
|
1012
1107
|
* findManifestOverlaps(draft) // ['src/core/BriefCompiler.ts']
|
|
@@ -1026,7 +1121,7 @@ function findManifestOverlaps(source) {
|
|
|
1026
1121
|
return overlaps;
|
|
1027
1122
|
}
|
|
1028
1123
|
/**
|
|
1029
|
-
*
|
|
1124
|
+
* Lists the open gaps with no assumption to stand on.
|
|
1030
1125
|
*
|
|
1031
1126
|
* @remarks
|
|
1032
1127
|
* The discipline is exactly one recorded assumption per open gap, so the open gaps past
|
|
@@ -1038,10 +1133,10 @@ function findManifestOverlaps(source) {
|
|
|
1038
1133
|
*
|
|
1039
1134
|
* @example
|
|
1040
1135
|
* ```ts
|
|
1041
|
-
* import {
|
|
1136
|
+
* import { buildBrief, buildGap, buildTask, findUnpairedGaps } from '@orkestrel/brief'
|
|
1042
1137
|
*
|
|
1043
|
-
* const draft =
|
|
1044
|
-
* gaps: [
|
|
1138
|
+
* const draft = buildBrief(buildTask('plan', 'ops', 'Plan the release.'), {
|
|
1139
|
+
* gaps: [buildGap('rules', 'Keep the wording?'), buildGap('output', 'Diff or files?')],
|
|
1045
1140
|
* assumptions: ['Wording is preserved.'],
|
|
1046
1141
|
* })
|
|
1047
1142
|
* findUnpairedGaps(draft).length // 1
|
|
@@ -1051,16 +1146,16 @@ function findUnpairedGaps(source) {
|
|
|
1051
1146
|
return source.gaps.filter((entry) => !entry.blocking).slice(source.assumptions.length);
|
|
1052
1147
|
}
|
|
1053
1148
|
/**
|
|
1054
|
-
*
|
|
1149
|
+
* Projects a brief into the reasons `Subject` of readiness measures the gate reads.
|
|
1055
1150
|
*
|
|
1056
1151
|
* @param source - The brief to measure.
|
|
1057
|
-
* @returns A flat record of counts plus the task's
|
|
1152
|
+
* @returns A flat record of counts plus the task's vocabulary values.
|
|
1058
1153
|
*
|
|
1059
1154
|
* @example
|
|
1060
1155
|
* ```ts
|
|
1061
|
-
* import {
|
|
1156
|
+
* import { briefToSubject, buildBrief, buildProof, buildTask } from '@orkestrel/brief'
|
|
1062
1157
|
*
|
|
1063
|
-
* briefToSubject(
|
|
1158
|
+
* briefToSubject(buildBrief(buildTask('test', 'code', 'Cover the gate.'), { proofs: [buildProof('x', 'y')] }))
|
|
1064
1159
|
* // { operation: 'test', domain: 'code', sentences: 1, proofs: 1, … }
|
|
1065
1160
|
* ```
|
|
1066
1161
|
*/
|
|
@@ -1087,7 +1182,7 @@ function briefToSubject(source) {
|
|
|
1087
1182
|
};
|
|
1088
1183
|
}
|
|
1089
1184
|
/**
|
|
1090
|
-
*
|
|
1185
|
+
* Runs the semantic pass over an already-shape-valid brief.
|
|
1091
1186
|
*
|
|
1092
1187
|
* @remarks
|
|
1093
1188
|
* ERRORS are the structural violations no assumption can paper over: a manifest
|
|
@@ -1101,11 +1196,11 @@ function briefToSubject(source) {
|
|
|
1101
1196
|
*
|
|
1102
1197
|
* @example
|
|
1103
1198
|
* ```ts
|
|
1104
|
-
* import {
|
|
1199
|
+
* import { buildBrief, buildProof, buildTask, validateBrief } from '@orkestrel/brief'
|
|
1105
1200
|
*
|
|
1106
|
-
* validateBrief(
|
|
1201
|
+
* validateBrief(buildBrief(buildTask('plan', 'ops', 'Plan the release.'))) // valid: false — no proofs
|
|
1107
1202
|
* validateBrief(
|
|
1108
|
-
*
|
|
1203
|
+
* buildBrief(buildTask('plan', 'ops', 'Plan the release.'), { proofs: [buildProof('ok', 'npm test')] }),
|
|
1109
1204
|
* ) // valid: true
|
|
1110
1205
|
* ```
|
|
1111
1206
|
*/
|
|
@@ -1133,7 +1228,7 @@ function validateBrief(source) {
|
|
|
1133
1228
|
};
|
|
1134
1229
|
}
|
|
1135
1230
|
/**
|
|
1136
|
-
*
|
|
1231
|
+
* Computes the canonical structural digest of a brief's content.
|
|
1137
1232
|
*
|
|
1138
1233
|
* @remarks
|
|
1139
1234
|
* `trace` and `hash` are stripped before digesting, so the value is the identity of what
|
|
@@ -1145,9 +1240,9 @@ function validateBrief(source) {
|
|
|
1145
1240
|
*
|
|
1146
1241
|
* @example
|
|
1147
1242
|
* ```ts
|
|
1148
|
-
* import {
|
|
1243
|
+
* import { briefToHash, buildBrief, buildTask, pinBrief } from '@orkestrel/brief'
|
|
1149
1244
|
*
|
|
1150
|
-
* const draft =
|
|
1245
|
+
* const draft = buildBrief(buildTask('plan', 'ops', 'Plan the release.'))
|
|
1151
1246
|
* briefToHash(draft) === briefToHash(pinBrief(draft)) // true — pinning does not move it
|
|
1152
1247
|
* ```
|
|
1153
1248
|
*/
|
|
@@ -1155,7 +1250,7 @@ function briefToHash(source) {
|
|
|
1155
1250
|
return (0, _orkestrel_interpret.digestValue)(briefToContent(source));
|
|
1156
1251
|
}
|
|
1157
1252
|
/**
|
|
1158
|
-
*
|
|
1253
|
+
* Renders the canonical text of exactly what a brief's hash describes.
|
|
1159
1254
|
*
|
|
1160
1255
|
* @remarks
|
|
1161
1256
|
* `trace` and `hash` are stripped, then interprets `canonicalize` renders the rest in a
|
|
@@ -1167,9 +1262,9 @@ function briefToHash(source) {
|
|
|
1167
1262
|
*
|
|
1168
1263
|
* @example
|
|
1169
1264
|
* ```ts
|
|
1170
|
-
* import {
|
|
1265
|
+
* import { briefToContent, buildBrief, buildTask, pinBrief } from '@orkestrel/brief'
|
|
1171
1266
|
*
|
|
1172
|
-
* const draft =
|
|
1267
|
+
* const draft = buildBrief(buildTask('plan', 'ops', 'Plan the release.'))
|
|
1173
1268
|
* briefToContent(draft) === briefToContent(pinBrief(draft)) // true — pinning adds no content
|
|
1174
1269
|
* ```
|
|
1175
1270
|
*/
|
|
@@ -1178,7 +1273,7 @@ function briefToContent(source) {
|
|
|
1178
1273
|
return (0, _orkestrel_interpret.canonicalize)(content);
|
|
1179
1274
|
}
|
|
1180
1275
|
/**
|
|
1181
|
-
*
|
|
1276
|
+
* Freezes a value and everything reachable from it.
|
|
1182
1277
|
*
|
|
1183
1278
|
* @remarks
|
|
1184
1279
|
* `Object.freeze` is SHALLOW, so freezing a record leaves every nested array and object
|
|
@@ -1192,7 +1287,7 @@ function briefToContent(source) {
|
|
|
1192
1287
|
* Reaches PLAIN objects and arrays, which is the whole of a `Brief` — it is JSON-serializable
|
|
1193
1288
|
* by contract. A `Map`, `Set`, or typed array is frozen as an object and its CONTENTS are left
|
|
1194
1289
|
* writable, and `Object.isFrozen` reports `true` for it either way. Nothing this package
|
|
1195
|
-
* produces contains one; a caller freezing their own value
|
|
1290
|
+
* produces contains one; the limit lands on a caller freezing their own value.
|
|
1196
1291
|
*
|
|
1197
1292
|
* @param value - The value to freeze in place; returned for convenience.
|
|
1198
1293
|
* @returns The same value, now deeply frozen.
|
|
@@ -1209,7 +1304,7 @@ function freezeDeep(value) {
|
|
|
1209
1304
|
return freezeBranch(value, /* @__PURE__ */ new WeakSet());
|
|
1210
1305
|
}
|
|
1211
1306
|
/**
|
|
1212
|
-
*
|
|
1307
|
+
* Freezes one branch of a value graph, skipping what the visited set already holds.
|
|
1213
1308
|
*
|
|
1214
1309
|
* @param value - The branch to freeze.
|
|
1215
1310
|
* @param seen - The objects already frozen on this walk; what makes a cycle terminate.
|
|
@@ -1231,7 +1326,7 @@ function freezeBranch(value, seen) {
|
|
|
1231
1326
|
return value;
|
|
1232
1327
|
}
|
|
1233
1328
|
/**
|
|
1234
|
-
*
|
|
1329
|
+
* Renders a value thrown by a stage into a message.
|
|
1235
1330
|
*
|
|
1236
1331
|
* @remarks
|
|
1237
1332
|
* TOTAL: it never throws, for any input. That is load-bearing rather than tidy, because this
|
|
@@ -1240,7 +1335,7 @@ function freezeBranch(value, seen) {
|
|
|
1240
1335
|
* falsifies the package's central promise that a failing stage yields an incomplete
|
|
1241
1336
|
* `Briefing` rather than an exception.
|
|
1242
1337
|
*
|
|
1243
|
-
*
|
|
1338
|
+
* Real inputs used to throw: an `Error` subclass whose `message` getter throws, a value
|
|
1244
1339
|
* whose string conversion throws, and a null-prototype object, which has no inherited
|
|
1245
1340
|
* conversion for String() to reach. Each is wrapped, and an unreadable value degrades to its
|
|
1246
1341
|
* type rather than propagating.
|
|
@@ -1264,10 +1359,10 @@ function errorToMessage(error) {
|
|
|
1264
1359
|
return `an unreadable ${typeof error} was thrown`;
|
|
1265
1360
|
}
|
|
1266
1361
|
/**
|
|
1267
|
-
*
|
|
1362
|
+
* Narrows unknown data to a `Brief`, throwing when it is off-contract.
|
|
1268
1363
|
*
|
|
1269
1364
|
* @remarks
|
|
1270
|
-
* The throwing half of the intake pair: this returns its argument by IDENTITY
|
|
1365
|
+
* The throwing half of the intake pair: this returns its argument by IDENTITY after the
|
|
1271
1366
|
* guard passes, while `parseBrief` returns `undefined` for bad input. It constructs
|
|
1272
1367
|
* nothing, so it is an assertion rather than a factory. Reserve it for programmer-error
|
|
1273
1368
|
* contexts where invalidity is a bug.
|
|
@@ -1281,24 +1376,24 @@ function errorToMessage(error) {
|
|
|
1281
1376
|
* `briefToTrace` read the value they are handed instead, so a caller reaching one of those
|
|
1282
1377
|
* directly owns that reading. Pass `assertBrief` a value you already own.
|
|
1283
1378
|
*
|
|
1284
|
-
* @param
|
|
1379
|
+
* @param value - The candidate brief value.
|
|
1285
1380
|
* @returns The same value, now known to satisfy {@link Brief}.
|
|
1286
|
-
* @throws {@link BriefError} `INVALID` when `
|
|
1381
|
+
* @throws {@link BriefError} `INVALID` when `value` fails `isBrief`.
|
|
1287
1382
|
*
|
|
1288
1383
|
* @example
|
|
1289
1384
|
* ```ts
|
|
1290
|
-
* import { assertBrief,
|
|
1385
|
+
* import { assertBrief, buildBrief, buildProof, buildTask } from '@orkestrel/brief'
|
|
1291
1386
|
*
|
|
1292
|
-
* assertBrief(
|
|
1387
|
+
* assertBrief(buildBrief(buildTask('plan', 'ops', 'Plan the release.'), { proofs: [buildProof('x', 'y')] }))
|
|
1293
1388
|
* assertBrief({ task: { operation: 'plan', domain: 'ops', statement: 'x.' } }) // throws INVALID
|
|
1294
1389
|
* ```
|
|
1295
1390
|
*/
|
|
1296
|
-
function assertBrief(
|
|
1297
|
-
if (!isBrief(
|
|
1298
|
-
return
|
|
1391
|
+
function assertBrief(value) {
|
|
1392
|
+
if (!isBrief(value)) throw new BriefError("INVALID", "Brief failed the exact-record contract", { field: "brief" });
|
|
1393
|
+
return value;
|
|
1299
1394
|
}
|
|
1300
1395
|
/**
|
|
1301
|
-
*
|
|
1396
|
+
* Returns a fresh brief with `trace` and `hash` derived from its own content.
|
|
1302
1397
|
*
|
|
1303
1398
|
* @remarks
|
|
1304
1399
|
* Deterministic: no clock, no randomness, no run-specific data. Any existing `trace` /
|
|
@@ -1314,9 +1409,9 @@ function assertBrief(data) {
|
|
|
1314
1409
|
*
|
|
1315
1410
|
* @example
|
|
1316
1411
|
* ```ts
|
|
1317
|
-
* import {
|
|
1412
|
+
* import { buildBrief, buildTask, pinBrief } from '@orkestrel/brief'
|
|
1318
1413
|
*
|
|
1319
|
-
* const pinned = pinBrief(
|
|
1414
|
+
* const pinned = pinBrief(buildBrief(buildTask('document', 'writing', 'Write the brief guide.')))
|
|
1320
1415
|
* pinned.hash // an 8-hex-digit structural digest
|
|
1321
1416
|
* pinned.trace // 'document/writing · outcomes:0 · gaps:0/0 · proofs:0'
|
|
1322
1417
|
* ```
|
|
@@ -1331,7 +1426,7 @@ function pinBrief(source) {
|
|
|
1331
1426
|
});
|
|
1332
1427
|
}
|
|
1333
1428
|
/**
|
|
1334
|
-
*
|
|
1429
|
+
* Renders the one-line census `pinBrief` stamps onto a brief.
|
|
1335
1430
|
*
|
|
1336
1431
|
* @remarks
|
|
1337
1432
|
* Extracted so it has ONE implementation. `pinBrief` derives it and `BriefManager` re-derives
|
|
@@ -1344,9 +1439,9 @@ function pinBrief(source) {
|
|
|
1344
1439
|
*
|
|
1345
1440
|
* @example
|
|
1346
1441
|
* ```ts
|
|
1347
|
-
* import {
|
|
1442
|
+
* import { briefToTrace, buildBrief, buildTask } from '@orkestrel/brief'
|
|
1348
1443
|
*
|
|
1349
|
-
* briefToTrace(
|
|
1444
|
+
* briefToTrace(buildBrief(buildTask('document', 'writing', 'Write the guide.')))
|
|
1350
1445
|
* // 'document/writing · outcomes:0 · gaps:0/0 · proofs:0'
|
|
1351
1446
|
* ```
|
|
1352
1447
|
*/
|
|
@@ -1359,7 +1454,7 @@ function briefToTrace(source) {
|
|
|
1359
1454
|
].join(" · ");
|
|
1360
1455
|
}
|
|
1361
1456
|
/**
|
|
1362
|
-
*
|
|
1457
|
+
* Renders one exemplar as markdown lines.
|
|
1363
1458
|
*
|
|
1364
1459
|
* @remarks
|
|
1365
1460
|
* An `Example`'s two sides are the only brief members permitted to span lines, so a
|
|
@@ -1371,9 +1466,9 @@ function briefToTrace(source) {
|
|
|
1371
1466
|
*
|
|
1372
1467
|
* @example
|
|
1373
1468
|
* ```ts
|
|
1374
|
-
* import {
|
|
1469
|
+
* import { buildExample, exampleToLines } from '@orkestrel/brief'
|
|
1375
1470
|
*
|
|
1376
|
-
* exampleToLines(
|
|
1471
|
+
* exampleToLines(buildExample('<input required>', 'el.validity')) // ['- ` <input required> ` → ` el.validity `']
|
|
1377
1472
|
* ```
|
|
1378
1473
|
*/
|
|
1379
1474
|
function exampleToLines(entry) {
|
|
@@ -1404,20 +1499,20 @@ function exampleToLines(entry) {
|
|
|
1404
1499
|
];
|
|
1405
1500
|
}
|
|
1406
1501
|
/**
|
|
1407
|
-
*
|
|
1502
|
+
* Projects a brief into the copy-ready agent prompt.
|
|
1408
1503
|
*
|
|
1409
1504
|
* @remarks
|
|
1410
1505
|
* Paths are REFERENCED, never inlined — the executor retrieves them. An empty section is
|
|
1411
1506
|
* omitted entirely, so the rendering carries no filler an executor must read past.
|
|
1412
1507
|
*
|
|
1413
|
-
* @param
|
|
1508
|
+
* @param input - The brief to render.
|
|
1414
1509
|
* @returns The markdown prompt.
|
|
1415
1510
|
*
|
|
1416
1511
|
* @example
|
|
1417
1512
|
* ```ts
|
|
1418
|
-
* import {
|
|
1513
|
+
* import { briefToMarkdown, buildBrief, buildTask } from '@orkestrel/brief'
|
|
1419
1514
|
*
|
|
1420
|
-
* briefToMarkdown(
|
|
1515
|
+
* briefToMarkdown(buildBrief(buildTask('review', 'code', 'Review the gate rules.')))
|
|
1421
1516
|
* // '# Brief: Review the gate rules.\n\nreview · code\n\n## Output\n\n- format: markdown\n'
|
|
1422
1517
|
* ```
|
|
1423
1518
|
*/
|
|
@@ -1511,21 +1606,21 @@ function briefToMarkdown(input) {
|
|
|
1511
1606
|
return lines.join("\n");
|
|
1512
1607
|
}
|
|
1513
1608
|
/**
|
|
1514
|
-
*
|
|
1609
|
+
* Projects a brief into a `/goal` completion condition.
|
|
1515
1610
|
*
|
|
1516
1611
|
* @remarks
|
|
1517
1612
|
* The proofs' commands VERBATIM plus a turn cap — the goal never adds a condition the
|
|
1518
1613
|
* brief does not carry.
|
|
1519
1614
|
*
|
|
1520
|
-
* @param
|
|
1521
|
-
* @param turns - The turn cap
|
|
1615
|
+
* @param input - The brief to render.
|
|
1616
|
+
* @param turns - The turn cap. Default: `DEFAULT_BRIEF_TURNS`.
|
|
1522
1617
|
* @returns The one-line completion condition.
|
|
1523
1618
|
*
|
|
1524
1619
|
* @example
|
|
1525
1620
|
* ```ts
|
|
1526
|
-
* import {
|
|
1621
|
+
* import { briefToGoal, buildBrief, buildProof, buildTask } from '@orkestrel/brief'
|
|
1527
1622
|
*
|
|
1528
|
-
* briefToGoal(
|
|
1623
|
+
* briefToGoal(buildBrief(buildTask('test', 'code', 'Cover the gate.'), { proofs: [buildProof('x', 'npm test')] }))
|
|
1529
1624
|
* // 'Done when every proof passes: npm test exits 0. Cap: 16 turns.'
|
|
1530
1625
|
* ```
|
|
1531
1626
|
*/
|
|
@@ -1534,27 +1629,33 @@ function briefToGoal(input, turns = 16) {
|
|
|
1534
1629
|
return `Done when every proof passes: ${source.proofs.length === 0 ? "no proofs recorded" : source.proofs.map((entry) => `${entry.command} exits 0`).join("; ")}. Cap: ${String(turns)} turns.`;
|
|
1535
1630
|
}
|
|
1536
1631
|
/**
|
|
1537
|
-
*
|
|
1632
|
+
* Projects a brief into a subagent `Dispatch`.
|
|
1538
1633
|
*
|
|
1539
1634
|
* @remarks
|
|
1540
1635
|
* `edit` is exactly `manifest.edit`, so two dispatches whose `edit` sets do not intersect
|
|
1541
1636
|
* can run concurrently under the same brief without conflict.
|
|
1542
1637
|
*
|
|
1543
1638
|
* `authority` is exactly `brief.authority` in rank order, and it is a SEPARATE axis from the
|
|
1544
|
-
*
|
|
1639
|
+
* permission sets rather than a further partition — a ranked path normally also appears in
|
|
1545
1640
|
* `read` or `locked`, because the executor has to open what it obeys. It is projected as
|
|
1546
1641
|
* paths so a machine consumer never has to parse `prompt`, which is written for a model.
|
|
1547
1642
|
*
|
|
1548
|
-
* @param
|
|
1549
|
-
* @returns The dispatch — the rendered prompt, the ranked authority, and the
|
|
1643
|
+
* @param input - The brief to project.
|
|
1644
|
+
* @returns The dispatch — the rendered prompt, the ranked authority, and the path sets.
|
|
1550
1645
|
*
|
|
1551
1646
|
* @example
|
|
1552
1647
|
* ```ts
|
|
1553
|
-
* import {
|
|
1554
|
-
*
|
|
1555
|
-
*
|
|
1556
|
-
*
|
|
1557
|
-
*
|
|
1648
|
+
* import {
|
|
1649
|
+
* briefToDispatch,
|
|
1650
|
+
* buildBrief,
|
|
1651
|
+
* buildManifest,
|
|
1652
|
+
* buildReference,
|
|
1653
|
+
* buildTask,
|
|
1654
|
+
* } from '@orkestrel/brief'
|
|
1655
|
+
*
|
|
1656
|
+
* const draft = buildBrief(buildTask('migrate', 'code', 'Migrate the stores.'), {
|
|
1657
|
+
* authority: [buildReference('AGENTS.md', 'project law')],
|
|
1658
|
+
* manifest: buildManifest({ edit: [buildReference('src/core/stores/**', 'the legacy stores')] }),
|
|
1558
1659
|
* })
|
|
1559
1660
|
* briefToDispatch(draft).edit // ['src/core/stores/**']
|
|
1560
1661
|
* briefToDispatch(draft).authority // ['AGENTS.md']
|
|
@@ -1572,36 +1673,39 @@ function briefToDispatch(input) {
|
|
|
1572
1673
|
};
|
|
1573
1674
|
}
|
|
1574
1675
|
/**
|
|
1575
|
-
*
|
|
1676
|
+
* Derives one imperative statement from free text.
|
|
1576
1677
|
*
|
|
1577
1678
|
* @remarks
|
|
1578
1679
|
* Whitespace collapses, the first character uppercases, and a terminator is appended
|
|
1579
1680
|
* when the text carries none. Nothing else is invented.
|
|
1580
1681
|
*
|
|
1581
1682
|
* @param text - The raw request text.
|
|
1582
|
-
* @returns The statement, or `
|
|
1683
|
+
* @returns The statement, or `undefined` for empty or whitespace-only text.
|
|
1583
1684
|
*
|
|
1584
1685
|
* @example
|
|
1585
1686
|
* ```ts
|
|
1586
1687
|
* import { deriveStatement } from '@orkestrel/brief'
|
|
1587
1688
|
*
|
|
1588
1689
|
* deriveStatement(' clean up useForm ') // 'Clean up useForm.'
|
|
1589
|
-
* deriveStatement('') //
|
|
1690
|
+
* deriveStatement('') // undefined
|
|
1590
1691
|
* ```
|
|
1591
1692
|
*/
|
|
1592
1693
|
function deriveStatement(text) {
|
|
1593
1694
|
const collapsed = (0, _orkestrel_interpret.collapseWhitespace)(text);
|
|
1594
|
-
if (collapsed.length === 0) return
|
|
1695
|
+
if (collapsed.length === 0) return void 0;
|
|
1595
1696
|
const capitalized = collapsed.charAt(0).toUpperCase() + collapsed.slice(1);
|
|
1596
1697
|
return /[.!?]$/u.test(capitalized) ? capitalized : `${capitalized}.`;
|
|
1597
1698
|
}
|
|
1598
1699
|
/**
|
|
1599
|
-
*
|
|
1700
|
+
* Derives a `Task` from an interprets `Intent` through the caller's vocabularies.
|
|
1600
1701
|
*
|
|
1601
1702
|
* @remarks
|
|
1602
1703
|
* The vocabularies are the CALLER's policy: this maps and never guesses. An action or
|
|
1603
1704
|
* domain the caller did not map — or mapped to an off-vocabulary value — yields
|
|
1604
|
-
* `undefined` rather than an invented task. Inherited keys never resolve.
|
|
1705
|
+
* `undefined` rather than an invented task. Inherited keys never resolve. `Intent.action`
|
|
1706
|
+
* and `Intent.domain` are optional, because `classifyIntent` leaves an unmatched axis
|
|
1707
|
+
* absent, and an absent axis is unmapped by definition: it yields `undefined` before
|
|
1708
|
+
* either vocabulary is read.
|
|
1605
1709
|
*
|
|
1606
1710
|
* @param intent - The classified intent from an interpret pipeline.
|
|
1607
1711
|
* @param text - The text the statement derives from.
|
|
@@ -1620,16 +1724,17 @@ function deriveStatement(text) {
|
|
|
1620
1724
|
* ```
|
|
1621
1725
|
*/
|
|
1622
1726
|
function deriveTask(intent, text, actions, domains) {
|
|
1727
|
+
if (intent.action === void 0 || intent.domain === void 0) return void 0;
|
|
1623
1728
|
const operationDescriptor = Object.getOwnPropertyDescriptor(actions, intent.action);
|
|
1624
1729
|
const domainDescriptor = Object.getOwnPropertyDescriptor(domains, intent.domain);
|
|
1625
1730
|
const operation = operationDescriptor === void 0 ? void 0 : "value" in operationDescriptor ? operationDescriptor.value : operationDescriptor.get === void 0 ? void 0 : Reflect.apply(operationDescriptor.get, actions, []);
|
|
1626
1731
|
const domain = domainDescriptor === void 0 ? void 0 : "value" in domainDescriptor ? domainDescriptor.value : domainDescriptor.get === void 0 ? void 0 : Reflect.apply(domainDescriptor.get, domains, []);
|
|
1627
1732
|
if (!isTaskOperation(operation) || !isTaskDomain(domain)) return void 0;
|
|
1628
1733
|
const statement = deriveStatement(text);
|
|
1629
|
-
return statement
|
|
1734
|
+
return statement === void 0 ? void 0 : buildTask(operation, domain, statement);
|
|
1630
1735
|
}
|
|
1631
1736
|
/**
|
|
1632
|
-
*
|
|
1737
|
+
* Derives `Given[]` from an interprets `Entity[]`.
|
|
1633
1738
|
*
|
|
1634
1739
|
* @remarks
|
|
1635
1740
|
* Every extracted entity becomes one `extracted` fact. A nameless entity is dropped; an
|
|
@@ -1648,10 +1753,10 @@ function deriveTask(intent, text, actions, domains) {
|
|
|
1648
1753
|
* ```
|
|
1649
1754
|
*/
|
|
1650
1755
|
function deriveGivens(entities) {
|
|
1651
|
-
return entities.filter((entity) => entity.name.length > 0).map((entity) =>
|
|
1756
|
+
return entities.filter((entity) => entity.name.length > 0).map((entity) => buildGiven("extracted", entity.name, typeof entity.value === "string" ? entity.value : typeof entity.value === "object" && entity.value !== null ? (0, _orkestrel_interpret.canonicalize)(entity.value) : String(entity.value)));
|
|
1652
1757
|
}
|
|
1653
1758
|
/**
|
|
1654
|
-
*
|
|
1759
|
+
* Derives `Gap[]` from an interprets `Ambiguity[]`.
|
|
1655
1760
|
*
|
|
1656
1761
|
* @remarks
|
|
1657
1762
|
* A REQUIRED ambiguity becomes a BLOCKING gap — the gate must fail closed on it. The
|
|
@@ -1672,7 +1777,7 @@ function deriveGivens(entities) {
|
|
|
1672
1777
|
function deriveGaps(ambiguities) {
|
|
1673
1778
|
return ambiguities.map((ambiguity) => {
|
|
1674
1779
|
const candidates = ambiguity.candidates.filter((candidate) => candidate.length > 0);
|
|
1675
|
-
return
|
|
1780
|
+
return buildGap((0, _orkestrel_reason.formatField)(ambiguity.field), ambiguity.question, {
|
|
1676
1781
|
blocking: ambiguity.required,
|
|
1677
1782
|
...candidates.length === 0 ? {} : { candidates }
|
|
1678
1783
|
});
|
|
@@ -1681,7 +1786,7 @@ function deriveGaps(ambiguities) {
|
|
|
1681
1786
|
//#endregion
|
|
1682
1787
|
//#region src/core/parsers.ts
|
|
1683
1788
|
/**
|
|
1684
|
-
*
|
|
1789
|
+
* Parses a JSON string into a `Brief`.
|
|
1685
1790
|
*
|
|
1686
1791
|
* @remarks
|
|
1687
1792
|
* The parse-then-trust boundary for a stored brief, a tool argument, or an agent's
|
|
@@ -1715,7 +1820,7 @@ function parseBrief(value) {
|
|
|
1715
1820
|
//#endregion
|
|
1716
1821
|
//#region src/core/BriefManager.ts
|
|
1717
1822
|
/**
|
|
1718
|
-
*
|
|
1823
|
+
* Implements the self-owning, versioned and content-hashed brief registry.
|
|
1719
1824
|
*
|
|
1720
1825
|
* @remarks
|
|
1721
1826
|
* Record ids are MINTED from each brief's own content hash unless the caller names one,
|
|
@@ -1725,10 +1830,10 @@ function parseBrief(value) {
|
|
|
1725
1830
|
*
|
|
1726
1831
|
* @example
|
|
1727
1832
|
* ```ts
|
|
1728
|
-
* import { BriefManager,
|
|
1833
|
+
* import { BriefManager, buildBrief, buildTask } from '@orkestrel/brief'
|
|
1729
1834
|
*
|
|
1730
1835
|
* const briefs = new BriefManager()
|
|
1731
|
-
* const record = briefs.add(
|
|
1836
|
+
* const record = briefs.add(buildBrief(buildTask('document', 'writing', 'Write the brief guide.')))
|
|
1732
1837
|
* record.id === record.hash // true
|
|
1733
1838
|
* briefs.destroy()
|
|
1734
1839
|
* ```
|
|
@@ -1755,7 +1860,7 @@ var BriefManager = class {
|
|
|
1755
1860
|
get emitter() {
|
|
1756
1861
|
return this.#emitter;
|
|
1757
1862
|
}
|
|
1758
|
-
get
|
|
1863
|
+
get count() {
|
|
1759
1864
|
return this.#records.size;
|
|
1760
1865
|
}
|
|
1761
1866
|
has(id) {
|
|
@@ -1770,9 +1875,9 @@ var BriefManager = class {
|
|
|
1770
1875
|
this.#refuseDestroyed();
|
|
1771
1876
|
return [...this.#records.values()];
|
|
1772
1877
|
}
|
|
1773
|
-
add(
|
|
1878
|
+
add(brief, options) {
|
|
1774
1879
|
this.#refuseDestroyed();
|
|
1775
|
-
const record = this.#stage(
|
|
1880
|
+
const record = this.#stage(brief, this.#records, options);
|
|
1776
1881
|
this.#commit(record);
|
|
1777
1882
|
return record;
|
|
1778
1883
|
}
|
|
@@ -1839,7 +1944,7 @@ var BriefManager = class {
|
|
|
1839
1944
|
//#endregion
|
|
1840
1945
|
//#region src/core/BriefCompiler.ts
|
|
1841
1946
|
/**
|
|
1842
|
-
*
|
|
1947
|
+
* Implements the compilation orchestrator — the `[interpret, draft, gate, pin]` pipeline.
|
|
1843
1948
|
*
|
|
1844
1949
|
* @remarks
|
|
1845
1950
|
* `compile` is genuinely SYNCHRONOUS and never throws for a brief it cannot emit: a
|
|
@@ -1849,13 +1954,13 @@ var BriefManager = class {
|
|
|
1849
1954
|
*
|
|
1850
1955
|
* @example
|
|
1851
1956
|
* ```ts
|
|
1852
|
-
* import { BriefCompiler,
|
|
1957
|
+
* import { BriefCompiler, buildProof, buildTask } from '@orkestrel/brief'
|
|
1853
1958
|
*
|
|
1854
1959
|
* const compiler = new BriefCompiler()
|
|
1855
1960
|
* const briefing = compiler.compile({
|
|
1856
|
-
* task:
|
|
1961
|
+
* task: buildTask('audit', 'code', 'Audit the barrel for undocumented exports.'),
|
|
1857
1962
|
* outcomes: [{ rank: 1, text: 'every export appears in the guide', required: true }],
|
|
1858
|
-
* proofs: [
|
|
1963
|
+
* proofs: [buildProof('parity passes', 'npm run test:guides')],
|
|
1859
1964
|
* })
|
|
1860
1965
|
* briefing.brief !== undefined // true — the presence of the brief IS the completeness test
|
|
1861
1966
|
* compiler.destroy()
|
|
@@ -2006,9 +2111,9 @@ var BriefCompiler = class {
|
|
|
2006
2111
|
this.#emitter.emit("compile", briefing);
|
|
2007
2112
|
return briefing;
|
|
2008
2113
|
}
|
|
2009
|
-
gate(
|
|
2114
|
+
gate(brief) {
|
|
2010
2115
|
this.#refuseDestroyed();
|
|
2011
|
-
const ruled = (0, _orkestrel_contract.attempt)(() => this.#own(this.#reason.reason(briefToSubject(
|
|
2116
|
+
const ruled = (0, _orkestrel_contract.attempt)(() => this.#own(this.#reason.reason(briefToSubject(brief), buildGateDefinition()), [
|
|
2012
2117
|
"reasoning",
|
|
2013
2118
|
"conclusion",
|
|
2014
2119
|
"rules",
|
|
@@ -2097,7 +2202,7 @@ var BriefCompiler = class {
|
|
|
2097
2202
|
message: `Gate refused: ${unready.join(", ")}`
|
|
2098
2203
|
};
|
|
2099
2204
|
if (verdict === void 0) return void 0;
|
|
2100
|
-
const refused = verdict.rules.filter((entry) => !entry.
|
|
2205
|
+
const refused = verdict.rules.filter((entry) => !entry.applied).map((entry) => entry.id).join(", ");
|
|
2101
2206
|
if (refused.length === 0) return {
|
|
2102
2207
|
stage: "gate",
|
|
2103
2208
|
code: "BLOCKED",
|
|
@@ -2112,7 +2217,7 @@ var BriefCompiler = class {
|
|
|
2112
2217
|
#unresolved(interpretation, failures) {
|
|
2113
2218
|
if (interpretation !== void 0) return [];
|
|
2114
2219
|
if (!failures.some((entry) => entry.stage === "interpret")) return [];
|
|
2115
|
-
return [
|
|
2220
|
+
return [buildGap("gaps", "The interpret stage failed, so the request is unread and its unknowns are unknown", { blocking: true })];
|
|
2116
2221
|
}
|
|
2117
2222
|
#draft(input, interpretation, unresolved) {
|
|
2118
2223
|
const derived = interpretation === void 0 ? void 0 : deriveTask(interpretation.intent, interpretation.text, this.#actions, this.#domains);
|
|
@@ -2121,9 +2226,9 @@ var BriefCompiler = class {
|
|
|
2121
2226
|
stage: "draft",
|
|
2122
2227
|
field: "task"
|
|
2123
2228
|
});
|
|
2124
|
-
return snapshotBrief(
|
|
2229
|
+
return snapshotBrief(buildBrief(subject, {
|
|
2125
2230
|
authority: input.authority ?? [],
|
|
2126
|
-
manifest: input.manifest ??
|
|
2231
|
+
manifest: input.manifest ?? buildManifest(),
|
|
2127
2232
|
outcomes: input.outcomes ?? [],
|
|
2128
2233
|
rules: input.rules ?? [],
|
|
2129
2234
|
invariants: input.invariants ?? [],
|
|
@@ -2137,7 +2242,7 @@ var BriefCompiler = class {
|
|
|
2137
2242
|
...input.gaps ?? []
|
|
2138
2243
|
],
|
|
2139
2244
|
risks: input.risks ?? [],
|
|
2140
|
-
output: input.output ??
|
|
2245
|
+
output: input.output ?? buildOutput("markdown"),
|
|
2141
2246
|
proofs: input.proofs ?? []
|
|
2142
2247
|
}));
|
|
2143
2248
|
}
|
|
@@ -2165,7 +2270,7 @@ var BriefCompiler = class {
|
|
|
2165
2270
|
//#endregion
|
|
2166
2271
|
//#region src/core/factories.ts
|
|
2167
2272
|
/**
|
|
2168
|
-
*
|
|
2273
|
+
* Creates a compilation orchestrator.
|
|
2169
2274
|
*
|
|
2170
2275
|
* @remarks
|
|
2171
2276
|
* With no engines supplied the compiler wires its own: a default `createInterpret()`
|
|
@@ -2173,7 +2278,8 @@ var BriefCompiler = class {
|
|
|
2173
2278
|
* `createReason` carrying one `LogicalReasoner` for the gate. Pass your own to share
|
|
2174
2279
|
* instances or observe their emitters — the compiler destroys ONLY what it created.
|
|
2175
2280
|
*
|
|
2176
|
-
* @param options - Engines to borrow, the
|
|
2281
|
+
* @param options - Engines to borrow, the `actions` and `domains` intent vocabularies, and
|
|
2282
|
+
* emitter hooks.
|
|
2177
2283
|
* @returns A working {@link BriefCompilerInterface}.
|
|
2178
2284
|
*
|
|
2179
2285
|
* @example
|
|
@@ -2188,7 +2294,7 @@ function createBriefCompiler(options) {
|
|
|
2188
2294
|
return new BriefCompiler(options);
|
|
2189
2295
|
}
|
|
2190
2296
|
/**
|
|
2191
|
-
*
|
|
2297
|
+
* Creates a brief registry.
|
|
2192
2298
|
*
|
|
2193
2299
|
* @param options - An optional seed collection plus emitter hooks.
|
|
2194
2300
|
* @returns A working {@link BriefManagerInterface}.
|
|
@@ -2198,7 +2304,7 @@ function createBriefCompiler(options) {
|
|
|
2198
2304
|
* import { createBriefManager } from '@orkestrel/brief'
|
|
2199
2305
|
*
|
|
2200
2306
|
* const briefs = createBriefManager()
|
|
2201
|
-
* briefs.
|
|
2307
|
+
* briefs.count // 0
|
|
2202
2308
|
* briefs.destroy()
|
|
2203
2309
|
* ```
|
|
2204
2310
|
*/
|
|
@@ -2206,7 +2312,7 @@ function createBriefManager(options) {
|
|
|
2206
2312
|
return new BriefManager(options);
|
|
2207
2313
|
}
|
|
2208
2314
|
/**
|
|
2209
|
-
*
|
|
2315
|
+
* Compiles `briefShape` into a guard, parser, JSON Schema, and seeded generator bundle.
|
|
2210
2316
|
*
|
|
2211
2317
|
* @remarks
|
|
2212
2318
|
* The schema is what a tool boundary needs — hand it to `schemaToParameters` — and
|
|
@@ -2244,7 +2350,6 @@ exports.SINGLE_LINE_PATTERN = SINGLE_LINE_PATTERN;
|
|
|
2244
2350
|
exports.TASK_DOMAINS = TASK_DOMAINS;
|
|
2245
2351
|
exports.TASK_OPERATIONS = TASK_OPERATIONS;
|
|
2246
2352
|
exports.assertBrief = assertBrief;
|
|
2247
|
-
exports.brief = brief;
|
|
2248
2353
|
exports.briefShape = briefShape;
|
|
2249
2354
|
exports.briefToContent = briefToContent;
|
|
2250
2355
|
exports.briefToDispatch = briefToDispatch;
|
|
@@ -2253,8 +2358,20 @@ exports.briefToHash = briefToHash;
|
|
|
2253
2358
|
exports.briefToMarkdown = briefToMarkdown;
|
|
2254
2359
|
exports.briefToSubject = briefToSubject;
|
|
2255
2360
|
exports.briefToTrace = briefToTrace;
|
|
2361
|
+
exports.buildBrief = buildBrief;
|
|
2362
|
+
exports.buildCitation = buildCitation;
|
|
2363
|
+
exports.buildExample = buildExample;
|
|
2364
|
+
exports.buildGap = buildGap;
|
|
2365
|
+
exports.buildGateDefinition = buildGateDefinition;
|
|
2366
|
+
exports.buildGiven = buildGiven;
|
|
2367
|
+
exports.buildManifest = buildManifest;
|
|
2368
|
+
exports.buildOutcome = buildOutcome;
|
|
2369
|
+
exports.buildOutput = buildOutput;
|
|
2370
|
+
exports.buildProof = buildProof;
|
|
2371
|
+
exports.buildReference = buildReference;
|
|
2372
|
+
exports.buildRisk = buildRisk;
|
|
2373
|
+
exports.buildTask = buildTask;
|
|
2256
2374
|
exports.captureValue = captureValue;
|
|
2257
|
-
exports.citation = citation;
|
|
2258
2375
|
exports.citationShape = citationShape;
|
|
2259
2376
|
exports.countSentences = countSentences;
|
|
2260
2377
|
exports.createBriefCompiler = createBriefCompiler;
|
|
@@ -2265,7 +2382,6 @@ exports.deriveGivens = deriveGivens;
|
|
|
2265
2382
|
exports.deriveStatement = deriveStatement;
|
|
2266
2383
|
exports.deriveTask = deriveTask;
|
|
2267
2384
|
exports.errorToMessage = errorToMessage;
|
|
2268
|
-
exports.example = example;
|
|
2269
2385
|
exports.exampleShape = exampleShape;
|
|
2270
2386
|
exports.exampleToLines = exampleToLines;
|
|
2271
2387
|
exports.findBlockingGaps = findBlockingGaps;
|
|
@@ -2275,10 +2391,7 @@ exports.findUnmetRules = findUnmetRules;
|
|
|
2275
2391
|
exports.findUnpairedGaps = findUnpairedGaps;
|
|
2276
2392
|
exports.freezeBranch = freezeBranch;
|
|
2277
2393
|
exports.freezeDeep = freezeDeep;
|
|
2278
|
-
exports.gap = gap;
|
|
2279
2394
|
exports.gapShape = gapShape;
|
|
2280
|
-
exports.gateDefinition = gateDefinition;
|
|
2281
|
-
exports.given = given;
|
|
2282
2395
|
exports.givenShape = givenShape;
|
|
2283
2396
|
exports.isBrief = isBrief;
|
|
2284
2397
|
exports.isBriefError = isBriefError;
|
|
@@ -2300,22 +2413,15 @@ exports.isTaskDomain = isTaskDomain;
|
|
|
2300
2413
|
exports.isTaskOperation = isTaskOperation;
|
|
2301
2414
|
exports.isText = isText;
|
|
2302
2415
|
exports.lineShape = lineShape;
|
|
2303
|
-
exports.manifest = manifest;
|
|
2304
2416
|
exports.manifestShape = manifestShape;
|
|
2305
|
-
exports.outcome = outcome;
|
|
2306
2417
|
exports.outcomeShape = outcomeShape;
|
|
2307
|
-
exports.output = output;
|
|
2308
2418
|
exports.outputShape = outputShape;
|
|
2309
2419
|
exports.parseBrief = parseBrief;
|
|
2310
2420
|
exports.pinBrief = pinBrief;
|
|
2311
|
-
exports.proof = proof;
|
|
2312
2421
|
exports.proofShape = proofShape;
|
|
2313
|
-
exports.reference = reference;
|
|
2314
2422
|
exports.referenceShape = referenceShape;
|
|
2315
|
-
exports.risk = risk;
|
|
2316
2423
|
exports.riskShape = riskShape;
|
|
2317
2424
|
exports.snapshotBrief = snapshotBrief;
|
|
2318
|
-
exports.task = task;
|
|
2319
2425
|
exports.taskShape = taskShape;
|
|
2320
2426
|
exports.textShape = textShape;
|
|
2321
2427
|
exports.validateBrief = validateBrief;
|