bareloop 0.40.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +96 -1
  2. package/README.md +13 -21
  3. package/bareloop.context.md +141 -128
  4. package/package.json +5 -4
  5. package/src/authorflow.js +346 -38
  6. package/src/authoring.js +92 -7
  7. package/src/authorjob.js +82 -20
  8. package/src/authorreadout.js +89 -5
  9. package/src/authorrun.js +39 -30
  10. package/src/authorscout.js +112 -4
  11. package/src/bundle.js +7 -4
  12. package/src/bundlerun.js +4 -1
  13. package/src/cli.js +1 -1
  14. package/src/config.js +129 -29
  15. package/src/declaredclose.js +23 -12
  16. package/src/draftspend.js +4 -4
  17. package/src/facts.js +317 -0
  18. package/src/factwords.js +129 -0
  19. package/src/index.js +2 -4
  20. package/src/inputlook.js +301 -0
  21. package/src/interviewrun.js +17 -25
  22. package/src/job.js +15 -8
  23. package/src/jobblock.js +7 -2
  24. package/src/judged.js +11 -43
  25. package/src/keysfile.js +15 -7
  26. package/src/kinds.js +86 -5
  27. package/src/labelscan.js +170 -0
  28. package/src/modellist.js +84 -0
  29. package/src/monthly.js +23 -43
  30. package/src/pagefetch.js +125 -0
  31. package/src/panel/authorroutes.js +34 -16
  32. package/src/panel/authorsession.js +161 -80
  33. package/src/panel/index.html +553 -152
  34. package/src/panel/jobplan.js +34 -11
  35. package/src/panel/runroutes.js +3 -0
  36. package/src/panel/server.js +54 -18
  37. package/src/panel/settingsroutes.js +232 -173
  38. package/src/planrun.js +5 -4
  39. package/src/providerrows.js +226 -141
  40. package/src/providers.js +58 -332
  41. package/src/providershapes.js +18 -0
  42. package/src/replay.js +1 -1
  43. package/src/rubricstep.js +804 -0
  44. package/src/source.js +166 -1
  45. package/src/thinking.js +130 -0
  46. package/src/u-readout.js +1 -1
  47. package/src/userrun.js +64 -75
  48. package/types/authorflow.d.ts +272 -18
  49. package/types/authoring.d.ts +29 -1
  50. package/types/authorjob.d.ts +9 -7
  51. package/types/authorreadout.d.ts +27 -2
  52. package/types/authorscout.d.ts +72 -2
  53. package/types/config.d.ts +23 -6
  54. package/types/declaredclose.d.ts +4 -2
  55. package/types/draftspend.d.ts +8 -8
  56. package/types/facts.d.ts +71 -0
  57. package/types/factwords.d.ts +42 -0
  58. package/types/index.d.ts +1 -1
  59. package/types/inputlook.d.ts +238 -0
  60. package/types/job.d.ts +5 -5
  61. package/types/jobblock.d.ts +8 -1
  62. package/types/judged.d.ts +5 -36
  63. package/types/keysfile.d.ts +15 -4
  64. package/types/labelscan.d.ts +38 -0
  65. package/types/modellist.d.ts +50 -0
  66. package/types/monthly.d.ts +4 -3
  67. package/types/pagefetch.d.ts +71 -0
  68. package/types/panel/authorsession.d.ts +20 -11
  69. package/types/panel/jobplan.d.ts +12 -4
  70. package/types/panel/server.d.ts +18 -6
  71. package/types/providerrows.d.ts +192 -99
  72. package/types/providers.d.ts +34 -159
  73. package/types/providershapes.d.ts +10 -0
  74. package/types/rubricstep.d.ts +286 -0
  75. package/types/source.d.ts +94 -0
  76. package/types/thinking.d.ts +90 -0
  77. package/types/userrun.d.ts +17 -1
@@ -63,13 +63,16 @@ export function labelsFor(verdictType: string): Record<string | number, string>;
63
63
  * close — one source, never a second hand-typed list — rendered through the
64
64
  * frozen line in {@link GUARD_DESCRIPTIONS}, plus the write fence (a real,
65
65
  * signed fence — {@link writeScopeBlock}'s own subject) when one is set.
66
- * @param {{verdictType: string, lang: string, writeScope?: string[]|null}} o
66
+ * @param {{verdictType: string, lang: string, writeScope?: string[]|null, jobLines?: {n: number}[]|null}} o
67
67
  * @returns {string[]}
68
68
  */
69
- export function confirmProtections({ verdictType, lang, writeScope }: {
69
+ export function confirmProtections({ verdictType, lang, writeScope, jobLines }: {
70
70
  verdictType: string;
71
71
  lang: string;
72
72
  writeScope?: string[] | null;
73
+ jobLines?: {
74
+ n: number;
75
+ }[] | null;
73
76
  }): string[];
74
77
  /**
75
78
  * The mechanical seam between the catalogue and the schema, read BOTH ways: a
@@ -107,12 +110,15 @@ export function schemaCoverage(catalogue?: Record<string, any>): {
107
110
  * and failing loudly beats emitting a schema that quietly cannot say something
108
111
  * the validator will then demand.
109
112
  * `questions` (P7 item 5, last drafting try only) adds the optional `questions` property; absent, the schema is byte-identical.
113
+ * `kinds` (Part 1a) narrows the branches to the kinds a language may use (`catalogueForLang`) WITHOUT narrowing the coverage check,
114
+ * which stays over the whole catalogue; null (the default) = no narrowing.
110
115
  * @param {Record<string, any>} [catalogue]
111
- * @param {{verdictType?: string|null, questions?: boolean}} [o]
116
+ * @param {{verdictType?: string|null, questions?: boolean, kinds?: string[]|null}} [o]
112
117
  */
113
- export function declarationSchema(catalogue?: Record<string, any>, { verdictType, questions }?: {
118
+ export function declarationSchema(catalogue?: Record<string, any>, { verdictType, questions, kinds }?: {
114
119
  verdictType?: string | null;
115
120
  questions?: boolean;
121
+ kinds?: string[] | null;
116
122
  }): {
117
123
  type: string;
118
124
  properties: {
@@ -192,6 +198,11 @@ export function declarationSchema(catalogue?: Record<string, any>, { verdictType
192
198
  minimum: number;
193
199
  description: string;
194
200
  };
201
+ rule: {
202
+ type: string;
203
+ minimum: number;
204
+ description: string;
205
+ };
195
206
  reason: {
196
207
  type: string;
197
208
  minLength: number;
@@ -211,14 +222,15 @@ export function declarationSchema(catalogue?: Record<string, any>, { verdictType
211
222
  * The output channel. It records and acknowledges; it takes no action, which is
212
223
  * why handing it to a toolless authoring call does not reopen D3.
213
224
  * @param {{calls: any[]}} box
214
- * @param {{catalogue?: Record<string, any>, verdictType?: string|null, questions?: boolean}} [o]
225
+ * @param {{catalogue?: Record<string, any>, verdictType?: string|null, questions?: boolean, kinds?: string[]|null}} [o]
215
226
  */
216
227
  export function declarationTool(box: {
217
228
  calls: any[];
218
- }, { catalogue, verdictType, questions }?: {
229
+ }, { catalogue, verdictType, questions, kinds }?: {
219
230
  catalogue?: Record<string, any>;
220
231
  verdictType?: string | null;
221
232
  questions?: boolean;
233
+ kinds?: string[] | null;
222
234
  }): {
223
235
  name: string;
224
236
  description: string;
@@ -301,6 +313,11 @@ export function declarationTool(box: {
301
313
  minimum: number;
302
314
  description: string;
303
315
  };
316
+ rule: {
317
+ type: string;
318
+ minimum: number;
319
+ description: string;
320
+ };
304
321
  reason: {
305
322
  type: string;
306
323
  minLength: number;
@@ -400,6 +417,7 @@ export function writeScopeBlock(writeScope: string[]): string;
400
417
  * never merge.
401
418
  * @param {{checks: string[], checkItems?: {text: string, fromLine: number[]|null}[], protections: string[], openQuestions?: string[], notChecked?: string[],
402
419
  * answeredQuestions?: string[]}} confirmed
420
+ * @param {{numbered?: boolean}} [o] `numbered` (a rubric job on files): each confirmed check carries its `#n`, which a part cites in `covers`
403
421
  */
404
422
  export function confirmedBlock(confirmed: {
405
423
  checks: string[];
@@ -411,6 +429,8 @@ export function confirmedBlock(confirmed: {
411
429
  openQuestions?: string[];
412
430
  notChecked?: string[];
413
431
  answeredQuestions?: string[];
432
+ }, { numbered }?: {
433
+ numbered?: boolean;
414
434
  }): string;
415
435
  /**
416
436
  * P7: the job-line tagging order (model-facing, registered). Rule 1 of the job block: every stage the drafter writes
@@ -439,12 +459,14 @@ export function jobLineTagBlock(count: number): string;
439
459
  * @param {{answers: Record<string|number, string>, questions?: Record<string|number, string>,
440
460
  * facts: any, listingBlock: string, lang: string, verdictType: string,
441
461
  * guards: {name: string, kind: string, params: Record<string, any>, fill: string[]}[],
442
- * ownedEnvNames?: string[], mode?: 'tool'|'text', catalogue?: Record<string, any>,
462
+ * ownedEnvNames?: string[], mode?: 'tool'|'text', catalogue?: Record<string, any>|null,
443
463
  * writeScope?: string[]|null,
444
464
  * jobLines?: {n: number}[]|null, inputs?: {n: number, label: string, value: string}[]|null,
445
- * confirmed?: {checks: string[], checkItems?: {text: string, fromLine: number[]|null}[], protections: string[], openQuestions?: string[], notChecked?: string[], answeredQuestions?: string[]}|null}} o
465
+ * confirmed?: {checks: string[], checkItems?: {text: string, fromLine: number[]|null}[], protections: string[], openQuestions?: string[], notChecked?: string[], answeredQuestions?: string[]}|null,
466
+ * labelLists?: string[]|null,
467
+ * }} o
446
468
  */
447
- export function authorPrompt({ answers, questions, facts, listingBlock, lang, verdictType, guards, ownedEnvNames, mode, catalogue, writeScope, jobLines, inputs, confirmed, }: {
469
+ export function authorPrompt({ answers, questions, facts, listingBlock, lang, verdictType, guards, ownedEnvNames, mode, catalogue: catalogueIn, writeScope, jobLines, inputs, confirmed, labelLists, }: {
448
470
  answers: Record<string | number, string>;
449
471
  questions?: Record<string | number, string>;
450
472
  facts: any;
@@ -459,7 +481,7 @@ export function authorPrompt({ answers, questions, facts, listingBlock, lang, ve
459
481
  }[];
460
482
  ownedEnvNames?: string[];
461
483
  mode?: "tool" | "text";
462
- catalogue?: Record<string, any>;
484
+ catalogue?: Record<string, any> | null;
463
485
  writeScope?: string[] | null;
464
486
  jobLines?: {
465
487
  n: number;
@@ -480,6 +502,45 @@ export function authorPrompt({ answers, questions, facts, listingBlock, lang, ve
480
502
  notChecked?: string[];
481
503
  answeredQuestions?: string[];
482
504
  } | null;
505
+ labelLists?: string[] | null;
506
+ }): string;
507
+ /**
508
+ * The composer prompt for a rubric job on local files (Part 1a, docs/product/ITEM33-BUILD.md). There is no repository
509
+ * and no survey: the facts are the numbered inputs and the listing is the frozen tree (input/ files, output/). It states
510
+ * the step-file contract the worker is also told ({@link stepFileContract}), so the stage and the file cannot drift.
511
+ * @param {{answers: Record<string|number, string>, questions?: Record<string|number, string>, facts: any, listingBlock: string,
512
+ * verdictType: string, guards: {name: string, kind: string, params: Record<string, any>, fill: string[]}[],
513
+ * mode?: 'tool'|'text', catalogue?: Record<string, any>, writeScope?: string[]|null,
514
+ * jobLines?: {n: number}[]|null, inputs?: {n: number, label: string, value: string}[]|null, confirmed?: any,
515
+ * labelLists?: string[]|null,
516
+ * }} o
517
+ * @returns {string}
518
+ */
519
+ export function rubricAuthorPrompt({ answers, questions, facts, listingBlock, verdictType, guards, mode, catalogue, writeScope, jobLines, inputs, confirmed, labelLists, }: {
520
+ answers: Record<string | number, string>;
521
+ questions?: Record<string | number, string>;
522
+ facts: any;
523
+ listingBlock: string;
524
+ verdictType: string;
525
+ guards: {
526
+ name: string;
527
+ kind: string;
528
+ params: Record<string, any>;
529
+ fill: string[];
530
+ }[];
531
+ mode?: "tool" | "text";
532
+ catalogue?: Record<string, any>;
533
+ writeScope?: string[] | null;
534
+ jobLines?: {
535
+ n: number;
536
+ }[] | null;
537
+ inputs?: {
538
+ n: number;
539
+ label: string;
540
+ value: string;
541
+ }[] | null;
542
+ confirmed?: any;
543
+ labelLists?: string[] | null;
483
544
  }): string;
484
545
  /**
485
546
  * The seed read, as the model sees it: mechanical labels, no editorial. Per-stage
@@ -619,7 +680,7 @@ export function resolveSourcePrefixes({ workdir, sourcePaths, seedFiles }: {
619
680
  */
620
681
  /**
621
682
  * @param {{ceilingUsd?: number|null,
622
- * onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingApplied?: boolean|null}) => void}} [o]
683
+ * onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingStatus?: string}) => void}} [o]
623
684
  * `ceilingUsd` is the OPERATOR's ceiling; `null`/absent is UNBOUNDED.
624
685
  * `onCall` is a REPORTING seam fired as each metered call lands — the shell's
625
686
  * only chance to know what has been spent while the run is still alive. It is
@@ -635,7 +696,7 @@ export function makeCostBook({ ceilingUsd, onCall }?: {
635
696
  label: string;
636
697
  costUsd: number | null;
637
698
  unpricedRounds: number;
638
- thinkingApplied?: boolean | null;
699
+ thinkingStatus?: string;
639
700
  }) => void;
640
701
  }): {
641
702
  /** @param {string} label @param {any} r a bare-agent run result @param {number} [attempt] */
@@ -700,7 +761,7 @@ export function makeCostBook({ ceilingUsd, onCall }?: {
700
761
  * `cacheMessages` (F18) and `maxTokens` (F30) are not optional on this stack.
701
762
  * `rates` is the customer's own price for this provider's key row (USD per 1K, `ratesFor`);
702
763
  * absent = bare-agent's built-in guess, exactly as before.
703
- * `draftThinking` ('on' | 'off', operator knob; default 'off') adds the drafter's per-call thinking option via `draftCallOptions`.
764
+ * `draftThinking` ('on' | 'off', the job's "Thinking on" tick spelled as a word; default 'off') adds the drafter's per-call thinking option via `thinkingCallOptions` (src/thinking.js, the one owner).
704
765
  * @param {any} provider @param {{system?: string, maxTokens?: number, rates?: {in: number, out: number}|null, draftThinking?: string}} [o]
705
766
  * @returns {(messages: any[], tools: any[], opts?: any) => Promise<any>}
706
767
  */
@@ -836,7 +897,8 @@ export function confirmPrompt({ answers, questions, labels, facts, listing, writ
836
897
  * generate: Function, book: ReturnType<typeof makeCostBook>,
837
898
  * ask: (step: {kind: string, [k: string]: any}) => Promise<string|null>,
838
899
  * onPhase?: (phase: string, data?: any) => void, mode?: 'tool'|'text',
839
- * worseThanBefore?: string, inputs?: {n: number, label: string, value: string}[]|null}} o retired field (hamr's ruling 2026-09-28):
900
+ * worseThanBefore?: string, inputs?: {n: number, label: string, value: string}[]|null,
901
+ * jobLines?: {n: number}[]|null}} o retired field (hamr's ruling 2026-09-28):
840
902
  * `worseThanBefore` is never asked any more and defaults to `''` — a
841
903
  * caller may still pass a string through (kept for a future, non-ask
842
904
  * source of the same constraint), it just never comes from an ask() step.
@@ -847,7 +909,7 @@ export function confirmPrompt({ answers, questions, labels, facts, listing, writ
847
909
  * worseThanBefore: string, openQuestions: string[], notChecked: string[], answeredQuestions?: string[]}|null,
848
910
  * reds: Red[], cost: any}>}
849
911
  */
850
- export function runConfirmTurn({ verdictType, answers, questions, labels, facts, listing, writeScope, isRepo, lang, generate, book, ask, onPhase, mode, worseThanBefore: presetWorseThanBefore, inputs, }: {
912
+ export function runConfirmTurn({ verdictType, answers, questions, labels, facts, listing, writeScope, isRepo, lang, generate, book, ask, onPhase, mode, worseThanBefore: presetWorseThanBefore, inputs, jobLines, }: {
851
913
  verdictType: string;
852
914
  answers: Record<string | number, string>;
853
915
  questions: Record<string | number, string>;
@@ -875,6 +937,9 @@ export function runConfirmTurn({ verdictType, answers, questions, labels, facts,
875
937
  label: string;
876
938
  value: string;
877
939
  }[] | null;
940
+ jobLines?: {
941
+ n: number;
942
+ }[] | null;
878
943
  }): Promise<{
879
944
  ok: boolean;
880
945
  stop: null | "cap-halt" | "pricing-red" | "provider-red" | "artifact-red" | "confirm-abandoned" | "confirm-restart";
@@ -936,7 +1001,7 @@ export function runConfirmTurn({ verdictType, answers, questions, labels, facts,
936
1001
  * generate: Function, seedReadFn?: Function, closeCtx?: any,
937
1002
  * ceilingUsd?: number|null,
938
1003
  * onPhase?: (phase: string, data?: any) => void,
939
- * onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingApplied?: boolean|null}) => void,
1004
+ * onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingStatus?: string}) => void,
940
1005
  * maxRevisions?: number, structureRetries?: number,
941
1006
  * structuredMode?: 'tool'|'text', catalogue?: Record<string, any>, writeScope?: string[]|null,
942
1007
  * priorCalls?: {label: string, costUsd: number|null, unpricedRounds: number}[]|null,
@@ -945,7 +1010,7 @@ export function runConfirmTurn({ verdictType, answers, questions, labels, facts,
945
1010
  * offerQuestions?: boolean,
946
1011
  * confirmed?: {checks: string[], checkItems?: {text: string, fromLine: number[]|null}[], protections: string[], openQuestions?: string[], notChecked?: string[], answeredQuestions?: string[]}|null}} o
947
1012
  */
948
- export function authorClose({ workdir, seedRef, lang, verdictType, answers, questions, writeScope, scout, listing, priorCalls, priorRaws, confirmed, jobLines, inputs, generate, seedReadFn, closeCtx, ceilingUsd, onPhase, onCall, maxRevisions, structureRetries, structuredMode, catalogue, offerQuestions, }: {
1013
+ export function authorClose({ workdir, seedRef, lang, verdictType, answers, questions, writeScope, scout, listing, priorCalls, priorRaws, confirmed, jobLines, inputs, generate, seedReadFn, closeCtx, ceilingUsd, onPhase, onCall, maxRevisions, structureRetries, structuredMode, catalogue: catalogueIn, offerQuestions, }: {
949
1014
  workdir: string;
950
1015
  seedRef: string;
951
1016
  lang: string;
@@ -976,7 +1041,7 @@ export function authorClose({ workdir, seedRef, lang, verdictType, answers, ques
976
1041
  label: string;
977
1042
  costUsd: number | null;
978
1043
  unpricedRounds: number;
979
- thinkingApplied?: boolean | null;
1044
+ thinkingStatus?: string;
980
1045
  }) => void;
981
1046
  maxRevisions?: number;
982
1047
  structureRetries?: number;
@@ -1522,12 +1587,195 @@ export const PARAM_SCHEMAS: Readonly<{
1522
1587
  };
1523
1588
  description: string;
1524
1589
  };
1590
+ step: {
1591
+ type: string;
1592
+ minimum: number;
1593
+ description: string;
1594
+ };
1595
+ parts: {
1596
+ type: string;
1597
+ description: string;
1598
+ items: {
1599
+ type: string;
1600
+ properties: {
1601
+ text: {
1602
+ type: string;
1603
+ minLength: number;
1604
+ description: string;
1605
+ };
1606
+ class: {
1607
+ enum: string[];
1608
+ };
1609
+ check: {
1610
+ enum: string[];
1611
+ description: string;
1612
+ };
1613
+ value: {
1614
+ type: string;
1615
+ minimum: number;
1616
+ description: string;
1617
+ };
1618
+ names: {
1619
+ type: string;
1620
+ minItems: number;
1621
+ items: {
1622
+ type: string;
1623
+ minLength: number;
1624
+ };
1625
+ description: string;
1626
+ };
1627
+ wordsPerSection: {
1628
+ type: string;
1629
+ minimum: number;
1630
+ };
1631
+ source: {
1632
+ type: string;
1633
+ minLength: number;
1634
+ description: string;
1635
+ };
1636
+ domains: {
1637
+ type: string;
1638
+ minItems: number;
1639
+ items: {
1640
+ type: string;
1641
+ minLength: number;
1642
+ };
1643
+ description: string;
1644
+ };
1645
+ covers: {
1646
+ type: string;
1647
+ minItems: number;
1648
+ uniqueItems: boolean;
1649
+ items: {
1650
+ type: string;
1651
+ minimum: number;
1652
+ };
1653
+ description: string;
1654
+ };
1655
+ rules: {
1656
+ type: string;
1657
+ minItems: number;
1658
+ uniqueItems: boolean;
1659
+ items: {
1660
+ type: string;
1661
+ minimum: number;
1662
+ };
1663
+ description: string;
1664
+ };
1665
+ facts: {
1666
+ type: string;
1667
+ minItems: number;
1668
+ maxItems: number;
1669
+ description: string;
1670
+ items: {
1671
+ type: string;
1672
+ properties: {
1673
+ name: {
1674
+ type: string;
1675
+ minLength: number;
1676
+ description: string;
1677
+ };
1678
+ shape: {
1679
+ enum: string[];
1680
+ description: string;
1681
+ };
1682
+ unit: {
1683
+ type: string;
1684
+ minLength: number;
1685
+ description: string;
1686
+ };
1687
+ currency: {
1688
+ enum: string[];
1689
+ description: string;
1690
+ };
1691
+ phrase: {
1692
+ type: string;
1693
+ minLength: number;
1694
+ description: string;
1695
+ };
1696
+ anchor: {
1697
+ type: string;
1698
+ minLength: number;
1699
+ description: string;
1700
+ };
1701
+ until: {
1702
+ type: string;
1703
+ minLength: number;
1704
+ description: string;
1705
+ };
1706
+ rule: {
1707
+ type: string;
1708
+ description: string;
1709
+ properties: {
1710
+ op: {
1711
+ enum: string[];
1712
+ };
1713
+ value: {
1714
+ type: string[];
1715
+ description: string;
1716
+ };
1717
+ lo: {
1718
+ type: string[];
1719
+ };
1720
+ hi: {
1721
+ type: string[];
1722
+ };
1723
+ };
1724
+ required: string[];
1725
+ additionalProperties: boolean;
1726
+ };
1727
+ aiProposal: {
1728
+ type: string;
1729
+ description: string;
1730
+ };
1731
+ };
1732
+ required: string[];
1733
+ additionalProperties: boolean;
1734
+ };
1735
+ };
1736
+ count: {
1737
+ type: string;
1738
+ description: string;
1739
+ properties: {
1740
+ min: {
1741
+ type: string;
1742
+ minimum: number;
1743
+ };
1744
+ max: {
1745
+ type: string;
1746
+ minimum: number;
1747
+ };
1748
+ };
1749
+ additionalProperties: boolean;
1750
+ };
1751
+ };
1752
+ required: string[];
1753
+ additionalProperties: boolean;
1754
+ };
1755
+ };
1525
1756
  ask: {
1526
1757
  type: string;
1527
1758
  minLength: number;
1528
1759
  description: string;
1529
1760
  };
1530
1761
  }>;
1762
+ /**
1763
+ * What a rubric job on local files means by DONE — the class statement of the text genre (Part 1a). It is stated as an order
1764
+ * about KINDS: every part of a job line is counted or checked against a quote, because nothing in this build judges.
1765
+ */
1766
+ export const RUBRIC_FILES_STATEMENT: string;
1767
+ /**
1768
+ * THE RUBRIC RULES, in one place (live fix B1): what the confirm step and the drafter are both told about turning the person's words
1769
+ * into checks. The confirm note ({@link RUBRIC_CONFIRM_NOTE}) and the composer brief ({@link REQUIRED_FACTS_BRIEF}) interpolate THIS
1770
+ * constant, so the two cannot drift (in smv6k6l8dxkzs the confirm step planned a limit the drafter then could not carry, and the
1771
+ * drafter added an airport code the person never wrote). Field-neutral: neither turn needs the other's field names.
1772
+ */
1773
+ export const RUBRIC_RULES: string;
1774
+ /**
1775
+ * REQUIRED FACTS, as the composer is told them (PART 1b, PRD item 33 RF1–RF17). The shape of the fact part is in the catalogue and the
1776
+ * schema; this is the judgement the schema cannot carry: what becomes a fact, where its words come from, and what is Not checked.
1777
+ */
1778
+ export const REQUIRED_FACTS_BRIEF: string;
1531
1779
  export const CONFIRM_TOOL_NAME: "confirm_plan";
1532
1780
  /** Acknowledgement text the confirm tool's `execute` returns — mirrors
1533
1781
  * {@link DECLARATION_ACK}'s role: an output channel that records and
@@ -1545,6 +1793,12 @@ export const CONFIRM_STRUCTURE_INSTRUCTION: string;
1545
1793
  * an ORDER to the model itself, the same register {@link AUTHOR_SYSTEM} and
1546
1794
  * {@link CLASS_STATEMENTS} already use, rather than a code matcher over prose.
1547
1795
  */
1796
+ /**
1797
+ * What the confirm turn tells the model about a rubric job on local text files (model-facing, registered). There is no
1798
+ * repository and no judge: a check is a limit a machine counts (words, lines, sections), or a claim a quote from a named
1799
+ * input must back. Everything else the person asked for is named in `notChecked`, in their words.
1800
+ */
1801
+ export const RUBRIC_CONFIRM_NOTE: string;
1548
1802
  export const CONFIRM_SYSTEM: string;
1549
1803
  export type Red = {
1550
1804
  code: string;
@@ -64,6 +64,15 @@ export function classMenu(verdictType: string | null, catalogue?: Record<string,
64
64
  * @param {string} kind @param {Record<string, KindSpec>} [catalogue]
65
65
  */
66
66
  export function envCapableKind(kind: string, catalogue?: Record<string, KindSpec>): boolean;
67
+ /**
68
+ * The catalogue a close of this language may use. A rubric job on local files (`RUBRIC_LANG`) sees only
69
+ * {@link RUBRIC_LANG_KINDS}; every code language sees the whole catalogue MINUS the rubric-only kinds, so a code job's
70
+ * composer, schema and validator can never reach for a stage that reads step files. One filter, both directions.
71
+ * @param {string|null|undefined} lang
72
+ * @param {Record<string, KindSpec>} [catalogue]
73
+ * @returns {Record<string, KindSpec>}
74
+ */
75
+ export function catalogueForLang(lang: string | null | undefined, catalogue?: Record<string, KindSpec>): Record<string, KindSpec>;
67
76
  /**
68
77
  * The floor's decision for one declared `cmd`, as a reason or null.
69
78
  *
@@ -80,6 +89,8 @@ export function envCapableKind(kind: string, catalogue?: Record<string, KindSpec
80
89
  * @param {string} cmd @returns {string|null}
81
90
  */
82
91
  export function deniedCommandReason(cmd: string): string | null;
92
+ /** @param {unknown} lang @returns {string} the genre a close of this language is authored under */
93
+ export function genreForLang(lang: unknown): string;
83
94
  /**
84
95
  * The warning line for a job whose ACTUAL stages carry the js `any` pattern, else
85
96
  * ''. Derived from the stages' patterns (never goal prose), so a job without the
@@ -274,7 +285,8 @@ export function judgedOutsideFence(paths: unknown, writeScope: string[] | null |
274
285
  * @param {{catalogue?: Record<string, KindSpec>, listing?: string[]|null,
275
286
  * guards?: {name: string, kind: string, params: Record<string, any>, fill: string[]}[]|null,
276
287
  * envOwned?: string[]|null, envInjected?: Record<string, string>|null, deferListing?: boolean,
277
- * verdictType?: string|null, writeScope?: string[]|null, jobLines?: {n: number}[]|null}} [opts]
288
+ * verdictType?: string|null, writeScope?: string[]|null, jobLines?: {n: number}[]|null, inputLabels?: string[]|null}} [opts]
289
+ * `inputLabels` — the labels of the person's inputs (Part 1a). Present, a rubric-step `cited` part must name one of them.
278
290
  * `jobLines` — the person's numbered job lines (P7). Present, every stage must name the line it serves and every
279
291
  * line needs a stage or a refusal ({@link checkJobLines}); absent (every spec that predates the job block), the
280
292
  * rule is not run.
@@ -310,6 +322,7 @@ export function validateDeclaration(declaration: any, opts?: {
310
322
  jobLines?: {
311
323
  n: number;
312
324
  }[] | null;
325
+ inputLabels?: string[] | null;
313
326
  }): {
314
327
  ok: boolean;
315
328
  reds: Red[];
@@ -482,6 +495,21 @@ export const DENIED_COMMANDS: readonly string[];
482
495
  */
483
496
  export const TYPES_GENRE_TEMPLATE: "1. The STRICT form of the language's type checker is used only when a confirmed check \u2014 or,\n absent a confirm turn, the goal and interview answers \u2014 asks for strict typing; otherwise the\n checker runs at whatever strictness the repo's own scripts already use.\n2. Tools are invoked so their binaries actually resolve \u2014 through the project's own package\n runner or language module runner, never a bare binary name.\n3. The WORK stages \u2014 typecheck (error count IN the target scope, baseline 0, lower-is-better),\n typecheck-outside (error count OUTSIDE the target scope, baseline measured at seed, a\n ceiling \u2014 required whenever a typecheck stage is scoped to a subset of the tree), tests-kept\n (a floor on tests that actually EXECUTED, baseline at seed, higher-is-better; a skipped or\n deselected test did not run and must not count), and suite-green (the suite exits clean AND\n reports zero failing tests \u2014 two assertions) \u2014 are composed ONLY for the checks a confirmed\n plan asked for (or, absent a confirm turn, the goal and interview answers). The GUARDS \u2014\n changed-from-seed and no-suppressions \u2014 are composed always, first-red-wins:\n changed-from-seed before every WORK stage, no-suppressions last.\n4. One population per stage \u2014 two structurally different counts never share a stage.\n5. The checker must judge the PATIENT's own tree: if imports could resolve to an installed or\n editable copy elsewhere, the environment is set so they resolve inside the patient.\n6. A number the tool did not report is unknown, never zero.";
484
497
  export const GENRE_LANGUAGES: readonly string[];
498
+ /**
499
+ * PART 1a: the "language" of a RUBRIC job on local text files. It is not a code language and carries no suppression
500
+ * battery, no environment and no instruments — it only lets such a close declare which genre-shaped guards apply to it
501
+ * (`classGuards`) without pretending the file is JavaScript. `GENRE_LANGUAGES` stays the code-language menu (it is what a
502
+ * repo job's language detection and the confirm turn offer); this is the one extra value a close may DECLARE.
503
+ */
504
+ export const RUBRIC_LANG: "text";
505
+ /** the genre label a close over local text files carries (`closeDecl.genre`); the code languages' is `TYPES_GENRE.name`. Never the other's. */
506
+ export const TEXT_GENRE: "TEXT";
507
+ /** every `closeDecl.lang` a close may declare: the code languages plus the rubric-files one */
508
+ export const DECLARABLE_LANGUAGES: readonly string[];
509
+ /** the kinds that exist only for a rubric job on local files — a code job's menu, schema and validator never offer them */
510
+ export const RUBRIC_ONLY_KINDS: readonly string[];
511
+ /** the whole kind menu of a rubric job on local files: the one machine guard that applies to a file tree, plus its own stage */
512
+ export const RUBRIC_LANG_KINDS: readonly string[];
485
513
  /** The worker-facing line that rides with the js `any` guard (run mv13ery3). */
486
514
  export const ANY_SUPPRESSION_WARNING: string;
487
515
  /**
@@ -30,18 +30,19 @@ export function refusalEvents(refusal: Refusal): {
30
30
  * makes between a locked verdict and an invalid one).
31
31
  *
32
32
  * @param {{answers: Record<string|number, any>, verdictType?: string|null,
33
- * repoPath?: string|null, questions?: Record<string|number, string>|null}} o
34
- * `verdictType` and `repoPath` are STRUCTURED input from the UI, never parsed
33
+ * repoPath?: string|null, questions?: Record<string|number, string>|null, required?: (string|number)[]|null}} o
34
+ * `required` — the answer keys that must be present; absent = the picked class's whole set. `verdictType` and `repoPath` are STRUCTURED input from the UI, never parsed
35
35
  * out of the prose of an answer: a class is picked off a radio and a path is
36
36
  * read off the machine, or neither exists.
37
37
  * @returns {{ok: boolean, answers: Record<string|number, string>,
38
38
  * verdictType: string|null, repoPath: string|null, refusal: Refusal|null, reds: Red[]}}
39
39
  */
40
- export function runInterview({ answers, verdictType, repoPath, questions }: {
40
+ export function runInterview({ answers, verdictType, repoPath, questions, required: requiredOverride }: {
41
41
  answers: Record<string | number, any>;
42
42
  verdictType?: string | null;
43
43
  repoPath?: string | null;
44
44
  questions?: Record<string | number, string> | null;
45
+ required?: (string | number)[] | null;
45
46
  }): {
46
47
  ok: boolean;
47
48
  answers: Record<string | number, string>;
@@ -85,8 +86,8 @@ export function refuseLockedKind(kind: string): Refusal;
85
86
  * seedRef?: string|null, scout?: any, listing?: any, ceilingUsd?: number|null, judgeModel?: string|null,
86
87
  * rates?: {in: number, out: number}|null, draftThinking?: 'on'|'off',
87
88
  * onPhase?: (phase: string, data?: any) => void,
88
- * onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingApplied?: boolean|null}) => void,
89
- * seedFn?: Function, scoutFn?: Function, listingFn?: Function,
89
+ * onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingStatus?: string}) => void,
90
+ * seedFn?: Function, scoutFn?: Function, listingFn?: Function, lookFn?: Function|null,
90
91
  * authorFn?: Function, authorOpts?: object, writeScope?: string[]|null,
91
92
  * signerFix?: Function|any, proposeFn?: Function, compileOpts?: object,
92
93
  * ask?: ((step: {kind: string, [k: string]: any}) => Promise<string|null>)|null,
@@ -98,7 +99,7 @@ export function refuseLockedKind(kind: string): Refusal;
98
99
  * closeDecl: any, seedRef: string|null, authoring: any, judged: any, reds: Red[],
99
100
  * stop: string|null, cost: any, interview: any, confirmed: any}>}
100
101
  */
101
- export function authorCloseForJob({ answers, repoPath, lang, verdictType, questions, jobLines, inputs, generate, provider, seedRef, scout, listing, ceilingUsd, rates, draftThinking, writeScope, judgeModel, onPhase, onCall, seedFn, scoutFn, listingFn, authorFn, authorOpts, signerFix, proposeFn, compileOpts, ask, confirmGenerate, isRepo, langResult, answerQuestions, }: {
102
+ export function authorCloseForJob({ answers, repoPath, lang, verdictType, questions, jobLines, inputs, generate, provider, seedRef, scout, listing, ceilingUsd, rates, draftThinking, writeScope, judgeModel, onPhase, onCall, seedFn, scoutFn, listingFn, lookFn, authorFn, authorOpts, signerFix, proposeFn, compileOpts, ask, confirmGenerate, isRepo, langResult, answerQuestions, }: {
102
103
  answers: Record<string | number, any>;
103
104
  repoPath?: string | null;
104
105
  lang: string;
@@ -130,11 +131,12 @@ export function authorCloseForJob({ answers, repoPath, lang, verdictType, questi
130
131
  label: string;
131
132
  costUsd: number | null;
132
133
  unpricedRounds: number;
133
- thinkingApplied?: boolean | null;
134
+ thinkingStatus?: string;
134
135
  }) => void;
135
136
  seedFn?: Function;
136
137
  scoutFn?: Function;
137
138
  listingFn?: Function;
139
+ lookFn?: Function | null;
138
140
  authorFn?: Function;
139
141
  authorOpts?: object;
140
142
  writeScope?: string[] | null;
@@ -199,6 +199,29 @@ export function plainKinds(): string[];
199
199
  export function plainReasons(reds: PlainRed[], { cases }?: {
200
200
  cases?: any;
201
201
  }): PlainReason[];
202
+ /**
203
+ * WHY one drafting try was refused, in the code's own words: the unique `detail` of each red it raised (the same sentences
204
+ * `draftStopText` quotes at a stop), else the plain `reason` the loop gave (a seed-read failure raises no red). Scrubbed,
205
+ * one line, bounded; never empty.
206
+ * @param {{reds?: PlainRed[]|null, reason?: string|null}} o
207
+ * @returns {string}
208
+ */
209
+ export function tryRefusedText({ reds, reason }: {
210
+ reds?: PlainRed[] | null;
211
+ reason?: string | null;
212
+ }): string;
213
+ /**
214
+ * A refused declaration as the drafting log keeps it (live fix A3), so a failed draft can be read and replayed at $0: the declaration
215
+ * itself, every secret masked as everywhere else (the JSON text goes through `redactSecrets`, then parses back), and bounded.
216
+ * @param {unknown} declaration
217
+ * @returns {{declaration: unknown}|{declarationText: string, declarationCut: true}|{}} nothing when there is no declaration
218
+ */
219
+ export function declarationRecord(declaration: unknown): {
220
+ declaration: unknown;
221
+ } | {
222
+ declarationText: string;
223
+ declarationCut: true;
224
+ } | {};
202
225
  /**
203
226
  * THE MESSAGE a person reads when the rubric proposal was refused. Both doors
204
227
  * (the panel's failed step and the CLI) print exactly this.
@@ -218,10 +241,11 @@ export function proposalStopText({ stop, reds, cases, spend, source }: {
218
241
  }): string;
219
242
  /**
220
243
  * @param {{stop: string, reds?: PlainRed[]|null, refusal?: {detail?: string}|null,
221
- * spend?: {knownUsd?: number|null, spendComplete?: boolean|null}|null}} o
244
+ * spend?: {knownUsd?: number|null, spendComplete?: boolean|null}|null, wholeJob?: boolean}} o `wholeJob` - a rubric job on the person's
245
+ * own inputs (PART 1c, I1): a failed draft asks nothing piecemeal; the person reviews the whole job and submits it again
222
246
  * @returns {string}
223
247
  */
224
- export function draftStopText({ stop, reds, refusal, spend }: {
248
+ export function draftStopText({ stop, reds, refusal, spend, wholeJob }: {
225
249
  stop: string;
226
250
  reds?: PlainRed[] | null;
227
251
  refusal?: {
@@ -231,6 +255,7 @@ export function draftStopText({ stop, reds, refusal, spend }: {
231
255
  knownUsd?: number | null;
232
256
  spendComplete?: boolean | null;
233
257
  } | null;
258
+ wholeJob?: boolean;
234
259
  }): string;
235
260
  /**
236
261
  * Plain sentences for the reds of a refused signing, one or more per red. Card and practice-case reds reuse the