bareloop 0.25.0 → 0.26.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 +317 -0
- package/bareloop.context.md +268 -83
- package/package.json +1 -1
- package/src/authorflow.js +713 -92
- package/src/authoring.js +33 -15
- package/src/authorjob.js +158 -5
- package/src/cardauthor.js +28 -18
- package/src/detectlang.js +200 -0
- package/src/index.js +29 -30
- package/src/job.js +3 -2
- package/src/kinds.js +5 -3
- package/src/promptregisters.js +6 -0
- package/src/providers.js +15 -3
- package/src/source.js +153 -33
- package/types/authorflow.d.ts +433 -104
- package/types/authoring.d.ts +23 -8
- package/types/authorjob.d.ts +22 -4
- package/types/cardauthor.d.ts +7 -3
- package/types/detectlang.d.ts +38 -0
- package/types/index.d.ts +16 -16
- package/types/job.d.ts +3 -2
- package/types/kinds.d.ts +5 -3
- package/types/providers.d.ts +9 -2
- package/types/source.d.ts +42 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,323 @@ All notable changes to bareloop are documented here. Format:
|
|
|
5
5
|
[SemVer](https://semver.org/spec/v2.0.0.html). Pre-1.0: **minor** = a ladder rung or
|
|
6
6
|
feature lands, **patch** = docs, fixes, scaffolding.
|
|
7
7
|
|
|
8
|
+
## [0.26.0] — 2026-09-14
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Source and Destination replace `--patient` (PRD item 33 M3, ruling 2):**
|
|
13
|
+
`scripts/run-interview.mjs` now asks Source and Destination as its own first two interactive
|
|
14
|
+
questions, before the picked verdict class's frozen set — never a `--patient` flag. Each is
|
|
15
|
+
proven mechanically, $0, the moment it is answered: Source is checked against the machine and
|
|
16
|
+
(for a local directory) language-detected immediately; Destination's SHAPE depends on what
|
|
17
|
+
Source turned out to be (the same `looksLikeRepoSource` rule `prepareSource` itself uses to
|
|
18
|
+
route this, now exported from `src/source.js` rather than duplicated) — for a repo Source, the
|
|
19
|
+
answer IS the write fence and fills `draft.writeScope` directly (the separate "FENCE" question
|
|
20
|
+
is gone); for every other kind, it is re-asked in a loop until it names an absolute, writable
|
|
21
|
+
directory (`proveDestination`). The moment both are answered, the interview calls
|
|
22
|
+
`prepareSource` itself to freeze Source into a hidden scratch copy under a fresh `into` nested
|
|
23
|
+
inside `--out`, and everything downstream — the class's own questions, the job spec's
|
|
24
|
+
`description`, and the `--source` handed to `scripts/run-author.mjs` — reads that PREPARED
|
|
25
|
+
COPY, never the original again. A non-repo Source gets Source and Destination proven and
|
|
26
|
+
frozen and then an honest named stop: bareloop's check catalogue is code-genre only today
|
|
27
|
+
(ruling 7 → M4); the prepared copy stays on disk regardless. `scripts/run-author.mjs` gains
|
|
28
|
+
`--source <tree>`, replacing `--patient <repoPath>`: it must be a tree a source door already
|
|
29
|
+
prepared (`readSourceManifest(dirname(source))` finds a manifest of kind `'repo'` beside it) —
|
|
30
|
+
an unprepared path dies loud naming the exact `scripts/prep-source.mjs` command to run first,
|
|
31
|
+
and a prepared non-repo source gets the same honest M4 stop, now recorded to the spine as
|
|
32
|
+
counted demand. `scripts/prep-source.mjs`'s printed next-step command follows suit.
|
|
33
|
+
|
|
34
|
+
- **A Source inside a repo (e.g. a monorepo package) is now a repo job (hamr's ruling A, PRD
|
|
35
|
+
item 34 loose end):** `looksLikeRepoSource`/`prepareSource` (`src/source.js`) used to treat a
|
|
36
|
+
folder as a repo source only when `.git` sat directly inside it, so a Source like
|
|
37
|
+
`myrepo/packages/api` fell to the plain-folder path (no checks yet, M4) and could hit an
|
|
38
|
+
untracked `node_modules` symlink as a refusal. A new `nearestGitAncestor(startDir)` walks up
|
|
39
|
+
from a directory to the nearest ancestor carrying a `.git` entry (a real repo directory, or a
|
|
40
|
+
linked-worktree/submodule file) — the one walk now shared by `looksLikeRepoSource`,
|
|
41
|
+
`prepareSource`'s own routing, and `src/detectlang.js`'s boundary walk, replacing three
|
|
42
|
+
separate copies. `prepareSource`'s directory branch freezes the WHOLE found repo's tracked
|
|
43
|
+
files when Source is a subfolder, exactly as it already did for a repo-root Source; the
|
|
44
|
+
manifest gains a `sourceSubdir` field (Source's path relative to the repo root, `''` at the
|
|
45
|
+
root) for a later piece to wire into scope — nothing reads it yet. Edge case, reported not
|
|
46
|
+
solved: a Source pointed at a deep folder under a large repo (e.g. one's whole home directory)
|
|
47
|
+
now freezes that WHOLE repo's tracked files, with no size or depth limit to catch it.
|
|
48
|
+
|
|
49
|
+
- **Language auto-detection (PRD item 33 M3, ruling 3):** `src/detectlang.js`'s `detectLanguage`
|
|
50
|
+
reads a code job's language off its own repository — `package.json` → js (TypeScript
|
|
51
|
+
included), `pyproject.toml`/`setup.py` → python — walking up from the Source folder to the
|
|
52
|
+
nearest ancestor manifest, never past the repository root (the nearest `.git`). A known
|
|
53
|
+
manifest this catalogue has no genre data for yet (`go.mod`, `Cargo.toml`, `pom.xml`,
|
|
54
|
+
`build.gradle(.kts)`, `*.csproj`/`*.sln`, `composer.json`) is a named `language-unsupported`
|
|
55
|
+
stop — never a silent fallback to js — carrying a `Refusal` shaped exactly like
|
|
56
|
+
`src/authorjob.js`'s own (`REFUSAL_LIB`/`REFUSAL_CATEGORY`, `request-red`). Two manifests at
|
|
57
|
+
the same nearest level is a named `ambiguous` result listing both; no manifest anywhere is
|
|
58
|
+
`no-code-job`, which is NOT an error (a plain-folder job still gets the form; M4 gives it
|
|
59
|
+
checks). The whole known-language table is one data list, keyed against `GENRE_LANGUAGES`
|
|
60
|
+
(`src/authoring.js`) — a later language landing there (M3b) needs no new code path here.
|
|
61
|
+
|
|
62
|
+
- **The question sets become the unified intake form (PRD item 33 M3 piece 3, signed ruling
|
|
63
|
+
"The intake form (RULED)").** `src/authorflow.js` reshapes the green/soft-green/hitl question
|
|
64
|
+
sets to the ruled 6-field form: Source and Destination (already asked as mechanical fields
|
|
65
|
+
since M3 piece 2) plus a free-text trio, numbered contiguously 1-3, whose text is now the
|
|
66
|
+
signed table's own "Holds" column, VERBATIM: Goal ("what you want to achieve"), What success
|
|
67
|
+
looks like ("checks a machine can count"), and Guardrails ("what must not happen or change" —
|
|
68
|
+
the old "must not change" and "worse than before" questions JOINED into one field; "worse than
|
|
69
|
+
before" is gone from the form entirely, moving to the confirm turn, piece 4, repo-only — now
|
|
70
|
+
built, see below). Soft-green adds a fourth field, Judge Examples ("one pass, one fail, and why" — the
|
|
71
|
+
old Q6 is retired as its own question, since the "why" half of a real pass/fail pair is what
|
|
72
|
+
`cardauthor.js`'s rubric compile already read it for). Each field's LABEL (Goal / What success
|
|
73
|
+
looks like / Guardrails / Judge examples) is shown for the first time too — a new `labelsFor`
|
|
74
|
+
reader alongside `questionsFor`/`requiredAnswersFor`, and the composer's own interview block
|
|
75
|
+
now shows the label with each answer. hitl (never shown, kept in code) renumbers the same way,
|
|
76
|
+
with no signed-table label for its own fourth question. Source and Destination's own wording
|
|
77
|
+
now also lives in `src/authorflow.js` (`SOURCE_FIELD`, `DESTINATION_FIELD_REPO`,
|
|
78
|
+
`DESTINATION_FIELD_PLAIN`, `destinationFieldFor`), so `scripts/run-interview.mjs` prints
|
|
79
|
+
library text for all six fields, none of its own. What the old Q2 used to tell the composer
|
|
80
|
+
(which files change, which are read-only) now reaches `authorPrompt` through a new optional
|
|
81
|
+
`writeScope` parameter (`writeScopeBlock`), fed from Destination's own proven write-scope
|
|
82
|
+
fence end to end (`authorClose` → `authorCloseForJob` → `scripts/run-author.mjs`'s
|
|
83
|
+
`draft.writeScope`) rather than silently vanishing.
|
|
84
|
+
|
|
85
|
+
- **The confirm turn (PRD item 33 M3 piece 4).** After the survey, `scripts/run-author.mjs`
|
|
86
|
+
now runs a paid, interactive confirm turn (`runConfirmTurn`, `src/authorjob.js` →
|
|
87
|
+
`src/authorflow.js`) before authoring: a $0 half (repo-only "worse than before", an
|
|
88
|
+
ambiguous-language pick, both asked BEFORE the scout) followed by up to 2 paid rounds where
|
|
89
|
+
the model drafts a plan — every check it will compose, the always-on guards as PROTECTIONS
|
|
90
|
+
(never named in the goal), and one signed goal sentence — and the person confirms it, fixes
|
|
91
|
+
it, types the goal themselves, or starts over. No hand-authored matcher ever compares the
|
|
92
|
+
goal against the checks (ruling 6) — the model states its own plan and the person is the one
|
|
93
|
+
judgement that accepts it. `scripts/run-interview.mjs` asks no separate goal question any
|
|
94
|
+
more (ruling 5's addendum, D2 = option B) and no longer dies on an ambiguous-language Source
|
|
95
|
+
(it defers the pick to the confirm turn, D7); `run-author.mjs`'s own ambiguous-language die()
|
|
96
|
+
is likewise gone. The confirm turn's own cost book absorbs the scout's prior spend (and its
|
|
97
|
+
own `costUsd: null` calls) before its first `capStop()` check, so a scout that already spent
|
|
98
|
+
most of the ceiling is visible to it immediately — only the confirm turn's OWN new calls
|
|
99
|
+
travel onward to `authorClose` as `priorCalls`/`priorRaws`, never the scout's a second time.
|
|
100
|
+
`run-author.mjs` is now interactive: a readline `ask` seam (same idiom as
|
|
101
|
+
`run-interview.mjs`'s own), closed in a `finally` around the whole paid span. The confirm
|
|
102
|
+
turn's open questions (a round-2 "fix" passed to the composer verbatim) print at the SIGNING
|
|
103
|
+
PREPARED readout (`openQuestionLines`, `scripts/author-readout.mjs`) — the signed spec format
|
|
104
|
+
itself is unchanged. `authorClose` gains a `confirmed` plan fed into `authorPrompt`'s new
|
|
105
|
+
`confirmedBlock` ("compose these checks and no other"). Every existing caller of
|
|
106
|
+
`authorCloseForJob`/`authorClose`/`authorPrompt` that passes no `ask` runs byte-identical to
|
|
107
|
+
before this piece existed. **`TYPES_GENRE_TEMPLATE` now composes its WORK stages only for a
|
|
108
|
+
confirmed check (D6 = A, "replace it", item 33 step S7):** the frozen TYPES genre template's
|
|
109
|
+
old unconditional work-stage skeleton (`typecheck`, `typecheck-outside`, `tests-kept`,
|
|
110
|
+
`suite-green`) and unconditional STRICT-checker mandate conflicted with ruling 6 ("a genre
|
|
111
|
+
never adds a check the goal did not ask for") for exactly the case run mtv8jihy surfaced (an
|
|
112
|
+
unasked `tsc --strict` stage). The STRICT form of the checker, and the WORK stages themselves,
|
|
113
|
+
are now composed only when a confirmed check — or, absent a confirm turn, the goal and
|
|
114
|
+
interview answers — asks for them; the GUARDS (`changed-from-seed`, `no-suppressions`) stay
|
|
115
|
+
always on, unaffected, since they are enforced structurally (`classGuards` +
|
|
116
|
+
`validateDeclaration`'s guards-absent red), never by this prompt text. The template is prompt
|
|
117
|
+
text handed to the authoring model only — never hashed into a signed spec, `closeDecl`, bundle
|
|
118
|
+
manifest, or bench row signature — so this edit changes nothing about an already-signed close.
|
|
119
|
+
`tests/authoring.test.js`'s byte-identity test is re-pinned to the new frozen block.
|
|
120
|
+
`scripts/run-interview.mjs` asks no separate GOAL question any more (ruling 5's
|
|
121
|
+
addendum, D2 = option B) and no longer dies on an ambiguous-language Source (D7 defers the
|
|
122
|
+
pick to the confirm turn); its own $0 validator pass filters both `goal`
|
|
123
|
+
(`CONFIRM_AUTHORED_FIELDS`) and, for a plain-folder job, `writeScope`
|
|
124
|
+
(`PLAIN_FOLDER_DEFERRED_FIELDS`, both `src/authorjob.js`) reds the same way it already filters
|
|
125
|
+
`AUTHORED_SPEC_FIELDS`'s. **A plain-folder Source no longer stops the interview at all (PRD
|
|
126
|
+
item 33 M3 piece 4, step S6, D5 = A ruling):** the form continues — class questions, job name,
|
|
127
|
+
budget, wall, and the offer — and the draft is written with no `writeScope` (Destination there
|
|
128
|
+
is an output directory, never a fence). The honest "no checks yet" stop (ruling 7 → M4) moves
|
|
129
|
+
to `run-author.mjs`, which now runs a plain-folder job's confirm turn too — over a $0, no-git
|
|
130
|
+
listing of the frozen tree rather than a scout (D5: the scout's register is code-only) — before
|
|
131
|
+
giving that same stop. If the confirm turn itself does not reach a signed plan, that stop
|
|
132
|
+
stands instead; the non-code-source stop only fires once a person actually confirmed one.
|
|
133
|
+
|
|
134
|
+
### Removed
|
|
135
|
+
|
|
136
|
+
- **BREAKING: soft-green's rubric-card/calibration answer keys change shape (PRD item 33 M3
|
|
137
|
+
piece 3).** The old two-question pair (`answers[6]`, `answers[7]`) is now ONE answer at key
|
|
138
|
+
`4` (`SOFTGREEN_JUDGE_EXAMPLES_KEY`) — `src/cardauthor.js`'s `cardCasesPrompt` reads that one
|
|
139
|
+
key instead. Any hand-authored `answers.json` from before this change needs its keys
|
|
140
|
+
reshaped: green's old five (1-5) become three (1-3, Guardrails absorbing the old 3 and 5);
|
|
141
|
+
soft-green's old seven (1-7) become four (1-4).
|
|
142
|
+
- **BREAKING: `--patient` is gone from `scripts/run-interview.mjs` and `scripts/run-author.mjs`
|
|
143
|
+
(PRD item 33 M3, ruling 2).** `run-interview.mjs` asks Source (and Destination) as its own
|
|
144
|
+
first questions instead; `run-author.mjs` takes `--source <tree>`, which must be a prepared
|
|
145
|
+
copy (see "Added", above). Passing `--patient` to either script now is a loud, explicit
|
|
146
|
+
refusal naming its replacement, rather than a silently-ignored or misrouted flag.
|
|
147
|
+
- **BREAKING: `--lang` is gone from `scripts/run-interview.mjs` and `scripts/run-author.mjs`.**
|
|
148
|
+
Language is now auto-detected from Source's own repository (see "Added", above) — it is
|
|
149
|
+
a fact of the repo, never a flag a person sets. Passing `--lang` now is a loud, explicit
|
|
150
|
+
refusal naming the flag and why, rather than a silently-ignored no-op.
|
|
151
|
+
|
|
152
|
+
### Fixed
|
|
153
|
+
|
|
154
|
+
- **The confirm turn's "protections" now come from code, never the model (item 34 loose-end
|
|
155
|
+
fix, finding #1 from live run mu0voeo4):** the confirm turn used to display whatever prose the
|
|
156
|
+
model invented for `protections`, and one live run invented a "behavior-preservation guard"
|
|
157
|
+
this build has no way to check (no kind in the catalogue can verify runtime behaviour). The
|
|
158
|
+
model is no longer asked for `protections` at all — the schema dropped the field — and what a
|
|
159
|
+
person sees and what gets recorded as `accepted.protections` is now rendered from the SAME
|
|
160
|
+
guards `classGuards` will actually compose (`src/authoring.js`'s `MECHANICAL_GUARDS`), through
|
|
161
|
+
a frozen plain-English line per guard (`GUARD_DESCRIPTIONS`, `src/authorflow.js`), plus the
|
|
162
|
+
write fence when one is set. The model instead returns `notChecked` — anything the person asked
|
|
163
|
+
for that no listed check can verify — shown under its own heading in the menu and in the
|
|
164
|
+
composer's confirmed-plan block, never silently dropped.
|
|
165
|
+
- **`run-interview.mjs`'s paid-step hand-off no longer describes a scout a plain folder
|
|
166
|
+
never gets (item 34 loose-end fix):** since 21561cf (D5=A), a non-repo Source gets no
|
|
167
|
+
scout — the confirm turn reads the file list and `run-author.mjs` stops at the M4 wall
|
|
168
|
+
("no checks for this kind of job yet") before signing is ever reached. The hand-off text
|
|
169
|
+
printed the repo-only wording ("a real scout over that repository", "It stops at
|
|
170
|
+
prepareSigning") for every source regardless. A plain-folder session now prints its own
|
|
171
|
+
line naming the confirm turn and the M4 stop; a repo session's wording is unchanged.
|
|
172
|
+
- **`run-author.mjs`'s `language-unsupported` stop is now counted admission demand (item 34
|
|
173
|
+
loose-end fix on M3):** the check used to print the refusal and `process.exit(1)` before the
|
|
174
|
+
run's spine even existed, so nothing recorded it. The spine is now bootstrapped first (before
|
|
175
|
+
any provider is resolved, before the API key is read, before any spend) and the stop is
|
|
176
|
+
emitted through the same `refusalEvents()` channel every other refusal in the script uses,
|
|
177
|
+
so it folds into `src/ledger.js`'s `classifyIncidents` admission count instead of vanishing.
|
|
178
|
+
`run-interview.mjs`'s own printed line for the same stop no longer claims "the refusal IS the
|
|
179
|
+
record" — that script keeps no spine of its own, so it now says plainly that nothing here
|
|
180
|
+
recorded it, and points at `run-author.mjs` for the one that does.
|
|
181
|
+
- **Scan-then-freeze TOCTOU closed in the source front door (PRD item 34 L1):**
|
|
182
|
+
`prepareSource`'s folder/repo path used to hash+secret-scan each file's bytes once, then
|
|
183
|
+
re-read the same file a SECOND time off disk (`copyFile`) to freeze it into the hidden
|
|
184
|
+
tree — a window where a file changed on disk between the two reads would have its secret
|
|
185
|
+
scan run against different bytes than the ones actually frozen. The freeze step now
|
|
186
|
+
re-hashes its own (second) read and refuses (`source-changed-after-scan`) on any mismatch
|
|
187
|
+
against the scan-time hash, rather than caching every file's buffer (which would hold a
|
|
188
|
+
whole repo in memory at once — the streaming scan design exists to avoid exactly that).
|
|
189
|
+
`copyFile`'s mode-bit preservation is kept explicitly (`stat` + `chmod` on the frozen
|
|
190
|
+
file), verified not to regress.
|
|
191
|
+
- **A gitignored/untracked subfolder inside a repo no longer freezes into an empty
|
|
192
|
+
claim (hamr's ruling A, PRD item 34 loose end, 2026-09-13):** the ruling-2 addendum's
|
|
193
|
+
"a Source subfolder is a repo job" rework froze the WHOLE repo's tracked files, but
|
|
194
|
+
`listRepoFiles` only ever returns tracked paths — when Source itself is a subfolder git
|
|
195
|
+
tracks nothing under (`.gitignore`'d, or simply never committed), the freeze used to
|
|
196
|
+
succeed anyway with a `kind: 'repo'` tree holding none of Source's own files, silently
|
|
197
|
+
vanishing the person's input. `prepareSource` now refuses `source-untracked-in-repo`
|
|
198
|
+
before `into` is created — a repo-root Source, and a subfolder with at least one tracked
|
|
199
|
+
file underneath it, are unaffected.
|
|
200
|
+
- **The documented-exports guard now reads the doc instead of a hand-typed array (F167,
|
|
201
|
+
PRD item 34 L4):** `tests/index.test.js`'s "documented public surface" test used to check
|
|
202
|
+
a list of names copied out of `bareloop.context.md` by hand — the same class of bug that
|
|
203
|
+
let `datedDestination`/`pickDelivery` ship `undefined` in v0.25.0 while the guard stayed
|
|
204
|
+
green. `documentedExportNames` now parses the doc live (import-block examples, Public API
|
|
205
|
+
section headings, `Menus exported:` lists, and tight "X is/are exported" proximity) and
|
|
206
|
+
found two more real gaps the hand list missed: `cliMain` and (already fixed) the two
|
|
207
|
+
source-front-door helpers. Covers the doc's explicit export-marker idioms, not every
|
|
208
|
+
function mentioned in flowing prose — a broader sweep was tried and produced 21 false
|
|
209
|
+
positives out of 97 candidates on this doc, noise a regex cannot safely resolve.
|
|
210
|
+
- **The export list now equals the documented contract exactly, guarded both ways (PRD
|
|
211
|
+
item 34 L20):** the 91 undocumented names that were genuinely discussed in
|
|
212
|
+
`bareloop.context.md` prose (the "Close authoring", "Bundles", "THE REVIEW DOOR", "The
|
|
213
|
+
reuse ENVELOPE" and ledger sections — none of which used per-function `###` headings, so
|
|
214
|
+
the extractor's marker idioms could not credit any name in them) now carry an explicit
|
|
215
|
+
`import { ... } from 'bareloop'` marker next to their existing prose, including
|
|
216
|
+
`JUDGED_MARKER` (previously undocumented anywhere despite being required by every close
|
|
217
|
+
script this repo ships and by `exportBundle`'s `close-import-unexported` legality check).
|
|
218
|
+
`tests/index.test.js`'s guard is now a full two-way check — every export must be
|
|
219
|
+
documented and every documented name must be exported — replacing the one-directional
|
|
220
|
+
guard and the item-34-L4-scoped "37 restored" test, both now fully subsumed. Two
|
|
221
|
+
exclusions carry forward unchanged: `main` (the doc's pre-rename local name for the real
|
|
222
|
+
export `cliMain`) and `resumableOutcomes` (its own "exported" sentence describes "bundle",
|
|
223
|
+
not this name — the real export is `CHECKPOINT_OUTCOMES`).
|
|
224
|
+
- **The doc-reading extractor's own coverage gap closed (PRD item 34 L4 follow-up):** the
|
|
225
|
+
switch to reading `bareloop.context.md` live covered fewer names than the hand-typed array
|
|
226
|
+
it replaced — 37 exported names (`mintBridge`, `appendGreen`, `BRIDGE_SCHEMA`, the rest of
|
|
227
|
+
the reuse registry, plus `runStages`/`globToPrefix`/`scanSecrets`/three ledger helpers) sat
|
|
228
|
+
in flowing prose with no marker idiom the extractor reads, so the guard silently stopped
|
|
229
|
+
covering them. `bareloop.context.md` now carries an explicit marker (an `import { ... }
|
|
230
|
+
from 'bareloop'` example, or a tight "X is/are exported" sentence) for each of the 37, and
|
|
231
|
+
`tests/index.test.js` pins that they stay derived. A live count found 169 of
|
|
232
|
+
`src/index.js`'s 255 exports still undocumented by any marker idiom — reported, not fixed
|
|
233
|
+
here; a full reverse guard (every real export documented) was considered and rejected as
|
|
234
|
+
out of this fix's scope.
|
|
235
|
+
- **`SCOUT_LABEL` gains a third state in `scripts/run-u.mjs` (PRD item 34 L2):** an explicit
|
|
236
|
+
`--scout on` used to print the identical "scout ON (default)" text as no flag at all,
|
|
237
|
+
indistinguishable in printed logs/re-invocation lines — which matters for the
|
|
238
|
+
SCOUT-CONTRAST bench row's provenance. It now prints `scout ON (--scout on — operator
|
|
239
|
+
explicit)`, distinct from the true default and from `--scout off`'s unchanged label.
|
|
240
|
+
- **Job authoring is LLM-agnostic (PRD item 34 L17):** `scripts/run-author.mjs` no longer
|
|
241
|
+
forces `PROVIDER_NAME = 'anthropic-api'` for its scout and drafter — the identity is now
|
|
242
|
+
resolved from the operator's own draft (`resolveProvider(draft.provider)`), the same
|
|
243
|
+
no-flag/no-default rule `scripts/run-u.mjs` applies to the worker; a missing or
|
|
244
|
+
unrecognized draft provider dies loud, at $0, before any paid call, naming the known
|
|
245
|
+
table. `scripts/run-interview.mjs` gains a REQUIRED `--provider` flag with no default (a
|
|
246
|
+
default would silently re-lock every interview onto one vendor) and writes it into the
|
|
247
|
+
draft; the paid-step offer's key line and unset-key notice now name whichever provider's
|
|
248
|
+
own env var applies, never a hardcoded `ANTHROPIC_API_KEY`. Non-Anthropic drafting is
|
|
249
|
+
legal as of this change but not yet proven live — that is M3's DeepSeek proof run, not
|
|
250
|
+
this one.
|
|
251
|
+
|
|
252
|
+
### Docs
|
|
253
|
+
|
|
254
|
+
- **`npx @scope/pkg`-shaped close commands documented as a KNOWN, KEPT limit (PRD item 34
|
|
255
|
+
L3):** `closeScriptCandidateToken`'s path-shaped test (`src/validate.js`) reads a scoped
|
|
256
|
+
package name as a script path because it contains `/`, so such a close can never be
|
|
257
|
+
signed — `bareloop.context.md` now says so next to the scope note it belongs beside. Not
|
|
258
|
+
fixed: it fails safe and no shipped job uses the shape.
|
|
259
|
+
|
|
260
|
+
### Changed
|
|
261
|
+
|
|
262
|
+
- **DeepSeek secondary model swap (F171, PRD item 34 L16):** `deepseek-chat` is no longer
|
|
263
|
+
served by DeepSeek's API (a live `/models` call returned only `deepseek-flash` and
|
|
264
|
+
`deepseek-v4-pro`). The `openai-api` tier table (`src/providers.js`) and its per-model
|
|
265
|
+
`legacyMaxTokens` request-key gating now name `deepseek-flash`. F149's gating measurement
|
|
266
|
+
was taken on `deepseek-chat` and is carried forward UNVERIFIED on `deepseek-flash`;
|
|
267
|
+
pricing stays the estimated default (F113 unchanged).
|
|
268
|
+
- **`hitl` removed from every customer-facing surface (PRD item 34 L19):** `bareloop.context.md`,
|
|
269
|
+
and the usage/help text of `scripts/run-author.mjs` and `scripts/run-interview.mjs`, no
|
|
270
|
+
longer name `hitl` anywhere. The class, its terminals (`hitl-pause`, `hitl-decision-red`,
|
|
271
|
+
the legacy human-close terminal) and its `human-confirms` stage kind are untouched in code —
|
|
272
|
+
kept admitted for reuse, never revived, never shown to a customer again. The counted-demand
|
|
273
|
+
refusal a person sees when they pick an off-menu verdict class is unchanged (it names the
|
|
274
|
+
class and fwdloop by design). `tests/hitl-hidden.test.js` pins the doc and both scripts
|
|
275
|
+
case-insensitively hitl-free.
|
|
276
|
+
|
|
277
|
+
### Removed
|
|
278
|
+
|
|
279
|
+
- **BREAKING: 78 undocumented names dropped from the `src/index.js` root export list (PRD
|
|
280
|
+
item 34 L20, owner's option A):** a live audit found 169 of 255 root exports had zero real
|
|
281
|
+
citation in `bareloop.context.md`; 91 of those were genuinely discussed in the doc's
|
|
282
|
+
prose and gained an explicit marker (see Fixed, above) instead of being dropped, but the
|
|
283
|
+
remaining 78 had no adopter-facing mention anywhere and no in-repo consumer reaching them
|
|
284
|
+
through the package root — a name imported directly from `import { x } from 'bareloop'`
|
|
285
|
+
and nothing else. Every dropped name's own module is untouched; only the root re-export
|
|
286
|
+
is gone, and each still exists inside its own module for the library's own internal use —
|
|
287
|
+
but `package.json`'s `exports` map only `"."` to `src/index.js`, so a package user can no
|
|
288
|
+
longer reach any of them, including via a submodule path such as `src/text.js`. Dropped:
|
|
289
|
+
`artifactHash`, `authorPrompt`,
|
|
290
|
+
`BASELINES`, `CALIBRATION_LABEL`, `cardCasesPrompt`, `CASE_VERDICTS`, `CATALOGUE_KINDS`,
|
|
291
|
+
`CATALOGUE_LIVE_KINDS`, `changedSet`, `classifySurvey`, `classMenu`, `CLASS_STATEMENTS`,
|
|
292
|
+
`CLOSE_DECL_FIELDS`, `closeGrade`, `compareExpectation`, `COMPILE_SYSTEM`,
|
|
293
|
+
`createReadShim`, `declarationSchema`, `DECLARED_CLOSE_CLASSES`, `DECLARED_GAP_KEEP`,
|
|
294
|
+
`DECLARED_GAP_PREFIX`, `DECLARED_GENRES`, `defaultJudgeLoop`, `DIRECTIONS`, `doorAgeGate`,
|
|
295
|
+
`doorRecordOf`, `EXIT_GREEN`, `EXIT_RED`, `EXIT_STOP`, `factsResist`, `GENRE`,
|
|
296
|
+
`GENRE_LANGUAGES`, `genreOwnedEnvNames`, `GREEN_QUESTIONS`, `guardNames`,
|
|
297
|
+
`HITL_DECISION_RED`, `HITL_PAUSE`, `HUMAN_CHECKPOINTS`, `INJECTION_CARD`,
|
|
298
|
+
`isDeclaredClose`, `JUDGED_FLOOR_KIND`, `JUDGE_MAX_TOKENS`, `LIVE_CLASSES`,
|
|
299
|
+
`LOCATE_AXES`, `LOCATE_LABEL`, `locatePrompt`, `makeLoopGenerate`, `makeSeedTrees`,
|
|
300
|
+
`MAX_PROPOSAL_RETRIES`, `MAX_STAGES`, `normalizeDeclaration`, `prepareWorkBranch`,
|
|
301
|
+
`PROPOSAL_LABEL`, `proposalSchema`, `proposalTool`, `PROPOSAL_TOOL_NAME`,
|
|
302
|
+
`QUARANTINED_CODE`, `QUESTION_SETS`, `RAW_TRIM_MARKER`, `READ_SHIM_ARMS`,
|
|
303
|
+
`readShimStrategy`, `REFUSAL_CATEGORY`, `REFUSAL_LIB`, `REVIEW_DOOR`, `seedFileList`,
|
|
304
|
+
`seedListing`, `shapeForkName`, `SOFTGREEN_QUESTIONS`, `SURVEY_CAUSES`, `TYPES_GENRE`,
|
|
305
|
+
`TYPES_GENRE_TEMPLATE`, `validateCard`, `validateFacts`, `validateJudgedArtifacts`,
|
|
306
|
+
`VERDICT_CLASSES`, `WORK_BRANCH_PREFIX`, `WORK_BRANCH_RE`, `wrapReadTool`. No in-repo
|
|
307
|
+
importer reached any of these through the package root (verified against every
|
|
308
|
+
`from '../src/index.js'` / `from './index.js'` / `from 'bareloop'` site in the tree), so
|
|
309
|
+
nothing else in this repo needed a path change.
|
|
310
|
+
|
|
311
|
+
## [0.25.1] — 2026-09-13
|
|
312
|
+
|
|
313
|
+
### Fixed
|
|
314
|
+
|
|
315
|
+
- **Package-root export gap (PRD item 33/M2 follow-up):** `bareloop.context.md` documents
|
|
316
|
+
`datedDestination(destination, now, n)` and `pickDelivery(destination, now?)` as exported
|
|
317
|
+
from the package root, but `src/index.js`'s `./source.js` re-export only carried
|
|
318
|
+
`prepareSource`, `proveDestination`, `copyOut`, `readSourceManifest`,
|
|
319
|
+
`frontDoorFromManifest` — both helpers existed in `src/source.js` but were `undefined`
|
|
320
|
+
when imported as `import { datedDestination, pickDelivery } from 'bareloop'`. Caught by a
|
|
321
|
+
clean-consumer import check of the published v0.25.0 package. Both names are now
|
|
322
|
+
re-exported from `src/index.js`; `tests/index.test.js` pins them against `src/source.js`
|
|
323
|
+
identity.
|
|
324
|
+
|
|
8
325
|
## [0.25.0] — 2026-09-12
|
|
9
326
|
|
|
10
327
|
### Added
|