Skip to content

Harden the user-driven loop with the loop-engineering rules - #3

Draft
drmikecrowe wants to merge 19 commits into
mainfrom
runner-scribe-v2
Draft

Harden the user-driven loop with the loop-engineering rules#3
drmikecrowe wants to merge 19 commits into
mainfrom
runner-scribe-v2

Conversation

@drmikecrowe

@drmikecrowe drmikecrowe commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Hardens the user-driven loop with the applicable rules from the loop-engineering design doc. Based directly on ca70137; depends on nothing after it. Seven commits, one concern each.

The two agents (259b13d)

  • agents/old-coder-gauntlet.md — a fresh-context runner executes the final gauntlet run: four inputs, one entry-point invocation, per-layer verdict in the closed five-status vocabulary. It fixes nothing; a layer with no log is FAILED whatever the exit code or record claims.
  • agents/old-coder-evidence.md — a fresh-context scribe drafts EVIDENCE from artifacts alone, holds no Bash (it can transcribe a number, never produce one), and writes absent evidence as failing rows. Author claims enter via FACTS.md as labeled assertions that never upgrade a status.
  • Minimal wiring: two SKILL.md paragraphs, the bundled-agents table, two tier rows, two EVIDENCE header fields, one gauntlet.md section. Required at Tier 3, optional at Tier 2; author-run is the recorded fallback.

The hardening (VE/CO/EX/DR rule ids from the doc)

  • cfa5e65 — completion record + exit vocabulary (VE-9, VE-11, CO-9, CO-10). The entry point's exit trap writes a record on green and red paths alike — result, layer sets, UTC time, source binding, toolchain pin — and its exit codes distinguish a failed layer from a violated orchestration contract from a crash. The runner reads it verbatim; the scribe copies the source state from it; the report's consistency check gains a Record line.
  • f4fe609 — reviewed content is data (EX-8). Both existing reviewer briefs now treat an embedded directive as a finding to report, never an order to follow.
  • 4af4df4 — a breached budget voids the round; the final round narrows to the blocker (CO-4, CO-13). An uncounted or over-budget review round is a failed round, rerun, never averaged in. The last permitted round fixes and re-briefs only the blocking finding.
  • 4715021 — the orchestration proves it can fail (VE-13). Two one-off negative controls: an absent layer must redden the audit; a failing layer must redden the exit and the record.
  • 6fd0365 — CONTRIBUTING: skill text is behavior (DR-4). A change that alters what the gauntlet accepts ships with the case that fails without it.
  • daa3f8c — stop on a repeated failure signature (CO-3, read for a human-driven loop). Two rounds failing identically escalate to the human instead of buying a third.
  • 8716360 — a wake re-enters a task; it does not restart one. A finished task named again is reported, not redone; a standing escalation is a wall only a human clears; every skip is narrated because silence on a wake reads as a hang.
  • f80b755 — tracker traffic stays honest across runs. Post only to a destination the human already made; mark the skill's own comments so a later run never answers itself; never filter by author, which would drop the human's approval.
  • 9891061 — compute arithmetic decisions, never weigh them. The consistency lines and the stagnation compare are set membership and string matching; where a script exists, the script's answer is the answer.
  • e7e2332 — a marked proposal beats an empty spec field on autonomous runs. Investigate before you invent; a value read from the code beats one composed; an explicit proposal the reviewer can veto beats a hole found mid-build.
  • aebcabf — classify the request kind in the spec intent review (IN-1, applied per kind). The reviewer classifies the request (bug / ui / feature) and holds the spec to that kind's required substance: a bug needs a reproduction or the RED test cannot exist; a feature needs problem, value, and criteria a test could fail; a UI change needs a concrete visual expectation. A heading with no content counts as absent.

Gauntlet construction, specified

  • 5a36125 — the six-step build procedure with an output contract per layer (IN-3 for the apparatus). A layer's command is wired in only if it exits nonzero on violation, writes its own log, and emits the number its EVIDENCE row will cite; changed-line coverage must gate and fail, never print a global percentage.
  • 819bc52 — the gauntlet proposal table in the SPEC setup plan. The tooling exchange with the human becomes one approvable table: layer, pinned tool, command, what it catches, what EVIDENCE gets. A struck row is UNAVAILABLE, never substituted.
  • 0e0de1dagents/old-coder-gauntlet-verifier (EX-3 at the instrument). The builder writes the entry point, so a read-only fresh-context agent certifies it before first use: wiring against the approved table, fail-closed traits, the output contract, the commissioning reds, and what the certification binds to. Voids on any later edit; EVIDENCE gains a Gauntlet commissioned: field.
  • 24c90aa — two closures: the scribe fails the report when the runner's executed command differs from the Entry point: header, and the adversary's hunt list opens with the entry-point script whenever the diff touches it.

Deliberately not adopted

Outer-loop automation (iteration counting, durable locked state, scheduled drift evaluation) — the human is this loop's controller; those rules activate the day the skill runs on a trigger instead of an ask.

What this does not claim

The entry point's own exit remains the gate; both agents report and decide nothing. The scribe is a model: it removes author-correlation only, and EVIDENCE names who ran and who drafted so a reader can weigh the claim.

Supersedes #2.

The final gauntlet run and the EVIDENCE draft were the loop's last two
self-report surfaces: the author executed the run and narrated its
result. Two fresh-context briefs close that, the same maker-and-checker
split the spec-intent and adversary agents already apply. The runner
executes the entry point once and transcribes a per-layer verdict; it
fixes nothing, and a layer with no log is a failed row whatever the
exit code says. The scribe drafts EVIDENCE from artifacts alone and
holds no Bash, so it can transcribe a number but never produce one; the
author's claims enter through FACTS.md as labeled assertions that never
upgrade a status. Both required at Tier 3, optional at Tier 2;
author-run remains the fallback, recorded in EVIDENCE as a downgrade
like the brief path.
@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

EVIDENCE is model-written and the runner agent only transcribes; nothing
non-model attested that the run happened, on this tree, after the last
edit. The entry point's exit trap now writes that record on the green
and red paths alike, and the exit code distinguishes a failed layer
from a violated orchestration contract from a crash. The runner reads
the record verbatim and fails a run whose record is absent or
mis-bound; the scribe copies the source state from it; the report's
consistency check gains a Record line. Loop-engineering VE-9, VE-11,
CO-9, CO-10.
The adversary reads potentially hostile repo content with a live tool
set, and the spec reviewer reads text the requester controls; neither
brief said what to do with a directive found inside it. Now both:
an embedded instruction is a finding to report, never an order to
follow. Loop-engineering EX-8.
The adversary's 10-call budget was a limit with no consequence: an
uncounted or over-budget round could still be averaged into confidence.
Now it is a failed round, recorded and rerun. And the last permitted
round fixes and re-briefs only the blocking finding, so it cannot be
spent on cosmetics while the blocker stands. Loop-engineering CO-4,
CO-13.
Every checker in the gauntlet must show a red before its green counts;
the entry point that runs them all was the one checker exempt. Two
one-off negative controls close that: an absent layer must redden the
audit, and a failing layer must redden the exit and the record.
Loop-engineering VE-13.
The prose is the mechanism, so a change that alters what the gauntlet
accepts ships with the case that fails without it. Loop-engineering
DR-4.
Two review rounds failing the same way prove the fix changed nothing;
a third round spends budget to learn it again. Compare what failed, not
its wording, and escalate to the human with both attempts.
Loop-engineering CO-3, read for a human-driven loop.
@drmikecrowe drmikecrowe changed the title Run the final gauntlet and draft EVIDENCE in fresh-context agents Harden the user-driven loop with the loop-engineering rules Aug 31, 2026
A spec is complete only against the kind of request it answers: a bug
without a reproduction cannot produce its RED test, a feature without
the problem stated apart from the proposal invites building the wrong
thing, a UI change without a visual expectation is unfalsifiable. The
reviewer classifies first (bug / ui / feature), holds the spec to that
kind's required substance, and reports the kind so the author can
dispute the classification. Adapted from the ticket-enhancer judge in
the reliable-agentic-lab workshop.
Two failure modes from running loops on a schedule: redoing finished
work because the task was named again, and silently retrying past a
standing escalation only a human can clear. Both are stops, and both
are narrated — silence on a wake reads as a hang. Adapted from the
reliable-agentic-lab enhancer loop's state check and sticky
needs-human label; MAST's unaware-of-done mode.
Post only to a destination the human already made; mark this skill's
own comments so a later run never answers itself; never filter by
author, which would also drop the human's approval. Adapted from the
reliable-agentic-lab enhancer loop's comment marker and
never-create-an-issue rules.
The consistency lines and the stagnation compare are set membership
and string matching, and a decision computed that way cannot be talked
past. Where a script exists, the script's answer is the answer. The
stance is the enhancer loop's: ready comes from check_fields.py, stop
from check_stop.py, never from the model's own judgment.
Where the request and the codebase do not settle a value, an explicit
proposed value the reviewer can veto beats a hole discovered mid-build,
and a value read from the code beats one composed. The enhancer doer's
investigate-before-you-invent rule, applied to spec drafting.
Construction was one dense bullet plus fallback tables; now it is six
steps. The new piece is the output contract: a layer's command is wired
in only if it exits nonzero on violation, writes its own log, and emits
the number its EVIDENCE row will cite — changed-line coverage must gate
and fail, not print a global percentage. A tool that cannot meet the
contract goes to the human, never in as a report-only step.
The tooling exchange with the human becomes a structured artifact:
one row per layer with the pinned tool, the command, and the number
EVIDENCE gets from it. Approving the spec approves the rows not
struck; a struck row is UNAVAILABLE, never substituted.
The builder writes the entry point, so the instrument was the one
piece of the trust chain no fresh eyes checked. A read-only
fresh-context agent now certifies it against the approved table before
first use: wiring, fail-closed traits, the output contract, the
commissioning reds, and what the certification binds to. It runs
nothing and fixes nothing; certification voids on any later edit.
EVIDENCE gains a Gauntlet commissioned field.
…ry point

Two closures for the instrument-authored-by-the-author gap: the scribe
fails the report when the runner's executed command differs from the
Entry point field, and the adversary's hunt list opens with the entry
point script whenever the diff touches it — every green number
downstream rests on it.
A subagent's final response can come back empty, truncated, or mangled — hit
in practice on an adversary round. When that was the only copy, the whole
round had to be re-run and re-paid.

Both reviewing agents now take a report path in their prompt —
logs/spec-intent.md and logs/adversary-round-<n>.md under the task directory —
write the complete report there, then return the same text as their response.
The orchestrator reads the response as usual and recovers from the file when
the reply is damaged; the file is the authoritative copy and EVIDENCE cites it
either way. Under worktree isolation logs/ sits in the durable root, so the
copy also survives the worktree's cleanup.

That requires Write in both briefs' tool lists, scoped in the text to that one
file: spec-intent stays codebase-blind, and the adversary's write is exempt
from its 10-call budget so persisting the report cannot void a round.
4e9e96c gave the two reviewing agents a report file to survive a lost or
truncated response. The other three subagents return through the same channel
and carry the same exposure, so the contract now covers all five.

Each brief takes a report path — non-blocking, unlike the required inputs:
given none, the agent notes it and returns the text alone. The runner and
verifier gain Write scoped to that one file; the runner's "edit no file"
becomes "edit no project file", and the verifier's description drops
"read-only" for "writes only its own report file". The evidence scribe already
held Write; it now also persists its report-back block, whose consistency-check
per-line result lives nowhere else once the response is lost.

The bundled-agents section replaces the two-agent paragraph with a path table
(logs/spec-intent.md, gauntlet-verifier.md, adversary-round-<n>.md,
gauntlet-runner.md, evidence-report.md) and states once that the write is
exempt from every call budget, so persisting a report can never void a round.
Seven improvements from an adversarial reviewer's own report on how its brief
performed, generalized past that review's specifics:

- Budget 10 -> 12, with ingestion planned: call 1 captures the diff to a file,
  read in bounded pages. A wide diff overflowed the return and cost an
  unplanned read of the persisted result before hunting began; the raise pays
  for ingestion instead of exempting it.
- What counts as a call is now stated: every tool invocation, persisted-result
  reads and retries included; only the report write is exempt. The reviewer
  had to guess and counted conservatively.
- Generator sentences get a width test beside the reach test, in SKILL.md step
  2 and the adversary's hunt 3: a finding inside the mechanism but outside the
  sentence's noun means the noun is too narrow ("a device" misses the data the
  device holds), and both the author's enumeration and the reviewer's stop at
  the same boundary.
- Hunt 4 asks the inverse question explicitly: does the fixture describe the
  machine this runs on? The round's strongest finding — fixtures modeling a
  state the deployment never produces — was reached only by luck.
- Findings carry a three-word severity (unrecoverable | recoverable |
  nuisance) and the fixture input that would have caught them, so the author
  can triage without re-reading triggers and each finding arrives as an
  addable test.
- The doubled deliverable is gone, for all five agents: the file is the
  deliverable, the response a path-plus-summary receipt. Full-text-and-file
  paid the report's tokens twice; the no-path fallback still returns full text.

Kept unchanged, on the same feedback: round briefing withholds the previous
round's fixes and hands the generator plus enumeration — the reviewer
confirmed it rediscovered none of the listed fixes.
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