Phantom zero-hop / queue bypass — flyPlane now consumes queue[0] when dispatching to the first queued destination, so landing no longer triggers a zero-distance self-leg from auto-chain. Skip-ahead (/fly to a non-first queued dest) stays allowed as an explicit override; FIFO order is preserved (documented in code).
Auto-chain full-tank backstop — engine chain path now grounds the plane ('available', queue intact) when the next leg's required fuel exceeds tank capacity, mirroring flyPlane's 409.
Defensive self-leg drop — chain skips a queue[0] === locationIcao entry without flying (legacy rows only).
sellPlane guard — 409 "cancel queued legs first" when the plane has queued legs (previously discarded silently).
E2E +4 (54 → 58): new e2e/queue.spec.ts — 3-leg FIFO ordering across two landings; refuel-between-legs at exact rep-discounted cost (drained tank via set-fuel); cancel-mid-chain while flying. Extended state.spec.ts — staged queue survives docker compose restart flight. Reworked two-planes.spec.ts — 240 s phantom-absorbing poll replaced by explicit no-self-leg assertions.
New test hook /api/test/set-cash (absolute wallet set; add-cash is additive-only). Test hooks are out-of-spec by convention, so OpenAPI unchanged (lib/openapi.test.ts pins the path list).
Verification
Local: tsc --noEmit clean · vitest run 373/373 · playwright test --list 58 tests in 15 files. Full e2e runs in CI (dind stack) per AGENTS.md.
Closes #88
## Fixes (root causes found while adding the tests)
- **Phantom zero-hop / queue bypass** — `flyPlane` now consumes `queue[0]` when dispatching to the first queued destination, so landing no longer triggers a zero-distance self-leg from auto-chain. Skip-ahead (`/fly` to a non-first queued dest) stays allowed as an explicit override; FIFO order is preserved (documented in code).
- **Auto-chain full-tank backstop** — engine chain path now grounds the plane ('available', queue intact) when the next leg's required fuel exceeds tank capacity, mirroring `flyPlane`'s 409.
- **Defensive self-leg drop** — chain skips a `queue[0] === locationIcao` entry without flying (legacy rows only).
- **sellPlane guard** — 409 "cancel queued legs first" when the plane has queued legs (previously discarded silently).
## Tests
- Unit +5 (368 → 373): consume-on-dispatch, skip-ahead no-mutation, sell 409, full-tank backstop, defensive self-leg drop.
- E2E +4 (54 → 58): new `e2e/queue.spec.ts` — 3-leg FIFO ordering across two landings; refuel-between-legs at exact rep-discounted cost (drained tank via set-fuel); cancel-mid-chain while flying. Extended `state.spec.ts` — staged queue survives `docker compose restart flight`. Reworked `two-planes.spec.ts` — 240 s phantom-absorbing poll replaced by explicit no-self-leg assertions.
- New test hook `/api/test/set-cash` (absolute wallet set; add-cash is additive-only). Test hooks are out-of-spec by convention, so OpenAPI unchanged (`lib/openapi.test.ts` pins the path list).
## Verification
Local: `tsc --noEmit` clean · `vitest run` 373/373 · `playwright test --list` 58 tests in 15 files. Full e2e runs in CI (dind stack) per AGENTS.md.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #88
Fixes (root causes found while adding the tests)
flyPlanenow consumesqueue[0]when dispatching to the first queued destination, so landing no longer triggers a zero-distance self-leg from auto-chain. Skip-ahead (/flyto a non-first queued dest) stays allowed as an explicit override; FIFO order is preserved (documented in code).flyPlane's 409.queue[0] === locationIcaoentry without flying (legacy rows only).Tests
e2e/queue.spec.ts— 3-leg FIFO ordering across two landings; refuel-between-legs at exact rep-discounted cost (drained tank via set-fuel); cancel-mid-chain while flying. Extendedstate.spec.ts— staged queue survivesdocker compose restart flight. Reworkedtwo-planes.spec.ts— 240 s phantom-absorbing poll replaced by explicit no-self-leg assertions./api/test/set-cash(absolute wallet set; add-cash is additive-only). Test hooks are out-of-spec by convention, so OpenAPI unchanged (lib/openapi.test.tspins the path list).Verification
Local:
tsc --noEmitclean ·vitest run373/373 ·playwright test --list58 tests in 15 files. Full e2e runs in CI (dind stack) per AGENTS.md.