Skip to content

test(adaptive): prove the repaired-run continue end to end - #67

Merged
sanil-23 merged 4 commits into
tinyhumansai:mainfrom
sanil-23:feat/continue-after-repair-proof
Aug 19, 2026
Merged

test(adaptive): prove the repaired-run continue end to end#67
sanil-23 merged 4 commits into
tinyhumansai:mainfrom
sanil-23:feat/continue-after-repair-proof

Conversation

@sanil-23

Copy link
Copy Markdown
Contributor

test(adaptive): prove the continue end to end, on an invocation counter

The gate's unit tests ask whether an edit is safe. The engine's e2e asks
whether a continue re-enters the right node. Neither can catch the chain
being wired up wrong — a gate that says yes to a ResumePoint nobody
threads through, a runner handed one for a workflow the chooser did not
pick — because each of them is one joint.

This drives Loop::run end to end against a real engine, a real
checkpointer and a real store. Only the model and the tool are doubles,
and both have to be: the model so the repair is a known edit rather than
a guess, the tool so "did the prefix run again" is answerable at all.

The workflow is start → post_comment → tally, named for the argument.
tally calls a slug that is down; the scripted repair points it at one
that answers, which is an edit to the failed node and nothing else. Two
attempts, and the assertion is a count:

post_comment  1   the effectful prefix, across both attempts
tally_broken  1   the attempt that broke
tally         1   the continue

plus both legs running under one thread, which is what "continued" means
here. A state comparison would pass whether the prefix ran once or twice.

The second test is the one that makes the gate load-bearing rather than
decorative: the same episode with a repair that also edits the node
UPSTREAM of the failure. The loop must start over, and the observable
cost of starting over is post_comment running twice.

Checked by falsification. With the runner ignoring Attempt::resume and
always starting fresh, the first test reports left: 2, right: 1 on the
effectful node — so it is measuring the continue, not agreeing with it.

Writing it also reproduced a defect worth naming, because it is the same
one in the same shape a real host hit: a runner that reports no steps and
an empty changed for a failed run gets settled mechanically as terminal
MissingEvidence before the judge is ever asked, and the episode stands
down after one attempt. A failed run still did whatever it did before it
broke; the report has to say so. The runner here reads its steps back out
of the failure boundary's committed state for exactly that reason.

Stacked: needs may_continue and Attempt::resume (#65) and
retry_with_checkpointer / failure_boundary (#66). This branch is the
two merged plus the test, so it is also the first place CI runs them
together.

The gate's unit tests ask whether an edit is safe. The engine's e2e asks
whether a continue re-enters the right node. Neither can catch the chain
being wired up wrong — a gate that says yes to a `ResumePoint` nobody
threads through, a runner handed one for a workflow the chooser did not
pick — because each of them is one joint.

This drives `Loop::run` end to end against a real engine, a real
checkpointer and a real store. Only the model and the tool are doubles,
and both have to be: the model so the repair is a known edit rather than
a guess, the tool so "did the prefix run again" is answerable at all.

The workflow is `start → post_comment → tally`, named for the argument.
`tally` calls a slug that is down; the scripted repair points it at one
that answers, which is an edit to the failed node and nothing else. Two
attempts, and the assertion is a **count**:

    post_comment  1   the effectful prefix, across both attempts
    tally_broken  1   the attempt that broke
    tally         1   the continue

plus both legs running under one thread, which is what "continued" means
here. A state comparison would pass whether the prefix ran once or twice.

The second test is the one that makes the gate load-bearing rather than
decorative: the same episode with a repair that also edits the node
UPSTREAM of the failure. The loop must start over, and the observable
cost of starting over is `post_comment` running twice.

Checked by falsification. With the runner ignoring `Attempt::resume` and
always starting fresh, the first test reports `left: 2, right: 1` on the
effectful node — so it is measuring the continue, not agreeing with it.

Writing it also reproduced a defect worth naming, because it is the same
one in the same shape a real host hit: a runner that reports no steps and
an empty `changed` for a failed run gets settled mechanically as terminal
`MissingEvidence` before the judge is ever asked, and the episode stands
down after one attempt. A failed run still did whatever it did before it
broke; the report has to say so. The runner here reads its steps back out
of the failure boundary's committed state for exactly that reason.

Stacked: needs `may_continue` and `Attempt::resume` (tinyhumansai#65) and
`retry_with_checkpointer` / `failure_boundary` (tinyhumansai#66). This branch is the
two merged plus the test, so it is also the first place CI runs them
together.
@coderabbitai

coderabbitai Bot commented Aug 19, 2026

Copy link
Copy Markdown

Important

Review skipped

This review includes 1 billable file. This on-demand review is free during your promotion.

Your included review limit has been reached. Run @coderabbitai review --use-credits to review the latest changes using usage credits.

  • Run review — free
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 06e887c3-0ac6-4a33-b765-12fd0da4ba12

📥 Commits

Reviewing files that changed from the base of the PR and between d486edb and 70ccecb.

📒 Files selected for processing (1)
  • crates/adaptive/tests/continue_after_repair.rs

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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.

@tinysweeper

tinysweeper Bot commented Aug 19, 2026

Copy link
Copy Markdown

How this change flows

0 changed behaviours across 3 relationships. 4 surrounding behaviours are shown (60 graph nodes walked). 35 further behaviours left out to keep the diagram readable.

flowchart LR
  n0["run"]:::impacted
  n1["LlmProvider"]:::impacted
  n2["...air_starts_over_and_the_prefix_runs_again"]:::impacted
  n3["...from_the_break_without_redoing_the_prefix"]:::impacted
  n2 -->|calls| n0
  n2 -->|uses| n1
  n3 -->|calls| n0
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading

Green: changed behaviour. Grey: surrounding behaviour. Arrows name the call, use, implementation, or test relationship. Orange: has findings. Red: has a finding that blocks the merge.

tinysweeper 0.1.0

@tinysweeper tinysweeper 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.

tinysweeper found nothing blocking. Approving.

$0.0000 · 0 in / 0 out · 756 embedded · openrouter/openai/text-embedding-3-small

@tinysweeper tinysweeper Bot added the priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect. label Aug 19, 2026
@sanil-23
sanil-23 merged commit dbab492 into tinyhumansai:main Aug 19, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant