diff --git a/docs/NOTES.md b/docs/NOTES.md index 2d2d271..c11d86b 100644 --- a/docs/NOTES.md +++ b/docs/NOTES.md @@ -673,3 +673,20 @@ P3 items need no behavior change except where noted. (OCI-2.5-noerrors) is deferred: the stub cannot emit `error` events except via the fake binary, and no passing-path turn emits them; the unit pin covers the fallback. + +## M14 decision checklist 14-25 + +- decision 14: `src/run.ts` runs `runStep("install"/"build")` before `ensureEntriesOrThrow` and passes `serverEntry` to tier 1 (`src/tiers/load.ts` takes `serverEntry`, checks shim + real paths in logs); test `test/unit/run-entry.test.ts` (build-before-dist-entry, plugin.entry plumbing, missing-entry ConfigError, TUI entry, StepError). +- decision 15: `src/plugin/entry.ts` missing explicit `plugin.entry` throws `ConfigError` (never falls back), `src/cli.ts` `validate` warns when `plugin.build` is set; test `test/unit/entry.test.ts` "missing explicit entry throws instead of falling back". +- decision 16: `src/run.ts` passes each `.opencode-ci` test file as an explicit `./`-relative path (`bun test ` skips dot-dirs); test `test/unit/run-bun-test.test.ts` (passing file passes, failing file fails with its name). +- decision 17: `src/tiers/live.ts` `budgetStop` fails the case with `(budget exhausted …)` once attempts ran (skip only when none ran), `src/run.ts` holds one `LiveBudget` above the version loop; tests `test/unit/live-loop.test.ts` "running out of budget after a failed attempt is a failure, not a skip" and `test/unit/run-budget.test.ts` (shared budget, `latest` skips). +- decision 18: `src/util/fs.ts` `resetDir` (refuses outside root) called by all four tiers, `src/config/schema.ts` `RESERVED_IDS` (`load`, `bun-test`) + workspace containment, `src/cli.ts` exported `parseRunArgs` validates `--opencode` via `versionSchema`, `src/run.ts` unknown `--scenario` throws `ConfigError`; tests `test/unit/run-inputs.test.ts` (re-run isolation, resetDir guard, unknown scenario, --opencode) + `test/unit/scenario-rules.test.ts`. +- decision 19: `src/config/schema.ts` removes `expect.providers`/`models`, `gate.window`/`threshold`, scenario `judgeReply` (fail validation), `live.timeoutMs` wired as the live default (`src/tiers/live.ts` `scenario.timeoutMs ?? live.timeoutMs`, `src/tiers/scripted.ts` `?? 120_000`, scenario `timeoutMs` optional); test `test/unit/config-schema.test.ts` (removed fields fail, no schema default) + regenerated `schema/config.json` + `schema/scenario.json`. +- decision 20: `src/assert/matchers.ts` missing value fails every matcher except `exists: false` (`no value was recorded (check the field name)`); test `test/unit/matchers-missing.test.ts` (4 pass: notContains/notMatches/equals fail, `exists: false` passes, null recorded). +- decision 21: `src/assert/expect.ts` `normalizeToolName` maps all spellings to the effective `_` in `tools`/`noTools`/`hooks[].tool`, bare names fail with a `did you mean …?` hint; test `test/unit/namespaced-tools.test.ts` (4 pass: dotted catalog matches, bare-name hint `ns_spike_echo`). +- decision 22: `src/gate/history.ts` `historyBranch` reads PR history from `GITHUB_BASE_REF`, used by `src/gate/gate.ts`; test `test/unit/gate-wiring.test.ts` (PR `4/merge` reads `main`). +- decision 23: `action.yml` passes `artifact-name` via `IN_ARTIFACT` as CLI `--gate-artifact` (`src/cli.ts` `parseRunArgs`, `src/run.ts` overrides `gate.artifact`), still no `config` input and no `skipped` output; test `test/unit/gate-wiring.test.ts` (`--gate-artifact` both spellings). +- decision 24: `src/plugin/install.ts` `StepError` (failing install/build exits 1), `src/run.ts` unknown `--scenario` is `ConfigError` (exit 2), results keep the requested `opencode` version (`opencode: version`); tests `test/unit/run-entry.test.ts` (build-failure message), `test/unit/run-inputs.test.ts` (unknown scenario), `test/unit/run-exit-codes.test.ts` (required/allowed exits). +- decision 25: `test/helpers/fake-opencode.ts` fake binary + `test/helpers/run-ci.ts`/`tmp.ts` shared setup cover `runCi`/live loop, `.github/workflows/ci.yml` `uses: ./` self-test job (`tool-direct` pass, `throws` fail); tests `run-exit-codes`/`run-entry`/`run-budget`/`live-loop` + `bun run test:e2e` 28 pass. + +Verification: `bun run check` 315 pass, `bun run test:e2e` 28 pass, `git status` clean, `ls TMPDIR` 0 (`run-plugin-`/`run-fake-`/`live-loop-`), `live:` not run.