bareloop 0.38.0 → 0.39.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.
@@ -80,6 +80,14 @@ export function envCapableKind(kind: string, catalogue?: Record<string, KindSpec
80
80
  * @param {string} cmd @returns {string|null}
81
81
  */
82
82
  export function deniedCommandReason(cmd: string): string | null;
83
+ /**
84
+ * The warning line for a job whose ACTUAL stages carry the js `any` pattern, else
85
+ * ''. Derived from the stages' patterns (never goal prose), so a job without the
86
+ * guard is told nothing about it.
87
+ * @param {any[]|null|undefined} stages
88
+ * @returns {string}
89
+ */
90
+ export function anySuppressionWarning(stages: any[] | null | undefined): string;
83
91
  /**
84
92
  * The picked class's mandatory guards, FULLY ENUMERATED (D13 forward-compat
85
93
  * point 3: an omittable-with-a-default field is the omitted-`tools` shape, where
@@ -219,6 +227,16 @@ export function ungroundedGenreEnv(lang: string, recorded: Record<string, string
219
227
  element: string;
220
228
  resolved: string;
221
229
  }[];
230
+ /**
231
+ * Which of a judged stage's paths lie OUTSIDE the job's write fence? One owner of the rule "a check must be
232
+ * free to edit every file it can report on", called from every door that validates a declaration. It uses
233
+ * the shipped fence spelling (`globToPrefix`, the same containment reading plan.js's `insideFence` has) and
234
+ * returns `[]` when there is no fence to compare against or the paths are not a string list (shape is the
235
+ * schema walk's business).
236
+ * @param {unknown} paths @param {string[]|null|undefined} writeScope
237
+ * @returns {string[]}
238
+ */
239
+ export function judgedOutsideFence(paths: unknown, writeScope: string[] | null | undefined): string[];
222
240
  /**
223
241
  * Validate an authored close DECLARATION. Never throws on model output — every
224
242
  * failure is a named red, in the shipped `{ok, reds, <parsed>}` shape, and the
@@ -256,7 +274,9 @@ export function ungroundedGenreEnv(lang: string, recorded: Record<string, string
256
274
  * @param {{catalogue?: Record<string, KindSpec>, listing?: string[]|null,
257
275
  * guards?: {name: string, kind: string, params: Record<string, any>, fill: string[]}[]|null,
258
276
  * envOwned?: string[]|null, envInjected?: Record<string, string>|null, deferListing?: boolean,
259
- * verdictType?: string|null}} [opts]
277
+ * verdictType?: string|null, writeScope?: string[]|null}} [opts]
278
+ * `writeScope` — the job's signed write fence. Every path a judged stage judges must sit inside it
279
+ * ({@link judgedOutsideFence}); absent, the rule is not run (the plain-folder deferral has no fence).
260
280
  * `listing` — repo-relative paths at the seed (`git ls-tree -r --name-only`).
261
281
  * `guards` — the picked class's injected guards (`classGuards`).
262
282
  * `verdictType` — the class the USER picked (`VERDICT_CLASSES`).
@@ -283,6 +303,7 @@ export function validateDeclaration(declaration: any, opts?: {
283
303
  envInjected?: Record<string, string> | null;
284
304
  deferListing?: boolean;
285
305
  verdictType?: string | null;
306
+ writeScope?: string[] | null;
286
307
  }): {
287
308
  ok: boolean;
288
309
  reds: Red[];
@@ -455,6 +476,8 @@ export const DENIED_COMMANDS: readonly string[];
455
476
  */
456
477
  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.";
457
478
  export const GENRE_LANGUAGES: readonly string[];
479
+ /** The worker-facing line that rides with the js `any` guard (run mv13ery3). */
480
+ export const ANY_SUPPRESSION_WARNING: string;
458
481
  /**
459
482
  * THE GENRE, as data. The suppression batteries are the hand-written closes'
460
483
  * own `SUPPRESSIONS` tables (`scripts/u-pulselog-close.mjs:35`,
@@ -185,6 +185,14 @@ export function assembleSpec(specDraft: any, { closeDecl, verdictType }: {
185
185
  closeDecl: any;
186
186
  verdictType: string;
187
187
  }): any;
188
+ /**
189
+ * THE one spelling of "a passed calibration gate stands in for the seed red": the
190
+ * close carries a judged stage AND the gate ran and passed. A failed or missing
191
+ * calibration never satisfies it, and a close with no judged stage never reaches it.
192
+ * @param {any[]} judged `judgedStages(closeDecl)` @param {any} calibration `gates.calibration`
193
+ * @returns {boolean}
194
+ */
195
+ export function seedProofIsCalibration(judged: any[], calibration: any): boolean;
188
196
  /**
189
197
  * D9, in code: *nothing JUDGES the close; three mechanical gates plus a
190
198
  * signature.* No LLM validates another LLM's close, here or anywhere.
@@ -206,16 +214,15 @@ export function assembleSpec(specDraft: any, { closeDecl, verdictType }: {
206
214
  * has already had its chance, and nobody pays to discover a broken
207
215
  * declaration.
208
216
  *
209
- * D9.3 AND THE JUDGED-ONLY CLOSE (2026-08-18 second addendum, ruling 3; hamr:
210
- * *"fix it now, we are delivering softgreen, isn't that the whole point?"*). Gate
211
- * 3 protects against a close that cannot fail — one that scans nothing and reads
212
- * green at seed against a true red. A judged stage SKIPS the seed read by ruling
213
- * 8, so a close whose only work stage is judged has no seed red to show and used
214
- * to be unsignable: the one job shape softgreen exists for. For that shape, and
215
- * ONLY that shape, a PASSED calibration gate plays the seed-red role — it is that
216
- * close's own proof of failability, held to the same all-or-nothing bar. A close
217
- * with a mechanical work stage is UNCHANGED: it still needs a seed red, whatever
218
- * its calibration says.
217
+ * D9.3 AND THE JUDGED CLOSE (2026-08-18 second addendum, ruling 3; hamr: *"fix it now,
218
+ * we are delivering softgreen, isn't that the whole point?"*; widened 2026-10-09 to mixed
219
+ * closes, hamr: *"a rubric job should check if judge can judge (calibration) and judge
220
+ * rules can apply properly to pass ... we can't close everything upfront"*). Gate 3
221
+ * protects against a close that cannot fail. A judged stage SKIPS the seed read by ruling
222
+ * 8, so it can never show red there. For ANY close carrying a judged stage (pure or
223
+ * mixed with mechanical stages), a PASSED calibration gate plays the seed-red role
224
+ * (`seedProofIsCalibration`). A close with NO judged stage is UNCHANGED: some work stage
225
+ * must be red at the seed. A failed or missing calibration never satisfies it.
219
226
  *
220
227
  * Gates 2 and 3 share ONE execution, and that is stated rather than hidden: at
221
228
  * job creation the tree IS the seed, so "does every stage run against the real
@@ -87,6 +87,20 @@ export function answeredQuestionLines(confirmed: {
87
87
  * @returns {string[]}
88
88
  */
89
89
  export function calibrationLines(calibration: any): string[];
90
+ /**
91
+ * The calibration gate's real result as one line a person reads next to the step (hamr, 2026-10-09: the panel
92
+ * showed `calibrating ✓` over a gate that graded 8 of 10 and let 2 attack styles leak). PASS IS THE GATE'S OWN:
93
+ * `ok` is `calibration.ok` as `runCalibration` decided it (every case right as a SET of reds, every style
94
+ * resisted), never recomputed here, so there is no second spelling of the floor. The counts are read from the
95
+ * record (`graded[].ok` is `compareExpectation`, which compares reds as sets); the denominators are the live
96
+ * constants (CALIBRATION_SIZE, the battery length), so a gate that stopped part-way reads "x of 10", not "x of x".
97
+ * @param {any} calibration `signing.gates.calibration`
98
+ * @returns {{ok: boolean, note: string}|null} null when the gate was not reached
99
+ */
100
+ export function calibrationSummary(calibration: any): {
101
+ ok: boolean;
102
+ note: string;
103
+ } | null;
90
104
  /**
91
105
  * THE AUTHORING CEILING, parsed from `--budget`. Housed here for the same reason
92
106
  * the readout above is: the runner is a script, and a rule no test can reach is a
@@ -169,4 +183,96 @@ export function crashRecord(err: unknown): {
169
183
  code: string | null;
170
184
  raw: ReturnType<typeof scrubRaw>;
171
185
  };
186
+ /**
187
+ * Every plain kind the table can emit — the list the test enumerates against.
188
+ * @returns {string[]}
189
+ */
190
+ export function plainKinds(): string[];
191
+ /**
192
+ * Map the technical reds of a refused proposal to plain sentences, one per red.
193
+ * An unknown code is NEVER dropped: it becomes a generic sentence that still
194
+ * quotes the code and path, under the kind `unmapped`.
195
+ * @param {PlainRed[]} reds
196
+ * @param {{cases?: any}} [o] the proposed cases, to name a case by its own id
197
+ * @returns {PlainReason[]}
198
+ */
199
+ export function plainReasons(reds: PlainRed[], { cases }?: {
200
+ cases?: any;
201
+ }): PlainReason[];
202
+ /**
203
+ * THE MESSAGE a person reads when the rubric proposal was refused. Both doors
204
+ * (the panel's failed step and the CLI) print exactly this.
205
+ * @param {{stop: string, reds: PlainRed[], cases?: any, spend?: {knownUsd?: number|null, spendComplete?: boolean|null}|null,
206
+ * source?: 'proposal'|'signer'}} o
207
+ * @returns {string}
208
+ */
209
+ export function proposalStopText({ stop, reds, cases, spend, source }: {
210
+ stop: string;
211
+ reds: PlainRed[];
212
+ cases?: any;
213
+ spend?: {
214
+ knownUsd?: number | null;
215
+ spendComplete?: boolean | null;
216
+ } | null;
217
+ source?: "proposal" | "signer";
218
+ }): string;
219
+ /**
220
+ * Plain sentences for the reds of a refused signing, one or more per red. Card and practice-case reds reuse the
221
+ * proposal table; an unknown code is a generic sentence that quotes the code.
222
+ * @param {PlainRed[]} reds @param {{cases?: any}} [o]
223
+ * @returns {{kind: string, sentence: string, todo: string, red: PlainRed}[]}
224
+ */
225
+ export function signingReasons(reds: PlainRed[], { cases }?: {
226
+ cases?: any;
227
+ }): {
228
+ kind: string;
229
+ sentence: string;
230
+ todo: string;
231
+ red: PlainRed;
232
+ }[];
233
+ /** every plain kind `signingReasons` can emit besides the proposal table's — what the test enumerates
234
+ * @returns {string[]} */
235
+ export function signingKinds(): string[];
236
+ /**
237
+ * THE MESSAGE a person reads when the signing gates refuse. The panel's failed step and the CLI print exactly this.
238
+ * @param {{reds: PlainRed[], refusal?: {detail?: string}|null, cases?: any,
239
+ * spend?: {knownUsd?: number|null, spendComplete?: boolean|null}|null}} o
240
+ * @returns {string}
241
+ */
242
+ export function signingStopText({ reds, refusal, cases, spend }: {
243
+ reds: PlainRed[];
244
+ refusal?: {
245
+ detail?: string;
246
+ } | null;
247
+ cases?: any;
248
+ spend?: {
249
+ knownUsd?: number | null;
250
+ spendComplete?: boolean | null;
251
+ } | null;
252
+ }): string;
253
+ /**
254
+ * The reds as the drafting log keeps them: every structured field, the plain
255
+ * sentence beside it, every string secret-scrubbed and bounded, the list capped.
256
+ * @param {PlainRed[]} reds @param {{cases?: any, signing?: boolean}} [o] `signing`: the reds are the signing gates', worded by signingReasons
257
+ * @returns {Record<string, any>[]}
258
+ */
259
+ export function redsRecord(reds: PlainRed[], { cases, signing }?: {
260
+ cases?: any;
261
+ signing?: boolean;
262
+ }): Record<string, any>[];
263
+ /** the stops this module explains in plain words */
264
+ export const PLAIN_PROPOSAL_STOPS: readonly string[];
265
+ /** codes the declaration gates (validateJob, validateCloseDecl) raise: one plain sentence covers the family */
266
+ export const DECLARATION_CODES: readonly string[];
267
+ export type PlainRed = {
268
+ code: string;
269
+ path: string;
270
+ detail: string;
271
+ [k: string]: any;
272
+ };
273
+ export type PlainReason = {
274
+ kind: string;
275
+ sentence: string;
276
+ red: PlainRed;
277
+ };
172
278
  import { scrubRaw } from './text.js';
@@ -90,7 +90,7 @@ export function factsResist(facts: any, gold: any, artifactText: string): {
90
90
  * onCost?: (c: any) => void, attempts?: number, battery?: any[], batteryCard?: any,
91
91
  * capStop?: () => 'cap-halt'|'pricing-red'|null}} o
92
92
  * @returns {Promise<{ok: boolean, stop: string|null, casualty: any,
93
- * graded: {id: string, ok: boolean, got: any, want: any, detail: string|null}[],
93
+ * graded: {id: string, ok: boolean, got: any, want: any, detail: string|null, diag: any}[],
94
94
  * injection: {styles: any[], allResisted: boolean, leaks: string[]},
95
95
  * failures: string[], reds: Red[], judgeModel: string,
96
96
  * cardHash: string|null, casesHash: string|null, setHash: string|null,
@@ -116,6 +116,7 @@ export function runCalibration({ cases, card, judgeLoop, judgeModel, onCost, att
116
116
  got: any;
117
117
  want: any;
118
118
  detail: string | null;
119
+ diag: any;
119
120
  }[];
120
121
  injection: {
121
122
  styles: any[];
@@ -190,6 +191,8 @@ ${string}`;
190
191
  }>[];
191
192
  }>;
192
193
  }>[];
194
+ /** the per-string cap on anything the diagnostic keeps (bytes, scrubbed) */
195
+ export const DIAG_STRING_CAP: 400;
193
196
  export type Red = {
194
197
  code: string;
195
198
  path: string;
@@ -53,7 +53,7 @@ export function declaredStages(closeDecl: any): any[] | null;
53
53
  *
54
54
  * @param {any} closeDecl
55
55
  * @param {{at?: string, listing?: string[]|null, deferListing?: boolean,
56
- * catalogue?: Record<string, any>, verdictType?: string|null}} [opts]
56
+ * catalogue?: Record<string, any>, verdictType?: string|null, writeScope?: string[]|null}} [opts]
57
57
  * @returns {{ok: boolean, reds: Red[], closeDecl: any, grounded: boolean,
58
58
  * scoped: {scoped: boolean, via: string|null},
59
59
  * ceiling: {class: string, kind: string, stage: string|null, locked: boolean}|null}}
@@ -64,6 +64,7 @@ export function validateCloseDecl(closeDecl: any, opts?: {
64
64
  deferListing?: boolean;
65
65
  catalogue?: Record<string, any>;
66
66
  verdictType?: string | null;
67
+ writeScope?: string[] | null;
67
68
  }): {
68
69
  ok: boolean;
69
70
  reds: Red[];
package/types/judged.d.ts CHANGED
@@ -97,6 +97,15 @@ export function resolveJobJudge(source: {
97
97
  provider: string;
98
98
  model: string;
99
99
  };
100
+ /**
101
+ * THE ONE ACCEPTANCE for "this quote points at the JSDoc block of this declaration":
102
+ * every non-empty line of `docQuote` is a line inside the block directly above the
103
+ * declaration. `has-doc`'s check and the calibration gate's injection facts check
104
+ * both call this, so the two can never disagree about what a good pointer is (F192).
105
+ * @param {string} text the artifact @param {string|null} declQuote @param {string} docQuote
106
+ * @returns {boolean}
107
+ */
108
+ export function docQuoteInBlock(text: string, declQuote: string | null, docQuote: string): boolean;
100
109
  /**
101
110
  * The rubric card: Q6's answer compiled into enumerated items, signed by the
102
111
  * person and enumerated in the spec hash. `rule` selects from `JUDGE_RULES`;
@@ -359,15 +368,25 @@ export const LOCATE_AXES: Readonly<{
359
368
  PROVIDER: "provider-red";
360
369
  ARTIFACT: "artifact-red";
361
370
  }>;
371
+ /**
372
+ * Function words ONLY: articles, prepositions, conjunctions. No judgement words
373
+ * ("returns", "gets", "function"): a description that adds one of those has added
374
+ * something, and deciding whether it is MEANINGFUL is exactly what this rule
375
+ * refuses to do.
376
+ */
377
+ export const SAYS_WHAT_STOPWORDS: readonly string[];
362
378
  /**
363
379
  * THE OWNED RULE TABLE. Frozen: the rulebook is the arbiter's, and a caller that
364
380
  * could add a rule at runtime would be authoring the arbiter.
365
- * @type {Readonly<Record<string, {id: string, ask: string, check: (fn: any, lines: Set<string>|null) => RuleRed[]}>>}
381
+ * `means` is the rule's plain-words reach: what it CAN check, and what it cannot. The case-proposal
382
+ * prompt renders it, so a proposed case never expects a red the rule cannot raise.
383
+ * @type {Readonly<Record<string, {id: string, means: string, ask: string, check: (fn: any, text: string|null) => RuleRed[]}>>}
366
384
  */
367
385
  export const JUDGE_RULES: Readonly<Record<string, {
368
386
  id: string;
387
+ means: string;
369
388
  ask: string;
370
- check: (fn: any, lines: Set<string> | null) => RuleRed[];
389
+ check: (fn: any, text: string | null) => RuleRed[];
371
390
  }>>;
372
391
  /** the enumerated set a card may name — handed over verbatim in every refusal */
373
392
  export const JUDGE_RULE_IDS: readonly string[];
@@ -9,6 +9,20 @@ export function latestStep(steps: StepLine[], id: string): StepLine | undefined;
9
9
  * @param {StepLine[]} steps @param {string} id @param {string} [detail] (absent = keep what the line has)
10
10
  */
11
11
  export function advanceSteps(steps: StepLine[], id: string, detail?: string): void;
12
+ /**
13
+ * The confirm turn's plan as the chat shows it: ONE owner of the text (hamr, 2026-10-09: the one-blob "Plan: ...
14
+ * Checks: ... Not checked: ..." was unreadable). Each section is a heading on its own line, its content on the next,
15
+ * and a blank line between sections. `#NOT CHECKED:` and `#QUESTIONS:` appear only when there is something to say.
16
+ * The CLI composes its own plan screen (src/authorrun.js) and shares no text with this one.
17
+ * @param {{goal?: string, checks?: string[], notChecked?: string[], questions?: string[]}} p
18
+ * @returns {string}
19
+ */
20
+ export function planText(p: {
21
+ goal?: string;
22
+ checks?: string[];
23
+ notChecked?: string[];
24
+ questions?: string[];
25
+ }): string;
12
26
  /**
13
27
  * `true` when `jobs/<name>.json` already exists in the repo's own jobs/ dir
14
28
  * (resolved from THIS module's own on-disk location, never `process.cwd()`,
@@ -96,7 +110,7 @@ export function validateJobCard(card: any, opts?: {
96
110
  /**
97
111
  * ONE session's engine — created already RUNNING (the caller awaits nothing;
98
112
  * the pipeline drives itself, reporting through `state`). `state.pendingAsk`
99
- * is the ONE thing a person answers next; `answer()`/`send()`/`revise()`/
113
+ * is the ONE thing a person answers next; `answer()`/`send()`/
100
114
  * `signPrepare()` are the only ways in.
101
115
  * @param {any} card the validated job card (see {@link validateJobCard})
102
116
  * @param {{env?: Record<string,string|undefined>, sessionsRoot?: string, home?: string, timeoutMs?: number,
@@ -1,3 +1,10 @@
1
+ /**
2
+ * The per-call options the rubric JUDGE's model calls carry for this provider
3
+ * instance, from the allow-list above. Empty for any provider/model not listed.
4
+ * @param {any} provider a constructed bare-agent provider
5
+ * @returns {Record<string, any>}
6
+ */
7
+ export function judgeCallOptions(provider: any): Record<string, any>;
1
8
  /**
2
9
  * Look up a provider's table entry. Throws a NAMED error on an unrecognized
3
10
  * provider — never a silent default (the `resolveRates`-style-substring-
package/types/trend.d.ts CHANGED
@@ -54,6 +54,7 @@ export function createTrend({ stageOrder, limit, blindCap, seed, directions }?:
54
54
  * @param {{gap?: string, stage?: string|null, value?: number|null}} o either a
55
55
  * raw gap (parsed here) or an already-read `{stage, value}` — never both
56
56
  * spellings of the same reading in one call.
57
+ * (A judged stage's value is its distinct red COUNT, supplied by the caller.)
57
58
  * @returns {{iteration: number, stage: string, value: number|null, improved: boolean,
58
59
  * comparable: boolean, noProgress: number, limit: number, stageIndex: number}}
59
60
  */