Skip to content

Add quote provision and quote pull; extract the shared rails - #10

Merged
piekstra merged 3 commits into
mainfrom
feat/quote-pull-provision
Jul 28, 2026
Merged

Add quote provision and quote pull; extract the shared rails#10
piekstra merged 3 commits into
mainfrom
feat/quote-pull-provision

Conversation

@piekstra

@piekstra piekstra commented Jul 28, 2026

Copy link
Copy Markdown
Owner

What

Completes the quote family, and — with three call sites now real — factors the safety rails into a single check_placement. This is the extraction I committed to in #9 rather than declining it permanently: the point was to shape it from real call sites instead of guessing from one. plan_recenter also drops its private book/mid derivation for a shared market_from, so mid and best-bid/best-ask (with our own size subtracted) are computed in exactly one place and cannot drift.

quote provision

Posts a fresh two-sided quote, and refuses to leave you one-sided. If either leg fails a rail — most often too few tokens to back the ask — nothing is sent and the shortfall is reported. Placing just the half that works would consume cover and earn $0, which is the worst possible outcome.

It never buys inventory for you. Acquiring tokens moves real money through a different venue and stays an explicit, separate amm swap.

quote pull

Stands down from a property. --keep-above protects orders you mean to leave resting — typically a cost-basis recovery ask parked above the band — so standing down never sweeps away the sell that's waiting to recover your position:

$ lofty quote pull --property-id <ID> --keep-above 13.00
DRY RUN — nothing sent.
  keep   sell $13.60 x1 (untouched)
re-run with --execute to apply

It also flags when a pull would leave a one-sided remainder, since that rests, costs cover, and earns nothing.

Two output bugs found by dogfooding

Neither was reachable from the unit tests, which assert on JSON rather than rendered text:

  1. A pull plan has no market, so the header printed mid $0.00, reward band [$0.00, $0.00] — a market that doesn't exist. Now omitted when a plan places nothing.
  2. --execute with an empty plan printed DRY RUN — nothing sent … re-run with --execute, which reads as though the flag had been ignored. No-op is now its own render mode: nothing to do — no matching orders.

Testing

12 new unit tests (90 total): provision planning both legs, defaulting size to minContracts, refusing rather than leaving a paid-for one-sided half, refusing when already quoting, and enforcing every rail; pull cancelling both sides, --keep-above protecting a recovery ask, --keep-above not protecting a bid, side filtering, the one-sided-remainder note, and an empty plan. Plus an invariant test that a pull plan carries no mid/band while a placing plan does.

Dogfooded live on the real account: pull --keep-above under --execute cancelled nothing and left the $13.60 recovery ask intact; provision refused on a property already quoted. All three render modes verified against the live binary.

fmt, clippy -D warnings, all 91 tests clean.

Completes the `quote` family and, with three call sites now real, factors the
safety rails into one `check_placement` — the extraction promised in review #9
rather than a second command copy-pasting the first. `plan_recenter` also drops
its private book/mid derivation for the shared `market_from`, so mid, best-bid
and best-ask (our own size subtracted) are computed in exactly one place.

`provision` posts a fresh two-sided quote and REFUSES to leave a one-sided
result: if either leg fails a rail — most often too few tokens to back the ask —
nothing is sent, because the half that would rest still consumes cover and earns
nothing. It never buys inventory; acquiring tokens stays an explicit `amm swap`.

`pull` stands down, with `--keep-above` protecting deliberate holds so a
stand-down never cancels the cost-basis recovery ask parked above the band.

Two output bugs found by dogfooding, neither reachable from the unit tests
(which assert on JSON, not rendered text):
- a pull plan has no market, so the header printed a defaulted
  "mid $0.00, reward band [$0.00, $0.00]" — a market that does not exist. The
  header is now omitted when a plan places nothing.
- `--execute` with an empty plan printed "DRY RUN — nothing sent … re-run with
  --execute", implying the flag had been ignored. No-op is now its own mode.

Dogfooded live: `pull --keep-above` under `--execute` correctly cancelled nothing
and left the recovery ask intact, and `provision` refused on a property already
quoted.

Claude-Session: https://claude.ai/code/session_01J7bz8aijn2Uwv1yF5rUenW
@piekstra
piekstra requested a review from piekstra-dev July 28, 2026 20:22

@piekstra-dev piekstra-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated PR Review

Reviewed commit: 6d5996fc5a16
Profile: reviewer - Posting as: piekstra-dev

Summary

Reviewer Findings
policies:conventions 0
structure:repo-health 1
structure:repo-health (1 finding)

Major - src/commands/quote.rs:123

This PR extracts fetch_state/apply_or_show specifically so the three quote primitives can't drift, but Cmd::Recenter (lines ~136-276) still inlines its own copy of the exact same program/orders/orderbook/balance/position fetch (duplicating fetch_state, lines 344-393) and its own copy of the cancel/create apply loop with partial-failure reporting (duplicating apply_or_show, lines 397-467), instead of calling the new shared helpers. Only 2 of 3 call sites actually converged; Recenter is now a second, independent copy that must be kept in sync by hand — the exact compounding risk check_placement/market_from were extracted to avoid, just one level up the call stack. A future change to active-order filtering, the confirm/partial-failure message, or noop handling only needs to touch apply_or_show/fetch_state for provision/pull but would silently miss Recenter unless someone remembers to update both. Fix: route Cmd::Recenter through fetch_state for its state gathering and through apply_or_show (or a shared variant that also takes the mid/band fields recenter computes) for confirm+apply, removing the duplicated inline block.

Reviewer Coverage

Reviewer Status Inspected Skipped Constraints
policies:conventions complete_broad README.md, src/commands/quote.rs unavailable No sibling ../cli-common/docs or ../.github checkout was present in the workbench, so shared Open CLI Collective standards were assessed only via this repo's AGENTS.md/CONTRIBUTING.md, not the canonical upstream docs.
structure:repo-health complete_broad src/commands/quote.rs unavailable unavailable

0 PR discussion threads considered. 0 summarized; 0 resolved.


Completed in 2m 02s | $1.50 | claude-sonnet-5 | cr 0.10.268
Field Value
Model claude-sonnet-5
Reviewers policies:conventions, structure:repo-health
Engine claude_cli · claude-sonnet-5
Reviewed by cr · piekstra-dev
Duration 2m 02s wall · 2m 52s compute
Cost $1.50
Tokens 68 in / 12.1k out

Per-workstream usage

Workstream Model In Out Cache read Cache create Cost Duration
orchestrator-selection claude-sonnet-5 6 2.5k 49.2k 14.3k $0.14 30s
policies:conventions claude-sonnet-5 34 5.1k 684.8k 50.0k $0.58 1m 15s
structure:repo-health claude-sonnet-5 22 4.0k 422.3k 62.9k $0.56 53s
orchestrator-rollup claude-sonnet-5 6 493 48.4k 31.8k $0.21 12s

Comment thread src/commands/quote.rs
Review (major): the extraction only converged 2 of 3 call sites. Recenter kept
its own copy of the program/orders/orderbook/balance/position gather and its own
cancel/create apply loop with partial-failure reporting, so a future change to
active-order filtering, the confirm text, the partial-failure message or no-op
handling would land for provision/pull and silently miss recenter — the same
compounding drift the rails extraction was meant to end, one level up.

Recenter now uses fetch_state and apply_or_show like the others. Verified live
after the change: a dry run went through the shared path and its coverage rail
correctly refused a bid the wallet could no longer back.

Claude-Session: https://claude.ai/code/session_01J7bz8aijn2Uwv1yF5rUenW
@piekstra
piekstra requested a review from piekstra-dev July 28, 2026 20:32

@piekstra-dev piekstra-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated PR Review

Reviewed commit: db7d88de9d88
Profile: reviewer - Posting as: piekstra-dev

Summary

Reviewer Findings
policies:conventions 0
structure:repo-health 1
structure:repo-health (1 finding)

Major - src/commands/quote.rs:51

apply_or_show (line 299) was generalized to take a what: &str so recenter/provision/pull share one execute-and-report path, but the failure-reporting helpers it calls on a partial failure — partial_failure_message (line 667, hardcoded "recenter failed partway..." at line 674) and partial_failure_lines (line 685, hardcoded "recenter FAILED partway" at line 687) — never received that parameter and still hardcode "recenter". So a partial failure during quote provision --execute or quote pull --execute reports "recenter failed partway on ..." in both the --json error string and the stderr diagnostic, misidentifying which command actually failed. This is exactly the kind of cross-call-site drift the fetch_state/apply_or_show/market_from/check_placement extraction was meant to eliminate, and it's a real gap: partial_failure_message's own doc comment says the string alone must be enough to diagnose a failure in --json mode, but it now lies about the command for 2 of the 3 call sites. None of the 12 new provision/pull tests exercise the failure path, so it isn't caught. Fix: thread what into both helpers (e.g. partial_failure_message(what, &done, step, &e) / partial_failure_lines(what, &done, step)) and add a provision or pull partial-failure test asserting the reported command name is correct.

Reviewer Coverage

Reviewer Status Inspected Skipped Constraints
policies:conventions complete_broad README.md, src/commands/quote.rs unavailable Repo checkout was read-only for this review's tooling (git commands were not permitted), so findings are based on full-file reads of the head checkout plus the provided PR intent/change-map rather than a line-level diff.
structure:repo-health complete_broad src/commands/quote.rs unavailable Scope limited to src/commands/quote.rs per assignment; README.md changes in the diff were not reviewed.

1 PR discussion threads considered. 1 summarized; 1 resolved.


Completed in 3m 02s | $1.60 | claude-sonnet-5 | cr 0.10.268
Field Value
Model claude-sonnet-5
Reviewers policies:conventions, structure:repo-health
Engine claude_cli · claude-sonnet-5
Reviewed by cr · piekstra-dev
Duration 3m 02s wall · 3m 31s compute
Cost $1.60
Tokens 70 in / 14.9k out

Per-workstream usage

Workstream Model In Out Cache read Cache create Cost Duration
orchestrator-selection claude-sonnet-5 6 1.0k 70.7k 23.9k $0.18 13s
policies:conventions claude-sonnet-5 40 8.3k 897.5k 65.8k $0.79 2m 03s
structure:repo-health claude-sonnet-5 18 5.0k 243.3k 48.9k $0.44 1m 03s
orchestrator-rollup claude-sonnet-5 6 511 80.9k 27.0k $0.19 11s

Comment thread src/commands/quote.rs
Review (major): the failure helpers are shared by all three primitives but still
hardcoded "recenter", so a partial failure during `quote provision --execute` or
`quote pull --execute` reported "recenter failed partway". Under --json that
string is the entire report, so it misattributed the failure to a command the
operator never ran — the same cross-call-site drift the extraction was meant to
end, and untested because no provision/pull test exercised the failure path.

Both helpers now take the command name, and a test asserts all three report
themselves correctly.

Claude-Session: https://claude.ai/code/session_01J7bz8aijn2Uwv1yF5rUenW
@piekstra
piekstra requested a review from piekstra-dev July 28, 2026 20:37

@piekstra-dev piekstra-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated PR Review

Reviewed commit: ccd55575ecc6
Profile: reviewer - Posting as: piekstra-dev

Summary

Reviewer Findings
policies:conventions 0
structure:repo-health 0

Reviewer Coverage

Reviewer Status Inspected Skipped Constraints
policies:conventions complete_broad README.md, src/commands/quote.rs unavailable Sibling convenience copies of cli-common/.github docs were not present in the workbench; reviewed against this repo's own AGENTS.md/CLAUDE.md conventions and the existing command modules instead.
structure:repo-health complete_broad src/commands/quote.rs unavailable unavailable

1 PR discussion threads considered. 1 summarized; 1 resolved.


Completed in 3m 34s | $1.57 | claude-sonnet-5 | cr 0.10.268
Field Value
Model claude-sonnet-5
Reviewers policies:conventions, structure:repo-health
Engine claude_cli · claude-sonnet-5
Reviewed by cr · piekstra-dev
Duration 3m 34s wall · 3m 49s compute
Cost $1.57
Tokens 56 in / 10.9k out

Per-workstream usage

Workstream Model In Out Cache read Cache create Cost Duration
orchestrator-selection claude-sonnet-5 6 1.1k 90.5k 34.1k $0.25 14s
policies:conventions claude-sonnet-5 32 6.1k 760.0k 61.3k $0.69 2m 38s
structure:repo-health claude-sonnet-5 12 3.3k 158.6k 47.8k $0.38 48s
orchestrator-rollup claude-sonnet-5 6 399 100.6k 36.4k $0.25 8s

@piekstra
piekstra merged commit ed262a4 into main Jul 28, 2026
2 checks passed
@piekstra
piekstra deleted the feat/quote-pull-provision branch July 28, 2026 20:45
piekstra added a commit that referenced this pull request Jul 29, 2026
Ships the mutating quote family and the stale-quantity fix:

- `lofty quote recenter`  — move a resting quote safely (#9)
- `lofty quote provision` — post a fresh two-sided quote, refusing to leave you
  one-sided (#10)
- `lofty quote pull`      — stand down, `--keep-above` protecting recovery asks (#10)
- fix: read orders from the list that isn't stale after a partial fill (#11)

All three are a DRY RUN unless `--execute`, and share one implementation of the
rails: never cross the market, never exceed cover, never go under minContracts,
stay in the reward band, and touch only the sides given a price.

Exercised against a live account before release — a there-and-back recenter
restored the exact starting state, and every rail was confirmed refusing a real
attempt.

Claude-Session: https://claude.ai/code/session_01J7bz8aijn2Uwv1yF5rUenW
piekstra added a commit that referenced this pull request Jul 30, 2026
* Add quote provision and quote pull; extract the shared rails

Completes the `quote` family and, with three call sites now real, factors the
safety rails into one `check_placement` — the extraction promised in review #9
rather than a second command copy-pasting the first. `plan_recenter` also drops
its private book/mid derivation for the shared `market_from`, so mid, best-bid
and best-ask (our own size subtracted) are computed in exactly one place.

`provision` posts a fresh two-sided quote and REFUSES to leave a one-sided
result: if either leg fails a rail — most often too few tokens to back the ask —
nothing is sent, because the half that would rest still consumes cover and earns
nothing. It never buys inventory; acquiring tokens stays an explicit `amm swap`.

`pull` stands down, with `--keep-above` protecting deliberate holds so a
stand-down never cancels the cost-basis recovery ask parked above the band.

Two output bugs found by dogfooding, neither reachable from the unit tests
(which assert on JSON, not rendered text):
- a pull plan has no market, so the header printed a defaulted
  "mid $0.00, reward band [$0.00, $0.00]" — a market that does not exist. The
  header is now omitted when a plan places nothing.
- `--execute` with an empty plan printed "DRY RUN — nothing sent … re-run with
  --execute", implying the flag had been ignored. No-op is now its own mode.

Dogfooded live: `pull --keep-above` under `--execute` correctly cancelled nothing
and left the recovery ask intact, and `provision` refused on a property already
quoted.

* Route recenter through the shared fetch/apply helpers too

Review (major): the extraction only converged 2 of 3 call sites. Recenter kept
its own copy of the program/orders/orderbook/balance/position gather and its own
cancel/create apply loop with partial-failure reporting, so a future change to
active-order filtering, the confirm text, the partial-failure message or no-op
handling would land for provision/pull and silently miss recenter — the same
compounding drift the rails extraction was meant to end, one level up.

Recenter now uses fetch_state and apply_or_show like the others. Verified live
after the change: a dry run went through the shared path and its coverage rail
correctly refused a bid the wallet could no longer back.

* Report the command that actually failed on a partial failure

Review (major): the failure helpers are shared by all three primitives but still
hardcoded "recenter", so a partial failure during `quote provision --execute` or
`quote pull --execute` reported "recenter failed partway". Under --json that
string is the entire report, so it misattributed the failure to a command the
operator never ran — the same cross-call-site drift the extraction was meant to
end, and untested because no provision/pull test exercised the failure path.

Both helpers now take the command name, and a test asserts all three report
themselves correctly.
piekstra added a commit that referenced this pull request Jul 30, 2026
Ships the mutating quote family and the stale-quantity fix:

- `lofty quote recenter`  — move a resting quote safely (#9)
- `lofty quote provision` — post a fresh two-sided quote, refusing to leave you
  one-sided (#10)
- `lofty quote pull`      — stand down, `--keep-above` protecting recovery asks (#10)
- fix: read orders from the list that isn't stale after a partial fill (#11)

All three are a DRY RUN unless `--execute`, and share one implementation of the
rails: never cross the market, never exceed cover, never go under minContracts,
stay in the reward band, and touch only the sides given a price.

Exercised against a live account before release — a there-and-back recenter
restored the exact starting state, and every rail was confirmed refusing a real
attempt.
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.

2 participants