bareloop 0.26.0 → 0.28.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 +271 -0
- package/bareloop.context.md +308 -38
- package/package.json +4 -3
- package/src/authorflow.js +255 -33
- package/src/authorjob.js +12 -9
- package/src/authorreadout.js +323 -0
- package/src/authorrun.js +1337 -0
- package/src/authorscout.js +16 -11
- package/src/cli.js +130 -8
- package/src/index.js +14 -2
- package/src/interviewrun.js +842 -0
- package/src/job.js +42 -26
- package/src/planrun.js +82 -3
- package/src/promptregisters.js +8 -0
- package/src/providers.js +36 -0
- package/src/replayio.js +153 -0
- package/src/reuse.js +1 -1
- package/src/run.js +1 -1
- package/src/source.js +138 -1
- package/src/text.js +45 -0
- package/src/u-patient.js +73 -0
- package/src/u-readout.js +451 -0
- package/src/userrun.js +2273 -0
- package/src/validate.js +25 -1
- package/types/authorflow.d.ts +49 -7
- package/types/authorreadout.d.ts +172 -0
- package/types/authorrun.d.ts +37 -0
- package/types/index.d.ts +3 -2
- package/types/interviewrun.d.ts +46 -0
- package/types/job.d.ts +21 -0
- package/types/planrun.d.ts +43 -3
- package/types/providers.d.ts +28 -0
- package/types/replayio.d.ts +93 -0
- package/types/reuse.d.ts +2 -2
- package/types/run.d.ts +2 -2
- package/types/source.d.ts +45 -0
- package/types/text.d.ts +35 -0
- package/types/u-patient.d.ts +39 -0
- package/types/u-readout.d.ts +247 -0
- package/types/userrun.d.ts +134 -0
- package/types/validate.d.ts +22 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,277 @@ 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.28.0] — 2026-09-24
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`bareloop run-u`, `bareloop interview`, `bareloop author`, and `bareloop replay` (+
|
|
13
|
+
`--all`)** — four new CLI commands giving the panel's (N6) planned History/Run/Audit
|
|
14
|
+
surfaces, and any other adopter, a library-backed door onto machinery that previously
|
|
15
|
+
existed only as standalone scripts (`scripts/run-u.mjs`, `scripts/run-interview.mjs`,
|
|
16
|
+
`scripts/run-author.mjs`, `scripts/run-replay.mjs`). Each new command dispatches argv
|
|
17
|
+
straight to a library module's own `main(argv, deps)` — one owner per flag grammar — so
|
|
18
|
+
the CLI and the standalone script converge on the exact same code path. `bareloop replay
|
|
19
|
+
--all <dir>` lists every spine under a directory.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **`scripts/run-u.mjs`, `scripts/run-interview.mjs`, `scripts/run-author.mjs`, and
|
|
24
|
+
`scripts/run-replay.mjs` lifted into `src/`** (`src/userrun.js`, `src/interviewrun.js`,
|
|
25
|
+
`src/authorrun.js`, `src/replayio.js`, plus `src/authorreadout.js`, `src/u-patient.js`,
|
|
26
|
+
`src/u-readout.js` moved outright to sit under `tsc`'s `rootDir`). Each script is now a
|
|
27
|
+
thin (~15–20 line) adapter over its library module, the same shape `bin/bareloop.mjs`
|
|
28
|
+
already is over `src/cli.js`. Behaviour-preserving: every `console.log`/`console.error`
|
|
29
|
+
became an injectable `out`/`err`, every `process.exit(n)` became a thrown `ExitSignal(n)`
|
|
30
|
+
caught at the function's own boundary (a library function never calls `process.exit`
|
|
31
|
+
itself), and `process.env`/`process.argv` reads became injectable parameters. Moving this
|
|
32
|
+
code under `rootDir` exposed it to `tsc` for the first time, surfacing and fixing ~26 real
|
|
33
|
+
`strictNullChecks` errors (no `!`, `as any`, or `@ts-ignore`), including one genuine
|
|
34
|
+
type-annotation bug (`humanRuling.text` declared `string?` when the real value flows
|
|
35
|
+
`string|null`).
|
|
36
|
+
- **`src/cli.js`'s bare interactive menu** now lists `run-u`, `interview`, `author`, and
|
|
37
|
+
`replay` alongside the existing commands (previously unlisted even though they already
|
|
38
|
+
existed on the command line), and usage/error text in `src/interviewrun.js`/
|
|
39
|
+
`src/authorrun.js` now names the command actually typed (`bareloop interview`/`bareloop
|
|
40
|
+
author`) instead of a hardcoded script path, when invoked that way.
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- **`doRun`'s job-end spine read could crash an otherwise-successful run's tail.** A
|
|
45
|
+
hand-rolled `readFileSync(...).split('\n').map(JSON.parse)` outside any try/catch threw
|
|
46
|
+
uncaught on a spine with a malformed/truncated final line (e.g. a process killed
|
|
47
|
+
mid-append). Retargeted onto the existing tolerant `parseJsonl` (now in
|
|
48
|
+
`src/replayio.js`), which skips a bad line instead of throwing.
|
|
49
|
+
- **F193/F194 — the prompt-commit-check's prose-only exemption.** A commit touching a
|
|
50
|
+
registered prompt-register file normally needs Failure/Addresses/Corrects labels plus a
|
|
51
|
+
run citation; a narrow, fail-closed exemption now applies when every changed line in
|
|
52
|
+
every touched prompt-register file is provably prose-only (whitespace or a comment),
|
|
53
|
+
decided by scanning real old/new diff text rather than the commit message. F194 closed a
|
|
54
|
+
follow-up hole where a blank line inserted or deleted inside a still-open template
|
|
55
|
+
literal was misclassified prose-only and wrongly exempted.
|
|
56
|
+
|
|
57
|
+
## [0.27.0] — 2026-09-21
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
|
|
61
|
+
- **`bare-agent` bumped `^0.42.0` → `^0.43.0`.** Ships BA-27 (bareloop's own corroborating
|
|
62
|
+
upstream ask, `docs/product/UPSTREAM-ASKS.md`): `OpenAIProvider`/`OllamaProvider.generate` no
|
|
63
|
+
longer throw a raw `SyntaxError` when a model's tool-call `arguments` string is malformed JSON —
|
|
64
|
+
the shared `parseToolCalls` helper returns the round priced (real `usage`) with `toolCalls: []`
|
|
65
|
+
plus its own `malformedToolCall: {name, error}` marker instead, and `Loop.run` surfaces that
|
|
66
|
+
marker unchanged on its return. No other package changed (`package-lock.json` diff is
|
|
67
|
+
`bare-agent` only).
|
|
68
|
+
|
|
69
|
+
### Removed
|
|
70
|
+
|
|
71
|
+
- **`withMalformedToolCallShim`, bareloop's local F179 stopgap (`src/authorflow.js`, added
|
|
72
|
+
2026-09-15 commit `96866d5`).** Deleted now that bare-agent 0.43.0 fixes BA-27 upstream —
|
|
73
|
+
`makeLoopGenerate` calls `loop.run()` directly again, no delegate provider. `askStructured`'s
|
|
74
|
+
`r?.malformedToolCall` check (`e9e2839`) is unchanged and now reads bare-agent's own field.
|
|
75
|
+
- **`callCasualty`'s SyntaxError admission (`src/text.js`)**, dead code once no provider bareloop
|
|
76
|
+
constructs (`AnthropicProvider`, `OpenAIProvider`, `GeminiProvider` — `src/providers.js`) can
|
|
77
|
+
still throw a JSON `SyntaxError` out of `generate()` after a billed round: verified against
|
|
78
|
+
0.43.0's installed source that Anthropic and Gemini read tool-call arguments as already-parsed
|
|
79
|
+
objects (nothing to `JSON.parse` in their response paths), and every provider's raw-HTTP-body
|
|
80
|
+
parse is already try/catch-wrapped inside `_request`. The idle-timeout (ETIMEDOUT/TimeoutError)
|
|
81
|
+
admission is unchanged.
|
|
82
|
+
|
|
83
|
+
### Fixed
|
|
84
|
+
|
|
85
|
+
- **The publish workflow now fails when `package-lock.json`'s version drifts from `package.json`.** npm writes that field on install, so a release that bumps `package.json` without running one leaves it behind — and nothing caught it: `npm ci` fails when the lockfile's *dependency* entries disagree, but never checks the lockfile's copy of the project's own version. `scripts/check-lockfile.mjs` (`npm run check:lockfile`) compares both places npm writes it and runs in the publish workflow. No lockfile is not a failure.
|
|
86
|
+
|
|
87
|
+
- **F191 — a plain-folder source's confirm turn crashed live (run `mu4hc7sp`), leaving a
|
|
88
|
+
two-record spine (`author-start`, `author-phase confirm`) with no ending at all.**
|
|
89
|
+
`confirmProtections` computes protections via `classGuards` (`src/authoring.js`), which is
|
|
90
|
+
keyed by CODE LANGUAGE and throws on a plain folder's `lang: 'none-detected'` — a plain
|
|
91
|
+
folder has no language, so a confirm turn cannot honestly show real, code-derived protections
|
|
92
|
+
for one. `scripts/run-author.mjs` no longer runs a confirm turn over a plain folder at all:
|
|
93
|
+
the honest "no checks yet" stop now fires immediately after `author-start`, at $0 — no scout,
|
|
94
|
+
no confirm turn, no model call. The now-unreachable confirm-turn branch (~70 lines) is
|
|
95
|
+
deleted. Alongside it, the try/catch crash net (which used to start ~300 lines after
|
|
96
|
+
`author-start`, leaving exactly the gap this crash fell into) now opens immediately after the
|
|
97
|
+
spine exists, and its crash message reads the run's own metered-call list rather than
|
|
98
|
+
unconditionally claiming "died inside the paid span". Customer-facing text in
|
|
99
|
+
`scripts/run-interview.mjs`/`bareloop.context.md` that promised a plain-folder confirm turn
|
|
100
|
+
is corrected to match. Fail-first proven in tests (each of the three code changes shown red
|
|
101
|
+
against the prior commit, green after); a new live end-to-end test proves zero provider calls.
|
|
102
|
+
Three follow-up fixes landed in the same pass: the stop's own text claimed "Nothing was spent
|
|
103
|
+
and nothing was written," while the same branch writes `authored.json` into `--out` — both this
|
|
104
|
+
message and `scripts/run-interview.mjs`'s matching install-gap line now read "Nothing was spent.
|
|
105
|
+
Your source was not changed." (true on both counts: no provider call happens on this path, and
|
|
106
|
+
the source tree itself is never touched); an F71 regression (`process.exit(1)` right after a
|
|
107
|
+
`console.log`, which can discard already-queued stdout under a slow reader) was fixed back to
|
|
108
|
+
`process.exitCode = 1`; and a duplicate `spine <path>` print this exitCode fix's fall-through
|
|
109
|
+
briefly introduced was removed (the shared tail print already covers this exit path). Not yet
|
|
110
|
+
re-run against the original crashing patient (`docs/logs/FINDINGS.md` F191).
|
|
111
|
+
- **F190 — fixed properly this pass.** The prior fix (commit 56bbee8) hand-copied
|
|
112
|
+
`scripts/run-u.mjs`'s same-provider `baseUrl` conditional a second time. Both the author and
|
|
113
|
+
judge provider constructions in `scripts/run-author.mjs` now go through `buildRunnerProviders`
|
|
114
|
+
(`src/providers.js`), the one seam `src/cli.js` already used — this file was the one call
|
|
115
|
+
site that had not adopted it. Not yet re-proven live (`docs/logs/FINDINGS.md` F190).
|
|
116
|
+
- **F185 — an interview-authored repo job had no code path INTO `scripts/run-u.mjs`: a person
|
|
117
|
+
finishing the authoring interview was left holding a signed, hash-stable `resolved-spec.json`
|
|
118
|
+
with no way to run it, only a developer hand-step (`cp` the spec into `jobs/` + hand-add a
|
|
119
|
+
`JOBS` row).** hamr's ruling (2026-09-16, option A): `scripts/run-u.mjs` now accepts `--spec
|
|
120
|
+
<path to resolved-spec.json>` as an alternative to `--job <key>` (giving both, or neither, is a
|
|
121
|
+
loud $0 refusal). It `validateJob`'s the spec explicitly and early, then reads the workdir and
|
|
122
|
+
seed off the prepared copy's OWN source manifest (`readSourceManifest`, `src/source.js` — the
|
|
123
|
+
same reader `run-author.mjs` already uses) — the one `source-*/` sibling directory beside the
|
|
124
|
+
spec that carries a `source.json`; never typed, guessed, or defaulted, and a missing/ambiguous
|
|
125
|
+
manifest or a gone tree each refuse by name. `scripts/run-author.mjs`'s "SIGNING PREPARED — NOT
|
|
126
|
+
SIGNED" end screen now prints the exact ready-to-paste run command (real spec path, real
|
|
127
|
+
`--approve <hash>`, the provider's real env-key name per F187). Every existing arbiter gate —
|
|
128
|
+
the `--approve` signature, the budget/wall ceilings, coldReset, the close-first precheck —
|
|
129
|
+
applies unchanged; `--spec` only NAMES the job. Not yet proven live (`docs/logs/FINDINGS.md`
|
|
130
|
+
F185).
|
|
131
|
+
- **F183 — the confirm turn's model-facing prompt never showed the model the real, code-derived
|
|
132
|
+
guards or write fence, so `notChecked` could (and twice live did, runs `mu2bjmed` and
|
|
133
|
+
`mu2qmept`) falsely claim an already-enforced protection was missing** (e.g. "no ts-ignore
|
|
134
|
+
comments" and "do not edit or delete tests", while `no-suppressions` and the write fence
|
|
135
|
+
already covered both). hamr's ruling A (2026-09-16): feed the real protections in as facts,
|
|
136
|
+
never drop the model's list. `confirmProtections`'s existing code-derived list (the same one
|
|
137
|
+
already shown to the person, `src/authorflow.js`) is now computed once, before the model
|
|
138
|
+
drafts, and threaded into `confirmPrompt`'s model-facing prompt as an "ALREADY COVERED" block;
|
|
139
|
+
`CONFIRM_SYSTEM` now orders the model to check that list before naming anything in
|
|
140
|
+
`notChecked`. The model still authors `notChecked` freely — nothing made deterministic, no
|
|
141
|
+
second hand-typed guard list. Not yet proven live (`docs/logs/FINDINGS.md` F183).
|
|
142
|
+
- **Item 6 — `src/authoring.js`'s `TYPES_GENRE_TEMPLATE` (model-facing prompt text,
|
|
143
|
+
interpolated verbatim into the authoring prompt) was missing from `src/
|
|
144
|
+
promptregisters.js`'s `PROMPT_REGISTERS` inventory entirely.** Added; no other prompt content
|
|
145
|
+
found in that file. `docs/product/PRD.md`'s item 33 close-out box ticked.
|
|
146
|
+
- **F182 — the interview never waited for the install, so "Run it now?" was unreachable for a
|
|
147
|
+
repo that needs packages.** `scripts/run-interview.mjs` printed the install-gap message right
|
|
148
|
+
after `prepareSource` and fell straight through to the class questions, only re-checking
|
|
149
|
+
`missingDependencies` once, at hand-off — too late for the offer to ever fire. It now pauses
|
|
150
|
+
right there and loops on the same check (`"Press Enter once it has finished to check again, or
|
|
151
|
+
type skip to carry on without it: "`), printing `"packages found — carrying on."` on a
|
|
152
|
+
resolved recheck; `skip` or end of input carries on unresolved, same as before. Also drops the
|
|
153
|
+
misleading "then rerun this command" wording, which pointed at restarting the whole interview
|
|
154
|
+
when only the install is needed. Not yet proven live.
|
|
155
|
+
- **F181 — a key with an embedded newline (or other control character, or stray whitespace)
|
|
156
|
+
read as "set" by every presence-only key check and then crashed Node's own header-encode
|
|
157
|
+
(`ERR_INVALID_CHAR`) inside the paid span, rather than refusing at $0.** One exported pure
|
|
158
|
+
helper, `apiKeyProblem(value)` (`src/providers.js`, beside the provider table), reports a
|
|
159
|
+
plain-English reason (or `null`) for a value carrying CR, LF, TAB, another C0/DEL control
|
|
160
|
+
character, or leading/trailing whitespace — it never trims or repairs. Wired at every door
|
|
161
|
+
that already presence-checks a key: `scripts/run-author.mjs` (worker and judge keys),
|
|
162
|
+
`scripts/run-u.mjs` (worker and judge keys), `src/cli.js`'s `bareloop run`
|
|
163
|
+
(`ANTHROPIC_API_KEY`), and `scripts/run-interview.mjs`'s `KEYED` offer gate (a malformed key
|
|
164
|
+
no longer counts as keyed). Every refusal names the env var and the reason class, never the
|
|
165
|
+
value. Not yet proven live.
|
|
166
|
+
- **F187 — `scripts/run-u.mjs`'s printed invocation hints (the "approve and run" line and the
|
|
167
|
+
sleep-inhibitor wrapper line, both built through the shared `invoke()` helper) always named
|
|
168
|
+
`ANTHROPIC_API_KEY`, regardless of the job's actual provider.** A job on `openai-api`
|
|
169
|
+
(DeepSeek) printed the wrong variable name to set. `invoke()` now reads `providerEntry.envKey`
|
|
170
|
+
— the same resolved name the real key check at launch already uses. Not yet proven live.
|
|
171
|
+
- **F186 — the printed BEHAVIOUR line (and any replay) counted tool calls from EVERY run that
|
|
172
|
+
ever touched the patient tree, not just the run being read, because the authoring scout's gate
|
|
173
|
+
audit is written directly into the patient tree and the tree's `.gitignore` denies `*.jsonl`,
|
|
174
|
+
so a cold reset never removes it.** Fixed at the source, never by filtering `runBehaviour` on
|
|
175
|
+
`run_id` (a single run legitimately spans several). `scripts/run-author.mjs` now archives its
|
|
176
|
+
own gate audit out of the patient tree the moment authoring ends (`archiveGateAudit()`, called
|
|
177
|
+
from `finally` and once more before the one `process.exit()` path that skips it).
|
|
178
|
+
`scripts/run-u.mjs` now moves any stale audit aside right after `coldReset`, before its own
|
|
179
|
+
Gate ever opens (`moveStaleGateAudit`, new export from `scripts/u-patient.mjs`) — never on the
|
|
180
|
+
resume branch, where the tree's audit is that same run's own prior leg. Not yet proven live.
|
|
181
|
+
- **F184 — a malformed tool-call round on the WORKER path (`src/planrun.js`'s Loop-path `ask()`)
|
|
182
|
+
ended an attempt with nothing on the spine naming it — indistinguishable from the model
|
|
183
|
+
genuinely producing no useful work.** `ask()` now reads bare-agent 0.43.0's own
|
|
184
|
+
`r.malformedToolCall` marker (present since BA-27) and emits a distinct `worker-malformed-tool-
|
|
185
|
+
call` record (`{phase, iteration, name, error}`, scrubbed and length-capped) — visibility only:
|
|
186
|
+
no retry, no change to strikes/ladder/attempt counting/verdict routing, all arbiter-adjacent and
|
|
187
|
+
out of scope. Not yet proven live.
|
|
188
|
+
- **F179 — a malformed tool-call JSON on the FIRST authoring call had no earlier sound
|
|
189
|
+
declaration to fall back to, so 318e066's provider-red stopped the run outright.** hamr's
|
|
190
|
+
2026-09-15 ruling: retry, never repair. `withMalformedToolCallShim` (`src/authorflow.js`,
|
|
191
|
+
wired into `makeLoopGenerate`) is a delegate provider (`Object.create`, never a mutation of
|
|
192
|
+
the shared instance) whose `_request` strips a malformed tool call out of the raw response
|
|
193
|
+
BEFORE `generate()`'s own `JSON.parse` can throw on it, so the round comes back PRICED on
|
|
194
|
+
bare-agent's own real usage instead of crashing. `askStructured` reads the resulting round
|
|
195
|
+
through its EXISTING malformed-emission retry ladder (`MAX_STRUCTURE_RETRIES`, no new cap),
|
|
196
|
+
tagged with a new `malformed-tool-call-arguments` axis — checked BEFORE the accept path and
|
|
197
|
+
regardless of how many calls survived the strip, so a reply carrying a malformed call
|
|
198
|
+
alongside a valid one is never accepted either (follow-up fix, same day, review-caught).
|
|
199
|
+
Scoped to `makeLoopGenerate` only — the authoring declaration calls and the confirm turn; the
|
|
200
|
+
scout and the worker path build their own provider wiring and still only get 318e066's stop
|
|
201
|
+
(an open gap). Not yet proven live.
|
|
202
|
+
- **F179/F180 — bare-agent 0.42.0's OpenAIProvider could throw a raw SyntaxError mid-call (a
|
|
203
|
+
malformed tool-call `arguments` string, `JSON.parse` with no try/catch), crashing past
|
|
204
|
+
`askStructured` and discarding an already-sound, already-measured declaration while the
|
|
205
|
+
billed call went unbooked.** `askStructured` (`src/authorflow.js`) now wraps its `generate`
|
|
206
|
+
call in try/catch, tested against a new shared predicate, `callCasualty` (`src/text.js`,
|
|
207
|
+
beside `priceOf`): a `HaltError` still re-raises (a governance exit, never laundered); an
|
|
208
|
+
ETIMEDOUT/TimeoutError-shaped throw or a JSON-mentioning SyntaxError lands as the same typed
|
|
209
|
+
`providerError` the resolved-`{error}` path already produced, booked at `costUsd: null`
|
|
210
|
+
(honest-unknown, never a complete-looking floor); anything else still crashes.
|
|
211
|
+
`authorscout.js`'s `settled` seam, which already hand-caught its own narrower idle-timeout
|
|
212
|
+
class, now delegates to the same predicate. No JSON repair, no new retry. Not yet proven live
|
|
213
|
+
(run `mu2bjmed` is the live crash this fixes; the corroborating upstream ask is BA-27 in
|
|
214
|
+
`docs/product/UPSTREAM-ASKS.md`).
|
|
215
|
+
- **F178/F177 — a signed fence could name `.git` or `node_modules` directly (or reach a nested
|
|
216
|
+
`node_modules` through an otherwise-legal fence), letting writes there go invisibly to
|
|
217
|
+
`changedSet`.** `scopeContained` (`src/validate.js`, the one containment law `validateJob`
|
|
218
|
+
and `validatePlan` both go through) now refuses any fence/scope whose normalized prefix has a
|
|
219
|
+
whole path segment equal to `.git` or `node_modules` (hamr's ruling, 2026-09-14, option B) —
|
|
220
|
+
a look-alike like `.github`/`my.git`/`node_modules_util` stays admitted. The runtime belt for
|
|
221
|
+
a NESTED `node_modules` a legal fence can still reach uses `tools.denyArgPatterns`
|
|
222
|
+
(`FORBIDDEN_WRITE_SEGMENT_PATTERN`, `src/planrun.js`), scoped to `write`/`edit` only —
|
|
223
|
+
bareguard's `fs.deny` was tried first for `.git` and reverted: it blocks ALL fs actions,
|
|
224
|
+
reads included, which silently over-blocked (caught by the full gate's own drift test,
|
|
225
|
+
`tests/tools.test.js`); `fs.deny` is never used for either book now. Not yet proven live.
|
|
226
|
+
- **F177 — a repo source whose tracked `.gitignore` did not mention `node_modules` let
|
|
227
|
+
installed packages read as the worker's own writes.** `changedSet` (`src/kinds.js`) unions
|
|
228
|
+
the tracked diff with `git ls-files --others --exclude-standard`, so an unignored
|
|
229
|
+
`node_modules` installed into the copy (live-verified: 247 files on a real copy of pulselog)
|
|
230
|
+
read as changes the worker made. `prepareSource` now hides `node_modules` in the copy's own
|
|
231
|
+
PRIVATE `.git/info/exclude` (hamr's ruling, 2026-09-14, option A) — the source repo's tracked
|
|
232
|
+
files, `.gitignore` included, are never touched. Not yet proven live.
|
|
233
|
+
- **PRD item 33 close-out — `prepareSource` freezes tracked files only, so a JS/TS repo's
|
|
234
|
+
prepared copy never carried `node_modules`, and every close stage needing a tool (`tsc`, a
|
|
235
|
+
test runner) instrument-stopped with nothing telling the person why.** bareloop never runs an
|
|
236
|
+
install itself (hamr's ruling, 2026-09-14, option A): `missingDependencies` (`src/source.js`,
|
|
237
|
+
exported) is a pure, $0, JS/TS-only detector that names the exact install command.
|
|
238
|
+
`scripts/run-interview.mjs` prints it right after `prepareSource` succeeds and again at the
|
|
239
|
+
hand-off, where a still-open gap suppresses the "Run it now?" offer entirely.
|
|
240
|
+
`scripts/run-author.mjs` refuses `source-deps-missing` at $0, before the scout and before the
|
|
241
|
+
provider/key are even read. Not yet proven live end to end (the detector and the refusal
|
|
242
|
+
paths are each proven directly; a real `npm ci` against a real prepared copy of a real repo
|
|
243
|
+
confirmed the hidden git's seed stays clean when the source's `.gitignore` ignores
|
|
244
|
+
`node_modules` — see the build report for the gap this does NOT cover, a repo whose
|
|
245
|
+
`.gitignore` does not ignore `node_modules`).
|
|
246
|
+
- **PRD item 33 close-out (L17) — the authoring interview never admitted an endpoint, so a
|
|
247
|
+
DeepSeek draft (`--provider openai-api`) authored against api.openai.com instead.**
|
|
248
|
+
`scripts/run-interview.mjs` now takes an optional `--base-url <url>` flag (no default; absent
|
|
249
|
+
leaves the draft's `baseUrl` field out entirely, never `null`/`''`) and validates it through
|
|
250
|
+
the existing `validateJob` `baseUrl` rule at $0 before writing anything. The interview's
|
|
251
|
+
header, the hand-off command, and `scripts/run-author.mjs`'s own start banner/`author-start`
|
|
252
|
+
event now name the endpoint when one is set; the key hint still points at the provider's own
|
|
253
|
+
env var (`OPENAI_API_KEY` for a DeepSeek endpoint) since there is no separate
|
|
254
|
+
endpoint-specific key. Not yet proven live.
|
|
255
|
+
- **F176 — the revise ladder kept a later revision even when it measured worse than an earlier
|
|
256
|
+
one.** `authorClose` (`src/authorflow.js`) now tracks every MEASURED (validated + seed-read)
|
|
257
|
+
iteration and falls back to the NEWEST SOUND one — a real red/green verdict, never an
|
|
258
|
+
instrument-stop — when the last measured iteration is unsound and an earlier one is not.
|
|
259
|
+
`stop` is never changed; the swap is reported via a new `fellBack` return field, an
|
|
260
|
+
`onPhase('author-fallback', …)` event, and the terminal signing readout. Not yet proven live.
|
|
261
|
+
- **F175 — the confirm turn's own honestly-raised `questions` never reached
|
|
262
|
+
`accepted.openQuestions`.** `runConfirmTurn` now carries the model's own `questions` from the
|
|
263
|
+
plan being accepted into `accepted.openQuestions` on every accepting path (confirm, type-goal,
|
|
264
|
+
the round-2 "fix" terminal), and fixes a related ledger bug where round 1's "fix" text (the
|
|
265
|
+
answer to round 2's redraft) was carried forward even after round 2 was accepted outright. Not
|
|
266
|
+
yet proven live.
|
|
267
|
+
- **F175's open half — "Confirm" and "Type the goal yourself" could still accept a plan whose own
|
|
268
|
+
raised question was never answered, silently confirming a genuinely-missing answer away** (run
|
|
269
|
+
`mu0voeo4`; only the silent-drop half above was covered by the first F175 fix). hamr's
|
|
270
|
+
2026-09-16 ruling (option a): `runConfirmTurn`'s `confirm`/`type-goal` paths now force each
|
|
271
|
+
raised question through a new `kind: 'answer'` step before returning — no extra model call, a
|
|
272
|
+
blank answer re-asks the same question, `null` abandons like every other `ask`. Answers land in
|
|
273
|
+
a new `accepted.answeredQuestions` (Q:/A: pairs), kept separate from `openQuestions` (which
|
|
274
|
+
keeps its "could not resolve" meaning and is honestly empty on these two paths now).
|
|
275
|
+
`confirmedBlock` renders the answers as binding, and the SIGNING PREPARED readout
|
|
276
|
+
(`scripts/author-readout.mjs`'s new `answeredQuestionLines`) prints them when non-empty. The
|
|
277
|
+
`fix` path is unchanged. Not yet proven live.
|
|
278
|
+
|
|
8
279
|
## [0.26.0] — 2026-09-14
|
|
9
280
|
|
|
10
281
|
### Added
|