Repository navigation
feat: Oracle-timeout block keeps the card's worktree so board_salvage_feature can publish green work - #545
Conversation
…_feature can publish green work
There was a problem hiding this comment.
QA panel review — PASS
code-review-structural · head 9527f0217e07 · formal
Low-risk PR: the oracle-timeout path now keeps the worktree instead of discarding it, enabling salvage. All finders agreed the logic is correct; the only actionable items are a stale doc row in docs/lifecycle.md that contradicts the new keep-instead-of-discard behavior, and a dead base parameter. Verification confirmed both findings with no changes. No gaps.
Findings
| Severity | Location | Finding | Verified | |
|---|---|---|---|---|
| 🟡 | minor | docs/lifecycle.md:550 |
The 'Edge | What it does with such a tree' table states a drive's terminal block 'saves the drive's own tree, removes it', but this PR makes the oracle-timeou… | confirmed |
| ⚪ | nit | loop/drive.py:457 |
_keep_tree_for_salvage accepts a base keyword argument that is never used in its body — a dead parameter copied from _discard_tree's signature. |
confirmed |
findings JSON (machine-readable)
[
{
"file": "docs/lifecycle.md",
"line": 550,
"severity": "minor",
"category": "conventions",
"claim": "The 'Edge | What it does with such a tree' table states a drive's terminal block 'saves the drive's own tree, removes it', but this PR makes the oracle-timeout terminal block KEEP the tree, so the doc now contradicts the code for that class and the exception is not noted.",
"evidence": "| a drive's terminal block, or an operator cancel | saves the drive's own tree, removes it, and says so on the card.",
"verdict": "confirmed",
"note": "Read docs/lifecycle.md at head: the table row says 'saves the drive's own tree, removes it' for all terminal blocks; the diff replaces _discard_tree with _keep_tree_for_salvage for oracle-timeout, so the doc's blanket 'removes it' is now wrong for that class. No exception noted in the doc."
},
{
"file": "loop/drive.py",
"line": 457,
"severity": "nit",
"category": "conventions",
"claim": "_keep_tree_for_salvage accepts a `base` keyword argument that is never used in its body \u2014 a dead parameter copied from _discard_tree's signature.",
"evidence": "async def _keep_tree_for_salvage(self, store, fid: str, repo: str, wt, branch, *, base: str = \"\") -> None:",
"verdict": "confirmed",
"note": "Read loop/drive.py lines 457\u2013488 at head: `base` appears only in the signature; the body (trees/kept/salvage/text/_comment) never references it. Call site passes base=base but the function ignores it."
}
]1 finding(s) excluded from the verdict by in-diff confinement (file not among this PR's changed paths):
docs/lifecycle.md(minor) — The 'Edge | What it does with such a tree' table states a drive's terminal block 'saves the drive's own tree, removes it', but this PR makes the oracle-timeout
There was a problem hiding this comment.
Promoting the PASS verdict for head 9527f0217e07: all checks terminal-green, zero unresolved review threads. (approve-on-green)
Open findings carried by this approval — non-blocking, but they did not go away:
- minor
docs/lifecycle.md:550— The 'Edge | What it does with such a tree' table states a drive's terminal block 'saves the drive's own tree, removes it', but this PR makes the oracle-timeout terminal block KEEP the tree, so the doc - nit
loop/drive.py:457— _keep_tree_for_salvage accepts abasekeyword argument that is never used in its body — a dead parameter copied from _discard_tree's signature.
Approving a WARN does not resolve its findings (issue #22).
Review findings (blocking)1 finding(s): 1 major. Major
The coder is re-driving a fix for these findings. |
…s every candidate before the keep-the-tree code runs (#538 follow-up to #545) (#547) * feat: Oracle-timeout block really keeps the worktree: dispatch() reaps every candidate before the keep-the-tree code runs (#538 follow-up to #545) * feat: Oracle-timeout block really keeps the worktree: dispatch() reaps every candidate before the keep-the-tree code runs (#538 follow-up to #545)
Summary
An
oracle-timeoutblock now keeps the card's worktree soboard_salvage_featurecan publish green work (#538).When
coder.solve()trips the acceptance-oracle timeout breaker (#459), the card is blockedoracle-timeout. A timeout is not a verdict on the code — the build it judged is often green (bd-b4pr: a dependency bump whose build and tests passed). The drive used to_discard_treethat worktree (saving it to astranded/…branch and removing it), after whichboard_salvage_feature— which publishes only from a live worktree — refused with "no worktree of has changes vs main."loop/drive.py: on theOracleTimeoutpath, replace the_discard_treecall with a new_keep_tree_for_salvagehelper that keeps the worktree and writes a card comment naming the tree path (falling back to the card'sfeature_worktrees, since the solve offload reaps its own candidate trees and the drive'swtis usuallyNonehere) and the salvage that can publish it (board_salvage_feature/POST /features/<id>/salvage), or a cancel if the work is unwanted. This is the same keep-the-work stance the closed-source-issue guard takes (protoAgent#3832). Nothing reaps the tree meanwhile: the health sweep's reaper only takesdone/cancelled/gone trees, andoracle-timeoutis not in_SELF_HEALING_BLOCKS, so the blocked sweep neither requeues nor removes it — it escalates to a human and waits for salvage or cancel.SolveExhausted) keeps its existing_discard_treebehaviour, and the oracle budget (coder_solve_test_timeout_s) is unchanged.tests/test_oracle_timeout_keeps_tree_538.py(new) covers all five requirements with real git worktrees: the drive keeps the tree and names the salvage (r1),loop.salvagepublishes the kept tree instead of refusing (r2), the health-sweep reaper and the blocked sweep both leave the tree in place while the card stays blocked (r3), and a non-oracleSolveExhaustedstill discards (r4).changelog.d/538.md(new) records the change.Fixes #538