@orkestrel/brief 0.0.6 → 0.0.8

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.
@@ -1,32 +1,32 @@
1
- import { Ambiguity } from '@orkestrel/interpret';
1
+ import type { Ambiguity } from '@orkestrel/interpret';
2
2
  import { ArrayShape } from '@orkestrel/contract';
3
3
  import { BooleanShape } from '@orkestrel/contract';
4
- import { ContractInterface } from '@orkestrel/contract';
5
- import { EmitterErrorHandler } from '@orkestrel/emitter';
6
- import { EmitterHooks } from '@orkestrel/emitter';
7
- import { EmitterInterface } from '@orkestrel/emitter';
8
- import { Entity } from '@orkestrel/interpret';
9
- import { Guard } from '@orkestrel/contract';
10
- import { Intent } from '@orkestrel/interpret';
11
- import { Interpretation } from '@orkestrel/interpret';
12
- import { InterpretInterface } from '@orkestrel/interpret';
4
+ import type { ContractInterface } from '@orkestrel/contract';
5
+ import type { EmitterErrorHandler } from '@orkestrel/emitter';
6
+ import type { EmitterHooks } from '@orkestrel/emitter';
7
+ import type { EmitterInterface } from '@orkestrel/emitter';
8
+ import type { Entity } from '@orkestrel/interpret';
9
+ import type { Guard } from '@orkestrel/contract';
10
+ import type { Intent } from '@orkestrel/interpret';
11
+ import type { Interpretation } from '@orkestrel/interpret';
12
+ import type { InterpretInterface } from '@orkestrel/interpret';
13
13
  import { LiteralShape } from '@orkestrel/contract';
14
- import { LogicalDefinition } from '@orkestrel/reason';
15
- import { LogicalResult } from '@orkestrel/reason';
16
- import { ManagerAddOptions } from '@orkestrel/interpret';
14
+ import type { LogicalDefinition } from '@orkestrel/reason';
15
+ import type { LogicalResult } from '@orkestrel/reason';
17
16
  import { NumberShape } from '@orkestrel/contract';
18
17
  import { ObjectShape } from '@orkestrel/contract';
19
18
  import { OptionalShape } from '@orkestrel/contract';
20
- import { ReasonInterface } from '@orkestrel/reason';
21
- import { ReasonValidationResult } from '@orkestrel/reason';
22
- import { StringShape } from '@orkestrel/contract';
23
- import { Subject } from '@orkestrel/reason';
19
+ import type { ReasonInterface } from '@orkestrel/reason';
20
+ import type { ReasonValidationResult } from '@orkestrel/reason';
21
+ import type { RecordOptions } from '@orkestrel/interpret';
22
+ import type { StringShape } from '@orkestrel/contract';
23
+ import type { Subject } from '@orkestrel/reason';
24
24
 
25
25
  /**
26
- * Narrow unknown data to a `Brief`, throwing when it is off-contract.
26
+ * Narrows unknown data to a `Brief`, throwing when it is off-contract.
27
27
  *
28
28
  * @remarks
29
- * The throwing half of the intake pair: this returns its argument by IDENTITY once the
29
+ * The throwing half of the intake pair: this returns its argument by IDENTITY after the
30
30
  * guard passes, while `parseBrief` returns `undefined` for bad input. It constructs
31
31
  * nothing, so it is an assertion rather than a factory. Reserve it for programmer-error
32
32
  * contexts where invalidity is a bug.
@@ -40,22 +40,22 @@ import { Subject } from '@orkestrel/reason';
40
40
  * `briefToTrace` read the value they are handed instead, so a caller reaching one of those
41
41
  * directly owns that reading. Pass `assertBrief` a value you already own.
42
42
  *
43
- * @param data - The candidate brief data.
43
+ * @param value - The candidate brief value.
44
44
  * @returns The same value, now known to satisfy {@link Brief}.
45
- * @throws {@link BriefError} `INVALID` when `data` fails `isBrief`.
45
+ * @throws {@link BriefError} `INVALID` when `value` fails `isBrief`.
46
46
  *
47
47
  * @example
48
48
  * ```ts
49
- * import { assertBrief, brief, proof, task } from '@orkestrel/brief'
49
+ * import { assertBrief, buildBrief, buildProof, buildTask } from '@orkestrel/brief'
50
50
  *
51
- * assertBrief(brief(task('plan', 'ops', 'Plan the release.'), { proofs: [proof('x', 'y')] }))
51
+ * assertBrief(buildBrief(buildTask('plan', 'ops', 'Plan the release.'), { proofs: [buildProof('x', 'y')] }))
52
52
  * assertBrief({ task: { operation: 'plan', domain: 'ops', statement: 'x.' } }) // throws INVALID
53
53
  * ```
54
54
  */
55
- export declare function assertBrief(data: unknown): Brief;
55
+ export declare function assertBrief(value: unknown): Brief;
56
56
 
57
57
  /**
58
- * A string of one or more spaces and nothing else.
58
+ * Matches a string of one or more spaces and nothing else.
59
59
  *
60
60
  * @remarks
61
61
  * The one exemplar side `exampleToLines` must NOT pad. CommonMark strips a fully-blank code
@@ -68,10 +68,10 @@ import { Subject } from '@orkestrel/reason';
68
68
  export declare const BLANK_PATTERN: RegExp;
69
69
 
70
70
  /**
71
- * The closed execution contract — a rough request with every implicit decision resolved.
71
+ * Represents the closed execution contract — a rough request with every implicit decision resolved.
72
72
  *
73
73
  * @remarks
74
- * `trace` and `hash` are DERIVED by `pinBrief`. The `brief` builder cannot set them, so
74
+ * `trace` and `hash` are DERIVED by `pinBrief`. The `buildBrief` builder cannot set them, so
75
75
  * nothing this package produces authors them.
76
76
  *
77
77
  * They are still SHAPE-checked rather than verified on the way in: `isBrief` and `parseBrief`
@@ -100,28 +100,7 @@ import { Subject } from '@orkestrel/reason';
100
100
  }
101
101
 
102
102
  /**
103
- * Build a `Brief` from a `Task` plus section overrides.
104
- *
105
- * @param subject - The task the brief is about.
106
- * @param overrides - Any sections to fill; every absent collection defaults to `[]`,
107
- * `output` defaults to `output('markdown')`, and `trace` / `hash` stay OMITTED so
108
- * `pinBrief` can fill them.
109
- * @returns A fresh, unpinned `Brief`.
110
- *
111
- * @example
112
- * ```ts
113
- * import { brief, outcome, proof, task } from '@orkestrel/brief'
114
- *
115
- * brief(task('audit', 'code', 'Audit the barrel for undocumented exports.'), {
116
- * outcomes: [outcome(1, 'every export appears in the guide')],
117
- * proofs: [proof('parity passes', 'npm run test:guides')],
118
- * })
119
- * ```
120
- */
121
- export declare function brief(subject: Task, overrides?: Partial<Omit<Brief, 'task' | 'trace' | 'hash'>>): Brief;
122
-
123
- /**
124
- * The compilation orchestrator — the four-stage `[interpret, draft, gate, pin]` pipeline.
103
+ * Implements the compilation orchestrator the `[interpret, draft, gate, pin]` pipeline.
125
104
  *
126
105
  * @remarks
127
106
  * `compile` is genuinely SYNCHRONOUS and never throws for a brief it cannot emit: a
@@ -131,13 +110,13 @@ import { Subject } from '@orkestrel/reason';
131
110
  *
132
111
  * @example
133
112
  * ```ts
134
- * import { BriefCompiler, proof, task } from '@orkestrel/brief'
113
+ * import { BriefCompiler, buildProof, buildTask } from '@orkestrel/brief'
135
114
  *
136
115
  * const compiler = new BriefCompiler()
137
116
  * const briefing = compiler.compile({
138
- * task: task('audit', 'code', 'Audit the barrel for undocumented exports.'),
117
+ * task: buildTask('audit', 'code', 'Audit the barrel for undocumented exports.'),
139
118
  * outcomes: [{ rank: 1, text: 'every export appears in the guide', required: true }],
140
- * proofs: [proof('parity passes', 'npm run test:guides')],
119
+ * proofs: [buildProof('parity passes', 'npm run test:guides')],
141
120
  * })
142
121
  * briefing.brief !== undefined // true — the presence of the brief IS the completeness test
143
122
  * compiler.destroy()
@@ -150,30 +129,64 @@ import { Subject } from '@orkestrel/reason';
150
129
  get interpret(): InterpretInterface;
151
130
  get reason(): ReasonInterface;
152
131
  compile(input: BriefInput): Briefing;
153
- gate(source: Brief): LogicalResult;
132
+ gate(brief: Brief): LogicalResult;
154
133
  destroy(): void;
155
134
  }
156
135
 
157
- /** The `BriefCompiler`'s push observation surface. */
136
+ /**
137
+ * Declares the `BriefCompiler`'s push observation surface.
138
+ *
139
+ * @remarks
140
+ * `compile` carries the `Briefing` the call produced, `block` carries the blocking `Gap` list
141
+ * that stopped emission, `error` carries the thrown value, and `destroy` carries nothing.
142
+ */
158
143
  export declare type BriefCompilerEventMap = {
159
- compile: readonly [briefing: Briefing];
160
- block: readonly [questions: readonly Gap[]];
161
- error: readonly [error: unknown];
162
- destroy: readonly [];
144
+ readonly compile: readonly [briefing: Briefing];
145
+ readonly block: readonly [questions: readonly Gap[]];
146
+ readonly error: readonly [error: unknown];
147
+ readonly destroy: readonly [];
163
148
  };
164
149
 
165
- /** The compilation orchestrator contract. */
150
+ /** Declares the compilation orchestrator contract. */
166
151
  export declare interface BriefCompilerInterface {
152
+ /** Holds the typed emitter carrying `compile`, `block`, `error`, and `destroy`. */
167
153
  readonly emitter: EmitterInterface<BriefCompilerEventMap>;
154
+ /** Holds the interpret pipeline the `interpret` stage delegates to, owned or borrowed. */
168
155
  readonly interpret: InterpretInterface;
156
+ /** Holds the reasoner the gate evaluates its `LogicalDefinition` on, owned or borrowed. */
169
157
  readonly reason: ReasonInterface;
158
+ /**
159
+ * Runs the `interpret` → `draft` → `gate` → `pin` pipeline over a `BriefInput`, returning a
160
+ * complete or visible-incomplete result.
161
+ *
162
+ * @remarks
163
+ * Synchronous, and it never throws for a brief it cannot emit: a blocking gap, a refused
164
+ * gate, and a thrown stage each record their cause on `failures` and leave `brief` absent.
165
+ *
166
+ * @param input - The caller's text, interpretation, and authored sections.
167
+ * @returns The `Briefing` for this call, complete exactly when `brief` is present.
168
+ */
170
169
  compile(input: BriefInput): Briefing;
170
+ /**
171
+ * Evaluates one brief's readiness through the reasons gate — `briefToSubject` against
172
+ * `buildGateDefinition()`.
173
+ *
174
+ * @param brief - The brief to measure.
175
+ * @returns The reasoner's traceable verdict, whose `conclusion` is the `ready` fact.
176
+ */
171
177
  gate(brief: Brief): LogicalResult;
178
+ /**
179
+ * Tears the orchestrator down idempotently — owned engines first, the emitter last.
180
+ *
181
+ * @remarks
182
+ * Emits `destroy` between the two, and releases only the engines it created. Every method
183
+ * except this one throws `BriefError('DESTROYED', …)` afterwards.
184
+ */
172
185
  destroy(): void;
173
186
  }
174
187
 
175
188
  /**
176
- * Input to `createBriefCompiler`.
189
+ * Represents the input to `createBriefCompiler`.
177
190
  *
178
191
  * @remarks
179
192
  * `interpret` and `reason` are BORROWED when supplied — the compiler destroys only
@@ -221,9 +234,12 @@ import { Subject } from '@orkestrel/reason';
221
234
  }
222
235
 
223
236
  /**
224
- * The one error class this package throws.
237
+ * Represents the one error class this package throws.
225
238
  *
226
239
  * @remarks
240
+ * Extends `Error` with a readonly `code` on the `BriefErrorCode` vocabulary and an optional
241
+ * readonly `context` record carrying whatever the raising site can supply.
242
+ *
227
243
  * Throws are reserved for caller misuse: `assertBrief`, `snapshotBrief`, and `pinBrief` on
228
244
  * off-contract data throw `INVALID`; any method after `destroy()` throws `DESTROYED`; and `BriefCompiler.gate` throws
229
245
  * `GATE_FAILED` when a borrowed reasoner returns a non-logical result. A stage that fails
@@ -247,26 +263,26 @@ import { Subject } from '@orkestrel/reason';
247
263
  }
248
264
 
249
265
  /**
250
- * The machine-readable reasons a {@link BriefError} carries.
266
+ * Names the machine-readable reasons a {@link BriefError} carries.
251
267
  *
252
268
  * @remarks
253
- * Inside `compile` every stage failure is CONTAINED: the four `*_FAILED` codes and
254
- * `BLOCKED` mark it on the {@link Briefing} rather than throwing.
269
+ * Inside `compile` every stage failure is CONTAINED: the `*_FAILED` codes and `BLOCKED`
270
+ * mark it on the {@link Briefing} rather than throwing.
255
271
  *
256
272
  * `INTERPRET_FAILED` needs a FOREIGN `InterpretInterface`. `@orkestrel/interpret` contains
257
273
  * its own stage failures and returns a degraded `Interpretation` rather than throwing, so
258
274
  * the default engine never raises it; `BriefCompilerOptions.interpret` is the seam a caller
259
- * reaches it through. Three codes also reach a
260
- * throw, from methods outside that containment `INVALID` from `assertBrief`,
261
- * `snapshotBrief`, and `pinBrief`; `DESTROYED` from any method after
262
- * `destroy()`; and `GATE_FAILED` from `BriefCompiler.gate` when a borrowed reasoner returns a
263
- * non-logical result OR throws its own error, which is translated rather than leaked so that
264
- * every throw out of this module stays a `BriefError` an `isBriefError` catch can narrow.
275
+ * reaches it through. Other codes also reach a throw, from methods outside that containment —
276
+ * `INVALID` from `assertBrief`, `snapshotBrief`, and `pinBrief`; `DESTROYED` from any method
277
+ * after `destroy()`; and `GATE_FAILED` from `BriefCompiler.gate` when a borrowed reasoner
278
+ * returns a non-logical result OR throws its own error, which is translated rather than
279
+ * leaked so that every throw out of this module stays a `BriefError` an `isBriefError` catch
280
+ * can narrow.
265
281
  */
266
282
  export declare type BriefErrorCode = 'INTERPRET_FAILED' | 'DRAFT_FAILED' | 'GATE_FAILED' | 'PIN_FAILED' | 'BLOCKED' | 'INVALID' | 'DESTROYED';
267
283
 
268
284
  /**
269
- * The full, replayable outcome of one `compile()` call.
285
+ * Represents the full, replayable outcome of one `compile()` call.
270
286
  *
271
287
  * @remarks
272
288
  * `brief` is present exactly when the compile completed, so it is ALSO the completeness
@@ -279,7 +295,7 @@ import { Subject } from '@orkestrel/reason';
279
295
  * types — import them from `@orkestrel/interpret` and `@orkestrel/reason`.
280
296
  *
281
297
  * `digest` identifies this OUTCOME — the brief, the questions, and the failures together — so
282
- * two identical compiles share it and a refused compile has one just as a complete one does.
298
+ * two identical compiles share it and a refused compile has one the same way a complete one does.
283
299
  * It is not `Brief.hash`, which identifies the brief's content alone and exists only on an
284
300
  * emitted brief. Key a cache of compile results by `digest`; key a registry of briefs by
285
301
  * `hash`.
@@ -295,14 +311,15 @@ import { Subject } from '@orkestrel/reason';
295
311
  }
296
312
 
297
313
  /**
298
- * One `compile()` input.
314
+ * Represents one `compile()` input.
299
315
  *
300
316
  * @remarks
301
- * THREE classes of input, not two. `text` selects the interpret stage. `interpretation`
302
- * supplies that stage's result directly: with no `text` it drives `deriveTask`,
303
- * `deriveGivens`, and `deriveGaps` without running the language pipeline at all, and with
304
- * `text` present it is also the FALLBACK the draft uses when the interpret engine throws.
305
- * Every remaining key is a caller-authored section merged OVER whatever the draft derived.
317
+ * `text`, `interpretation`, and the caller-authored sections are SEPARATE classes of input.
318
+ * `text` selects the interpret stage. `interpretation` supplies that stage's result
319
+ * directly: with no `text` it drives `deriveTask`, `deriveGivens`, and `deriveGaps` without
320
+ * running the language pipeline at all, and with `text` present it is also the FALLBACK the
321
+ * draft uses when the interpret engine throws. Every remaining key is a caller-authored
322
+ * section merged OVER whatever the draft derived.
306
323
  *
307
324
  * Supplying both `text` and `interpretation` is therefore meaningful: the engine's result
308
325
  * wins when it succeeds, and the supplied one carries the compile when it does not.
@@ -327,7 +344,7 @@ import { Subject } from '@orkestrel/reason';
327
344
  }
328
345
 
329
346
  /**
330
- * The self-owning, versioned and content-hashed brief registry.
347
+ * Implements the self-owning, versioned and content-hashed brief registry.
331
348
  *
332
349
  * @remarks
333
350
  * Record ids are MINTED from each brief's own content hash unless the caller names one,
@@ -337,10 +354,10 @@ import { Subject } from '@orkestrel/reason';
337
354
  *
338
355
  * @example
339
356
  * ```ts
340
- * import { BriefManager, brief, task } from '@orkestrel/brief'
357
+ * import { BriefManager, buildBrief, buildTask } from '@orkestrel/brief'
341
358
  *
342
359
  * const briefs = new BriefManager()
343
- * const record = briefs.add(brief(task('document', 'writing', 'Write the brief guide.')))
360
+ * const record = briefs.add(buildBrief(buildTask('document', 'writing', 'Write the brief guide.')))
344
361
  * record.id === record.hash // true
345
362
  * briefs.destroy()
346
363
  * ```
@@ -349,54 +366,107 @@ import { Subject } from '@orkestrel/reason';
349
366
  #private;
350
367
  constructor(options?: BriefManagerOptions);
351
368
  get emitter(): EmitterInterface<BriefManagerEventMap>;
352
- get size(): number;
369
+ get count(): number;
353
370
  has(id: string): boolean;
354
371
  brief(id: string): BriefRecord | undefined;
355
372
  briefs(): readonly BriefRecord[];
356
- add(source: Brief, options?: ManagerAddOptions): BriefRecord;
373
+ add(brief: Brief, options?: RecordOptions): BriefRecord;
357
374
  remove(ids: readonly string[]): boolean;
358
375
  remove(id: string): boolean;
359
376
  remove(): void;
360
377
  destroy(): void;
361
378
  }
362
379
 
363
- /** The `BriefManager`'s push observation surface. */
380
+ /**
381
+ * Declares the `BriefManager`'s push observation surface.
382
+ *
383
+ * @remarks
384
+ * `add` and `remove` each carry the record id the store minted from the brief's content hash,
385
+ * and `destroy` carries nothing.
386
+ */
364
387
  export declare type BriefManagerEventMap = {
365
- add: readonly [id: string];
366
- remove: readonly [id: string];
367
- destroy: readonly [];
388
+ readonly add: readonly [id: string];
389
+ readonly remove: readonly [id: string];
390
+ readonly destroy: readonly [];
368
391
  };
369
392
 
370
393
  /**
371
- * The brief registry contract.
394
+ * Declares the brief registry contract.
372
395
  *
373
396
  * @remarks
374
397
  * The array overload of `remove` is declared FIRST so an id list resolves to the batch
375
- * form. `add` takes the fleet's own `ManagerAddOptions` from `@orkestrel/interpret`;
398
+ * form. `add` takes the fleet's own `RecordOptions` from `@orkestrel/interpret`;
376
399
  * omit its `id` and the record is keyed by the brief's own content hash, so re-adding
377
400
  * unchanged content is a version no-op.
378
401
  */
379
402
  export declare interface BriefManagerInterface {
403
+ /** Holds the typed emitter carrying `add`, `remove`, and `destroy`. */
380
404
  readonly emitter: EmitterInterface<BriefManagerEventMap>;
381
- readonly size: number;
405
+ /** Holds how many records are registered. */
406
+ readonly count: number;
407
+ /**
408
+ * Reports whether a brief with the given id is registered.
409
+ *
410
+ * @param id - The record id to look for.
411
+ * @returns True if a record carries that id; false otherwise.
412
+ */
382
413
  has(id: string): boolean;
414
+ /**
415
+ * Looks up one registered brief record by id.
416
+ *
417
+ * @param id - The record id to read.
418
+ * @returns The record, or `undefined` when no record carries that id.
419
+ */
383
420
  brief(id: string): BriefRecord | undefined;
421
+ /**
422
+ * Lists every registered brief record.
423
+ *
424
+ * @returns The records, in registration order.
425
+ */
384
426
  briefs(): readonly BriefRecord[];
385
- add(brief: Brief, options?: ManagerAddOptions): BriefRecord;
427
+ /**
428
+ * Registers one brief from its data, minting the id from its content hash when none is given.
429
+ *
430
+ * @remarks
431
+ * Emits `add`. `version` bumps only when the content hash moves, so re-adding unchanged
432
+ * content is a no-op that keeps the record it already had.
433
+ *
434
+ * @param brief - The brief to register.
435
+ * @param options - An explicit `id` to key the record by.
436
+ * @returns The registered record.
437
+ */
438
+ add(brief: Brief, options?: RecordOptions): BriefRecord;
439
+ /**
440
+ * Removes the listed briefs by id, one brief by id, or every brief.
441
+ *
442
+ * @remarks
443
+ * Emits `remove` once per removed id. The array overload is declared first so an id list
444
+ * resolves to the batch form, which reports `true` only when every listed id was present.
445
+ *
446
+ * @param ids - The record ids to remove.
447
+ * @returns True when every listed id was registered; false otherwise.
448
+ */
386
449
  remove(ids: readonly string[]): boolean;
387
450
  remove(id: string): boolean;
388
451
  remove(): void;
452
+ /**
453
+ * Tears the registry down idempotently — the collection first, the emitter last.
454
+ *
455
+ * @remarks
456
+ * Emits `destroy` between the two. Every method except this one throws
457
+ * `BriefError('DESTROYED', …)` afterwards.
458
+ */
389
459
  destroy(): void;
390
460
  }
391
461
 
392
- /** Input to `createBriefManager`. */
462
+ /** Represents the input to `createBriefManager`. */
393
463
  export declare interface BriefManagerOptions {
394
464
  readonly briefs?: readonly Brief[];
395
465
  readonly on?: EmitterHooks<BriefManagerEventMap>;
396
466
  readonly error?: EmitterErrorHandler;
397
467
  }
398
468
 
399
- /** A versioned, content-hashed `Brief` inside a {@link BriefManagerInterface}. */
469
+ /** Represents a versioned, content-hashed `Brief` inside a {@link BriefManagerInterface}. */
400
470
  export declare interface BriefRecord {
401
471
  readonly id: string;
402
472
  readonly brief: Brief;
@@ -405,92 +475,92 @@ import { Subject } from '@orkestrel/reason';
405
475
  }
406
476
 
407
477
  /**
408
- * The whole `Brief` shape, section shapes composed.
478
+ * Describes the whole `Brief` shape, section shapes composed.
409
479
  *
410
480
  * @remarks
411
481
  * `trace` and `hash` are optional because `pinBrief` fills them; an unpinned draft is
412
482
  * on-contract without them.
413
483
  */
414
- export declare const briefShape: ObjectShape<{
415
- task: ObjectShape<{
416
- operation: LiteralShape<readonly TaskOperation[]>;
417
- domain: LiteralShape<readonly TaskDomain[]>;
418
- statement: StringShape;
419
- }, false>;
420
- authority: ArrayShape<ObjectShape<{
421
- path: StringShape;
422
- note: StringShape;
423
- }, false>>;
424
- manifest: ObjectShape<{
425
- read: ArrayShape<ObjectShape<{
426
- path: StringShape;
427
- note: StringShape;
428
- }, false>>;
429
- edit: ArrayShape<ObjectShape<{
430
- path: StringShape;
431
- note: StringShape;
432
- }, false>>;
433
- locked: ArrayShape<ObjectShape<{
434
- path: StringShape;
435
- note: StringShape;
436
- }, false>>;
437
- forbidden: ArrayShape<ObjectShape<{
438
- path: StringShape;
439
- note: StringShape;
440
- }, false>>;
441
- }, false>;
442
- outcomes: ArrayShape<ObjectShape<{
443
- rank: NumberShape;
444
- text: StringShape;
445
- required: BooleanShape;
446
- }, false>>;
447
- rules: ArrayShape<StringShape>;
448
- invariants: ArrayShape<StringShape>;
449
- givens: ArrayShape<ObjectShape<{
450
- category: StringShape;
451
- name: StringShape;
452
- value: StringShape;
453
- }, false>>;
454
- examples: ArrayShape<ObjectShape<{
455
- input: StringShape;
456
- output: StringShape;
457
- note: OptionalShape<StringShape>;
458
- }, false>>;
459
- assumptions: ArrayShape<StringShape>;
460
- citations: ArrayShape<ObjectShape<{
461
- name: StringShape;
462
- url: StringShape;
463
- note: StringShape;
464
- }, false>>;
465
- gaps: ArrayShape<ObjectShape<{
466
- field: StringShape;
467
- question: StringShape;
468
- blocking: BooleanShape;
469
- candidates: OptionalShape<ArrayShape<StringShape>>;
470
- }, false>>;
471
- risks: ArrayShape<ObjectShape<{
472
- severity: LiteralShape<readonly RiskSeverity[]>;
473
- text: StringShape;
474
- mitigation: StringShape;
475
- }, false>>;
476
- output: ObjectShape<{
477
- format: LiteralShape<readonly OutputFormat[]>;
478
- sections: OptionalShape<ArrayShape<StringShape>>;
479
- include: OptionalShape<ArrayShape<StringShape>>;
480
- exclude: OptionalShape<ArrayShape<StringShape>>;
481
- }, false>;
482
- proofs: ArrayShape<ObjectShape<{
483
- text: StringShape;
484
- command: StringShape;
485
- }, false>>;
486
- trace: OptionalShape<StringShape>;
487
- hash: OptionalShape<StringShape>;
484
+ export declare const briefShape: ObjectShape< {
485
+ task: ObjectShape< {
486
+ operation: LiteralShape<readonly TaskOperation[]>;
487
+ domain: LiteralShape<readonly TaskDomain[]>;
488
+ statement: StringShape;
489
+ }, false>;
490
+ authority: ArrayShape<ObjectShape< {
491
+ path: StringShape;
492
+ note: StringShape;
493
+ }, false>>;
494
+ manifest: ObjectShape< {
495
+ read: ArrayShape<ObjectShape< {
496
+ path: StringShape;
497
+ note: StringShape;
498
+ }, false>>;
499
+ edit: ArrayShape<ObjectShape< {
500
+ path: StringShape;
501
+ note: StringShape;
502
+ }, false>>;
503
+ locked: ArrayShape<ObjectShape< {
504
+ path: StringShape;
505
+ note: StringShape;
506
+ }, false>>;
507
+ forbidden: ArrayShape<ObjectShape< {
508
+ path: StringShape;
509
+ note: StringShape;
510
+ }, false>>;
511
+ }, false>;
512
+ outcomes: ArrayShape<ObjectShape< {
513
+ rank: NumberShape;
514
+ text: StringShape;
515
+ required: BooleanShape;
516
+ }, false>>;
517
+ rules: ArrayShape<StringShape>;
518
+ invariants: ArrayShape<StringShape>;
519
+ givens: ArrayShape<ObjectShape< {
520
+ category: StringShape;
521
+ name: StringShape;
522
+ value: StringShape;
523
+ }, false>>;
524
+ examples: ArrayShape<ObjectShape< {
525
+ input: StringShape;
526
+ output: StringShape;
527
+ note: OptionalShape<StringShape>;
528
+ }, false>>;
529
+ assumptions: ArrayShape<StringShape>;
530
+ citations: ArrayShape<ObjectShape< {
531
+ name: StringShape;
532
+ url: StringShape;
533
+ note: StringShape;
534
+ }, false>>;
535
+ gaps: ArrayShape<ObjectShape< {
536
+ field: StringShape;
537
+ question: StringShape;
538
+ blocking: BooleanShape;
539
+ candidates: OptionalShape<ArrayShape<StringShape>>;
540
+ }, false>>;
541
+ risks: ArrayShape<ObjectShape< {
542
+ severity: LiteralShape<readonly RiskSeverity[]>;
543
+ text: StringShape;
544
+ mitigation: StringShape;
545
+ }, false>>;
546
+ output: ObjectShape< {
547
+ format: LiteralShape<readonly OutputFormat[]>;
548
+ sections: OptionalShape<ArrayShape<StringShape>>;
549
+ include: OptionalShape<ArrayShape<StringShape>>;
550
+ exclude: OptionalShape<ArrayShape<StringShape>>;
551
+ }, false>;
552
+ proofs: ArrayShape<ObjectShape< {
553
+ text: StringShape;
554
+ command: StringShape;
555
+ }, false>>;
556
+ trace: OptionalShape<StringShape>;
557
+ hash: OptionalShape<StringShape>;
488
558
  }, false>;
489
559
 
490
- /** The four fixed compilation phases, in pipeline order. */
560
+ /** Names the fixed compilation phases, in pipeline order. */
491
561
  export declare type BriefStage = 'interpret' | 'draft' | 'gate' | 'pin';
492
562
 
493
- /** A visible marker for a phase that failed. */
563
+ /** Represents a visible marker for a phase that failed. */
494
564
  export declare interface BriefStageFailure {
495
565
  readonly stage: BriefStage;
496
566
  readonly code: BriefErrorCode;
@@ -498,7 +568,7 @@ import { Subject } from '@orkestrel/reason';
498
568
  }
499
569
 
500
570
  /**
501
- * One pipeline phase, discriminated by `stage`.
571
+ * Represents one pipeline phase, discriminated by `stage`.
502
572
  *
503
573
  * @remarks
504
574
  * Narrowing on `stage` types both payloads exactly, so a consumer reads a replay without
@@ -507,7 +577,7 @@ import { Subject } from '@orkestrel/reason';
507
577
  export declare type BriefStageRecord = InterpretStageRecord | DraftStageRecord | GateStageRecord | PinStageRecord;
508
578
 
509
579
  /**
510
- * The canonical text of exactly what a brief's hash describes.
580
+ * Renders the canonical text of exactly what a brief's hash describes.
511
581
  *
512
582
  * @remarks
513
583
  * `trace` and `hash` are stripped, then interprets `canonicalize` renders the rest in a
@@ -519,36 +589,43 @@ import { Subject } from '@orkestrel/reason';
519
589
  *
520
590
  * @example
521
591
  * ```ts
522
- * import { brief, briefToContent, pinBrief, task } from '@orkestrel/brief'
592
+ * import { briefToContent, buildBrief, buildTask, pinBrief } from '@orkestrel/brief'
523
593
  *
524
- * const draft = brief(task('plan', 'ops', 'Plan the release.'))
594
+ * const draft = buildBrief(buildTask('plan', 'ops', 'Plan the release.'))
525
595
  * briefToContent(draft) === briefToContent(pinBrief(draft)) // true — pinning adds no content
526
596
  * ```
527
597
  */
528
598
  export declare function briefToContent(source: Brief): string;
529
599
 
530
600
  /**
531
- * Project a brief into a subagent `Dispatch`.
601
+ * Projects a brief into a subagent `Dispatch`.
532
602
  *
533
603
  * @remarks
534
- * `edit` is exactly `manifest.edit`, so two dispatches whose `edit` sets do not intersect
535
- * can run concurrently under the same brief without conflict.
604
+ * `edit` is exactly `manifest.edit` — the owned set — so two dispatches whose `edit` sets do
605
+ * not intersect can run concurrently under the same brief without conflict. `locked` and
606
+ * `forbidden` cross unchanged as the do-not-touch sets.
536
607
  *
537
- * `authority` is exactly `brief.authority` in rank order, and it is a SEPARATE axis from the
538
- * four permission sets rather than a fifth partition — a ranked path normally also appears in
608
+ * `authority` is exactly `brief.authority` in rank order, and it is a separate axis from the
609
+ * permission sets rather than a further partition — a ranked path normally also appears in
539
610
  * `read` or `locked`, because the executor has to open what it obeys. It is projected as
540
611
  * paths so a machine consumer never has to parse `prompt`, which is written for a model.
541
612
  *
542
- * @param source - The brief to project.
543
- * @returns The dispatch — the rendered prompt, the ranked authority, and the four path sets.
613
+ * @param input - The brief to project.
614
+ * @returns The dispatch — the rendered prompt, the ranked authority, and the path sets.
544
615
  *
545
616
  * @example
546
617
  * ```ts
547
- * import { brief, briefToDispatch, manifest, reference, task } from '@orkestrel/brief'
548
- *
549
- * const draft = brief(task('migrate', 'code', 'Migrate the stores.'), {
550
- * authority: [reference('AGENTS.md', 'project law')],
551
- * manifest: manifest({ edit: [reference('src/core/stores/**', 'the legacy stores')] }),
618
+ * import {
619
+ * briefToDispatch,
620
+ * buildBrief,
621
+ * buildManifest,
622
+ * buildReference,
623
+ * buildTask,
624
+ * } from '@orkestrel/brief'
625
+ *
626
+ * const draft = buildBrief(buildTask('migrate', 'code', 'Migrate the stores.'), {
627
+ * authority: [buildReference('AGENTS.md', 'project law')],
628
+ * manifest: buildManifest({ edit: [buildReference('src/core/stores/**', 'the legacy stores')] }),
552
629
  * })
553
630
  * briefToDispatch(draft).edit // ['src/core/stores/**']
554
631
  * briefToDispatch(draft).authority // ['AGENTS.md']
@@ -557,28 +634,28 @@ import { Subject } from '@orkestrel/reason';
557
634
  export declare function briefToDispatch(input: Brief): Dispatch;
558
635
 
559
636
  /**
560
- * Project a brief into a `/goal` completion condition.
637
+ * Projects a brief into a `/goal` completion condition.
561
638
  *
562
639
  * @remarks
563
640
  * The proofs' commands VERBATIM plus a turn cap — the goal never adds a condition the
564
641
  * brief does not carry.
565
642
  *
566
- * @param source - The brief to render.
567
- * @param turns - The turn cap; defaults to `DEFAULT_BRIEF_TURNS`.
643
+ * @param input - The brief to render.
644
+ * @param turns - The turn cap. Default: `DEFAULT_BRIEF_TURNS`.
568
645
  * @returns The one-line completion condition.
569
646
  *
570
647
  * @example
571
648
  * ```ts
572
- * import { brief, briefToGoal, proof, task } from '@orkestrel/brief'
649
+ * import { briefToGoal, buildBrief, buildProof, buildTask } from '@orkestrel/brief'
573
650
  *
574
- * briefToGoal(brief(task('test', 'code', 'Cover the gate.'), { proofs: [proof('x', 'npm test')] }))
651
+ * briefToGoal(buildBrief(buildTask('test', 'code', 'Cover the gate.'), { proofs: [buildProof('x', 'npm test')] }))
575
652
  * // 'Done when every proof passes: npm test exits 0. Cap: 16 turns.'
576
653
  * ```
577
654
  */
578
655
  export declare function briefToGoal(input: Brief, turns?: number): string;
579
656
 
580
657
  /**
581
- * The canonical structural digest of a brief's content.
658
+ * Computes the canonical structural digest of a brief's content.
582
659
  *
583
660
  * @remarks
584
661
  * `trace` and `hash` are stripped before digesting, so the value is the identity of what
@@ -590,52 +667,53 @@ import { Subject } from '@orkestrel/reason';
590
667
  *
591
668
  * @example
592
669
  * ```ts
593
- * import { brief, briefToHash, pinBrief, task } from '@orkestrel/brief'
670
+ * import { briefToHash, buildBrief, buildTask, pinBrief } from '@orkestrel/brief'
594
671
  *
595
- * const draft = brief(task('plan', 'ops', 'Plan the release.'))
672
+ * const draft = buildBrief(buildTask('plan', 'ops', 'Plan the release.'))
596
673
  * briefToHash(draft) === briefToHash(pinBrief(draft)) // true — pinning does not move it
597
674
  * ```
598
675
  */
599
676
  export declare function briefToHash(source: Brief): string;
600
677
 
601
678
  /**
602
- * Project a brief into the copy-ready agent prompt.
679
+ * Projects a brief into the copy-ready agent prompt.
603
680
  *
604
681
  * @remarks
605
- * Paths are REFERENCED, never inlined the executor retrieves them. An empty section is
606
- * omitted entirely, so the rendering carries no filler an executor must read past.
682
+ * Sections render in authority order, so the executor meets what wins a conflict before what
683
+ * it may touch. Paths are referenced, never inlined the executor retrieves them. An empty
684
+ * section is omitted entirely, so the rendering carries no filler an executor must read past.
607
685
  *
608
- * @param source - The brief to render.
686
+ * @param input - The brief to render.
609
687
  * @returns The markdown prompt.
610
688
  *
611
689
  * @example
612
690
  * ```ts
613
- * import { brief, briefToMarkdown, task } from '@orkestrel/brief'
691
+ * import { briefToMarkdown, buildBrief, buildTask } from '@orkestrel/brief'
614
692
  *
615
- * briefToMarkdown(brief(task('review', 'code', 'Review the gate rules.')))
693
+ * briefToMarkdown(buildBrief(buildTask('review', 'code', 'Review the gate rules.')))
616
694
  * // '# Brief: Review the gate rules.\n\nreview · code\n\n## Output\n\n- format: markdown\n'
617
695
  * ```
618
696
  */
619
697
  export declare function briefToMarkdown(input: Brief): string;
620
698
 
621
699
  /**
622
- * Project a brief into the reasons `Subject` of readiness measures the gate reads.
700
+ * Projects a brief into the reasons `Subject` of readiness measures the gate reads.
623
701
  *
624
702
  * @param source - The brief to measure.
625
- * @returns A flat record of counts plus the task's two vocabulary values.
703
+ * @returns A flat record of counts plus the task's vocabulary values.
626
704
  *
627
705
  * @example
628
706
  * ```ts
629
- * import { brief, briefToSubject, proof, task } from '@orkestrel/brief'
707
+ * import { briefToSubject, buildBrief, buildProof, buildTask } from '@orkestrel/brief'
630
708
  *
631
- * briefToSubject(brief(task('test', 'code', 'Cover the gate.'), { proofs: [proof('x', 'y')] }))
709
+ * briefToSubject(buildBrief(buildTask('test', 'code', 'Cover the gate.'), { proofs: [buildProof('x', 'y')] }))
632
710
  * // { operation: 'test', domain: 'code', sentences: 1, proofs: 1, … }
633
711
  * ```
634
712
  */
635
713
  export declare function briefToSubject(source: Brief): Subject;
636
714
 
637
715
  /**
638
- * The one-line census `pinBrief` stamps onto a brief.
716
+ * Renders the one-line census `pinBrief` stamps onto a brief.
639
717
  *
640
718
  * @remarks
641
719
  * Extracted so it has ONE implementation. `pinBrief` derives it and `BriefManager` re-derives
@@ -648,14 +726,260 @@ import { Subject } from '@orkestrel/reason';
648
726
  *
649
727
  * @example
650
728
  * ```ts
651
- * import { brief, briefToTrace, task } from '@orkestrel/brief'
729
+ * import { briefToTrace, buildBrief, buildTask } from '@orkestrel/brief'
652
730
  *
653
- * briefToTrace(brief(task('document', 'writing', 'Write the guide.')))
731
+ * briefToTrace(buildBrief(buildTask('document', 'writing', 'Write the guide.')))
654
732
  * // 'document/writing · outcomes:0 · gaps:0/0 · proofs:0'
655
733
  * ```
656
734
  */
657
735
  export declare function briefToTrace(source: Brief): string;
658
736
 
737
+ /**
738
+ * Assembles a `Brief` from a `Task` plus section overrides.
739
+ *
740
+ * @param subject - The task the brief is about.
741
+ * @param overrides - Any sections to fill; `trace` / `hash` stay OMITTED so `pinBrief` can
742
+ * fill them. Default: `[]` for every absent collection and `buildOutput('markdown')` for
743
+ * `output`.
744
+ * @returns A fresh, unpinned `Brief`.
745
+ *
746
+ * @example
747
+ * ```ts
748
+ * import { buildBrief, buildOutcome, buildProof, buildTask } from '@orkestrel/brief'
749
+ *
750
+ * buildBrief(buildTask('audit', 'code', 'Audit the barrel for undocumented exports.'), {
751
+ * outcomes: [buildOutcome(1, 'every export appears in the guide')],
752
+ * proofs: [buildProof('parity passes', 'npm run test:guides')],
753
+ * })
754
+ * ```
755
+ */
756
+ export declare function buildBrief(subject: Task, overrides?: Partial<Omit<Brief, 'task' | 'trace' | 'hash'>>): Brief;
757
+
758
+ /**
759
+ * Assembles a `Citation` from a name, a URL, and the note that justifies citing it.
760
+ *
761
+ * @param name - The source's display name.
762
+ * @param url - Where the source lives.
763
+ * @param note - Why the source is cited.
764
+ * @returns A fresh `Citation`.
765
+ *
766
+ * @example
767
+ * ```ts
768
+ * import { buildCitation } from '@orkestrel/brief'
769
+ *
770
+ * buildCitation(
771
+ * 'MDN Constraint Validation',
772
+ * 'https://developer.mozilla.org/',
773
+ * 'the native validity behavior being adopted',
774
+ * )
775
+ * ```
776
+ */
777
+ export declare function buildCitation(name: string, url: string, note: string): Citation;
778
+
779
+ /**
780
+ * Assembles an `Example` from an exemplar input and its expected output.
781
+ *
782
+ * @param input - The exemplar input.
783
+ * @param output - The expected output for that input.
784
+ * @param note - Optional detail; the key is OMITTED when absent.
785
+ * @returns A fresh `Example`.
786
+ *
787
+ * @example
788
+ * ```ts
789
+ * import { buildExample } from '@orkestrel/brief'
790
+ *
791
+ * buildExample('<input required>', 'validity read from el.validity')
792
+ * ```
793
+ */
794
+ export declare function buildExample(input: string, output: string, note?: string): Example;
795
+
796
+ /**
797
+ * Assembles a `Gap` from the section it belongs to and the question that would close it.
798
+ *
799
+ * @param field - The brief section the unknown belongs to.
800
+ * @param question - The question that would close it.
801
+ * @param overrides - Optional `blocking` and `candidates`; an absent `candidates` key is
802
+ * OMITTED entirely. Default: `blocking: false`.
803
+ * @returns A fresh `Gap`.
804
+ *
805
+ * @example
806
+ * ```ts
807
+ * import { buildGap } from '@orkestrel/brief'
808
+ *
809
+ * buildGap('rules', 'Does validation message wording need to change?') // blocking: false
810
+ * buildGap('output', 'Diff or full files?', { blocking: true, candidates: ['diff', 'code'] })
811
+ * ```
812
+ */
813
+ export declare function buildGap(field: string, question: string, overrides?: Partial<Omit<Gap, 'field' | 'question'>>): Gap;
814
+
815
+ /**
816
+ * Assembles the fail-closed readiness gate as a reasons `LogicalDefinition`.
817
+ *
818
+ * @remarks
819
+ * Each readiness rule derives one named fact from `briefToSubject`'s measures, and a final
820
+ * `ready` rule conjoins them all. Forward chaining reports the LAST rule's conclusion, so
821
+ * `LogicalResult.conclusion` is exactly `ready`.
822
+ *
823
+ * The gate takes NO parameters, and that is deliberate rather than unfinished. The
824
+ * reasoner overlays every derived fact into one flat namespace, so a caller rule named
825
+ * for a readiness fact overwrites it and `ready` then conjoins a fact no base rule
826
+ * proved — a refusal silently becomes a pass. Readiness is this package's contract, not
827
+ * a caller setting. A caller who needs different readiness composes their own
828
+ * `LogicalDefinition` over `briefToSubject` and evaluates it on their own reasoner; both
829
+ * are exported for exactly that, and neither can reach this definition.
830
+ *
831
+ * @returns A fresh `LogicalDefinition` with id `GATE_ID`.
832
+ *
833
+ * @example
834
+ * ```ts
835
+ * import { briefToSubject, buildGateDefinition } from '@orkestrel/brief'
836
+ * import { createLogicalReasoner, createReason } from '@orkestrel/reason'
837
+ *
838
+ * const reason = createReason({ reasoners: [createLogicalReasoner()] })
839
+ * const verdict = reason.reason(briefToSubject(pinned), buildGateDefinition())
840
+ * reason.destroy()
841
+ * ```
842
+ */
843
+ export declare function buildGateDefinition(): LogicalDefinition;
844
+
845
+ /**
846
+ * Assembles a `Given` from a category, a name, and a value.
847
+ *
848
+ * @param category - The kind of fact — a convention, a version, a constraint.
849
+ * @param name - The fact's name.
850
+ * @param value - The fact's value, already rendered as text.
851
+ * @returns A fresh `Given`.
852
+ *
853
+ * @example
854
+ * ```ts
855
+ * import { buildGiven } from '@orkestrel/brief'
856
+ *
857
+ * buildGiven('convention', 'indentation', 'tabs')
858
+ * ```
859
+ */
860
+ export declare function buildGiven(category: string, name: string, value: string): Given;
861
+
862
+ /**
863
+ * Assembles a `Manifest`, defaulting every absent partition to an empty list.
864
+ *
865
+ * @param partitions - The partitions to fill; a partial literal is enough.
866
+ * @returns A fresh `Manifest` with every partition present.
867
+ *
868
+ * @example
869
+ * ```ts
870
+ * import { buildManifest, buildReference } from '@orkestrel/brief'
871
+ *
872
+ * buildManifest({ edit: [buildReference('src/core/helpers.ts', 'implementation')] })
873
+ * ```
874
+ */
875
+ export declare function buildManifest(partitions?: Partial<Manifest>): Manifest;
876
+
877
+ /**
878
+ * Assembles an `Outcome` from a rank and its result text.
879
+ *
880
+ * @param rank - The one-based rank; lower ranks matter more.
881
+ * @param text - The result, never a step.
882
+ * @param required - If `true`, the outcome gates "done"; if `false`, it is desirable but not
883
+ * blocking. Default: `true`.
884
+ * @returns A fresh `Outcome`.
885
+ *
886
+ * @example
887
+ * ```ts
888
+ * import { buildOutcome } from '@orkestrel/brief'
889
+ *
890
+ * buildOutcome(1, 'useForm uses native FormData with no behavior change') // required: true
891
+ * buildOutcome(2, 'the diff stays under 200 lines', false)
892
+ * ```
893
+ */
894
+ export declare function buildOutcome(rank: number, text: string, required?: boolean): Outcome;
895
+
896
+ /**
897
+ * Assembles an `Output` from a format plus its optional refinements.
898
+ *
899
+ * @param format - The closed deliverable format.
900
+ * @param overrides - Optional `sections` / `include` / `exclude`; absent keys are OMITTED.
901
+ * @returns A fresh `Output`.
902
+ *
903
+ * @example
904
+ * ```ts
905
+ * import { buildOutput } from '@orkestrel/brief'
906
+ *
907
+ * buildOutput('markdown') // { format: 'markdown' }
908
+ * buildOutput('diff', { include: ['updated useForm.ts'] })
909
+ * ```
910
+ */
911
+ export declare function buildOutput(format: OutputFormat, overrides?: Partial<Omit<Output, 'format'>>): Output;
912
+
913
+ /**
914
+ * Assembles a `Proof` from what the check settles and the command that settles it.
915
+ *
916
+ * @param text - What the check settles.
917
+ * @param command - The command whose exit signal settles it.
918
+ * @returns A fresh `Proof`.
919
+ *
920
+ * @example
921
+ * ```ts
922
+ * import { buildProof } from '@orkestrel/brief'
923
+ *
924
+ * buildProof('type-check and lint pass', 'npm run check')
925
+ * ```
926
+ */
927
+ export declare function buildProof(text: string, command: string): Proof;
928
+
929
+ /**
930
+ * Assembles a `Reference` from a path and the note that justifies listing it.
931
+ *
932
+ * @remarks
933
+ * The one builder for an authority entry and a manifest entry alike: the container the record
934
+ * lands in is what says whether the path is ranked or permitted.
935
+ *
936
+ * @param path - The referenced path or glob.
937
+ * @param note - Why the path is listed.
938
+ * @returns A fresh `Reference`.
939
+ *
940
+ * @example
941
+ * ```ts
942
+ * import { buildReference } from '@orkestrel/brief'
943
+ *
944
+ * buildReference('AGENTS.md', 'project law') // { path: 'AGENTS.md', note: 'project law' }
945
+ * ```
946
+ */
947
+ export declare function buildReference(path: string, note: string): Reference;
948
+
949
+ /**
950
+ * Assembles a `Risk` from a severity, what could go wrong, and the mitigation that answers it.
951
+ *
952
+ * @param severity - The closed severity.
953
+ * @param text - What could go wrong.
954
+ * @param mitigation - What answers it.
955
+ * @returns A fresh `Risk`.
956
+ *
957
+ * @example
958
+ * ```ts
959
+ * import { buildRisk } from '@orkestrel/brief'
960
+ *
961
+ * buildRisk('medium', 'native validation differs subtly', 'assert message and state in tests')
962
+ * ```
963
+ */
964
+ export declare function buildRisk(severity: RiskSeverity, text: string, mitigation: string): Risk;
965
+
966
+ /**
967
+ * Assembles a `Task` from an operation, a domain, and a statement.
968
+ *
969
+ * @param operation - What the brief asks for, from the closed operation vocabulary.
970
+ * @param domain - The subject matter, from the closed domain vocabulary.
971
+ * @param statement - One imperative sentence naming the object of the work.
972
+ * @returns A fresh `Task`.
973
+ *
974
+ * @example
975
+ * ```ts
976
+ * import { buildTask } from '@orkestrel/brief'
977
+ *
978
+ * buildTask('refactor', 'code', 'Refactor useForm to native browser form APIs.')
979
+ * ```
980
+ */
981
+ export declare function buildTask(operation: TaskOperation, domain: TaskDomain, statement: string): Task;
982
+
659
983
  /**
660
984
  * Captures one stable, frozen view of a foreign contract value.
661
985
  *
@@ -683,7 +1007,7 @@ import { Subject } from '@orkestrel/reason';
683
1007
  export declare function captureValue(source: unknown, members: readonly string[]): unknown;
684
1008
 
685
1009
  /**
686
- * One external source — what it is called, where it lives, and why it is cited.
1010
+ * Represents one external source — what it is called, where it lives, and why it is cited.
687
1011
  *
688
1012
  * @remarks
689
1013
  * List ORDER is the trust order; there is no per-entry weight.
@@ -703,12 +1027,13 @@ import { Subject } from '@orkestrel/reason';
703
1027
  * and the shape DSL's seeded generator builds a random alphanumeric string and throws when it
704
1028
  * fails the pattern — so any pattern requiring a scheme's colon makes `createBriefContract()`
705
1029
  * ungeneratable for the whole brief. Constraining only the guard would leave the guard and the
706
- * compiled shape disagreeing, which is the parity this package holds in lockstep. Four working
707
- * mechanisms beat one stricter member.
1030
+ * compiled shape disagreeing, which is the parity this package holds in lockstep. Keeping the
1031
+ * guard, the compiled shape, the generator, and `createBriefContract()` working beats one
1032
+ * stricter member.
708
1033
  *
709
- * The cost lands on one migration: `citation` takes `(name, url, note)` where it once took
710
- * `(name, role, url)` — three strings either way, so a stale call still compiles and still
711
- * passes the guard, and only renders wrong. Nothing is published, so a version bump carries it.
1034
+ * The cost lands on one migration: `buildCitation` takes `(name, url, note)` where the 0.0.6
1035
+ * release took `(name, role, url)` — strings in the same positions either way, so a stale call
1036
+ * still compiles and still passes the guard, and only renders wrong.
712
1037
  */
713
1038
  export declare interface Citation {
714
1039
  readonly name: string;
@@ -716,36 +1041,15 @@ import { Subject } from '@orkestrel/reason';
716
1041
  readonly note: string;
717
1042
  }
718
1043
 
719
- /**
720
- * Build a `Citation`.
721
- *
722
- * @param name - The source's display name.
723
- * @param url - Where the source lives.
724
- * @param note - Why the source is cited.
725
- * @returns A fresh `Citation`.
726
- *
727
- * @example
728
- * ```ts
729
- * import { citation } from '@orkestrel/brief'
730
- *
731
- * citation(
732
- * 'MDN Constraint Validation',
733
- * 'https://developer.mozilla.org/',
734
- * 'the native validity behavior being adopted',
735
- * )
736
- * ```
737
- */
738
- export declare function citation(name: string, url: string, note: string): Citation;
739
-
740
- /** The `Citation` shape — a name, a locator, and why the source is cited. */
741
- export declare const citationShape: ObjectShape<{
742
- name: StringShape;
743
- url: StringShape;
744
- note: StringShape;
1044
+ /** Describes the `Citation` shape — a name, a locator, and why the source is cited. */
1045
+ export declare const citationShape: ObjectShape< {
1046
+ name: StringShape;
1047
+ url: StringShape;
1048
+ note: StringShape;
745
1049
  }, false>;
746
1050
 
747
1051
  /**
748
- * Count the sentences a statement holds.
1052
+ * Counts the sentences a statement holds.
749
1053
  *
750
1054
  * @remarks
751
1055
  * A terminator run (`.`, `!`, `?`) followed by whitespace or the end of the text closes one
@@ -778,7 +1082,7 @@ import { Subject } from '@orkestrel/reason';
778
1082
  export declare function countSentences(statement: string): number;
779
1083
 
780
1084
  /**
781
- * Create a compilation orchestrator.
1085
+ * Creates a compilation orchestrator.
782
1086
  *
783
1087
  * @remarks
784
1088
  * With no engines supplied the compiler wires its own: a default `createInterpret()`
@@ -786,9 +1090,49 @@ import { Subject } from '@orkestrel/reason';
786
1090
  * `createReason` carrying one `LogicalReasoner` for the gate. Pass your own to share
787
1091
  * instances or observe their emitters — the compiler destroys ONLY what it created.
788
1092
  *
789
- * @param options - Engines to borrow, the two intent vocabularies, and emitter hooks.
1093
+ * @param options - Engines to borrow, the `actions` and `domains` intent vocabularies, and
1094
+ * emitter hooks.
790
1095
  * @returns A working {@link BriefCompilerInterface}.
791
1096
  *
1097
+ * @example Compile and project a brief
1098
+ * ```ts
1099
+ * import {
1100
+ * briefToGoal,
1101
+ * briefToMarkdown,
1102
+ * buildOutcome,
1103
+ * buildProof,
1104
+ * buildTask,
1105
+ * createBriefCompiler,
1106
+ * } from '@orkestrel/brief'
1107
+ *
1108
+ * const compiler = createBriefCompiler()
1109
+ *
1110
+ * const briefing = compiler.compile({
1111
+ * task: buildTask('refactor', 'code', 'Refactor useForm to native browser form APIs.'),
1112
+ * authority: [{ path: 'AGENTS.md', note: 'project law; wins every conflict' }],
1113
+ * manifest: {
1114
+ * read: [
1115
+ * { path: 'AGENTS.md', note: 'project law; wins every conflict' },
1116
+ * { path: 'guides/browser.md', note: 'the composable contract' },
1117
+ * ],
1118
+ * edit: [{ path: 'src/browser/composables/useForm.ts', note: 'the composable being refactored' }],
1119
+ * locked: [{ path: 'src/browser/types.ts', note: 'the published contract' }],
1120
+ * forbidden: [{ path: 'app/**', note: 'out of scope' }],
1121
+ * },
1122
+ * outcomes: [buildOutcome(1, 'useForm uses native FormData with no behavior change')],
1123
+ * proofs: [buildProof('type-check and lint pass', 'npm run check')],
1124
+ * })
1125
+ *
1126
+ * briefing.brief !== undefined // true — the brief is present exactly when the gate passed
1127
+ * if (briefing.brief !== undefined) {
1128
+ * briefToMarkdown(briefing.brief) // the copy-ready agent prompt
1129
+ * briefToGoal(briefing.brief) // the /goal completion condition
1130
+ * }
1131
+ *
1132
+ * compiler.emitter.on('block', (questions) => questions.length)
1133
+ * compiler.destroy()
1134
+ * ```
1135
+ *
792
1136
  * @example
793
1137
  * ```ts
794
1138
  * import { createBriefCompiler } from '@orkestrel/brief'
@@ -800,7 +1144,7 @@ import { Subject } from '@orkestrel/reason';
800
1144
  export declare function createBriefCompiler(options?: BriefCompilerOptions): BriefCompilerInterface;
801
1145
 
802
1146
  /**
803
- * Compile `briefShape` into a guard, parser, JSON Schema, and seeded generator bundle.
1147
+ * Compiles `briefShape` into a guard, parser, JSON Schema, and seeded generator bundle.
804
1148
  *
805
1149
  * @remarks
806
1150
  * The schema is what a tool boundary needs — hand it to `schemaToParameters` — and
@@ -823,7 +1167,7 @@ import { Subject } from '@orkestrel/reason';
823
1167
  export declare function createBriefContract(): ContractInterface<Brief>;
824
1168
 
825
1169
  /**
826
- * Create a brief registry.
1170
+ * Creates a brief registry.
827
1171
  *
828
1172
  * @param options - An optional seed collection plus emitter hooks.
829
1173
  * @returns A working {@link BriefManagerInterface}.
@@ -833,14 +1177,14 @@ import { Subject } from '@orkestrel/reason';
833
1177
  * import { createBriefManager } from '@orkestrel/brief'
834
1178
  *
835
1179
  * const briefs = createBriefManager()
836
- * briefs.size // 0
1180
+ * briefs.count // 0
837
1181
  * briefs.destroy()
838
1182
  * ```
839
1183
  */
840
1184
  export declare function createBriefManager(options?: BriefManagerOptions): BriefManagerInterface;
841
1185
 
842
1186
  /**
843
- * `16` — the default turn cap `briefToGoal` renders.
1187
+ * Holds `16` — the default turn cap `briefToGoal` renders.
844
1188
  *
845
1189
  * @remarks
846
1190
  * Domain-qualified so the barrel stays collision-free as sibling modules add their own
@@ -849,7 +1193,7 @@ import { Subject } from '@orkestrel/reason';
849
1193
  export declare const DEFAULT_BRIEF_TURNS = 16;
850
1194
 
851
1195
  /**
852
- * Derive `Gap[]` from an interprets `Ambiguity[]`.
1196
+ * Derives `Gap[]` from an interprets `Ambiguity[]`.
853
1197
  *
854
1198
  * @remarks
855
1199
  * A REQUIRED ambiguity becomes a BLOCKING gap — the gate must fail closed on it. The
@@ -870,7 +1214,7 @@ import { Subject } from '@orkestrel/reason';
870
1214
  export declare function deriveGaps(ambiguities: readonly Ambiguity[]): readonly Gap[];
871
1215
 
872
1216
  /**
873
- * Derive `Given[]` from an interprets `Entity[]`.
1217
+ * Derives `Given[]` from an interprets `Entity[]`.
874
1218
  *
875
1219
  * @remarks
876
1220
  * Every extracted entity becomes one `extracted` fact. A nameless entity is dropped; an
@@ -891,32 +1235,35 @@ import { Subject } from '@orkestrel/reason';
891
1235
  export declare function deriveGivens(entities: readonly Entity[]): readonly Given[];
892
1236
 
893
1237
  /**
894
- * Derive one imperative statement from free text.
1238
+ * Derives one imperative statement from free text.
895
1239
  *
896
1240
  * @remarks
897
1241
  * Whitespace collapses, the first character uppercases, and a terminator is appended
898
1242
  * when the text carries none. Nothing else is invented.
899
1243
  *
900
1244
  * @param text - The raw request text.
901
- * @returns The statement, or `''` for empty or whitespace-only text.
1245
+ * @returns The statement, or `undefined` for empty or whitespace-only text.
902
1246
  *
903
1247
  * @example
904
1248
  * ```ts
905
1249
  * import { deriveStatement } from '@orkestrel/brief'
906
1250
  *
907
1251
  * deriveStatement(' clean up useForm ') // 'Clean up useForm.'
908
- * deriveStatement('') // ''
1252
+ * deriveStatement('') // undefined
909
1253
  * ```
910
1254
  */
911
- export declare function deriveStatement(text: string): string;
1255
+ export declare function deriveStatement(text: string): string | undefined;
912
1256
 
913
1257
  /**
914
- * Derive a `Task` from an interprets `Intent` through the caller's vocabularies.
1258
+ * Derives a `Task` from an interprets `Intent` through the caller's vocabularies.
915
1259
  *
916
1260
  * @remarks
917
1261
  * The vocabularies are the CALLER's policy: this maps and never guesses. An action or
918
1262
  * domain the caller did not map — or mapped to an off-vocabulary value — yields
919
- * `undefined` rather than an invented task. Inherited keys never resolve.
1263
+ * `undefined` rather than an invented task. Inherited keys never resolve. `Intent.action`
1264
+ * and `Intent.domain` are optional, because `classifyIntent` leaves an unmatched axis
1265
+ * absent, and an absent axis is unmapped by definition: it yields `undefined` before
1266
+ * either vocabulary is read.
920
1267
  *
921
1268
  * @param intent - The classified intent from an interpret pipeline.
922
1269
  * @param text - The text the statement derives from.
@@ -937,23 +1284,24 @@ import { Subject } from '@orkestrel/reason';
937
1284
  export declare function deriveTask(intent: Intent, text: string, actions: Readonly<Record<string, TaskOperation>>, domains: Readonly<Record<string, TaskDomain>>): Task | undefined;
938
1285
 
939
1286
  /**
940
- * The subagent projection of a brief.
1287
+ * Represents the subagent projection of a brief.
941
1288
  *
942
1289
  * @remarks
943
- * Two orthogonal axes, not five partitions. PERMISSION is `read`, `edit`, `locked`, and
944
- * `forbidden`, with `edit` the owned set two concurrent dispatches must not intersect on and
945
- * `locked` and `forbidden` do-not-touch. PRECEDENCE is `authority`, in ranked order, index 0
946
- * winning every conflict.
1290
+ * PERMISSION and PRECEDENCE are orthogonal axes rather than one flat partition set.
1291
+ * PERMISSION is `read`, `edit`, `locked`, and `forbidden`, with `edit` the owned set two
1292
+ * concurrent dispatches must not intersect on and `locked` and `forbidden` do-not-touch.
1293
+ * PRECEDENCE is `authority`, in ranked order, index 0 winning every conflict.
947
1294
  *
948
1295
  * `authority` therefore OVERLAPS the permission arrays by design: a ranked path ALWAYS also
949
1296
  * sits in `read`, `edit`, or `locked`, because the executor has to open what it obeys, and
950
- * the `granted` gate rule refuses a brief where it does not. Read the four to decide what may
951
- * be touched and `authority` to decide what wins. Never union all five — that was already
952
- * wrong before `authority` existed, because `forbidden` is an exclusion rather than a grant.
1297
+ * the `granted` gate rule refuses a brief where it does not. Read the permission arrays to
1298
+ * decide what may be touched and `authority` to decide what wins. Never union the permission
1299
+ * arrays with `authority` that was already wrong before `authority` existed, because
1300
+ * `forbidden` is an exclusion rather than a grant.
953
1301
  * `authority` is a path list rather than a rendered section because a machine consumer must
954
1302
  * reach mandatory authority without parsing `prompt`, which is written for a model.
955
1303
  *
956
- * The four permission arrays are mutually disjoint in a GATED brief — `findManifestOverlaps`
1304
+ * The permission arrays are mutually disjoint in a GATED brief — `findManifestOverlaps`
957
1305
  * measures it and the `disjoint` rule refuses on it. `briefToDispatch` is a pure projection
958
1306
  * and runs no gate, so projecting an unvetted draft can produce arrays that intersect. Gate
959
1307
  * before you dispatch, or treat disjointness as unproven.
@@ -967,7 +1315,7 @@ import { Subject } from '@orkestrel/reason';
967
1315
  readonly forbidden: readonly string[];
968
1316
  }
969
1317
 
970
- /** The `draft` phase snapshot — the caller's input in, an unpinned `Brief` out. */
1318
+ /** Records the `draft` phase snapshot — the caller's input in, an unpinned `Brief` out. */
971
1319
  export declare interface DraftStageRecord {
972
1320
  readonly stage: 'draft';
973
1321
  readonly input: BriefInput;
@@ -976,7 +1324,7 @@ import { Subject } from '@orkestrel/reason';
976
1324
  }
977
1325
 
978
1326
  /**
979
- * Render a value thrown by a stage into a message.
1327
+ * Renders a value thrown by a stage into a message.
980
1328
  *
981
1329
  * @remarks
982
1330
  * TOTAL: it never throws, for any input. That is load-bearing rather than tidy, because this
@@ -985,7 +1333,7 @@ import { Subject } from '@orkestrel/reason';
985
1333
  * falsifies the package's central promise that a failing stage yields an incomplete
986
1334
  * `Briefing` rather than an exception.
987
1335
  *
988
- * Three real inputs used to throw: an `Error` subclass whose `message` getter throws, a value
1336
+ * Real inputs used to throw: an `Error` subclass whose `message` getter throws, a value
989
1337
  * whose string conversion throws, and a null-prototype object, which has no inherited
990
1338
  * conversion for String() to reach. Each is wrapped, and an unreadable value degrades to its
991
1339
  * type rather than propagating.
@@ -1005,39 +1353,22 @@ import { Subject } from '@orkestrel/reason';
1005
1353
  */
1006
1354
  export declare function errorToMessage(error: unknown): string;
1007
1355
 
1008
- /** One input to output exemplar — the highest-leverage ambiguity remover. */
1356
+ /** Represents one input to output exemplar — the ambiguity remover that leaves the least to interpret. */
1009
1357
  export declare interface Example {
1010
1358
  readonly input: string;
1011
1359
  readonly output: string;
1012
1360
  readonly note?: string;
1013
1361
  }
1014
1362
 
1015
- /**
1016
- * Build an `Example`.
1017
- *
1018
- * @param input - The exemplar input.
1019
- * @param result - The expected output for that input.
1020
- * @param note - Optional detail; the key is OMITTED when absent.
1021
- * @returns A fresh `Example`.
1022
- *
1023
- * @example
1024
- * ```ts
1025
- * import { example } from '@orkestrel/brief'
1026
- *
1027
- * example('<input required>', 'validity read from el.validity')
1028
- * ```
1029
- */
1030
- export declare function example(input: string, result: string, note?: string): Example;
1031
-
1032
- /** The `Example` shape — one input to output exemplar. */
1033
- export declare const exampleShape: ObjectShape<{
1034
- input: StringShape;
1035
- output: StringShape;
1036
- note: OptionalShape<StringShape>;
1363
+ /** Describes the `Example` shape — one input to output exemplar. */
1364
+ export declare const exampleShape: ObjectShape< {
1365
+ input: StringShape;
1366
+ output: StringShape;
1367
+ note: OptionalShape<StringShape>;
1037
1368
  }, false>;
1038
1369
 
1039
1370
  /**
1040
- * Render one exemplar as markdown lines.
1371
+ * Renders one exemplar as markdown lines.
1041
1372
  *
1042
1373
  * @remarks
1043
1374
  * An `Example`'s two sides are the only brief members permitted to span lines, so a
@@ -1049,25 +1380,29 @@ import { Subject } from '@orkestrel/reason';
1049
1380
  *
1050
1381
  * @example
1051
1382
  * ```ts
1052
- * import { example, exampleToLines } from '@orkestrel/brief'
1383
+ * import { buildExample, exampleToLines } from '@orkestrel/brief'
1053
1384
  *
1054
- * exampleToLines(example('<input required>', 'el.validity')) // ['- ` <input required> ` → ` el.validity `']
1385
+ * exampleToLines(buildExample('<input required>', 'el.validity')) // ['- ` <input required> ` → ` el.validity `']
1055
1386
  * ```
1056
1387
  */
1057
1388
  export declare function exampleToLines(entry: Example): readonly string[];
1058
1389
 
1059
1390
  /**
1060
- * The gaps that block emission.
1391
+ * Lists the gaps that block emission.
1392
+ *
1393
+ * @remarks
1394
+ * A non-empty result means the gate must fail closed: a blocking gap has no safe default, so
1395
+ * the compile yields a visible incomplete `Briefing` carrying the questions instead of a brief.
1061
1396
  *
1062
1397
  * @param source - The brief to inspect.
1063
1398
  * @returns Every gap carrying `blocking: true`, in declaration order.
1064
1399
  *
1065
1400
  * @example
1066
1401
  * ```ts
1067
- * import { brief, findBlockingGaps, gap, task } from '@orkestrel/brief'
1402
+ * import { buildBrief, buildGap, buildTask, findBlockingGaps } from '@orkestrel/brief'
1068
1403
  *
1069
- * const draft = brief(task('plan', 'ops', 'Plan the release.'), {
1070
- * gaps: [gap('output', 'Diff or files?', { blocking: true })],
1404
+ * const draft = buildBrief(buildTask('plan', 'ops', 'Plan the release.'), {
1405
+ * gaps: [buildGap('output', 'Diff or files?', { blocking: true })],
1071
1406
  * })
1072
1407
  * findBlockingGaps(draft).length // 1
1073
1408
  * ```
@@ -1075,10 +1410,10 @@ import { Subject } from '@orkestrel/reason';
1075
1410
  export declare function findBlockingGaps(source: Brief): readonly Gap[];
1076
1411
 
1077
1412
  /**
1078
- * The paths appearing in more than one manifest partition.
1413
+ * Lists the paths appearing in more than one manifest partition.
1079
1414
  *
1080
1415
  * @remarks
1081
- * Duplicates WITHIN one partition are not an overlap; the four partitions must be
1416
+ * Duplicates WITHIN one partition are not an overlap; the partitions must be
1082
1417
  * mutually disjoint, which is what `validateBrief` errors on.
1083
1418
  *
1084
1419
  * Paths are compared as EXACT strings. A glob is never expanded, so `edit: 'app/file.ts'`
@@ -1090,12 +1425,18 @@ import { Subject } from '@orkestrel/reason';
1090
1425
  *
1091
1426
  * @example
1092
1427
  * ```ts
1093
- * import { brief, findManifestOverlaps, manifest, reference, task } from '@orkestrel/brief'
1094
- *
1095
- * const draft = brief(task('debug', 'code', 'Fix the leak.'), {
1096
- * manifest: manifest({
1097
- * edit: [reference('src/core/BriefCompiler.ts', 'the leaking pipeline')],
1098
- * locked: [reference('src/core/BriefCompiler.ts', 'the published contract')],
1428
+ * import {
1429
+ * buildBrief,
1430
+ * buildManifest,
1431
+ * buildReference,
1432
+ * buildTask,
1433
+ * findManifestOverlaps,
1434
+ * } from '@orkestrel/brief'
1435
+ *
1436
+ * const draft = buildBrief(buildTask('debug', 'code', 'Fix the leak.'), {
1437
+ * manifest: buildManifest({
1438
+ * edit: [buildReference('src/core/BriefCompiler.ts', 'the leaking pipeline')],
1439
+ * locked: [buildReference('src/core/BriefCompiler.ts', 'the published contract')],
1099
1440
  * }),
1100
1441
  * })
1101
1442
  * findManifestOverlaps(draft) // ['src/core/BriefCompiler.ts']
@@ -1104,18 +1445,18 @@ import { Subject } from '@orkestrel/reason';
1104
1445
  export declare function findManifestOverlaps(source: Brief): readonly string[];
1105
1446
 
1106
1447
  /**
1107
- * The authority paths the manifest never grants access to.
1448
+ * Lists the authority paths the manifest never grants access to.
1108
1449
  *
1109
1450
  * @remarks
1110
1451
  * An authority the executor cannot open is an instruction it cannot follow, so every ranked
1111
- * path must appear in `read`, `edit`, or `locked`. Those three are the grants: `locked` is a
1452
+ * path must appear in `read`, `edit`, or `locked`. Those are the grants: `locked` is a
1112
1453
  * grant, because read-only is exactly what obeying a file requires.
1113
1454
  *
1114
- * This subsumes the narrower question of an authority sitting in `forbidden`. The four
1115
- * partitions are disjoint — `findManifestOverlaps` and the `disjoint` rule enforce it — so a
1116
- * forbidden path is in none of the three grants and is reported here. An authority named in
1117
- * NO partition at all is reported for the same reason, and that is the case a forbidden-only
1118
- * check misses entirely: the brief simply never says the executor may open what it must obey.
1455
+ * This subsumes the narrower question of an authority sitting in `forbidden`. The partitions
1456
+ * are disjoint — `findManifestOverlaps` and the `disjoint` rule enforce it — so a forbidden
1457
+ * path is in none of the grants and is reported here. An authority named in NO partition at
1458
+ * all is reported for the same reason, and that is the case a forbidden-only check misses
1459
+ * entirely: the brief never says the executor may open what it must obey.
1119
1460
  *
1120
1461
  * Paths are compared as EXACT strings, matching `findManifestOverlaps`. A glob is never
1121
1462
  * expanded, so `read: 'guides/**'` does not grant `authority: 'guides/brief.md'`. State a
@@ -1126,11 +1467,17 @@ import { Subject } from '@orkestrel/reason';
1126
1467
  *
1127
1468
  * @example
1128
1469
  * ```ts
1129
- * import { brief, findUngrantedAuthority, manifest, reference, task } from '@orkestrel/brief'
1130
- *
1131
- * const draft = brief(task('debug', 'code', 'Fix the leak.'), {
1132
- * authority: [reference('AGENTS.md', 'project law')],
1133
- * manifest: manifest(),
1470
+ * import {
1471
+ * buildBrief,
1472
+ * buildManifest,
1473
+ * buildReference,
1474
+ * buildTask,
1475
+ * findUngrantedAuthority,
1476
+ * } from '@orkestrel/brief'
1477
+ *
1478
+ * const draft = buildBrief(buildTask('debug', 'code', 'Fix the leak.'), {
1479
+ * authority: [buildReference('AGENTS.md', 'project law')],
1480
+ * manifest: buildManifest(),
1134
1481
  * })
1135
1482
  * findUngrantedAuthority(draft) // ['AGENTS.md'] — ranked, but no partition opens it
1136
1483
  * ```
@@ -1138,30 +1485,30 @@ import { Subject } from '@orkestrel/reason';
1138
1485
  export declare function findUngrantedAuthority(source: Brief): readonly string[];
1139
1486
 
1140
1487
  /**
1141
- * The readiness rules a brief fails, computed directly from its own measures.
1488
+ * Lists the readiness rules a brief fails, computed directly from its own measures.
1142
1489
  *
1143
1490
  * @remarks
1144
- * The gate's decision, in code. `gateDefinition()` states the same six rules as data for a
1491
+ * The gate's decision, in code. `buildGateDefinition()` states the same rules as data for a
1145
1492
  * reasoner to narrate, and a narration is not a decision: `BriefCompilerOptions.reason` lets a
1146
1493
  * caller supply the engine, and an engine that answers "met" to everything would otherwise
1147
1494
  * emit a brief with no proofs. `compile` refuses on THIS and keeps the verdict for its
1148
1495
  * trace, so a supplied engine can add detail and never remove a refusal.
1149
1496
  *
1150
- * The two must agree. `tests/src/core/helpers.test.ts` drives both over one value set, which
1151
- * is what stops the data and the code from drifting apart.
1497
+ * The data and the code must agree. `tests/src/core/helpers.test.ts` drives both over one
1498
+ * value set, which is what stops them from drifting apart.
1152
1499
  *
1153
1500
  * @param source - The brief to measure.
1154
1501
  * @returns The unmet rule ids, in gate order; empty when the brief is ready.
1155
1502
  *
1156
1503
  * @example
1157
1504
  * ```ts
1158
- * import { brief, findUnmetRules, outcome, proof, task } from '@orkestrel/brief'
1505
+ * import { buildBrief, buildOutcome, buildProof, buildTask, findUnmetRules } from '@orkestrel/brief'
1159
1506
  *
1160
- * findUnmetRules(brief(task('plan', 'ops', 'Plan the release.'))) // ['aimed', 'proven']
1507
+ * findUnmetRules(buildBrief(buildTask('plan', 'ops', 'Plan the release.'))) // ['aimed', 'proven']
1161
1508
  * findUnmetRules(
1162
- * brief(task('plan', 'ops', 'Plan the release.'), {
1163
- * outcomes: [outcome(1, 'shipped')],
1164
- * proofs: [proof('x', 'npm test')],
1509
+ * buildBrief(buildTask('plan', 'ops', 'Plan the release.'), {
1510
+ * outcomes: [buildOutcome(1, 'shipped')],
1511
+ * proofs: [buildProof('x', 'npm test')],
1165
1512
  * }),
1166
1513
  * ) // []
1167
1514
  * ```
@@ -1169,7 +1516,7 @@ import { Subject } from '@orkestrel/reason';
1169
1516
  export declare function findUnmetRules(source: Brief): readonly string[];
1170
1517
 
1171
1518
  /**
1172
- * The open gaps with no assumption to stand on.
1519
+ * Lists the open gaps with no assumption to stand on.
1173
1520
  *
1174
1521
  * @remarks
1175
1522
  * The discipline is exactly one recorded assumption per open gap, so the open gaps past
@@ -1181,10 +1528,10 @@ import { Subject } from '@orkestrel/reason';
1181
1528
  *
1182
1529
  * @example
1183
1530
  * ```ts
1184
- * import { brief, findUnpairedGaps, gap, task } from '@orkestrel/brief'
1531
+ * import { buildBrief, buildGap, buildTask, findUnpairedGaps } from '@orkestrel/brief'
1185
1532
  *
1186
- * const draft = brief(task('plan', 'ops', 'Plan the release.'), {
1187
- * gaps: [gap('rules', 'Keep the wording?'), gap('output', 'Diff or files?')],
1533
+ * const draft = buildBrief(buildTask('plan', 'ops', 'Plan the release.'), {
1534
+ * gaps: [buildGap('rules', 'Keep the wording?'), buildGap('output', 'Diff or files?')],
1188
1535
  * assumptions: ['Wording is preserved.'],
1189
1536
  * })
1190
1537
  * findUnpairedGaps(draft).length // 1
@@ -1193,7 +1540,7 @@ import { Subject } from '@orkestrel/reason';
1193
1540
  export declare function findUnpairedGaps(source: Brief): readonly Gap[];
1194
1541
 
1195
1542
  /**
1196
- * Freeze one branch of a value graph, skipping what the visited set already holds.
1543
+ * Freezes one branch of a value graph, skipping what the visited set already holds.
1197
1544
  *
1198
1545
  * @param value - The branch to freeze.
1199
1546
  * @param seen - The objects already frozen on this walk; what makes a cycle terminate.
@@ -1209,7 +1556,7 @@ import { Subject } from '@orkestrel/reason';
1209
1556
  export declare function freezeBranch<T>(value: T, seen: WeakSet<object>): T;
1210
1557
 
1211
1558
  /**
1212
- * Freeze a value and everything reachable from it.
1559
+ * Freezes a value and everything reachable from it.
1213
1560
  *
1214
1561
  * @remarks
1215
1562
  * `Object.freeze` is SHALLOW, so freezing a record leaves every nested array and object
@@ -1223,7 +1570,7 @@ import { Subject } from '@orkestrel/reason';
1223
1570
  * Reaches PLAIN objects and arrays, which is the whole of a `Brief` — it is JSON-serializable
1224
1571
  * by contract. A `Map`, `Set`, or typed array is frozen as an object and its CONTENTS are left
1225
1572
  * writable, and `Object.isFrozen` reports `true` for it either way. Nothing this package
1226
- * produces contains one; a caller freezing their own value should know the limit.
1573
+ * produces contains one; the limit lands on a caller freezing their own value.
1227
1574
  *
1228
1575
  * @param value - The value to freeze in place; returned for convenience.
1229
1576
  * @returns The same value, now deeply frozen.
@@ -1239,7 +1586,7 @@ import { Subject } from '@orkestrel/reason';
1239
1586
  export declare function freezeDeep<T>(value: T): T;
1240
1587
 
1241
1588
  /**
1242
- * One unknown the brief has not resolved.
1589
+ * Represents one unknown the brief has not resolved.
1243
1590
  *
1244
1591
  * @remarks
1245
1592
  * `blocking: true` means no safe default exists and the gate must fail closed. An
@@ -1252,67 +1599,18 @@ import { Subject } from '@orkestrel/reason';
1252
1599
  readonly candidates?: readonly string[];
1253
1600
  }
1254
1601
 
1255
- /**
1256
- * Build a `Gap`.
1257
- *
1258
- * @param field - The brief section the unknown belongs to.
1259
- * @param question - The question that would close it.
1260
- * @param overrides - Optional `blocking` (defaults `false`) and `candidates`; an absent
1261
- * `candidates` key is OMITTED entirely.
1262
- * @returns A fresh `Gap`.
1263
- *
1264
- * @example
1265
- * ```ts
1266
- * import { gap } from '@orkestrel/brief'
1267
- *
1268
- * gap('rules', 'Should validation message wording change?') // blocking: false
1269
- * gap('output', 'Diff or full files?', { blocking: true, candidates: ['diff', 'code'] })
1270
- * ```
1271
- */
1272
- export declare function gap(field: string, question: string, overrides?: Partial<Omit<Gap, 'field' | 'question'>>): Gap;
1273
-
1274
- /** The `Gap` shape — an unknown, whether it blocks, and the candidates that would close it. */
1275
- export declare const gapShape: ObjectShape<{
1276
- field: StringShape;
1277
- question: StringShape;
1278
- blocking: BooleanShape;
1279
- candidates: OptionalShape<ArrayShape<StringShape>>;
1602
+ /** Describes the `Gap` shape — an unknown, whether it blocks, and the candidates that would close it. */
1603
+ export declare const gapShape: ObjectShape< {
1604
+ field: StringShape;
1605
+ question: StringShape;
1606
+ blocking: BooleanShape;
1607
+ candidates: OptionalShape<ArrayShape<StringShape>>;
1280
1608
  }, false>;
1281
1609
 
1282
- /** `'gate'` — the id of the `gateDefinition()` logical definition. */
1610
+ /** Holds `'gate'` — the id of the `buildGateDefinition()` logical definition. */
1283
1611
  export declare const GATE_ID = "gate";
1284
1612
 
1285
- /**
1286
- * Build the fail-closed readiness gate as a reasons `LogicalDefinition`.
1287
- *
1288
- * @remarks
1289
- * Six readiness rules each derive one named fact from `briefToSubject`'s measures, and a
1290
- * final `ready` rule conjoins all six. Forward chaining reports the LAST rule's
1291
- * conclusion, so `LogicalResult.conclusion` is exactly `ready`.
1292
- *
1293
- * The gate takes NO parameters, and that is deliberate rather than unfinished. The
1294
- * reasoner overlays every derived fact into one flat namespace, so a caller rule named
1295
- * for a readiness fact overwrites it and `ready` then conjoins a fact no base rule
1296
- * proved — a refusal silently becomes a pass. Readiness is this package's contract, not
1297
- * a caller setting. A caller who needs different readiness composes their own
1298
- * `LogicalDefinition` over `briefToSubject` and evaluates it on their own reasoner; both
1299
- * are exported for exactly that, and neither can reach this definition.
1300
- *
1301
- * @returns A fresh `LogicalDefinition` with id `GATE_ID`.
1302
- *
1303
- * @example
1304
- * ```ts
1305
- * import { briefToSubject, gateDefinition } from '@orkestrel/brief'
1306
- * import { createLogicalReasoner, createReason } from '@orkestrel/reason'
1307
- *
1308
- * const reason = createReason({ reasoners: [createLogicalReasoner()] })
1309
- * const verdict = reason.reason(briefToSubject(pinned), gateDefinition())
1310
- * reason.destroy()
1311
- * ```
1312
- */
1313
- export declare function gateDefinition(): LogicalDefinition;
1314
-
1315
- /** The `gate` phase snapshot — the readiness `Subject` in, the reasoner's verdict out. */
1613
+ /** Records the `gate` phase snapshot — the readiness `Subject` in, the reasoner's verdict out. */
1316
1614
  export declare interface GateStageRecord {
1317
1615
  readonly stage: 'gate';
1318
1616
  readonly input: Subject;
@@ -1320,39 +1618,22 @@ import { Subject } from '@orkestrel/reason';
1320
1618
  readonly error?: string;
1321
1619
  }
1322
1620
 
1323
- /** One context fact handed to the executor — a convention, a version, a constraint value. */
1621
+ /** Represents one context fact handed to the executor — a convention, a version, a constraint value. */
1324
1622
  export declare interface Given {
1325
1623
  readonly category: string;
1326
1624
  readonly name: string;
1327
1625
  readonly value: string;
1328
1626
  }
1329
1627
 
1330
- /**
1331
- * Build a `Given`.
1332
- *
1333
- * @param category - The kind of fact — a convention, a version, a constraint.
1334
- * @param name - The fact's name.
1335
- * @param value - The fact's value, already rendered as text.
1336
- * @returns A fresh `Given`.
1337
- *
1338
- * @example
1339
- * ```ts
1340
- * import { given } from '@orkestrel/brief'
1341
- *
1342
- * given('convention', 'indentation', 'tabs')
1343
- * ```
1344
- */
1345
- export declare function given(category: string, name: string, value: string): Given;
1346
-
1347
- /** The `Given` shape — one categorized context fact. */
1348
- export declare const givenShape: ObjectShape<{
1349
- category: StringShape;
1350
- name: StringShape;
1351
- value: StringShape;
1628
+ /** Describes the `Given` shape — one categorized context fact. */
1629
+ export declare const givenShape: ObjectShape< {
1630
+ category: StringShape;
1631
+ name: StringShape;
1632
+ value: StringShape;
1352
1633
  }, false>;
1353
1634
 
1354
1635
  /**
1355
- * Every published `Interpretation` member name, frozen.
1636
+ * Lists every published `Interpretation` member name, frozen.
1356
1637
  *
1357
1638
  * @remarks
1358
1639
  * The capture list `BriefCompiler` hands `captureValue` at each interpret door — the borrowed
@@ -1365,10 +1646,10 @@ import { Subject } from '@orkestrel/reason';
1365
1646
  * equality assertion beside the capture cases refuse a list that has fallen short of the
1366
1647
  * published shape.
1367
1648
  */
1368
- export declare const INTERPRETATION_MEMBERS: readonly ("text" | "normalized" | "intent" | "entities" | "subject" | "definition" | "mappings" | "ambiguities" | "prompt" | "stages" | "failures" | "complete" | "confidence" | "digest")[];
1649
+ export declare const INTERPRETATION_MEMBERS: readonly ("text" | "normalized" | "intent" | "entities" | "subject" | "definition" | "mappings" | "ambiguities" | "prompt" | "stages" | "failures" | "confidence" | "digest")[];
1369
1650
 
1370
1651
  /**
1371
- * The `interpret` phase snapshot — raw text in, an `Interpretation` out.
1652
+ * Records the `interpret` phase snapshot — raw text in, an `Interpretation` out.
1372
1653
  *
1373
1654
  * @remarks
1374
1655
  * `output` is absent exactly when `error` is present, which is what makes the phase
@@ -1382,19 +1663,22 @@ import { Subject } from '@orkestrel/reason';
1382
1663
  }
1383
1664
 
1384
1665
  /**
1385
- * `true` when the value satisfies the whole exact-record `Brief` contract.
1666
+ * Checks whether the value satisfies the whole exact-record `Brief` contract.
1386
1667
  *
1387
1668
  * @remarks
1388
1669
  * Every section must be present; an extra key fails. `trace` and `hash` are the only
1389
1670
  * optional members, because `pinBrief` rather than the author fills them.
1671
+ *
1672
+ * @param value - The value to inspect.
1673
+ * @returns True if `value` satisfies the whole exact-record `Brief` contract; false otherwise.
1390
1674
  */
1391
1675
  export declare const isBrief: Guard<Brief>;
1392
1676
 
1393
1677
  /**
1394
- * Narrow a caught value to a {@link BriefError}.
1678
+ * Narrows a caught value to a {@link BriefError}.
1395
1679
  *
1396
1680
  * @param value - The caught value to inspect.
1397
- * @returns `true` when `value` is a `BriefError`.
1681
+ * @returns True if `value` is a `BriefError`; false otherwise.
1398
1682
  *
1399
1683
  * @example
1400
1684
  * ```ts
@@ -1409,92 +1693,176 @@ import { Subject } from '@orkestrel/reason';
1409
1693
  */
1410
1694
  export declare function isBriefError(value: unknown): value is BriefError;
1411
1695
 
1412
- /** `true` when the value is a well-formed `Citation` — all three members single-line. */
1696
+ /**
1697
+ * Checks whether the value is a well-formed `Citation` — every member single-line.
1698
+ *
1699
+ * @param value - The value to inspect.
1700
+ * @returns True if `value` is a well-formed `Citation`; false otherwise.
1701
+ */
1413
1702
  export declare const isCitation: Guard<Citation>;
1414
1703
 
1415
1704
  /**
1416
- * `true` when the value is a well-formed `Example`.
1705
+ * Checks whether the value is a well-formed `Example`.
1417
1706
  *
1418
1707
  * @remarks
1419
1708
  * An exemplar's two sides are the ONLY members a brief lets span lines, because they
1420
1709
  * carry code. `briefToMarkdown` fences them rather than rendering them as a row.
1710
+ *
1711
+ * @param value - The value to inspect.
1712
+ * @returns True if `value` is a well-formed `Example`; false otherwise.
1421
1713
  */
1422
1714
  export declare const isExample: Guard<Example>;
1423
1715
 
1424
- /** `true` when the value is a well-formed `Gap`. */
1716
+ /**
1717
+ * Checks whether the value is a well-formed `Gap`.
1718
+ *
1719
+ * @param value - The value to inspect.
1720
+ * @returns True if `value` is a well-formed `Gap`; false otherwise.
1721
+ */
1425
1722
  export declare const isGap: Guard<Gap>;
1426
1723
 
1427
- /** `true` when the value is a well-formed `Given` — `value` may be empty but stays one line. */
1724
+ /**
1725
+ * Checks whether the value is a well-formed `Given` — its `value` may be empty but stays one line.
1726
+ *
1727
+ * @param value - The value to inspect.
1728
+ * @returns True if `value` is a well-formed `Given`; false otherwise.
1729
+ */
1428
1730
  export declare const isGiven: Guard<Given>;
1429
1731
 
1430
- /** `true` when the value is a non-empty string holding no line terminator. */
1732
+ /**
1733
+ * Checks whether the value is a non-empty string holding no line terminator.
1734
+ *
1735
+ * @remarks
1736
+ * The shape of nearly every brief field: a path, a note, a statement, a rule, and a command
1737
+ * all narrow through it.
1738
+ *
1739
+ * @param value - The value to inspect.
1740
+ * @returns True if `value` is a non-empty string holding no line terminator; false otherwise.
1741
+ */
1431
1742
  export declare const isLine: Guard<string>;
1432
1743
 
1433
1744
  /**
1434
- * `true` when the value is a well-formed `Manifest`.
1745
+ * Checks whether the value is a well-formed `Manifest`.
1435
1746
  *
1436
1747
  * @remarks
1437
1748
  * Partition presence only — disjointness is `validateBrief`'s semantic pass.
1749
+ *
1750
+ * @param value - The value to inspect.
1751
+ * @returns True if `value` is a well-formed `Manifest`; false otherwise.
1438
1752
  */
1439
1753
  export declare const isManifest: Guard<Manifest>;
1440
1754
 
1441
- /** `true` when the value is a well-formed `Outcome` — `rank` a positive integer. */
1755
+ /**
1756
+ * Checks whether the value is a well-formed `Outcome` — `rank` a positive integer.
1757
+ *
1758
+ * @param value - The value to inspect.
1759
+ * @returns True if `value` is a well-formed `Outcome`; false otherwise.
1760
+ */
1442
1761
  export declare const isOutcome: Guard<Outcome>;
1443
1762
 
1444
- /** `true` when the value is a well-formed `Output` — `format` on the closed vocabulary. */
1763
+ /**
1764
+ * Checks whether the value is a well-formed `Output` — `format` on the closed vocabulary.
1765
+ *
1766
+ * @param value - The value to inspect.
1767
+ * @returns True if `value` is a well-formed `Output`; false otherwise.
1768
+ */
1445
1769
  export declare const isOutput: Guard<Output>;
1446
1770
 
1447
- /** `true` when the value is one of the five `OutputFormat` literals. */
1771
+ /**
1772
+ * Checks whether the value is one of the `OutputFormat` literals.
1773
+ *
1774
+ * @param value - The value to inspect.
1775
+ * @returns True if `value` is one of the `OutputFormat` literals; false otherwise.
1776
+ */
1448
1777
  export declare const isOutputFormat: Guard<OutputFormat>;
1449
1778
 
1450
- /** `true` when the value is a well-formed `Proof`. */
1779
+ /**
1780
+ * Checks whether the value is a well-formed `Proof`.
1781
+ *
1782
+ * @param value - The value to inspect.
1783
+ * @returns True if `value` is a well-formed `Proof`; false otherwise.
1784
+ */
1451
1785
  export declare const isProof: Guard<Proof>;
1452
1786
 
1453
- /** `true` when the value is a well-formed `Reference` — both members required, both single-line. */
1787
+ /**
1788
+ * Checks whether the value is a well-formed `Reference` — both members required, both single-line.
1789
+ *
1790
+ * @param value - The value to inspect.
1791
+ * @returns True if `value` is a well-formed `Reference`; false otherwise.
1792
+ */
1454
1793
  export declare const isReference: Guard<Reference>;
1455
1794
 
1456
- /** `true` when the value is a well-formed `Risk` — `severity` on the closed vocabulary. */
1795
+ /**
1796
+ * Checks whether the value is a well-formed `Risk` — `severity` on the closed vocabulary.
1797
+ *
1798
+ * @param value - The value to inspect.
1799
+ * @returns True if `value` is a well-formed `Risk`; false otherwise.
1800
+ */
1457
1801
  export declare const isRisk: Guard<Risk>;
1458
1802
 
1459
- /** `true` when the value is one of the three `RiskSeverity` literals. */
1803
+ /**
1804
+ * Checks whether the value is one of the `RiskSeverity` literals.
1805
+ *
1806
+ * @param value - The value to inspect.
1807
+ * @returns True if `value` is one of the `RiskSeverity` literals; false otherwise.
1808
+ */
1460
1809
  export declare const isRiskSeverity: Guard<RiskSeverity>;
1461
1810
 
1462
- /** `true` when the value is a well-formed `Task` — both vocabularies closed, statement one line. */
1811
+ /**
1812
+ * Checks whether the value is a well-formed `Task` — both vocabularies closed, statement one line.
1813
+ *
1814
+ * @param value - The value to inspect.
1815
+ * @returns True if `value` is a well-formed `Task`; false otherwise.
1816
+ */
1463
1817
  export declare const isTask: Guard<Task>;
1464
1818
 
1465
- /** `true` when the value is one of the eight `TaskDomain` literals. */
1819
+ /**
1820
+ * Checks whether the value is one of the `TaskDomain` literals.
1821
+ *
1822
+ * @param value - The value to inspect.
1823
+ * @returns True if `value` is one of the `TaskDomain` literals; false otherwise.
1824
+ */
1466
1825
  export declare const isTaskDomain: Guard<TaskDomain>;
1467
1826
 
1468
- /** `true` when the value is one of the twelve `TaskOperation` literals. */
1827
+ /**
1828
+ * Checks whether the value is one of the `TaskOperation` literals.
1829
+ *
1830
+ * @param value - The value to inspect.
1831
+ * @returns True if `value` is one of the `TaskOperation` literals; false otherwise.
1832
+ */
1469
1833
  export declare const isTaskOperation: Guard<TaskOperation>;
1470
1834
 
1471
1835
  /**
1472
- * `true` when the value is a string holding no line terminator, empty included.
1836
+ * Checks whether the value is a string holding no line terminator, empty included.
1473
1837
  *
1474
1838
  * @remarks
1475
1839
  * `briefToMarkdown` renders each brief field as ONE markdown row, so a field carrying a
1476
1840
  * line break would forge a heading or an extra manifest row — which is how a rendered
1477
1841
  * prompt and `briefToDispatch`'s path sets could disagree about the same brief.
1842
+ *
1843
+ * @param value - The value to inspect.
1844
+ * @returns True if `value` is a string holding no line terminator, empty included; false
1845
+ * otherwise.
1478
1846
  */
1479
1847
  export declare const isText: Guard<string>;
1480
1848
 
1481
1849
  /**
1482
- * Every line terminator a brief field refuses.
1850
+ * Matches every line terminator a brief field refuses.
1483
1851
  *
1484
1852
  * @remarks
1485
- * The four ECMAScript line terminators, not just `\n`: a renderer that splits on any of
1486
- * them would let the other three forge a markdown row. CRLF leads the alternation so a
1487
- * Windows exemplar splits as ONE break rather than two, which would insert a blank line the
1488
- * caller never wrote. Kept unanchored and stateless — no `g` flag — so `test` never carries
1853
+ * Every ECMAScript line terminator, not only `\n`: a renderer that splits on any of them
1854
+ * would let the others forge a markdown row. CRLF leads the alternation so a Windows
1855
+ * exemplar splits as ONE break rather than two, which would insert a blank line the caller
1856
+ * never wrote. Kept unanchored and stateless — no `g` flag — so `test` never carries
1489
1857
  * `lastIndex` between calls.
1490
1858
  */
1491
1859
  export declare const LINE_BREAK_PATTERN: RegExp;
1492
1860
 
1493
- /** A non-empty single-line string — the shape mirror of `isLine`. */
1861
+ /** Describes a non-empty single-line string — the shape mirror of `isLine`. */
1494
1862
  export declare const lineShape: StringShape;
1495
1863
 
1496
1864
  /**
1497
- * The four disjoint file partitions of a brief.
1865
+ * Represents the disjoint file partitions of a brief.
1498
1866
  *
1499
1867
  * @remarks
1500
1868
  * `read` order is the reading order. A path in more than one partition is a
@@ -1508,42 +1876,33 @@ import { Subject } from '@orkestrel/reason';
1508
1876
  }
1509
1877
 
1510
1878
  /**
1511
- * Build a `Manifest`, defaulting every absent partition to an empty list.
1512
- *
1513
- * @param partitions - The partitions to fill; a partial literal is enough.
1514
- * @returns A fresh `Manifest` with all four partitions present.
1515
- *
1516
- * @example
1517
- * ```ts
1518
- * import { manifest, reference } from '@orkestrel/brief'
1879
+ * Describes the `Manifest` shape disjoint reference partitions.
1519
1880
  *
1520
- * manifest({ edit: [reference('src/core/helpers.ts', 'implementation')] })
1521
- * ```
1881
+ * @remarks
1882
+ * Each partition is an `arrayShape(referenceShape)`; disjointness is `validateBrief`'s pass
1883
+ * rather than the shape's.
1522
1884
  */
1523
- export declare function manifest(partitions?: Partial<Manifest>): Manifest;
1524
-
1525
- /** The `Manifest` shape — four disjoint reference partitions. */
1526
- export declare const manifestShape: ObjectShape<{
1527
- read: ArrayShape<ObjectShape<{
1528
- path: StringShape;
1529
- note: StringShape;
1530
- }, false>>;
1531
- edit: ArrayShape<ObjectShape<{
1532
- path: StringShape;
1533
- note: StringShape;
1534
- }, false>>;
1535
- locked: ArrayShape<ObjectShape<{
1536
- path: StringShape;
1537
- note: StringShape;
1538
- }, false>>;
1539
- forbidden: ArrayShape<ObjectShape<{
1540
- path: StringShape;
1541
- note: StringShape;
1542
- }, false>>;
1885
+ export declare const manifestShape: ObjectShape< {
1886
+ read: ArrayShape<ObjectShape< {
1887
+ path: StringShape;
1888
+ note: StringShape;
1889
+ }, false>>;
1890
+ edit: ArrayShape<ObjectShape< {
1891
+ path: StringShape;
1892
+ note: StringShape;
1893
+ }, false>>;
1894
+ locked: ArrayShape<ObjectShape< {
1895
+ path: StringShape;
1896
+ note: StringShape;
1897
+ }, false>>;
1898
+ forbidden: ArrayShape<ObjectShape< {
1899
+ path: StringShape;
1900
+ note: StringShape;
1901
+ }, false>>;
1543
1902
  }, false>;
1544
1903
 
1545
1904
  /**
1546
- * One ranked outcome — a result, never a step.
1905
+ * Represents one ranked outcome — a result, never a step.
1547
1906
  *
1548
1907
  * @remarks
1549
1908
  * `required: true` gates "done"; a demoted outcome is desirable but not blocking.
@@ -1555,32 +1914,19 @@ import { Subject } from '@orkestrel/reason';
1555
1914
  }
1556
1915
 
1557
1916
  /**
1558
- * Build an `Outcome`.
1559
- *
1560
- * @param rank - The one-based rank; lower ranks matter more.
1561
- * @param text - The result, never a step.
1562
- * @param required - Whether the outcome gates "done"; defaults to `true`.
1563
- * @returns A fresh `Outcome`.
1917
+ * Describes the `Outcome` shape — a one-based rank, the result text, and whether it gates done.
1564
1918
  *
1565
- * @example
1566
- * ```ts
1567
- * import { outcome } from '@orkestrel/brief'
1568
- *
1569
- * outcome(1, 'useForm uses native FormData with no behavior change') // required: true
1570
- * outcome(2, 'the diff stays under 200 lines', false)
1571
- * ```
1919
+ * @remarks
1920
+ * `rank` is an `integerShape({ min: 1 })`, so a zero or fractional rank is off-contract.
1572
1921
  */
1573
- export declare function outcome(rank: number, text: string, required?: boolean): Outcome;
1574
-
1575
- /** The `Outcome` shape — a one-based rank, the result text, and whether it gates done. */
1576
- export declare const outcomeShape: ObjectShape<{
1577
- rank: NumberShape;
1578
- text: StringShape;
1579
- required: BooleanShape;
1922
+ export declare const outcomeShape: ObjectShape< {
1923
+ rank: NumberShape;
1924
+ text: StringShape;
1925
+ required: BooleanShape;
1580
1926
  }, false>;
1581
1927
 
1582
1928
  /**
1583
- * The closed shape of the deliverable.
1929
+ * Represents the closed shape of the deliverable.
1584
1930
  *
1585
1931
  * @remarks
1586
1932
  * `format` is required; `sections` / `include` / `exclude` refine it.
@@ -1592,39 +1938,22 @@ import { Subject } from '@orkestrel/reason';
1592
1938
  readonly exclude?: readonly string[];
1593
1939
  }
1594
1940
 
1595
- /**
1596
- * Build an `Output`.
1597
- *
1598
- * @param format - The closed deliverable format.
1599
- * @param overrides - Optional `sections` / `include` / `exclude`; absent keys are OMITTED.
1600
- * @returns A fresh `Output`.
1601
- *
1602
- * @example
1603
- * ```ts
1604
- * import { output } from '@orkestrel/brief'
1605
- *
1606
- * output('markdown') // { format: 'markdown' }
1607
- * output('diff', { include: ['updated useForm.ts'] })
1608
- * ```
1609
- */
1610
- export declare function output(format: OutputFormat, overrides?: Partial<Omit<Output, 'format'>>): Output;
1611
-
1612
- /** The five `OutputFormat` values, frozen. */
1941
+ /** Lists the `OutputFormat` values, frozen. */
1613
1942
  export declare const OUTPUT_FORMATS: readonly OutputFormat[];
1614
1943
 
1615
- /** The closed vocabulary of deliverable shapes. */
1944
+ /** Names the closed vocabulary of deliverable shapes. */
1616
1945
  export declare type OutputFormat = 'markdown' | 'json' | 'code' | 'diff' | 'prose';
1617
1946
 
1618
- /** The `Output` shape — a closed format plus its optional refinements. */
1619
- export declare const outputShape: ObjectShape<{
1620
- format: LiteralShape<readonly OutputFormat[]>;
1621
- sections: OptionalShape<ArrayShape<StringShape>>;
1622
- include: OptionalShape<ArrayShape<StringShape>>;
1623
- exclude: OptionalShape<ArrayShape<StringShape>>;
1947
+ /** Describes the `Output` shape — a closed format plus its optional refinements. */
1948
+ export declare const outputShape: ObjectShape< {
1949
+ format: LiteralShape<readonly OutputFormat[]>;
1950
+ sections: OptionalShape<ArrayShape<StringShape>>;
1951
+ include: OptionalShape<ArrayShape<StringShape>>;
1952
+ exclude: OptionalShape<ArrayShape<StringShape>>;
1624
1953
  }, false>;
1625
1954
 
1626
1955
  /**
1627
- * Parse a JSON string into a `Brief`.
1956
+ * Parses a JSON string into a `Brief`.
1628
1957
  *
1629
1958
  * @remarks
1630
1959
  * The parse-then-trust boundary for a stored brief, a tool argument, or an agent's
@@ -1655,7 +1984,7 @@ import { Subject } from '@orkestrel/reason';
1655
1984
  export declare function parseBrief(value: string): Brief | undefined;
1656
1985
 
1657
1986
  /**
1658
- * Return a fresh brief with `trace` and `hash` derived from its own content.
1987
+ * Returns a fresh brief with `trace` and `hash` derived from its own content.
1659
1988
  *
1660
1989
  * @remarks
1661
1990
  * Deterministic: no clock, no randomness, no run-specific data. Any existing `trace` /
@@ -1671,16 +2000,16 @@ import { Subject } from '@orkestrel/reason';
1671
2000
  *
1672
2001
  * @example
1673
2002
  * ```ts
1674
- * import { brief, pinBrief, task } from '@orkestrel/brief'
2003
+ * import { buildBrief, buildTask, pinBrief } from '@orkestrel/brief'
1675
2004
  *
1676
- * const pinned = pinBrief(brief(task('document', 'writing', 'Write the brief guide.')))
2005
+ * const pinned = pinBrief(buildBrief(buildTask('document', 'writing', 'Write the brief guide.')))
1677
2006
  * pinned.hash // an 8-hex-digit structural digest
1678
2007
  * pinned.trace // 'document/writing · outcomes:0 · gaps:0/0 · proofs:0'
1679
2008
  * ```
1680
2009
  */
1681
2010
  export declare function pinBrief(source: Brief): Brief;
1682
2011
 
1683
- /** The `pin` phase snapshot — the drafted `Brief` in, the pinned `Brief` out. */
2012
+ /** Records the `pin` phase snapshot — the drafted `Brief` in, the pinned `Brief` out. */
1684
2013
  export declare interface PinStageRecord {
1685
2014
  readonly stage: 'pin';
1686
2015
  readonly input: Brief;
@@ -1689,40 +2018,24 @@ import { Subject } from '@orkestrel/reason';
1689
2018
  }
1690
2019
 
1691
2020
  /**
1692
- * One mechanical, transcript-provable check.
2021
+ * Represents one mechanical, transcript-provable check.
1693
2022
  *
1694
2023
  * @remarks
1695
- * `command` should carry a clear exit signal it becomes the `/goal` condition verbatim.
2024
+ * Give `command` a clear exit signal; it becomes the `/goal` condition verbatim.
1696
2025
  */
1697
2026
  export declare interface Proof {
1698
2027
  readonly text: string;
1699
2028
  readonly command: string;
1700
2029
  }
1701
2030
 
1702
- /**
1703
- * Build a `Proof`.
1704
- *
1705
- * @param text - What the check settles.
1706
- * @param command - The command whose exit signal settles it.
1707
- * @returns A fresh `Proof`.
1708
- *
1709
- * @example
1710
- * ```ts
1711
- * import { proof } from '@orkestrel/brief'
1712
- *
1713
- * proof('type-check and lint pass', 'npm run check')
1714
- * ```
1715
- */
1716
- export declare function proof(text: string, command: string): Proof;
1717
-
1718
- /** The `Proof` shape — the claim and the command that settles it. */
1719
- export declare const proofShape: ObjectShape<{
1720
- text: StringShape;
1721
- command: StringShape;
2031
+ /** Describes the `Proof` shape — the claim and the command that settles it. */
2032
+ export declare const proofShape: ObjectShape< {
2033
+ text: StringShape;
2034
+ command: StringShape;
1722
2035
  }, false>;
1723
2036
 
1724
2037
  /**
1725
- * One referenced path and why it is listed.
2038
+ * Represents one referenced path and why it is listed.
1726
2039
  *
1727
2040
  * @remarks
1728
2041
  * The ONE path record. A reference means different things in different containers, and the
@@ -1740,67 +2053,34 @@ import { Subject } from '@orkestrel/reason';
1740
2053
  readonly note: string;
1741
2054
  }
1742
2055
 
1743
- /**
1744
- * Build a `Reference`.
1745
- *
1746
- * @param path - The referenced path or glob.
1747
- * @param note - Why the path is listed.
1748
- * @returns A fresh `Reference`.
1749
- *
1750
- * @example
1751
- * ```ts
1752
- * import { reference } from '@orkestrel/brief'
1753
- *
1754
- * reference('AGENTS.md', 'project law') // { path: 'AGENTS.md', note: 'project law' }
1755
- * ```
1756
- */
1757
- export declare function reference(path: string, note: string): Reference;
1758
-
1759
- /** The `Reference` shape — a path and the note that justifies listing it. */
1760
- export declare const referenceShape: ObjectShape<{
1761
- path: StringShape;
1762
- note: StringShape;
2056
+ /** Describes the `Reference` shape — a path and the note that justifies listing it. */
2057
+ export declare const referenceShape: ObjectShape< {
2058
+ path: StringShape;
2059
+ note: StringShape;
1763
2060
  }, false>;
1764
2061
 
1765
- /** One pre-empted risk and the mitigation that answers it. */
2062
+ /** Represents one pre-empted risk and the mitigation that answers it. */
1766
2063
  export declare interface Risk {
1767
2064
  readonly severity: RiskSeverity;
1768
2065
  readonly text: string;
1769
2066
  readonly mitigation: string;
1770
2067
  }
1771
2068
 
1772
- /**
1773
- * Build a `Risk`.
1774
- *
1775
- * @param severity - The closed severity.
1776
- * @param text - What could go wrong.
1777
- * @param mitigation - What answers it.
1778
- * @returns A fresh `Risk`.
1779
- *
1780
- * @example
1781
- * ```ts
1782
- * import { risk } from '@orkestrel/brief'
1783
- *
1784
- * risk('medium', 'native validation differs subtly', 'assert message and state in tests')
1785
- * ```
1786
- */
1787
- export declare function risk(severity: RiskSeverity, text: string, mitigation: string): Risk;
1788
-
1789
- /** The three `RiskSeverity` values, frozen. */
2069
+ /** Lists the `RiskSeverity` values, frozen. */
1790
2070
  export declare const RISK_SEVERITIES: readonly RiskSeverity[];
1791
2071
 
1792
- /** The closed vocabulary of risk severities. */
2072
+ /** Names the closed vocabulary of risk severities. */
1793
2073
  export declare type RiskSeverity = 'low' | 'medium' | 'high';
1794
2074
 
1795
- /** The `Risk` shape — a closed severity, the risk, and its mitigation. */
1796
- export declare const riskShape: ObjectShape<{
1797
- severity: LiteralShape<readonly RiskSeverity[]>;
1798
- text: StringShape;
1799
- mitigation: StringShape;
2075
+ /** Describes the `Risk` shape — a closed severity, the risk, and its mitigation. */
2076
+ export declare const riskShape: ObjectShape< {
2077
+ severity: LiteralShape<readonly RiskSeverity[]>;
2078
+ text: StringShape;
2079
+ mitigation: StringShape;
1800
2080
  }, false>;
1801
2081
 
1802
2082
  /**
1803
- * The positive form of {@link LINE_BREAK_PATTERN}, for the shape DSL.
2083
+ * Holds the positive form of {@link LINE_BREAK_PATTERN}, for a `stringShape` `pattern`.
1804
2084
  *
1805
2085
  * @remarks
1806
2086
  * `stringShape`'s `pattern` must MATCH an accepted value, so the guard's refusal regex
@@ -1810,7 +2090,7 @@ import { Subject } from '@orkestrel/reason';
1810
2090
  export declare const SINGLE_LINE_PATTERN: RegExp;
1811
2091
 
1812
2092
  /**
1813
- * Return a deeply owned, deeply frozen copy of a brief, refusing anything off-contract.
2093
+ * Returns a deeply owned, deeply frozen copy of a brief, refusing anything off-contract.
1814
2094
  *
1815
2095
  * @remarks
1816
2096
  * The one reading boundary this package has, used by the pin, the registry, and every
@@ -1834,10 +2114,10 @@ import { Subject } from '@orkestrel/reason';
1834
2114
  *
1835
2115
  * @example
1836
2116
  * ```ts
1837
- * import { brief, outcome, snapshotBrief, task } from '@orkestrel/brief'
2117
+ * import { buildBrief, buildOutcome, buildTask, snapshotBrief } from '@orkestrel/brief'
1838
2118
  *
1839
- * const outcomes = [outcome(1, 'shipped')]
1840
- * const owned = snapshotBrief(brief(task('plan', 'ops', 'Plan the release.'), { outcomes }))
2119
+ * const outcomes = [buildOutcome(1, 'shipped')]
2120
+ * const owned = snapshotBrief(buildBrief(buildTask('plan', 'ops', 'Plan the release.'), { outcomes }))
1841
2121
  * owned.outcomes === outcomes // false — the alias is broken
1842
2122
  * Object.isFrozen(owned.outcomes) // true
1843
2123
  * ```
@@ -1845,7 +2125,7 @@ import { Subject } from '@orkestrel/reason';
1845
2125
  export declare function snapshotBrief(source: Brief): Brief;
1846
2126
 
1847
2127
  /**
1848
- * What the brief asks for, in one imperative sentence.
2128
+ * States what the brief asks for, in one imperative sentence.
1849
2129
  *
1850
2130
  * @remarks
1851
2131
  * A compound `statement` is two briefs — `validateBrief` errors on more than one sentence.
@@ -1856,53 +2136,49 @@ import { Subject } from '@orkestrel/reason';
1856
2136
  readonly statement: string;
1857
2137
  }
1858
2138
 
2139
+ /** Lists the `TaskDomain` values, frozen. */
2140
+ export declare const TASK_DOMAINS: readonly TaskDomain[];
2141
+
1859
2142
  /**
1860
- * Build a `Task`.
1861
- *
1862
- * @param operation - What the brief asks for, from the closed operation vocabulary.
1863
- * @param domain - The subject matter, from the closed domain vocabulary.
1864
- * @param statement - One imperative sentence naming the object of the work.
1865
- * @returns A fresh `Task`.
2143
+ * Lists the `TaskOperation` values, frozen.
1866
2144
  *
1867
- * @example
1868
- * ```ts
1869
- * import { task } from '@orkestrel/brief'
1870
- *
1871
- * task('refactor', 'code', 'Refactor useForm to native browser form APIs.')
1872
- * ```
2145
+ * @remarks
2146
+ * Compose the tuple rather than restating its members: `literalOf(TASK_OPERATIONS)` builds the
2147
+ * guard and `parseEnum(value, TASK_OPERATIONS)` coerces a bare value against it.
1873
2148
  */
1874
- export declare function task(operation: TaskOperation, domain: TaskDomain, statement: string): Task;
1875
-
1876
- /** The eight `TaskDomain` values, frozen. */
1877
- export declare const TASK_DOMAINS: readonly TaskDomain[];
1878
-
1879
- /** The twelve `TaskOperation` values, frozen. */
1880
2149
  export declare const TASK_OPERATIONS: readonly TaskOperation[];
1881
2150
 
1882
- /** The closed vocabulary of the subject matter a brief operates on. */
2151
+ /** Names the closed vocabulary of the subject matter a brief operates on. */
1883
2152
  export declare type TaskDomain = 'code' | 'writing' | 'research' | 'analysis' | 'design' | 'data' | 'ops' | 'other';
1884
2153
 
1885
2154
  /**
1886
- * The closed vocabulary of what a brief asks for.
2155
+ * Names the closed vocabulary of what a brief asks for.
1887
2156
  *
1888
2157
  * @remarks
1889
- * A request that fits none of these twelve is mis-scoped rather than a missing
1890
- * literal. Compose with `literalOf(TASK_OPERATIONS)` or `parseEnum(value, TASK_OPERATIONS)`.
2158
+ * A request that fits none of these is mis-scoped rather than a missing literal. Compose
2159
+ * with `literalOf(TASK_OPERATIONS)` or `parseEnum(value, TASK_OPERATIONS)`.
1891
2160
  */
1892
2161
  export declare type TaskOperation = 'create' | 'refactor' | 'debug' | 'extract' | 'migrate' | 'explain' | 'review' | 'optimize' | 'audit' | 'test' | 'document' | 'plan';
1893
2162
 
1894
- /** The `Task` shape — closed operation and domain vocabularies plus a non-empty statement. */
1895
- export declare const taskShape: ObjectShape<{
1896
- operation: LiteralShape<readonly TaskOperation[]>;
1897
- domain: LiteralShape<readonly TaskDomain[]>;
1898
- statement: StringShape;
2163
+ /**
2164
+ * Describes the `Task` shape — closed operation and domain vocabularies plus a non-empty
2165
+ * statement.
2166
+ *
2167
+ * @remarks
2168
+ * `literalShape(TASK_OPERATIONS)` and `literalShape(TASK_DOMAINS)` compile the same tuples the
2169
+ * guards read, and `statement` carries `min: 1`.
2170
+ */
2171
+ export declare const taskShape: ObjectShape< {
2172
+ operation: LiteralShape<readonly TaskOperation[]>;
2173
+ domain: LiteralShape<readonly TaskDomain[]>;
2174
+ statement: StringShape;
1899
2175
  }, false>;
1900
2176
 
1901
- /** A single-line string of any length, including empty. */
2177
+ /** Describes a single-line string of any length, including empty — the shape mirror of `isText`. */
1902
2178
  export declare const textShape: StringShape;
1903
2179
 
1904
2180
  /**
1905
- * The semantic pass over an already-shape-valid brief.
2181
+ * Runs the semantic pass over an already-shape-valid brief.
1906
2182
  *
1907
2183
  * @remarks
1908
2184
  * ERRORS are the structural violations no assumption can paper over: a manifest
@@ -1916,11 +2192,11 @@ import { Subject } from '@orkestrel/reason';
1916
2192
  *
1917
2193
  * @example
1918
2194
  * ```ts
1919
- * import { brief, proof, task, validateBrief } from '@orkestrel/brief'
2195
+ * import { buildBrief, buildProof, buildTask, validateBrief } from '@orkestrel/brief'
1920
2196
  *
1921
- * validateBrief(brief(task('plan', 'ops', 'Plan the release.'))) // valid: false — no proofs
2197
+ * validateBrief(buildBrief(buildTask('plan', 'ops', 'Plan the release.'))) // valid: false — no proofs
1922
2198
  * validateBrief(
1923
- * brief(task('plan', 'ops', 'Plan the release.'), { proofs: [proof('ok', 'npm test')] }),
2199
+ * buildBrief(buildTask('plan', 'ops', 'Plan the release.'), { proofs: [buildProof('ok', 'npm test')] }),
1924
2200
  * ) // valid: true
1925
2201
  * ```
1926
2202
  */