bareloop 0.43.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/bareloop.context.md +52 -13
- package/package.json +2 -2
- package/src/authorflow.js +26 -11
- package/src/authoring.js +1 -1
- package/src/authorjob.js +27 -15
- package/src/authorreadout.js +7 -6
- package/src/declaredclose.js +4 -1
- package/src/draftspend.js +20 -2
- package/src/facts.js +54 -9
- package/src/factwords.js +58 -6
- package/src/inputlook.js +38 -3
- package/src/job.js +1 -1
- package/src/kinds.js +5 -0
- package/src/pagedropwords.js +64 -0
- package/src/pagemap.js +264 -0
- package/src/pagerules.js +319 -0
- package/src/panel/authorroutes.js +34 -30
- package/src/panel/authorsession.js +29 -5
- package/src/panel/index.html +465 -65
- package/src/panel/jobplan.js +4 -2
- package/src/panel/runroutes.js +46 -22
- package/src/panel/server.js +791 -28
- package/src/panel/status.js +33 -0
- package/src/panelmoney.js +29 -0
- package/src/planrun.js +53 -4
- package/src/promptregisters.js +4 -0
- package/src/replay.js +118 -7
- package/src/rubricstep.js +123 -11
- package/src/runlist.js +2 -1
- package/src/schedulewords.js +6 -3
- package/src/source.js +18 -0
- package/src/thinking.js +63 -2
- package/src/userrun.js +28 -14
- package/types/authorflow.d.ts +42 -6
- package/types/authorjob.d.ts +10 -2
- package/types/declaredclose.d.ts +2 -0
- package/types/draftspend.d.ts +27 -1
- package/types/facts.d.ts +15 -0
- package/types/factwords.d.ts +26 -3
- package/types/inputlook.d.ts +15 -0
- package/types/kinds.d.ts +5 -0
- package/types/pagedropwords.d.ts +26 -0
- package/types/pagemap.d.ts +154 -0
- package/types/pagerules.d.ts +86 -0
- package/types/panel/authorroutes.d.ts +17 -14
- package/types/panel/runroutes.d.ts +2 -2
- package/types/panel/server.d.ts +155 -2
- package/types/panel/status.d.ts +51 -0
- package/types/panelmoney.d.ts +5 -0
- package/types/replay.d.ts +21 -1
- package/types/rubricstep.d.ts +57 -1
- package/types/runlist.d.ts +4 -1
- package/types/schedulewords.d.ts +4 -2
- package/types/source.d.ts +11 -0
- package/types/thinking.d.ts +39 -0
- package/types/userrun.d.ts +4 -0
package/types/panel/server.d.ts
CHANGED
|
@@ -303,6 +303,69 @@ export function getAcceptContext(runid: string, opts?: {
|
|
|
303
303
|
specPath: string | null;
|
|
304
304
|
specHash: string | null;
|
|
305
305
|
} | null;
|
|
306
|
+
/**
|
|
307
|
+
* The files a run delivered: its own `destination-written` spine records (userrun.js, on a minted green only), one per path, the last record of a
|
|
308
|
+
* path winning. This is the ONLY source of a delivered path anywhere in the panel — no request ever names one.
|
|
309
|
+
* @param {any[]} records
|
|
310
|
+
* @returns {{path: string, bytes: number|null, sha256: string|null}[]}
|
|
311
|
+
*/
|
|
312
|
+
export function deliveredOf(records: any[]): {
|
|
313
|
+
path: string;
|
|
314
|
+
bytes: number | null;
|
|
315
|
+
sha256: string | null;
|
|
316
|
+
}[];
|
|
317
|
+
/**
|
|
318
|
+
* `GET /api/runs/:runid/result` — the Result tab: for each rubric job line, its words and `~` rules from the signed spec, the facts it requires
|
|
319
|
+
* (worded by {@link factSentence}), and — read from the run's own delivered step file, sha256-checked against its `destination-written`
|
|
320
|
+
* record — one row per result with each fact's cell. `passed` is read from the run's own `check-run` record; the tab never re-decides. A red run
|
|
321
|
+
* delivers nothing, so it has no rows: it carries the check's own first gap instead. `null` = no such run or no result tab for it.
|
|
322
|
+
* @param {string} runid @param {{ home?: string }} opts
|
|
323
|
+
*/
|
|
324
|
+
export function getRunResult(runid: string, opts?: {
|
|
325
|
+
home?: string;
|
|
326
|
+
sessionsRoot?: string;
|
|
327
|
+
}): {
|
|
328
|
+
runid: string;
|
|
329
|
+
lines: any[];
|
|
330
|
+
pages: string[];
|
|
331
|
+
pageNote: string | null;
|
|
332
|
+
notChecked: string[];
|
|
333
|
+
door: {
|
|
334
|
+
head: "waiting for you";
|
|
335
|
+
ask: string;
|
|
336
|
+
};
|
|
337
|
+
delivered: {
|
|
338
|
+
i: number;
|
|
339
|
+
path: string;
|
|
340
|
+
name: string;
|
|
341
|
+
bytes: number | null;
|
|
342
|
+
state: "ok" | "changed" | "gone";
|
|
343
|
+
words: string | null;
|
|
344
|
+
}[];
|
|
345
|
+
gap: {
|
|
346
|
+
line: string;
|
|
347
|
+
more: number;
|
|
348
|
+
moreText: string | null;
|
|
349
|
+
} | null;
|
|
350
|
+
} | null;
|
|
351
|
+
/**
|
|
352
|
+
* `GET /api/runs/:runid/download?i=<n>` — delivered file `n` (an index into the run's own `destination-written` list), or why not. The path is
|
|
353
|
+
* the record's, never the request's; the sha256 must still match the record.
|
|
354
|
+
* @param {string} runid @param {unknown} index @param {{ home?: string }} opts
|
|
355
|
+
* @returns {{ok: true, name: string, type: string, buf: Buffer}|{ok: false, code: number, error: string}}
|
|
356
|
+
*/
|
|
357
|
+
export function getRunDownload(runid: string, index: unknown, opts?: {
|
|
358
|
+
home?: string;
|
|
359
|
+
}): {
|
|
360
|
+
ok: true;
|
|
361
|
+
name: string;
|
|
362
|
+
type: string;
|
|
363
|
+
buf: Buffer;
|
|
364
|
+
} | {
|
|
365
|
+
ok: false;
|
|
366
|
+
code: number;
|
|
367
|
+
error: string;
|
|
368
|
+
};
|
|
306
369
|
/**
|
|
307
370
|
* `GET /api/runs/:runid` — the full replay for the Run tab: steps (or
|
|
308
371
|
* iterations), counters, summary-box fields. Looks `runid` up in the run
|
|
@@ -387,11 +450,12 @@ export function getRunAudit(runid: string, opts?: {
|
|
|
387
450
|
* resolve to a real window, or the spine file is missing — the caller
|
|
388
451
|
* renders 404, same posture as {@link getRunAudit}/{@link getRunJob}.
|
|
389
452
|
* @param {string} runid
|
|
390
|
-
* @param {{ part?: number, attempt?: number, offset?: number, limit?: number }} query
|
|
453
|
+
* @param {{ all?: boolean, part?: number, attempt?: number, offset?: number, limit?: number }} query
|
|
391
454
|
* @param {{ home?: string }} [opts]
|
|
392
455
|
* @returns {any|null}
|
|
393
456
|
*/
|
|
394
457
|
export function getRunRounds(runid: string, query?: {
|
|
458
|
+
all?: boolean;
|
|
395
459
|
part?: number;
|
|
396
460
|
attempt?: number;
|
|
397
461
|
offset?: number;
|
|
@@ -399,6 +463,78 @@ export function getRunRounds(runid: string, query?: {
|
|
|
399
463
|
}, opts?: {
|
|
400
464
|
home?: string;
|
|
401
465
|
}): any | null;
|
|
466
|
+
/** the Round table's check row: the sign and the plain words, ONE place (PRD v1.106 Part 5 C) @param {number} passed @param {number} failed */
|
|
467
|
+
export function checkRowWords(passed: number, failed: number): {
|
|
468
|
+
sign: string;
|
|
469
|
+
text: string;
|
|
470
|
+
};
|
|
471
|
+
/**
|
|
472
|
+
* "71 model · 91 tool · 0 denied" — the Run summary's `calls:` row (PRD v1.106 Part 5 F). Model calls are the run's own spend records
|
|
473
|
+
* (`worker-round`, `judge-round`; the attempt-level `worker-result` echoes are not rounds and drafting is not the run's), tool and denied come
|
|
474
|
+
* from the gate-audit rows scoped to this run (the same figure `tools:` shows). No tool log saved says so, never a zero.
|
|
475
|
+
* @param {any[]} records the run's raw spine @param {{totalCalls: number, denied: number}|null} behaviour
|
|
476
|
+
* @returns {string}
|
|
477
|
+
*/
|
|
478
|
+
export function callsLineOf(records: any[], behaviour: {
|
|
479
|
+
totalCalls: number;
|
|
480
|
+
denied: number;
|
|
481
|
+
} | null): string;
|
|
482
|
+
/**
|
|
483
|
+
* "16 run · 8 passed · 8 failed (write-flight-facts tries 1-5, then tries 1-3)" — counts of what ran, never a fraction (the "checks N/M"
|
|
484
|
+
* headline stays withdrawn). Every `exit-eval` result plus every graded `outer-close` stage; the parenthesis names the steps and try ranges
|
|
485
|
+
* that failed, from the same `tries[]` the Audit reads. A run with neither says `not recorded`.
|
|
486
|
+
* @param {any[]} records the run's raw spine @param {any[]|null|undefined} parts the enriched parts
|
|
487
|
+
* @returns {string}
|
|
488
|
+
*/
|
|
489
|
+
export function checksLineOf(records: any[], parts: any[] | null | undefined): string;
|
|
490
|
+
/**
|
|
491
|
+
* The step card's extra line (PRD v1.106 Part 5 G): "5 tries · last try: 1 check passed, 1 failed", with the cut-off try named when there is one
|
|
492
|
+
* ("4 tries (the 4th cut off before its checks ran) · last try: no checks ran"). Words for what passed and failed, never a fraction. `null`
|
|
493
|
+
* when the step has no graded try (an old spine).
|
|
494
|
+
* @param {Array<{n: number, cutOff: boolean, passed: number, failed: number, ran: number}>} tries
|
|
495
|
+
* @returns {string|null}
|
|
496
|
+
*/
|
|
497
|
+
export function triesLineOf(tries: Array<{
|
|
498
|
+
n: number;
|
|
499
|
+
cutOff: boolean;
|
|
500
|
+
passed: number;
|
|
501
|
+
failed: number;
|
|
502
|
+
ran: number;
|
|
503
|
+
}>): string | null;
|
|
504
|
+
/**
|
|
505
|
+
* "tools: read 16 · grep 22 · write 5 · denied 0" — the step's tool calls by kind, then how many the gate denied (PRD v1.106 Part 5 C). The
|
|
506
|
+
* `shell_`/`ctx_` prefixes are stripped like the rest of the page. `null` when no tool log was saved (nothing honest to count).
|
|
507
|
+
* @param {Record<string, number>|null|undefined} byTool @param {number|null|undefined} blocked
|
|
508
|
+
* @returns {string|null}
|
|
509
|
+
*/
|
|
510
|
+
export function toolsTallyLine(byTool: Record<string, number> | null | undefined, blocked: number | null | undefined): string | null;
|
|
511
|
+
/**
|
|
512
|
+
* The try line's gap: the first failing reason, and how many more there are (PRD v1.106 Part 5 C). ONE function, beside {@link stageQuestionText}.
|
|
513
|
+
* @param {string|null|undefined} detail
|
|
514
|
+
* @returns {{ line: string, more: number }|null}
|
|
515
|
+
*/
|
|
516
|
+
export function gapOneLine(detail: string | null | undefined): {
|
|
517
|
+
line: string;
|
|
518
|
+
more: number;
|
|
519
|
+
} | null;
|
|
520
|
+
/**
|
|
521
|
+
* "from line 1 ~ under $450; not a red-eye" — the job line(s) a check serves and the `~` rules written under them (the signed `jobLines`).
|
|
522
|
+
* `null` when the stage serves no job line (a mandatory guard).
|
|
523
|
+
* @param {number[]} fromLine @param {any} spec
|
|
524
|
+
* @returns {string|null}
|
|
525
|
+
*/
|
|
526
|
+
export function fromLineText(fromLine: number[], spec: any): string | null;
|
|
527
|
+
/**
|
|
528
|
+
* "output judged: output/steps/1.json · 2.1 KB · sha256 674b…30" — the file a try's check read (PRD v1.106 Part 5 choice 14). ONE place owns
|
|
529
|
+
* these words. `size` is bytes under 1 KB, else KB with one decimal; the hash shows its first 4 and last 2 characters.
|
|
530
|
+
* @param {{path: string|null, bytes: number|null, sha256: string|null}} o
|
|
531
|
+
* @returns {string}
|
|
532
|
+
*/
|
|
533
|
+
export function judgedFileLine(o: {
|
|
534
|
+
path: string | null;
|
|
535
|
+
bytes: number | null;
|
|
536
|
+
sha256: string | null;
|
|
537
|
+
}): string;
|
|
402
538
|
/**
|
|
403
539
|
* The Signed row of the Job tab: `YYYY-MM-DD HH:MM · <first 6 of specHash>`, the time being the run's FIRST `job-start`
|
|
404
540
|
* in local time (hamr, P7). `null` when either part is not on record — never a made-up stamp.
|
|
@@ -627,10 +763,11 @@ export function getStartFromImport(id: string, opts?: {
|
|
|
627
763
|
* only `createPanelServer` below always supplies one.
|
|
628
764
|
* @param {import('node:http').IncomingMessage} req
|
|
629
765
|
* @param {import('node:http').ServerResponse} res
|
|
630
|
-
* @param {{ home?: string, packageJsonPath?: string, port: number, token?: string, authorRoutes?: ReturnType<typeof createAuthorRoutes>, settingsRoutes?: ReturnType<typeof createSettingsRoutes>, runRoutes?: ReturnType<typeof createRunRoutes>, importRoutes?: ReturnType<typeof createImportRoutes>, schedules?: ReturnType<typeof createScheduleDoor> }} opts
|
|
766
|
+
* @param {{ home?: string, sessionsRoot?: string, packageJsonPath?: string, port: number, token?: string, authorRoutes?: ReturnType<typeof createAuthorRoutes>, settingsRoutes?: ReturnType<typeof createSettingsRoutes>, runRoutes?: ReturnType<typeof createRunRoutes>, importRoutes?: ReturnType<typeof createImportRoutes>, schedules?: ReturnType<typeof createScheduleDoor> }} opts
|
|
631
767
|
*/
|
|
632
768
|
export function handleRequest(req: import("node:http").IncomingMessage, res: import("node:http").ServerResponse, opts: {
|
|
633
769
|
home?: string;
|
|
770
|
+
sessionsRoot?: string;
|
|
634
771
|
packageJsonPath?: string;
|
|
635
772
|
port: number;
|
|
636
773
|
token?: string;
|
|
@@ -731,11 +868,27 @@ export const RUNS_LIST_LIMITS: Readonly<{
|
|
|
731
868
|
olderRuns: 7;
|
|
732
869
|
needsYouDays: 7;
|
|
733
870
|
}>;
|
|
871
|
+
/** what the Result tab's open door asks, after the door's own head words */
|
|
872
|
+
export const RESULT_DOOR_ASK: "the checks passed; is this what you wanted?";
|
|
873
|
+
/** the two sentences for a delivered file that is no longer what the run wrote (code-owned, one spelling) */
|
|
874
|
+
export const RESULT_FILE_GONE: "the saved file is gone";
|
|
875
|
+
export const RESULT_FILE_CHANGED: "the saved file changed after the run";
|
|
876
|
+
/** the same two states for a red run's file, which is the last one the check read (not a delivered file) */
|
|
877
|
+
export const RESULT_JUDGED_GONE: "the file is gone";
|
|
878
|
+
export const RESULT_JUDGED_CHANGED: "the file changed after the check";
|
|
879
|
+
/** what a red run's rows are, said once above them */
|
|
880
|
+
export const RESULT_JUDGED_NOTE: "a red run delivers nothing; these rows are the last file the check read";
|
|
881
|
+
/** the words beside a Result-tab page link: the page is read again from the web, so it can differ from what the run read */
|
|
882
|
+
export const RESULT_PAGE_MAY_CHANGE: "The page may have changed since this run.";
|
|
883
|
+
/** the words after a fact whose limit the person agreed to in a Part 5b look ask */
|
|
884
|
+
export const RESULT_YOU_CONFIRMED: "(you confirmed)";
|
|
734
885
|
/** The default/max page size for {@link getRunRounds} — tighten-only,
|
|
735
886
|
* named so a future change is a deliberate, visible edit (item 5,
|
|
736
887
|
* 2026-09-25). */
|
|
737
888
|
export const ROUNDS_PAGE_DEFAULT: 50;
|
|
738
889
|
export const ROUNDS_PAGE_MAX: 200;
|
|
890
|
+
/** the Audit step table's page size (PRD v1.106 Part 5 choice 3): rows, not rounds */
|
|
891
|
+
export const STEP_ROWS_PAGE: 20;
|
|
739
892
|
import { createScheduleDoor } from './schedules.js';
|
|
740
893
|
import { createAuthorRoutes } from './authorroutes.js';
|
|
741
894
|
import { createSettingsRoutes } from './settingsroutes.js';
|
package/types/panel/status.d.ts
CHANGED
|
@@ -34,6 +34,26 @@ export function partStatusFor(part: {
|
|
|
34
34
|
sign: string;
|
|
35
35
|
word: string;
|
|
36
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* The words one door wears: header phrase, the `last answer:` line (with the time `HH:MM` once decided) and the table rows.
|
|
39
|
+
* @param {{at: string|null, paths: string[], decision: string|null, text: string|null, decidedAt: string|null}} door
|
|
40
|
+
* @returns {{ head: string, last: string, rows: Array<{path: string|null, text: string, time: string|null}> }}
|
|
41
|
+
*/
|
|
42
|
+
export function doorViewOf(door: {
|
|
43
|
+
at: string | null;
|
|
44
|
+
paths: string[];
|
|
45
|
+
decision: string | null;
|
|
46
|
+
text: string | null;
|
|
47
|
+
decidedAt: string | null;
|
|
48
|
+
}): {
|
|
49
|
+
head: string;
|
|
50
|
+
last: string;
|
|
51
|
+
rows: Array<{
|
|
52
|
+
path: string | null;
|
|
53
|
+
text: string;
|
|
54
|
+
time: string | null;
|
|
55
|
+
}>;
|
|
56
|
+
};
|
|
37
57
|
/** the sentence a passed run carries as its reason (the Ended block's `line`) */
|
|
38
58
|
export const GOAL_MET_LINE: "goal met";
|
|
39
59
|
/** @typedef {'running'|'waiting'|'passed'|'failed'|'capped'|'stopped'|'died'} StatusKey */
|
|
@@ -68,4 +88,35 @@ export const STATUS: Readonly<{
|
|
|
68
88
|
word: "died";
|
|
69
89
|
}>;
|
|
70
90
|
}>;
|
|
91
|
+
/**
|
|
92
|
+
* PRD v1.106 Part 5 (C, choice 9): the review door's words, ONE table. The door is the only human step bareloop has; there is no "you
|
|
93
|
+
* cancelled" (cancel is deleted). `decision` is the spine's `door-decision.decision`, or null while nothing has been decided.
|
|
94
|
+
*/
|
|
95
|
+
export const DOOR_WORDS: Readonly<{
|
|
96
|
+
waiting: Readonly<{
|
|
97
|
+
head: "waiting for you";
|
|
98
|
+
row: "paused for you";
|
|
99
|
+
last: "none yet";
|
|
100
|
+
}>;
|
|
101
|
+
accept: Readonly<{
|
|
102
|
+
head: "you accepted";
|
|
103
|
+
row: "you accepted";
|
|
104
|
+
last: "you accepted";
|
|
105
|
+
}>;
|
|
106
|
+
rerun: Readonly<{
|
|
107
|
+
head: "you said rerun";
|
|
108
|
+
row: "you said rerun";
|
|
109
|
+
last: "you said rerun";
|
|
110
|
+
}>;
|
|
111
|
+
pause: Readonly<{
|
|
112
|
+
head: "paused";
|
|
113
|
+
row: "paused";
|
|
114
|
+
last: "paused";
|
|
115
|
+
}>;
|
|
116
|
+
}>;
|
|
117
|
+
/** the marker a part wears for who did its work (PRD v1.106 Part 5 C/G): the model, or a person asked */
|
|
118
|
+
export const ACTOR_MARKER: Readonly<{
|
|
119
|
+
model: "[model]";
|
|
120
|
+
human: "[human · ask]";
|
|
121
|
+
}>;
|
|
71
122
|
export type StatusKey = "running" | "waiting" | "passed" | "failed" | "capped" | "stopped" | "died";
|
package/types/replay.d.ts
CHANGED
|
@@ -180,7 +180,26 @@ export function replayRun(spineEvents: any[], auditEvents?: any[], { runId, audi
|
|
|
180
180
|
startTs: number | null;
|
|
181
181
|
endTs: number | null;
|
|
182
182
|
exitEvalDetail: string | null;
|
|
183
|
+
checks: Array<{
|
|
184
|
+
type: string;
|
|
185
|
+
pass: boolean;
|
|
186
|
+
detail: string | null;
|
|
187
|
+
name: string | null;
|
|
188
|
+
}>;
|
|
189
|
+
outputJudged: Array<{
|
|
190
|
+
path: string | null;
|
|
191
|
+
bytes: number | null;
|
|
192
|
+
sha256: string | null;
|
|
193
|
+
}>;
|
|
183
194
|
}[];
|
|
195
|
+
cutOffTry: {
|
|
196
|
+
n: number;
|
|
197
|
+
iteration: any;
|
|
198
|
+
startSeq: any;
|
|
199
|
+
endSeq: any;
|
|
200
|
+
startTs: number | null;
|
|
201
|
+
endTs: number | null;
|
|
202
|
+
} | null;
|
|
184
203
|
stepStartSeq: any;
|
|
185
204
|
stepEndSeq: any;
|
|
186
205
|
stepStartTs: number | null;
|
|
@@ -291,9 +310,10 @@ export function replayRun(spineEvents: any[], auditEvents?: any[], { runId, audi
|
|
|
291
310
|
* @param {boolean|null} [draftSpendComplete] whether the drafting fold above was EXACT;
|
|
292
311
|
* `null`/`undefined`/`true` all read as exact (never a new enum value elsewhere) —
|
|
293
312
|
* only an explicit `false` triggers the floor wording.
|
|
313
|
+
* @param {number|null} [runUsd] the run's own spend as a number (excluding drafting), so the sum can be written
|
|
294
314
|
* @returns {string}
|
|
295
315
|
*/
|
|
296
|
-
export function moneyWithDraft(spendCore: string, draftSpentUsd: number | null, budgetUsd?: number | null, draftSpendComplete?: boolean | null): string;
|
|
316
|
+
export function moneyWithDraft(spendCore: string, draftSpentUsd: number | null, budgetUsd?: number | null, draftSpendComplete?: boolean | null, runUsd?: number | null): string;
|
|
297
317
|
/**
|
|
298
318
|
* Render a {@link replayRun} summary as one printable page: a header block
|
|
299
319
|
* (goal/shape/signed/branch/outcome/spent), a timeline (steps or iterations,
|
package/types/rubricstep.d.ts
CHANGED
|
@@ -35,6 +35,13 @@ export function rubricGoal({ jobLines, files, confirmedGoal, closeDecl }: {
|
|
|
35
35
|
confirmedGoal?: string | null;
|
|
36
36
|
closeDecl?: any;
|
|
37
37
|
}): string;
|
|
38
|
+
/**
|
|
39
|
+
* The sentence the person confirmed, out of a goal text: for a rubric brief the rest of the `CONFIRMED_GOAL_PREFIX` line,
|
|
40
|
+
* or null when the brief has none; any other goal (a code job's) comes back unchanged.
|
|
41
|
+
* @param {string} goal
|
|
42
|
+
* @returns {string|null}
|
|
43
|
+
*/
|
|
44
|
+
export function confirmedGoalOf(goal: string): string | null;
|
|
38
45
|
/**
|
|
39
46
|
* The SHAPE of a `rubric-step` stage's parameters — what a part may carry — and nothing about which class is allowed in
|
|
40
47
|
* this build (that is `checkRubricParts`, which also sees the whole job). Pure, never throws.
|
|
@@ -58,6 +65,28 @@ export function buildStepSpec(params: {
|
|
|
58
65
|
step: number;
|
|
59
66
|
parts: any[];
|
|
60
67
|
}, inputShas: Record<string, string>): Record<string, any>;
|
|
68
|
+
/**
|
|
69
|
+
* The files one named check READS, tree-relative: a `rubric-step` stage's own step file (`output/steps/N.json`). Any other kind reads
|
|
70
|
+
* none that a try's output can be told by, so `[]`. From the signed declaration, never guessed.
|
|
71
|
+
* @param {any} closeDecl @param {string|null|undefined} checkName
|
|
72
|
+
* @returns {string[]}
|
|
73
|
+
*/
|
|
74
|
+
export function judgedFilesOf(closeDecl: any, checkName: string | null | undefined): string[];
|
|
75
|
+
/**
|
|
76
|
+
* PRD v1.106 Part 5: what each file a try's `check-passes` checks read looked like WHEN it was judged: `{path, bytes, sha256}`. The step
|
|
77
|
+
* file is overwritten by the next try, so the spine's `output-judged` record is the only trace; the content itself is never written (hard
|
|
78
|
+
* line). A missing, non-regular or over-size file is skipped — nothing was judged there.
|
|
79
|
+
* @param {any} closeDecl @param {string} workdir @param {Array<{type?: string, name?: string}>} exits a step's declared exits
|
|
80
|
+
* @returns {Promise<Array<{path: string, bytes: number, sha256: string}>>}
|
|
81
|
+
*/
|
|
82
|
+
export function outputJudgedRecords(closeDecl: any, workdir: string, exits: Array<{
|
|
83
|
+
type?: string;
|
|
84
|
+
name?: string;
|
|
85
|
+
}>): Promise<Array<{
|
|
86
|
+
path: string;
|
|
87
|
+
bytes: number;
|
|
88
|
+
sha256: string;
|
|
89
|
+
}>>;
|
|
61
90
|
/**
|
|
62
91
|
* The step file's bytes as the close reads them: the parsed JSON object, or WHY there is none. A file cut off mid-write
|
|
63
92
|
* parses to nothing (reason `not-json`); text cut off INSIDE an otherwise valid JSON object cannot be told from a short
|
|
@@ -101,7 +130,9 @@ export function plainStepGap(step: number, why: string, g: any, params?: any): s
|
|
|
101
130
|
* `inputs` maps each cited label to its frozen TEXT; its sha256 is taken here from that text, and bareguard compares it to
|
|
102
131
|
* the manifest's recorded sha via `inputShas`.
|
|
103
132
|
* @param {Record<string, string>} inputShas the manifest's recorded sha256 per cited label
|
|
104
|
-
* @returns {Promise<{verdict: 'green'|'red'|'stopped', gapLines: string[], fault: string|null, detail: Record<string, any
|
|
133
|
+
* @returns {Promise<{verdict: 'green'|'red'|'stopped', gapLines: string[], fault: string|null, detail: Record<string, any>,
|
|
134
|
+
* evidence?: any[], evidenceTotal?: number}>} `evidence`/`evidenceTotal` are bareguard's `full.evidence` (what each `cited` check read), carried out
|
|
135
|
+
* for the report-only `rubric-evidence` spine record; no verdict, gap or count above is derived from them
|
|
105
136
|
*/
|
|
106
137
|
export function gradeStep({ params, bytes, outputBytes, inputs, factQuotes, factMissing }: {
|
|
107
138
|
params: {
|
|
@@ -118,6 +149,8 @@ export function gradeStep({ params, bytes, outputBytes, inputs, factQuotes, fact
|
|
|
118
149
|
gapLines: string[];
|
|
119
150
|
fault: string | null;
|
|
120
151
|
detail: Record<string, any>;
|
|
152
|
+
evidence?: any[];
|
|
153
|
+
evidenceTotal?: number;
|
|
121
154
|
}>;
|
|
122
155
|
/**
|
|
123
156
|
* The labels of a job's numbered inputs, or null when it carries none (a caller that has no inputs in hand skips the label rule).
|
|
@@ -178,6 +211,17 @@ export function settlePersonsWords(declaration: any, jobLines: any[] | null | un
|
|
|
178
211
|
* @param {any} declaration @returns {any}
|
|
179
212
|
*/
|
|
180
213
|
export function withFactBindings(declaration: any): any;
|
|
214
|
+
/**
|
|
215
|
+
* NO SILENT DROP (idea A core, spec 4.4): code writes the Not checked rows for what the page rules removed, before the declaration is validated.
|
|
216
|
+
* - a dropped FACT that carries a `~` rule no part carries and no `refused` entry names -> `closeDecl.refused` gets {line, rule, reason}
|
|
217
|
+
* (shown under that line in the person's own rule words by {@link ruleNotChecked});
|
|
218
|
+
* - any other drop (a fact from the job line itself, a rule another fact carries, a word dropped from a fact that is still checked, so a
|
|
219
|
+
* narrower check is still said) -> one line in `closeDecl.notes`, shown as Not checked (the AI's own reading).
|
|
220
|
+
* Never a line-level `refused` entry without `rule` (that would silence every other rule red on the line). A rule the drafter already listed
|
|
221
|
+
* itself is never listed twice, and running this twice adds nothing. Pure; the input is untouched.
|
|
222
|
+
* @param {any} declaration @param {import('./pagerules.js').Dropped[]|null|undefined} dropped @param {any[]|null|undefined} jobLines @returns {any}
|
|
223
|
+
*/
|
|
224
|
+
export function withDropNotes(declaration: any, dropped: import("./pagerules.js").Dropped[] | null | undefined, jobLines: any[] | null | undefined): any;
|
|
181
225
|
/**
|
|
182
226
|
* The ~ rules the drafter listed under Not checked (`refused` entries that name a `rule`), each as one line in the person's own
|
|
183
227
|
* words: `line N: "<the rule as written>" — <the drafter's reason>` (PART 1b, RF6 / RF16).
|
|
@@ -190,6 +234,11 @@ export function ruleNotChecked(closeDecl: any, jobLines: any[] | null | undefine
|
|
|
190
234
|
* @param {any} closeDecl @returns {string[]}
|
|
191
235
|
*/
|
|
192
236
|
export function proseNotChecked(closeDecl: any): string[];
|
|
237
|
+
/** the same items as {@link proseNotChecked} with the job line each belongs to (the stage's own `step`) @param {any} closeDecl @returns {{line: number, text: string}[]} */
|
|
238
|
+
export function proseNotCheckedItems(closeDecl: any): {
|
|
239
|
+
line: number;
|
|
240
|
+
text: string;
|
|
241
|
+
}[];
|
|
193
242
|
/**
|
|
194
243
|
* One countable part as a plain sentence, written by code from the part's signed fields (never from the model's words), so the
|
|
195
244
|
* plan card and the close are one thing seen twice.
|
|
@@ -269,6 +318,11 @@ export const STEP_DIR: "output/steps";
|
|
|
269
318
|
export function stepFileRel(n: number): string;
|
|
270
319
|
/** the largest step file the close reads: a bigger one is a stop, never silently truncated (bareguard's own source cap) */
|
|
271
320
|
export const STEP_MAX_BYTES: number;
|
|
321
|
+
/**
|
|
322
|
+
* What a rubric job's goal text is: the worker brief `rubricGoal` builds. The Job tab's "AI's summary" is only the one
|
|
323
|
+
* sentence the person confirmed, never this brief, so the first line and the confirmed-sentence prefix have ONE spelling.
|
|
324
|
+
*/
|
|
325
|
+
export const RUBRIC_GOAL_HEAD: "Do the job below from the input files, then write one JSON file per numbered line.";
|
|
272
326
|
/** the closed set of classes a part is sorted into; `none` = "I could not sort this one" (a red, in plain words, never a guess) */
|
|
273
327
|
export const PART_CLASSES: readonly string[];
|
|
274
328
|
/**
|
|
@@ -279,6 +333,8 @@ export const PART_CLASSES: readonly string[];
|
|
|
279
333
|
*/
|
|
280
334
|
export const COUNT_CHECKS: Readonly<Record<string, readonly string[]>>;
|
|
281
335
|
export function sha256Of(b: string | Buffer): string;
|
|
336
|
+
export function boundInWords(b: unknown, said: string): boolean;
|
|
337
|
+
export function wordsSaidOn(jl: any): string;
|
|
282
338
|
export type ShapeRed = {
|
|
283
339
|
code: string;
|
|
284
340
|
path: string;
|
package/types/runlist.d.ts
CHANGED
|
@@ -48,7 +48,8 @@ export function appendRun(row: RunRow, opts?: {
|
|
|
48
48
|
reason?: "duplicate-runid";
|
|
49
49
|
};
|
|
50
50
|
/**
|
|
51
|
-
* @typedef {{ runid: string, type: 'settled'|'released', by: string, at: string, reason?: string, spentUsd?: number, spendComplete?: boolean, leg?: number }} RunEvent
|
|
51
|
+
* @typedef {{ runid: string, type: 'settled'|'released', by: string, at: string, reason?: string, words?: string, spentUsd?: number, spendComplete?: boolean, leg?: number }} RunEvent
|
|
52
|
+
* `words` (2026-10-19): on a `settled` with `reason: 'refused before start'`, the plain refusal the panel shows for that run (it has no spine).
|
|
52
53
|
* `leg` (P5-R): which leg of the run the write-back is about; absent = leg 1 (every entry written before P5-R).
|
|
53
54
|
* A resumed run is ONE row, so `settled`/`released` are per leg: a later leg's `released` gives back THAT leg's
|
|
54
55
|
* claim and never removes the run.
|
|
@@ -226,6 +227,7 @@ export type RunRow = {
|
|
|
226
227
|
leg?: number;
|
|
227
228
|
};
|
|
228
229
|
/**
|
|
230
|
+
* `words` (2026-10-19): on a `settled` with `reason: 'refused before start'`, the plain refusal the panel shows for that run (it has no spine).
|
|
229
231
|
* `leg` (P5-R): which leg of the run the write-back is about; absent = leg 1 (every entry written before P5-R).
|
|
230
232
|
* A resumed run is ONE row, so `settled`/`released` are per leg: a later leg's `released` gives back THAT leg's
|
|
231
233
|
* claim and never removes the run.
|
|
@@ -241,6 +243,7 @@ export type RunEvent = {
|
|
|
241
243
|
by: string;
|
|
242
244
|
at: string;
|
|
243
245
|
reason?: string;
|
|
246
|
+
words?: string;
|
|
244
247
|
spentUsd?: number;
|
|
245
248
|
spendComplete?: boolean;
|
|
246
249
|
leg?: number;
|
package/types/schedulewords.d.ts
CHANGED
|
@@ -84,14 +84,16 @@ export function jobScheduleWords(f: {
|
|
|
84
84
|
export function retryNextWords(ms: number): string;
|
|
85
85
|
/**
|
|
86
86
|
* RULED 2026-10-15: the sign on the head of the Audit's `schedule` section. ONE small rule (hamr may still adjust it): [▶] only while a
|
|
87
|
-
* run of the job is running (as everywhere in the panel), [✗] when the SCHEDULE row is red, else [·] (on, waiting).
|
|
88
|
-
*
|
|
87
|
+
* run of the job is running (as everywhere in the panel), [✗] when the SCHEDULE row is red, else [·] (on, waiting). RULED 2026-10-18 (v1.106
|
|
88
|
+
* Part 4): the header reads `[sign] word schedule · ...`, the sign AND the word both from the one status table (src/panel/status.js), never typed here.
|
|
89
|
+
* @param {{running: boolean, red: boolean}} f @returns {{sign: string, word: string}}
|
|
89
90
|
*/
|
|
90
91
|
export function scheduleSignFor(f: {
|
|
91
92
|
running: boolean;
|
|
92
93
|
red: boolean;
|
|
93
94
|
}): {
|
|
94
95
|
sign: string;
|
|
96
|
+
word: string;
|
|
95
97
|
};
|
|
96
98
|
/** Audit schedule section, the `this run` words of a run the schedule started (the head already says which schedule and from where). @param {any} rec `trigger.json` */
|
|
97
99
|
export function sectionThisRunWords(rec: any): string;
|
package/types/source.d.ts
CHANGED
|
@@ -421,6 +421,17 @@ export function refreezeUrlInputs({ into, fetchUrl }: {
|
|
|
421
421
|
ok: false;
|
|
422
422
|
error: string;
|
|
423
423
|
}>;
|
|
424
|
+
/**
|
|
425
|
+
* PRD v1.106 Part 5 Q2: what `source.json` says about web inputs, read synchronously and never throwing: whether the copy has any web input
|
|
426
|
+
* (`inputs[].url`) and when the run-start refetch last finished (`refrozenAt`, written last by {@link refreezeUrlInputs}). The panel decides
|
|
427
|
+
* "fetching the page..." from this: it applies while a web input exists and no refetch has finished at or after `sinceIso`.
|
|
428
|
+
* @param {string} sourceJsonPath @param {string|null|undefined} sinceIso
|
|
429
|
+
* @returns {{ hasWeb: boolean, fetching: boolean }}
|
|
430
|
+
*/
|
|
431
|
+
export function webFetchState(sourceJsonPath: string, sinceIso: string | null | undefined): {
|
|
432
|
+
hasWeb: boolean;
|
|
433
|
+
fetching: boolean;
|
|
434
|
+
};
|
|
424
435
|
/** the per-file ceiling for a rubric input: bareguard's `cited` check searches a quote in a source only up to this size
|
|
425
436
|
* (its `quoteSourceMaxBytes`); a bigger file could never be cited from, so the door refuses it at $0 */
|
|
426
437
|
export const RUBRIC_INPUT_MAX_BYTES: number;
|
package/types/thinking.d.ts
CHANGED
|
@@ -84,6 +84,45 @@ export function thinkingRowText({ mode, support, status }: {
|
|
|
84
84
|
support?: true | false | "unverified";
|
|
85
85
|
status?: string;
|
|
86
86
|
}): string;
|
|
87
|
+
/**
|
|
88
|
+
* THE one decision for a worker model call (PRD v1.106 Part 1): from the phase label and attempt iteration `mkWorker` already holds,
|
|
89
|
+
* and the job's tick (`job.thinking === true`). Decided in code, never by the model.
|
|
90
|
+
* tick on -> 'on' for every call
|
|
91
|
+
* plan (draft, redraft, replan) -> 'on' (the planner is the hard part of a run)
|
|
92
|
+
* scout -> 'off'
|
|
93
|
+
* step:<id> attempt 1 -> 'off'
|
|
94
|
+
* step:<id> attempt >= 2 -> 'on'
|
|
95
|
+
* fix (close-fix) -> 'on'
|
|
96
|
+
* A step or fix iteration that is not a whole number >= 1 throws (operator error), as does an unknown phase — never a guess.
|
|
97
|
+
* @param {{ phase: unknown, iteration?: unknown, tick?: unknown }} o
|
|
98
|
+
* @returns {'on'|'off'}
|
|
99
|
+
*/
|
|
100
|
+
export function workerThinkingMode({ phase, iteration, tick }: {
|
|
101
|
+
phase: unknown;
|
|
102
|
+
iteration?: unknown;
|
|
103
|
+
tick?: unknown;
|
|
104
|
+
}): "on" | "off";
|
|
105
|
+
/**
|
|
106
|
+
* PRD v1.106 Part 3 — the words one worker call carries in the Audit, READ from the run's own spine, never guessed. Finds the LAST
|
|
107
|
+
* `thinking-decision` of `phase` (and `iteration`, when given) whose seq lies strictly between `lo` and `hi`, pairs it with the first
|
|
108
|
+
* `thinking-status` of the same phase and iteration after it (before the next decision), and words both through {@link thinkingRowText}
|
|
109
|
+
* (drafting's own words). `null` when the window holds no decision: a run from before the records existed shows no thinking word.
|
|
110
|
+
* @param {any[]} spine the run's spine records (each with a numeric `seq`)
|
|
111
|
+
* @param {{ phase: string, lo?: number, hi?: number, iteration?: number|null }} q
|
|
112
|
+
* @returns {string|null}
|
|
113
|
+
*/
|
|
114
|
+
export function thinkingWordsFrom(spine: any[], { phase, lo, hi, iteration }: {
|
|
115
|
+
phase: string;
|
|
116
|
+
lo?: number;
|
|
117
|
+
hi?: number;
|
|
118
|
+
iteration?: number | null;
|
|
119
|
+
}): string | null;
|
|
120
|
+
/**
|
|
121
|
+
* The Job tab's row words (PRD v1.106 Part 3): the default rule, or the job's "Thinking on" tick, but only for a run whose spine
|
|
122
|
+
* recorded a `thinking-decision`; a run from before the thinking rule reads `—`, never a guess from the job's tick (fwdloop M4d am28).
|
|
123
|
+
* @param {boolean} tick @param {boolean} recorded the run's spine holds at least one `thinking-decision` @returns {string}
|
|
124
|
+
*/
|
|
125
|
+
export function thinkingJobText(tick: boolean, recorded: boolean): string;
|
|
87
126
|
/** The words under a greyed "Thinking on" box (the server's `thinking.canChange` decides; the page decides nothing). */
|
|
88
127
|
export const THINKING_FIXED_SAY: "can't change this for this model";
|
|
89
128
|
/** The enumerated operator knob a drafting call is built with: 'on' | 'off' (the tick, spelled as a word). */
|
package/types/userrun.d.ts
CHANGED
|
@@ -219,6 +219,10 @@ export type RunCtx = {
|
|
|
219
219
|
* see `RunOpts.into`
|
|
220
220
|
*/
|
|
221
221
|
into?: string | undefined;
|
|
222
|
+
/**
|
|
223
|
+
* a FRESH `--spec` run: fetch the web inputs again AFTER the run is listed (never on resume/door/decide)
|
|
224
|
+
*/
|
|
225
|
+
refreeze?: boolean | undefined;
|
|
222
226
|
model: string | null;
|
|
223
227
|
providerKey: string | null;
|
|
224
228
|
readShim: string | null;
|