bareloop 0.14.0 → 0.15.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/src/index.js CHANGED
@@ -233,6 +233,12 @@ export { closeStagesOf } from './plan.js';
233
233
  // writes nothing to the spine; `runBehaviour` computes, `formatBehaviour`
234
234
  // renders the printable block.
235
235
  export { runBehaviour, formatBehaviour } from './behaviour.js';
236
+ // PRD build-list item 6 — generic run replay: point it at a run's spine (+
237
+ // its gate-audit sidecar) and get the whole story back as one object
238
+ // (`replayRun`) or one printable page (`formatReplay`). Reads only, mints no
239
+ // verdict, writes nothing to the spine — reuses `runBehaviour` rather than
240
+ // re-implementing the tool-call count.
241
+ export { replayRun, formatReplay } from './replay.js';
236
242
  // M4b — the interview, the refusal, the composition, and D9's three gates.
237
243
  // `prepareSigning` returns the resolved spec's HASH and the seed evidence; it
238
244
  // never signs — the approvals array and the human's word are unchanged.
@@ -240,3 +246,9 @@ export {
240
246
  runInterview, authorCloseForJob, assembleSpec, prepareSigning, refusalEvents, refuseLockedKind,
241
247
  GENRE, REFUSAL_LIB, REFUSAL_CATEGORY, AUTHORED_SPEC_FIELDS,
242
248
  } from './authorjob.js';
249
+ // PRD build-list item 5 (TODO #8) — the prompt-register inventory: every file
250
+ // known to carry model-facing prompt/instruction text, and the predicate a
251
+ // commit-message check (`scripts/prompt-commit-check.mjs`) uses to decide
252
+ // whether a changed file is one. The ONE place this list lives; exported so
253
+ // bareloop.context.md can point an adopter here instead of re-deriving it.
254
+ export { PROMPT_REGISTERS, isPromptFile } from './promptregisters.js';
package/src/ledger.js CHANGED
@@ -479,7 +479,7 @@ export function rateProvenance(record) {
479
479
  * Re-spelled rather than imported (src/run.js imports this module's siblings and a cycle
480
480
  * buys nothing here) — `tests/ledger.test.js` asserts the two spellings agree, because a
481
481
  * spend-slicing instrument that misses a writer is the F45 class this list exists to avoid. */
482
- const SPEND_RECORD_TYPES = Object.freeze(['worker-round', 'judge-round', 'worker-turn']);
482
+ export const SPEND_RECORD_TYPES = Object.freeze(['worker-round', 'judge-round', 'worker-turn']);
483
483
 
484
484
  /** @typedef {{rounds: number, usd: number, unpricedRounds: number}} ProvenanceBucket */
485
485
 
@@ -0,0 +1,93 @@
1
+ // THE PROMPT REGISTER INVENTORY — build-list item 5 (PRD TODO #8), Q9 answered
2
+ // (hamr, 2026-08-25): "a check". A commit that changes a prompt register must
3
+ // say, in its message, the failure that caused the change, what it addresses,
4
+ // and what it corrects — doctrine already stated once ("a frozen rule without
5
+ // a wired detector is prose", docs/product/2026-08-23-agreed-build-list.md:187-189)
6
+ // so convention-only was rejected. This module is the ONE place that inventory
7
+ // lives: `scripts/prompt-commit-check.mjs` reads it to decide which commits the
8
+ // rule applies to, and this file's own doc-comment is where a human reads it.
9
+ //
10
+ // The inventory is FILE-scoped, not const-scoped. Several of the files below
11
+ // hold more than one named prompt const, and at least two (authorscout.js,
12
+ // cardauthor.js) also build a model-facing prompt INLINE inside a function
13
+ // (template literals, not a top-level const) rather than assembling one from a
14
+ // named export. A const-scoped check would silently miss those; a file-scoped
15
+ // one does not, because the whole file is in scope once it appears here. The
16
+ // `name` field on each entry is documentation only — grepped to the byte range
17
+ // that motivated it — and carries no weight in `isPromptFile`.
18
+ //
19
+ // Verified against source 2026-08-25 (grepped for exported/module-level string
20
+ // consts that read as model-facing instruction text, and separately for inline
21
+ // template-literal prompts built inside a function). Files checked and found to
22
+ // carry NO prompt content: src/plan.js, src/validate.js, src/kinds.js,
23
+ // src/text.js, src/declaredclose.js, src/calibrate.js, src/index.js (the last
24
+ // is the barrel export only).
25
+
26
+ /**
27
+ * One entry in the prompt-register inventory: a file known to carry
28
+ * model-facing prompt/instruction text, and the name(s) that live there for a
29
+ * human reading this file. `name` may point at a named const OR at a function
30
+ * that builds a prompt inline (e.g. `scoutPrompt()`) — the check only ever
31
+ * keys on `file`.
32
+ * @typedef {{file: string, name: string}} PromptRegisterEntry
33
+ */
34
+
35
+ /** @type {ReadonlyArray<PromptRegisterEntry>} */
36
+ export const PROMPT_REGISTERS = Object.freeze([
37
+ // src/authorscout.js — the read-only repo-survey scout that opens authoring
38
+ Object.freeze({ file: 'src/authorscout.js', name: 'SCOUT_SYSTEM' }),
39
+ Object.freeze({ file: 'src/authorscout.js', name: 'SCOUT_RECOVERY_PROMPT' }),
40
+ Object.freeze({ file: 'src/authorscout.js', name: 'scoutPrompt() (inline template, not a const)' }),
41
+
42
+ // src/authorflow.js — the declaration-authoring turn (system + revise/re-ask)
43
+ Object.freeze({ file: 'src/authorflow.js', name: 'AUTHOR_SYSTEM' }),
44
+ Object.freeze({ file: 'src/authorflow.js', name: 'REVISE_INSTRUCTION' }),
45
+ Object.freeze({ file: 'src/authorflow.js', name: 'STRUCTURE_INSTRUCTION_TOOL' }),
46
+ Object.freeze({ file: 'src/authorflow.js', name: 'STRUCTURE_INSTRUCTION_TEXT' }),
47
+
48
+ // src/judged.js — the softgreen judge's locate prompt (spine + per-rule asks)
49
+ Object.freeze({ file: 'src/judged.js', name: 'PROMPT_HEAD' }),
50
+ Object.freeze({ file: 'src/judged.js', name: 'PROMPT_TAIL' }),
51
+ Object.freeze({ file: 'src/judged.js', name: 'JUDGE_RULES[*].ask (per-rule fragments)' }),
52
+ Object.freeze({ file: 'src/judged.js', name: 'locatePrompt() (inline template, not a const)' }),
53
+
54
+ // src/cardauthor.js — compiles a person's own words into a judged rubric
55
+ Object.freeze({ file: 'src/cardauthor.js', name: 'COMPILE_SYSTEM' }),
56
+ Object.freeze({ file: 'src/cardauthor.js', name: 'cardCasesPrompt() (inline template, not a const)' }),
57
+
58
+ // src/readshim.js — the capped/deduplicating read shim's worker-facing strategy
59
+ Object.freeze({ file: 'src/readshim.js', name: 'READ_SHIM_STRATEGY' }),
60
+ Object.freeze({ file: 'src/readshim.js', name: 'READ_SHIM_DIFF_STRATEGY' }),
61
+
62
+ // src/tools.js — the worker tool menu: personas, retrieval/edit/component strategy
63
+ Object.freeze({ file: 'src/tools.js', name: 'PERSONA_TOOLS' }),
64
+ Object.freeze({ file: 'src/tools.js', name: 'RETRIEVAL_STRATEGY' }),
65
+ Object.freeze({ file: 'src/tools.js', name: 'EDIT_STRATEGY' }),
66
+ Object.freeze({ file: 'src/tools.js', name: 'COMPONENT_STRATEGIES' }),
67
+ Object.freeze({ file: 'src/tools.js', name: 'strategyFor() (assembles per-grant strategy prose)' }),
68
+ Object.freeze({ file: 'src/tools.js', name: 'LINE_SPACE (module-private, not exported)' }),
69
+ Object.freeze({ file: 'src/tools.js', name: 'PERSONA (module-private, not exported, currently unreferenced)' }),
70
+
71
+ // src/planrun.js — the native-surface read-truncation strategy line
72
+ Object.freeze({ file: 'src/planrun.js', name: 'NATIVE_READ_STRATEGY' }),
73
+ ]);
74
+
75
+ /** The distinct file paths carrying prompt registers, repo-root-relative with
76
+ * forward slashes — derived from `PROMPT_REGISTERS` so the set can never drift
77
+ * from the entries above. @type {ReadonlySet<string>} */
78
+ const PROMPT_FILES = new Set(PROMPT_REGISTERS.map((e) => e.file));
79
+
80
+ /**
81
+ * True when `path` names one of the inventoried prompt-register files. Accepts
82
+ * either a repo-root-relative path (`src/tools.js`) or an absolute/relative
83
+ * path ending in one (`/home/x/bareloop/src/tools.js`, `./src/tools.js`) — git
84
+ * hands the check root-relative paths, but a caller working from an absolute
85
+ * path should not have to strip the prefix itself.
86
+ * @param {string} path
87
+ * @returns {boolean}
88
+ */
89
+ export function isPromptFile(path) {
90
+ if (typeof path !== 'string' || path === '') return false;
91
+ const normalized = path.replace(/\\/g, '/');
92
+ return [...PROMPT_FILES].some((f) => normalized === f || normalized.endsWith(`/${f}`));
93
+ }