Skip to content

Close the Alpaca native-fault engine gaps (C05 cancel-again sends DELETE; C04 documented definitive refusal) - #169

Merged
seathatflowsinourveins merged 6 commits into
mainfrom
claude/native-faults-c04-c05-20260924
Sep 24, 2026
Merged

seathatflowsinourveins merged 6 commits into
mainfrom
claude/native-faults-c04-c05-20260924

Conversation

@seathatflowsinourveins

Copy link
Copy Markdown
Owner

Closes the two Alpaca native-fault engine gaps named in catalogs/us-equities/gates-20260922.json, so that a paper run of native-faults/harness.py can reach native_faults_passed. Only offline evidence exists so far. native-faults/receipt.json is still the 2026-09-23 native_faults_incomplete run, bound to the old hashes.

C05, cancel_again (engine behaviour change; the trading-lane owner should review). AlpacaPaperTransport.cancel now always sends the broker DELETE for an owned order. It no longer short-circuits when it believes the order is already terminal.

  • Alpaca's answer is treated as data, per the DELETE reference: 422 means "The order status is not cancelable".
  • A 404 or 422 is accepted only when the follow-up lookup shows the order is terminal. If the order is still working, the cancel freezes as cancellation_unresolved.
  • Timeouts, 429s and 5xx responses freeze, as before.
  • Cost: cancelling an order already known to be terminal now takes a DELETE plus a GET, where it used to take one GET.

C04, definitive_rejection, by reclassification as the gate text allows. No fault answered with 401, 403 or 404 is reachable within the plan's bounds:

  • The create-order reference documents only 403 (insufficient buying power or shares) and 422.
  • The Ledger's own caps refuse both 403 cases before anything is sent.

So a 422 counts as definitive only when all of these hold:

  • the documented sub-penny body and code are present;
  • the intent's own price violates the tick;
  • a lookup returns 404, showing no order exists.

Every other 422 stays ambiguous, per README-safety.md. mark_broker_refused enforces this and records the refusal.

Verification (offline)

  • The pinned runtime is Python 3.12.3 with nautilus-trader 2.0.0rc5 and alpaca-py 0.44.0. On it, the adaptive-paper suite and test_native_faults_min pass 704 tests with 1 skip, up from a baseline of 688.
  • New tests cover:
    • the C05 422/404/500 paths;
    • a sub-penny 422 with a 404 that is not replayed;
    • the ambiguous 422 variants;
    • the ledger refusal guards;
    • the harness reaching native_faults_passed against the fake broker, while the old short-circuit is still classified as incomplete.
  • validate.py, validate_catalogs.py, landscape.py, evidence_manifest.py --check and verdict_review_gate ("no verdict rows changed") all pass.
  • Hashes were recomputed with host_receipts.register_file, and source-hashes.json was rebuilt from the file bytes.
  • Known local failure: in the full suite, test_effort_default_guard.test_shipped_guard_is_verbatim fails on this host only, because its ~/.claude hook is stale.

Review. An independent reviewer found no correctness or broker-safety defects: 1 medium and 2 low findings. All three were fixed in 8051464. The reviewer's suggested wording for one of them was adopted only in part, because the only evidence for that wording is this branch's mocked fixtures.

Still to do. Rerun the harness on paper per native-faults/README.md. That needs a paper credential file on the running host.

🤖 Generated with Claude Code

Scout and others added 2 commits September 24, 2026 03:20
C05 cancel_again: AlpacaPaperTransport.cancel now sends the DELETE for
every owned order to its known broker id. It no longer returns early when
a client-id lookup shows the order terminal. Alpaca's answer is data: 204
is an acknowledgement, and 404 or 422 ("The order status is not
cancelable", docs.alpaca.markets/us/reference/deleteorderbyorderid-1.md)
is accepted without a freeze only when the follow-up lookup shows the
order terminal. Timeout, 429 and 5xx still freeze. The repeated terminal
observation changes no ledger state.

C04 definitive_rejection: no 401/403/404 fault can be reached within the
plan's bounds. POST /v2/orders documents only 403 (buying power or
shares), which the Ledger refuses before send, and 422. So the change
reclassifies only the 422 that the docs prove definitive: Alpaca's
minimum-price-variance rejection (code 42210000, "sub-penny increment
does not fulfill minimum pricing criteria",
docs.alpaca.markets/us/docs/orders-at-alpaca.md). It must be for a price
that really violates the increment, on the first POST, followed by a
client-id lookup 404. Every other 422, including "client_order_id must
be unique", stays ambiguous. Ledger.mark_broker_refused accepts 422 only
with that refusal and a violating durable price. The pre-send
invalid_price_increment check stays for the engine. Only the harness's
FaultLedger exempts its single C04 client id.

Plan, harness judges, README, README-safety and README-transport are
updated. The README states what the next native run must show. New unit
tests use the fake broker and mocked HTTP. No paper run and no new
receipt; receipt.json stays the 2026-09-23 native_faults_incomplete run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…red 422

F1: native-faults/README.md no longer says the 2026-09-23 run "went exactly
that way" or that its plan and engine hashes match this tree. The run predates
the 2026-09-24 engine change; its plan, harness and engine hashes are the
pre-change ones.

F2: the sub-penny records (native-faults README and plan, README-safety,
README-transport, safety.py and transport.py comments) now say that
docs.alpaca.markets/us/docs/orders-at-alpaca.md documents the body (code
42210000 and message) and the rejection, not the HTTP status. The 422 is
inferred from the code prefix and the POST /v2/orders 422 entry and must be
confirmed by the native run. The message, not the code, is the
discriminator. Behaviour is unchanged: documented_refusal still requires
status 422, so any other status stays ambiguous.

F3: the native-fault-behaviour gate note gets a dated, status-unchanged
sentence for the 2026-09-24 offline engine change. The gate stays
not_established.

Comment-only engine edits update source-hashes.json; changed files are
re-registered with host_receipts.register_file. No paper run, no receipt.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-24T07:36:44.979511Z 8051464 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

…lip candidate

Merge origin/main into claude/native-faults-c04-c05-20260924. Both sides had
changed adaptive-paper/source-hashes.json and manifests/evidence.json; the
hashes are recomputed from the merged files, and receipt, source-hashes and
catalog entries are registered with host_receipts.register_file.
runner.py, safety.py, transport.py, harness.py and plan.json are
byte-identical to 8051464, the commit the run used.

Record the coordinator's live Alpaca paper run from 8051464 (WSL2
workstation, paper account dedicated to that PC, 14:39:05Z). C01 submit 200,
C02 cancel 204, C05 DELETE sent and answered 204 plus read 200, C04 submit
422 with the documented sub-penny body then lookup 404, cleanup flat with cash
delta 0.00. The receipt binds this tree's harness, plan and engine hashes. The
raw stdout stays private; only its sha256 is recorded. The 2026-09-23
incomplete receipt is retained byte-identical as receipt-20260923.json.

native-fault-behaviour is now a trading_gates flip candidate. Its status
stays not_established because the gate requires manual qualification before a
dated flip commit, and the acceptance policy does not accept the harness's
own passed field as that. An independent observation of the run's orders is
still required. runtime-target next_acceptance broker-state-failures records
native_fault_receipt_passed_independent_observation_pending.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… listing)

Retain the workflow coordinator's independent observation of prefix
nf-20260924t143905-29d7ec-, made at 2026-09-24T15:01:47Z by a separate
method: an alpaca-py 0.44.0 script on Python 3.12.3, not harness.py and not
the engine transport. Script and stdout are byte-identical copies of the
private files (sha256 6f4b1c19... and 420d762c...); stderr empty, exit 0.
Neither file contains a credential, account id or host path.

Observed: one broker order with the prefix since started_at (c01, canceled,
filled 0); the c01 client-id lookup returns the same; the c04 lookup returns
404, so no order exists; 0 open orders and 0 positions. This matches the
receipt (one accepted submit later canceled, one 422-refused submit, cleanup
flat). The claim boundary: same broker and account, independent code; it does
not observe the run's own HTTP statuses or the engine's handling of a 422
cancel refusal.

The README records the observation. The gate flip is a separate dated commit.
manifests/evidence.json updates only the README entry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Sep 24, 2026
…ine)

On macos-m5pro-20260924, from a read-only git archive of main 6f7a77c, in
the hash-locked CPython 3.12.14 runtime built from the #176 lock:

- Trial a (config-sip.json, 300 s, 1x, SIP, one-share orders) passed. It
  made 33 submits and 3 cancel-replaces, and got 30 native fills in 15 round
  trips. It reconciled flat, with realized P&L of -1.51 USD.
- STOP drill: the working entry was canceled 115 ms after STOP, with 0
  filled, and no order followed. recover passed flat, and STOP was archived
  with a release record.
- Native-faults harness: C01 and C02 passed with native_paper evidence. C04
  and C05 are still blocked on #169.
- Host receipt alpaca-py/use (native_proven, second physical machine).
- Rebuilt the rate-limit evidence for the new trial headers (trading 419 to
  641, data 9 to 13) and updated the pinned test totals and README row to
  match.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ication)

Dated flip commit under the ladder rule: a status changes only by a dated
commit after scripts/trading_gates.py lists the gate as a flip candidate, and
this gate requires manual qualification that native (non-synthetic) faults
were exercised. The note's new dated qualification entry cites:
- the receipt native-faults/receipt.json (native_faults_passed, Alpaca paper
  14:39:05Z; C01 200, C02 204, C05 DELETE answered 204, C04 422 sub-penny
  body then lookup 404, cleanup flat);
- the independent alpaca-py observation
  native-faults/evidence/independent-observation-20260924.json (c01 canceled
  filled 0, no order for c04, 0 open orders and positions; counts match);
- the Codex GitHub review of PR #169 at 8051464, the commit the run used,
  completed 2026-09-24T07:36:44Z with no findings.

evidence_class is native_proven, not native_paper: scripts/trading_gates.py
accepts only native_proven, local_integration, synthetic, source_review and
none, and the other paper-run gates (alpaca-paper-smoke,
adaptive-paper-broker-trial) use native_proven. The receipt's per-case class
stays native_paper. The checker is unchanged.

runtime-target next_acceptance broker-state-failures is now
bounded_alpaca_synthetic_cases_passed_native_fault_behaviour_established_alpaca_paper.
Its scope says C05's DELETE was answered 204, so the engine's handling of a
422 cancel refusal remains offline-tested only; the C04 422 is one
paper-endpoint observation, not live evidence; IBKR is not covered.

trading_gates.py --check: passed, no flip candidates; rung_ready sim true,
paper true, live false (blocking: leverage-ladder-1x/2x/4x,
ibkr-local-acceptance, live-go). manifests/evidence.json updates only the
README, gates and runtime-target entries. No verdict-review-gate trust input
changed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Sep 24, 2026
…ine) (#188)

On macos-m5pro-20260924, from a read-only git archive of main 6f7a77c, in
the hash-locked CPython 3.12.14 runtime built from the #176 lock:

- Trial a (config-sip.json, 300 s, 1x, SIP, one-share orders) passed. It
  made 33 submits and 3 cancel-replaces, and got 30 native fills in 15 round
  trips. It reconciled flat, with realized P&L of -1.51 USD.
- STOP drill: the working entry was canceled 115 ms after STOP, with 0
  filled, and no order followed. recover passed flat, and STOP was archived
  with a release record.
- Native-faults harness: C01 and C02 passed with native_paper evidence. C04
  and C05 are still blocked on #169.
- Host receipt alpaca-py/use (native_proven, second physical machine).
- Rebuilt the rate-limit evidence for the new trial headers (trading 419 to
  641, data 9 to 13) and updated the pinned test totals and README row to
  match.

Co-authored-by: seathatflowsinourveins <234074349+seathatflowsinourveins@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The gate note and the broker-state-failures scope now state that the only
native fault exercised was one sub-penny submit answered 422; ambiguous or
in-flight submits (timeouts, 429, 5xx, partial fills, restart) remain
synthetic or offline-only. The runtime-target scope no longer says native
in-flight behaviour is unqualified and then that the gate is established
without saying which class each sentence covers. Evidence hashes updated for
the two changed files only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@seathatflowsinourveins

Copy link
Copy Markdown
Owner Author

Request from the Mac coordinator session (trading lane), for the execution-boundary acceptance.

The foundation lane will record agent-ecosystem's alpaca-research / execution-boundary for mac-coordinator (Alpaca paper scope) only when two things exist on native evidence:

  1. Idempotency: C04 (definitive refusal) and C05 (cancel-again sends DELETE) passing against the real paper broker — this PR. The Mac paper account already has C01/C02 passing natively (Alpaca paper lane end to end on macOS (second physical machine): SIP trial passed, STOP drill, native-fault C01/C02 #188, trials/mac-2026-09-24-native-faults), and this session will run this PR's cases on the Mac paper account once it merges, unless you'd rather run them.
  2. Risk: a native pre-trade denial. The engine sets LiveRiskEngineConfig(bypass=False, max_order_submit_rate="180/00:01:00", ...) (native_adapter.py:486) and app-level caps in safety.py/config.json, but no retained artifact shows a denial. Proposal: add a harness case (e.g. C06) that, on paper, (a) attempts one order above the per-order notional / share cap and (b) a submit burst above the configured rate, and proves each is denied before any broker POST (zero new broker orders, a denial event in the ledger/log, flat end state), recorded in the same receipt format as C01-C05.

If you prefer to keep this PR scoped to C04/C05, say so here and this session will open the risk case as a separate PR after this one merges.

🤖 Generated with Claude Code

@seathatflowsinourveins
seathatflowsinourveins merged commit 2d11464 into main Sep 24, 2026
22 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the claude/native-faults-c04-c05-20260924 branch September 24, 2026 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane:trading Trading lane: sim, paper and live north star

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant