Skip to content

feat(improve-pr): the improvement radar measures first, and states its cost - #145

Merged
debuggingfuture merged 2 commits into
mainfrom
improve-pr-run
Aug 22, 2026
Merged

feat(improve-pr): the improvement radar measures first, and states its cost#145
debuggingfuture merged 2 commits into
mainfrom
improve-pr-run

Conversation

@debuggingfuture

Copy link
Copy Markdown
Member

What

improve-pr — the third of the maintenance loop's three use cases (§6), and half of that doc's Gap 3. A sibling of spec-drift-pr: same completeStructured engine, same CONFIG_KV-resolved backend, same container-only-for-git posture, same draft-PR output.

One run with a dimension input (ci-speed | security | size) rather than three runs — they differ in their measurement step and rubric and share everything else.

Measure first; the model only interprets

A model asked "how could this CI be faster?" invents plausible advice. A model handed "0 steps use a cache action across 3 workflows" writes a specific PR. Each dimension runs a deterministic script in the container, and only the measurement reaches the model. That is also what makes a finding checkable — a proposal whose numbers a reviewer cannot re-derive is an opinion.

Every finding states its cost

cost is a required schema field beside saving. The schema can't make a reviewer weigh them, but it can refuse to let a proposal omit the half that argues against itself — and a model asked only "how could this be better?" never volunteers it. Below the materiality floor (default 10%) a finding is a report line, never a PR.

What it deliberately does not do

The honest bound matters more than the impressive one, so the header says all of this:

  • The scripts do not install, build, or reach the network. So size reads the dependency surface and largest tracked files, not wrangler deploy --dry-run bundle bytes; ci-speed reads the workflow configuration that predicts slowness (no cache action, no concurrency group), not real per-step durations — those live in the Actions API and our own executions rows, and neither is wired in.
  • A dimension that cannot measure reports nothing rather than guessing. The deterministic exit makes that free — no model call at all.
  • finops is not a fourth member. finops-audit exists, runs Mondays, and reads account usage rather than a checkout.

No cron, on purpose

No schedules entry and nothing in wrangler.jsonc. §6 staggers one dimension per weekday across T1, and arming that is a product decision — a storm of agent runs is both a cost spike and an unreviewable pile of PRs. It ships dispatchable by hand, exactly as triage-prs and triage-issues do, and a test asserts the absent schedule so cron parity cannot drift silently.

Suppression key names the location, not the prose

§10 gap 11 records that a model-authored key drifts between runs, so a declined.jsonl entry suppresses one spelling. A path is copied out of the measurement, so the same finding about the same file keys the same way next week whatever the model calls it.

The other half of Gap 3 is blocked, and not on effort

upstream-upgrade-pr is not in this PR and cannot be built as specified. §4 has it "query the brain for HIGH/MEDIUM items since the last run", and no run capability can read the storepackages/core/src/services/ has no memory/context service. That is ADR-0002, which is unimplemented, and which the loop itself just filed as org#157. The gap row sizes both runs as "siblings of spec-drift-pr"; that is true of this one and not of that one.

Test

7 tests: the floor in both directions, an operator-lowered floor, the deterministic exit reaching no model, the unset-estate no-op, the unconfigured backend failing loudly, and the absent schedule. Full runs suite green — 358 passed. Typecheck clean.

…s cost

The third of the maintenance loop's three use cases (org
process/content/maintenance-loop.md §6), and a sibling of `spec-drift-pr`:
same `completeStructured` engine, same CONFIG_KV-resolved backend, same
container-only-for-git posture, same draft-PR output.

One run with a `dimension` input rather than three runs. The dimensions differ
in their measurement step and their rubric and share everything else — the
estate, the backend, the floor, the PR shape, the suppression key. Three runs
would be three copies of everything except the part that differs.

**Measure first; the model only interprets.** A model asked "how could this CI
be faster?" invents plausible advice. A model handed "0 steps use a cache
action across 3 workflows" writes a specific PR. Each dimension runs a
deterministic script in the container and only the measurement reaches the
model, which is also what makes the finding checkable: a proposal whose numbers
a reviewer cannot re-derive is an opinion.

**Every finding states its cost.** `cost` is a required schema field beside
`saving`. The schema cannot make a reviewer weigh them, but it can refuse to
let a proposal omit the half that argues against itself — and a model asked
only "how could this be better?" never volunteers it. Below the materiality
floor (default 10%) a finding is a report line, never a PR.

Three things I deliberately did NOT do, because the honest bound matters more
than the impressive one:

The measurement scripts do not install, build, or reach the network. So
`size` reads the dependency surface and the largest tracked files rather than
`wrangler deploy --dry-run` bundle bytes, and `ci-speed` reads the workflow
CONFIGURATION that predicts slowness — no cache action, no concurrency group —
rather than real per-step durations, which live in the GitHub Actions API and
in our own `executions` rows and are wired into neither. The header says so.
A dimension that cannot measure reports nothing rather than guessing, and the
deterministic exit makes that free.

`finops` is not a fourth member. `finops-audit` exists, runs Mondays, and reads
Cloudflare account usage rather than a checkout; a member here shelling to the
same data would be a second implementation of a run we have.

And there is no `schedules` entry and no cron. §6 staggers one dimension per
weekday across T1 and arming that is a product decision — a storm of agent runs
is both a cost spike and an unreviewable pile of PRs. It ships dispatchable by
hand, exactly as `triage-prs` and `triage-issues` do, and a test asserts the
absence so the two halves of cron parity cannot drift apart silently.

The suppression key names the finding's LOCATION, not the model's prose for it.
§10 gap 11 records why: a model-authored key drifts between runs, so a
`declined.jsonl` entry suppresses one spelling rather than one finding. A path
is copied out of the measurement, so the same finding about the same file keys
the same way next week whatever the model calls it.

Tests: 7 covering the floor in both directions, an operator-lowered floor, the
deterministic exit reaching no model, the unset-estate no-op, the unconfigured
backend failing loudly, and the absent schedule. Full runs suite green (358).

@flaredispatch-fractalboxdev flaredispatch-fractalboxdev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI code review — 💬 Comment

Risk tier: full · 0 critical · 1 warnings · 1 suggestions

Reviewers: security ⚠️ · performance ⚠️ · code-quality ⚠️ · documentation 2 · release-management ⚠️ · compliance ⚠️ · agents-md ⚠️

1. ⚠️ Warning — Documented suppression key is not implemented

📍 runs/improve-pr.ts:553-565

The comments describe a stable suppression key and the PR body emits 'maintenance-key' values, but this run never reads or checks declined/suppression state before opening a PR. Either implement the documented suppression behavior or revise these comments and generated text so operators are not told that findings can be suppressed when they cannot.

2. 💡 Suggestion — Add operator-facing documentation for the new run

📍 runs/improve-pr.ts:36-48

The new dispatchable run exposes several CONFIG_KV settings and three input dimensions, but those instructions exist only in source comments. Update the repository's run catalog/maintenance documentation with how to invoke 'improve-pr', valid dimensions, required backend/model configuration, and the intentional absence of a schedule so operators can discover and use it without reading TypeScript.

📋 View full logs & reviewed diff ↗

… run

CI caught two things my typecheck did not, and both are the registry doing its
job. Adding a run to `runs/index.ts` and `registry.ts` is three of the five
places a run exists.

`grant-catalog.test.ts` asserts an entry for EVERY registered run, so a run
that ships without a declared egress grant fails the build rather than
defaulting to one. That is the correct direction and it caught me.

The entry is `["public-repo-read"]` — the narrow one, the same as
`org-spec-audit` and deliberately not `spec-drift-pr`'s `JS_BUILD`. Every
measurement script in this run is read-only: no install, no build, no network.
A container that could reach a registry would be a grant wider than any use.
That is the same decision as the honest measurement bound in the header — it
is why `size` reports the dependency surface rather than built bundle bytes,
and the grant and the measurement are two faces of one choice rather than a
limitation I worked around.

`GET /health` publishes the registered run names and its test pins the list,
so the run is now in it, alphabetically.

Worth recording why I did not catch these: I ran `tsc` against
`apps/dispatcher/tsconfig.json` and the `runs` project's vitest suite, and
reported "358 passed" from that. The repo's own gate is `pnpm typecheck &&
pnpm test` across every workspace, which is what `offload-test` runs, and it
is where both failures live. A green subset is not a green suite, and I
described one as the other.

Full suite now: 174 files, 2292 passed, 1 skipped.
@debuggingfuture
debuggingfuture merged commit 63283c4 into main Aug 22, 2026
4 checks passed
@debuggingfuture
debuggingfuture deleted the improve-pr-run branch August 22, 2026 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant