feat(fleet): stranded-cargo fallback frees parked-full traders (v2.9.3)#56
Merged
Conversation
Closes #55. A trader parked FULL of a good the local market doesn't buy sat idle ~1h live (2026-07-05, PROTOTRADER-1 with 40 AMMONIA_ICE) — _trade_loop's no-route branch just slept, and the engine only *detected* the strand as a sitrep hint (fleet.py report()), never acted on it. New _clear_stranded_hold, called ONLY from _trade_loop's no-route branch (so it never pre-empts a real run), repositions the ship to the nearest in-system market that BUYS the stranded good and sells it, accepting sub-margin — freeing the ship beats hoarding dead capital. Guards (each tested): never act mid-flight; NEVER liquidate contract-deliver cargo (a stuck contract lead reaches _trade_loop still holding its haul — /my/contracts is the authoritative signal, and an unreadable list protects EVERYTHING, fail-safe); an unproven buyer scan (T._good_markets raised) or a provably-empty buyer set leaves the cargo aboard — this SELLS stranded cargo, it never jettisons; at most one side-trip per window. 8 new tests (test_stranded_cargo.py): reposition+sell, contract-cargo protected, no-buyer holds, unproven-scan holds, in-transit no-op, unreadable-contracts fail-safe, empty-hold no-op, and the once-per-window wiring in _trade_loop. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
👀 Quinn is reviewing — verdict (PASS / WARN / FAIL) + findings to follow. |
There was a problem hiding this comment.
QA Audit — PR #56 | feat(fleet): stranded-cargo fallback frees parked-full traders (v2.9.3)
VERDICT: WARN (CI still settling — test: in_progress; approve-on-green policy promotes this to APPROVED automatically once every check passes terminal-green)
CI Status
- test: in_progress ⏳
Diff Review (3 files, +290/-1)
fleet.py: New_clear_stranded_hold()called from_trade_loop's no-route branch — repositions a parked-full trader to the nearest in-system market that buys the stranded good, sells it sub-margin, then loops to re-check routes. One side-trip per window viaclearedflag.protoagent.plugin.yaml: version bump 2.9.2 → 2.9.3.test_stranded_cargo.py: 8 new tests covering reposition+sell, contract-cargo protection, no-buyer hold, unproven-scan hold, in-transit no-op, unreadable-contracts fail-safe, empty-hold no-op, once-per-window wiring.
Observations
- CLAWPATCH/LOW: Test suite feature mapped as structurally sound — 8 features mapped, 1 finding (test-suite signal), no correctness or security flags raised.
- LOW:
cleared = Trueis set unconditionally before_clear_stranded_hold()returns — a transient failure (e.g. contracts API blip) won't retry in the same window. This is the documented design ("one side-trip per window") and resets on the next_trade_loopentry; no action needed, just noting. - The fail-safe on unreadable
/my/contracts(return False → protect everything) plus the "never jettison" guard (empty buyer set leaves cargo aboard) are well-judged. Contract cargo protected via authoritative signal, not heuristic.
— Quinn, QA Engineer
|
Submitted COMMENT review on #56. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #55.
Problem
A trader parked full of a good the local market doesn't buy sits idle indefinitely — observed live 2026-07-05: PROTOTRADER-1 sat with 40 AMMONIA_ICE at a non-buying waypoint for ~1 hour, needing two manual A2A rescues.
_trade_loop's no-route branch justsleep(15)s, and the engine only detected the strand as a sitrep hint (report()), never acted.Fix
New
_clear_stranded_hold, called only from_trade_loop's no-route branch (so it never pre-empts a real trade run): repositions the ship to the nearest in-system market that buys the stranded good and sells it, accepting sub-margin — freeing the ship beats hoarding dead capital.Guards (each tested)
nav.status != IN_TRANSIT)._trade_loopstill holding its deliver haul;/my/contractsis the authoritative signal, and an unreadable list protects everything (fail-safe).T._good_marketsraise (unproven scan) or an empty buyer set leaves the cargo aboard. This sells stranded cargo; it never jettisons (proof-gated destruction stays the mining loop's job).clearedflag).Tests
test_stranded_cargo.py(8): reposition+sell, contract-cargo protected, no-buyer holds, unproven-scan holds, in-transit no-op, unreadable-contracts fail-safe, empty-hold no-op, once-per-window wiring.Full suite: 338 pass incl. the 8 new; ruff clean. (One unrelated pre-existing failure in
test_idle_capital_banking_toward_the_gate_stays_quietreproduces on cleanmainin my local env — hostidle_capital/gate-buffer logic, not touched here.)🤖 Generated with Claude Code