Repository navigation
Adaptive-paper engine P0 release: per-execution fill booking, guarded callbacks, halt/LULD state - #221
Conversation
…alt and LULD state Items 2-4 of the 2026-09-24 data and execution convergence record (E2-E4), as one engine release of blueprints/us-equities/adaptive-paper. E2, per-execution fill booking. native_adapter.observe books each fill or partial_fill trade update that carries execution_id, qty and price as exactly that execution (TradeId = execution_id, last_px = its price), keyed by the order's cumulative quantity after it; no price is derived from Alpaca's 6-decimal cumulative average (the APUS 26 @ 5.62, 2 @ 5.61, 1 @ 5.61 sell now books three exact fills instead of freezing on a derived 5.610004). A cumulative quantity no booked execution explains is a fill gap closed after 2 s by one read of GET /v2/account/activities/FILL?order_id= (added to GuardedSession's read allowlist with only order_id, asc, page_size <= 100 and an activity-id page_token), joined on cumulative quantity; a cancel or expiry reported before its fills waits for them. _generate_fill_reports reports adopted open orders' executions from the activities, so a restart with fills no longer raises. The post-terminal and same-quantity guards still freeze; every documented trade_updates event has one handling, undocumented ones (including corrections and busts) freeze. The transport forwards a stream fill with a new execution_id even after a REST read advanced the cumulative quantity; safety.Ledger records executions durably and books exact execution prices when they tile an advance, otherwise cumulative averages with a 6-decimal rounding tolerance on the limit check. E3, order and position callback guard. Every on_order_* / on_position_* handler of AdaptiveStrategy, MoverStrategy and CapacityProbe is wrapped by guarded_callback: an exception records the callback, freezes the ledger with strategy_callback_exception_<handler>, latches faulted (no further submit), stops the session through fault_sink (NativeSession.fail) and ends needs_attention with the residual handed to recovery. An AST test fails on any unwrapped handler; a LiveNode characterization test shows rc5 discarding an unguarded handler's exception (upstream #5039) and fails if a later release surfaces it (E3's overturn). E4, halt and LULD state. On the sip feed the quote connection also subscribes trading statuses and LULD bands; statuses map to per-symbol halt state per Alpaca's documented CTA and UTP codes (CTA 2 with reason M a LULD pause; 5 halts; 6, E and F never change the state, per the CTS Pillar output specification v2.11b; UTP H, Q, P halt, T resumes; market-wide circuit breakers labelled), out-of-order safe with a halt winning a tie. A startup seed from one Nasdaq Trader trade halts RSS read covers symbols already halted at subscribe time (fail-open, recorded; entries wait at most 3 s for it). No entries and no exit re-pricing while a symbol is halted, in both lanes. On iex neither channel is subscribed and nothing is seeded. source-hashes.json and manifests/evidence.json re-pinned; README text updated. Evidence: synthetic fixtures (documented trade_updates, FILL activity, trading status, LULD and halts RSS schemas) and local integration against the real NautilusTrader 2.0.0rc5 LiveNode. No paper session has run this release. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…, halts, rc5 startup Follow-up to 0b49261 (items 2-4 of the 2026-09-24 data and execution convergence record), resolving both reviews' findings in blueprints/us-equities/adaptive-paper. Fills (E2). A cancel or expiry the broker reports before its fills are booked now fixes the order's final quantity: pending_terminal keeps the filled quantity it reported, and a stream row, a stream execution or a FILL activity ending above it freezes (post_terminal_fill_requires_reconciliation) instead of being booked. Each fill gap gets its own 2 s grace: a gap opened while another was pending, or a larger cumulative quantity reported during the activities read, waits for its own grace instead of failing the read. A gap still open at stop is the adapter error fill_gap_open_at_stop (needs_attention), and receipts carry native_assertions (fill_events_carry_execution_fields, no_fill_gap_open_at_stop) with named overturn_signals. Startup with an adopted, partly filled order (overnight holds): activities are read once at connect, the order report is stamped accepted no later than the first execution (rc5 applies reconciliation events in timestamp order and dropped the real fills, then synthesized a second order for the position; reproduced on a real LiveNode), and fill reports honour venue_order_id/instrument_id and never reset booked state. Halts (E4). Exits and exit re-pricing in both lanes wait on the status stream and startup seed only (Controller.is_halted); the quote's unverified condition flag blocks entries only. A halt only the seed asserts expires at its resumption trade time or 12 minutes after a LULD pause began (LUDP, LUDS, M; LULD Plan Amendment 12), and a seed row already past that is not applied. A status message with a missing or unrecognized tape reads its code from both tables, so a documented resume still resumes. The halts RSS body is read one socket read at a time (urllib3 read1, identity encoding) with the deadline checked before each read. Callbacks (E3). A faulted MoverStrategy no longer evaluates the book on quotes or ticks. blueprints/us-equities/engine-nautilus/probes/repro_5039.py moves the #5039 reproduction into the repo (exit 0 while rc5 still discards the exception). Also: a stale error name in mover.py, the sessions halt test skipped without the native runtime, dated binding amendments to the native-fault-behaviour gate note, runtime-target and native-faults README (the receipt qualifies the engine of cbbd589), README text, source-hashes.json and manifests/evidence.json re-pinned. Evidence: synthetic fixtures, local integration against the real NautilusTrader 2.0.0rc5 LiveNode, and a loopback HTTP server through the installed requests/urllib3. No paper session, no network beyond read-only doc and source lookups, no orders. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Combine the engine release (per-execution fill booking from trade_updates execution_id with FILL-activity gap-fill, guarded order/position callbacks, SIP trading statuses/LULD halt state with the Nasdaq RSS seed) with main's order-contract boundary (#198), the 18:58Z native-fault receipt on it and the first 1x leverage-ladder attempt (#212). Conflicts: - runner.py: transport import carries both order_contract_status and halt_statuses_supported/nasdaq_halt_seed. - transport.py: imports keep hashlib and importlib.util; the FILL-activity and execution constants sit beside the order-contract loader. - source-hashes.json: regenerated from file bytes (same 48 keys). - manifests/evidence.json: sha256/bytes re-registered for the nine files both sides changed, then sorted with scripts/evidence_manifest.py --write. - native-faults/README.md and gates-20260922.json: main's text kept; the release's binding amendment now names the current 18:58Z receipt (main 3b7ae71 engine sources), which predates the release, so the gate still qualifies the earlier engine until the plan is re-run on the release. - runtime-target.json (auto-merged): the same amendment corrected from cbbd589 to the current receipt. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…porate-action and credential guards Main moved 19 commits since 5ed8538. The conflicts were resolved by keeping both sides: - native_strategy.py: AdaptiveStrategy takes both halted= (E4) and corporate_action_guard= (#222). The constructor keeps the halt and callback-fault state and the corporate-action guard state. cancel_expired keeps the halted-exit skip (E4) and gains #222's symbols= immediate-cancel set. - runner.py: the strategy gets both halted=controller.is_halted and the corporate-action guard. The shutdown runs stop_halt_seed() inside #222's try/finally, so the corporate-action refresh cleanup still runs if the halt-seed stop raises. - source-hashes.json: the union of both sides' keys, every digest recomputed from the merged tree. - manifests/evidence.json: main's registry, plus the branch's new engine-nautilus probe, with all stale digests refreshed. The branch's entries for the renamed CI lock (#233) and the renamed grype fixture (#224) are dropped. Checks on the merged tree: - pinned rc5 runtime, 23 paper modules: 1,320 tests OK (2 skipped); - full python3 -m unittest: 4,944 tests OK (600 skipped); - validate.py, evidence_manifest.py --check, and the source-hashes manifest test: pass. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Carried forward (2026-09-25, native-agent-stack-e7). This PR had been idle for about 9 hours, and no live session predates its last update. Its two review rounds were complete: one major finding fixed, and the recheck approved with 3 minor findings left as residuals. So I merged current Conflicts.
Checks on the merged tree:
I'll squash-merge once CI is green. This PR's own "Open before citing gates" list still applies after the merge: the native-fault plan must re-run on paper on this engine. 🤖 Generated with Claude Code |
… engine merges and credential blocker (#248) - Simulation lane: hftbacktest agrees with NautilusTrader within 0.36% once our driver's use-after-free is fixed (#245). The evidence reference points to the cross-check receipt. - Paper lane: the engine P0 release (#221) and exact cancel identity (#242) merged today. The native-fault rerun and the 1x ladder attempt are blocked: at the open, the stored paper keys were rejected with HTTP 401 on the trading account and on both data feeds, so they need rotating through the credential terminal. No order was sent. Co-authored-by: Scout <scout@local> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
#242 and #284 (#350) * Paper engine: fix the retroactive cross-family review findings on #221, #242 and #284 GPT-6 (gpt-6-astra, effort max) reviewed three merged paper-engine PRs on main ca8e37f; #243 passed. - #221: activity-based gap recovery booked fills natively without persisting them to the durable ledger (native 3, durable 1); a continuing LULD pause auto-cleared after twelve minutes and let cancel_expired cancel the exit it protected; cash and realized P&L depended on REST-snapshot versus stream delivery order. - #242: replay_compare scheduled a named cancel stamped before its submit and silently skipped it; cancelling the transport task cleared the cancel identity before the HTTP worker sent the DELETE. - #284: a clean exporter stop released the port before deregistering, so it could remove a replacement exporter's target; configure.py's initialization could overwrite a concurrent registration; malformed nested labels passed validation and would make Prometheus reject the whole target list. Each fix was implemented test-first by a GPT-6 implementer in its own worktree; every new regression failed before its fix. Coordinator integration: source-hashes.json and evidence pins refreshed; the 20260923g sim-paper-compare receipt replayed from its retained pages with the new code (identical apart from run-local fields and runner_sha256, updated as in #242); sim-capacity's frozen replay_compare source re-pinned with a dated limitation (AST check: the 8 definitions sim-capacity uses are unchanged). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Paper engine repair round: persist recovered fills through the transport's real observation hook Independent verification of cad7faf found #221 finding 1 unresolved in production: reconcile_fills persisted recovered fills only through a port.controller attribute that no real Alpaca port has (AlpacaPaperTransport and the native-faults FaultTransport are wired with sink_observation=controller.observe); only the test-only SimulatedPort carried it. - native_adapter.py: persist through the port's sink_observation (the hook the transport already uses for stream rows), after validating that the recovered activities tile the fill contiguously (fail closed otherwise). - simulation.py: SimulatedPort exposes the same sink_observation hook, so tests and production share one path. - Tests: a real-shaped port (no .controller) regression that failed on cad7faf with Decimal('1') != Decimal('3'), restart persistence, incomplete tiling; the two accounting-replay guards in safety.py; fast build_decisions-level tests for the cancel-before-submit refusal and its equality boundary. Implemented by a GPT-6 implementer test-first; 514 tests across the five affected modules pass. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Scout <scout@local> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ealized-loss delivery-order major; follow-up to #350) (#355) * Paper engine: fix the retroactive cross-family review findings on #221, #242 and #284 GPT-6 (gpt-6-astra, effort max) reviewed three merged paper-engine PRs on main ca8e37f; #243 passed. - #221: activity-based gap recovery booked fills natively without persisting them to the durable ledger (native 3, durable 1); a continuing LULD pause auto-cleared after twelve minutes and let cancel_expired cancel the exit it protected; cash and realized P&L depended on REST-snapshot versus stream delivery order. - #242: replay_compare scheduled a named cancel stamped before its submit and silently skipped it; cancelling the transport task cleared the cancel identity before the HTTP worker sent the DELETE. - #284: a clean exporter stop released the port before deregistering, so it could remove a replacement exporter's target; configure.py's initialization could overwrite a concurrent registration; malformed nested labels passed validation and would make Prometheus reject the whole target list. Each fix was implemented test-first by a GPT-6 implementer in its own worktree; every new regression failed before its fix. Coordinator integration: source-hashes.json and evidence pins refreshed; the 20260923g sim-paper-compare receipt replayed from its retained pages with the new code (identical apart from run-local fields and runner_sha256, updated as in #242); sim-capacity's frozen replay_compare source re-pinned with a dated limitation (AST check: the 8 definitions sim-capacity uses are unchanged). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Paper engine repair round: persist recovered fills through the transport's real observation hook Independent verification of cad7faf found #221 finding 1 unresolved in production: reconcile_fills persisted recovered fills only through a port.controller attribute that no real Alpaca port has (AlpacaPaperTransport and the native-faults FaultTransport are wired with sink_observation=controller.observe); only the test-only SimulatedPort carried it. - native_adapter.py: persist through the port's sink_observation (the hook the transport already uses for stream rows), after validating that the recovered activities tile the fill contiguously (fail closed otherwise). - simulation.py: SimulatedPort exposes the same sink_observation hook, so tests and production share one path. - Tests: a real-shaped port (no .controller) regression that failed on cad7faf with Decimal('1') != Decimal('3'), restart persistence, incomplete tiling; the two accounting-replay guards in safety.py; fast build_decisions-level tests for the cancel-before-submit refusal and its equality boundary. Implemented by a GPT-6 implementer test-first; 514 tests across the five affected modules pass. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Paper engine: book realized P&L and gross loss per exact execution in accounting replay The accounting replay summed a status delta's executions into one notional before computing P&L, so a sell filled at a gain and a loss inside one delta netted the loss away, and the result depended on whether the stream or the REST snapshot arrived first. Replay now books each execution that tiles the delta separately (QuantConnect/Lean 985ef30: SecurityPortfolioModel.cs per-fill closing P&L; TradeStatistics.cs accumulates losses separately), falling back to the delta notional only while executions are incomplete. Two regressions: mixed-profit gross loss across stream-first, REST-first, duplicate and restart deliveries, and basis preservation at each booking. With the fix reverted, 4 cases fail (rest_first, duplicates, restart, basis). Paper suites (safety, runner, native, transport): 407 tests OK. Implemented by GPT-6 (gpt-6-astra, effort max) test-first; verified by the coordinator. Pins: source-hashes.json safety.py and manifests/evidence.json. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Paper engine repair round (#355 review): replay executions in execution order, versioned marker Independent review of c81a3d5 (needs_changes): - Finding 1 (major): the replay booked fills in observation order. Stream fills now carry Alpaca's own trade_updates timestamp (event_at_ns; FILL recovery forwards transaction_time_ns), the ledger keeps it in a new optional executions.at_ns column (added on open for existing ledgers), and replay fills each symbol's timed execution slots in execution order, tie-broken by event id then cumulative quantity. Adoptions, untimed executions and uncovered provisional bookings keep their journal positions. - Finding 3: the marker is execution_accounting:v2:<client_id>, so ledgers replayed under the observation-order rule re-derive once. - Finding 4: a test for an uncovered REST-only booking beside another order's late executions. - Finding 2 (adopted open orders) is covered by #356's startup persistence. The A/B/C case gives cash 70, realized -15, gross loss 25, and 1 share at 115 under stream, REST-ahead, recovered, late-buy and nanosecond deliveries. Reverting the three production files fails 10 cases (4 new tests, 2 strengthened). Paper suites: 411 OK; trading gates 26 OK; validate.py passed. Implemented by GPT-6 (gpt-6-astra, effort max) test-first; verified by the coordinator. Pins: source-hashes.json (safety, transport, native_adapter) and manifests/evidence.json. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Re-pin the changed paper test files in adaptive-paper/source-hashes.json source-hashes.json also pins test files; CI's test_adaptive_paper_source_hashes_manifest caught the stale entries. Pins only, no code change: the changed tests' entries and their manifests/evidence.json registration. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Reduce #355 to the reviewed-safe subset; defer execution-order replay The re-check of cc6d7cb found two new majors in the execution-order replay: - Moving an earlier-executed fill into another order's slot can make an uncovered REST-only sell go short. The replay then raises, the fill rolls back and the transport freezes, although the real history is consistent. - Removing the early exit let that failure block fills in every symbol and added a full replay to every fill. Under the bounded review loop (one review, one repair, then land with residuals), this commit lands the parts both reviews confirmed. It keeps: - c81a3d5's per-execution P&L and gross loss within a delta; - the versioned execution_accounting:v2 marker (F3); - the uncovered-fallback test (F4), with its oracle stated for observation-order replay. It reverts: - the slot-substitution replay and the early-exit removal; - the executions.at_ns column, which also avoids the unversioned schema change (re-check F3); - the stream and recovery timestamp plumbing. Execution-time ordering is a recorded follow-up, with the reviewer's constraints: never reorder into a short (fall back to observation order), a targeted replay trigger, and a schema version bump. Revert checks: the v1 marker fails the F3 test; skipping the uncovered fallback errors the F4 test. Paper suites: 409 OK; source-hashes and trading gates: 33 OK; validate.py passed. Pins: safety.py and its test file only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Scout <scout@local> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
#221 (8bd4ca7, merged 2026-09-25) books each trade_updates fill as its own execution and closes fill gaps from GET /v2/account/activities/FILL, so the adapter never derives a price from a cumulative average. That supersedes fills.py's inference (trading-lane proposal on PR #205, step 1). - Remove blueprints/us-equities/adaptive-paper/fills.py and tests/test_adaptive_paper_fills.py. - Restore native_adapter.py, tests/test_adaptive_paper_native.py and README-mover.md to the merge base, so the merge takes main's versions. The native test changes exercised fills.py's price recovery from rounded averages (dropped). The same-quantity average-correction test duplicates main's test_same_quantity_with_a_changed_average_still_freezes (dropped). - Keep tests/test_adaptive_paper_safety.py's test_a_certain_limit_violation_still_halts: main's ledger still books a cumulative-only observation from the averages, with a rounding tolerance, and this is the only test that a certain violation still halts there. - source-hashes.json: the base copy, re-pinned for the kept safety test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on branch Conflicts and their resolution: - manifests/evidence.json: main's copy, unchanged here. The branch's files are re-registered in the last commit (docs/lanes.md hot-file protocol). - blueprints/us-equities/adaptive-paper/source-hashes.json: main's copy, re-pinned for the one file the merge leaves changed, tests/test_adaptive_paper_safety.py (main plus the kept test_a_certain_limit_violation_still_halts). native_adapter.py, tests/test_adaptive_paper_native.py and README-mover.md now equal main's (#221 per-execution booking; #559 FEE reconciliation). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the partial-fill precision fix (#205) * Mover mode's first paper run (Mac) and the partial-fill precision fix Trial mover-mac-20260924a ran the mover trial mode against Alpaca paper for the first time: five scanner-selected entries and three X2 exits filled, then GRML's exit filled in parts at 15.00 and 15.01. Alpaca's six-decimal cumulative average (15.000833) made the native adapter derive 15.009996 and stop with cumulative_fill_precision_requires_reconciliation. Forced recovery sold the rest; the account reconciled flat, P&L +0.87 USD, recover proof passed. The trial record and its offline verifier are under trials/mac-2026-09-24-mover-a/. native_adapter.execution_price takes each fill's own execution price from the trade-update event when its quantity equals the new shares and it agrees with the reported average; otherwise it rounds the derived price only when the average's reporting bound is under half a price unit. Anything else still stops the adapter. The new native tests reproduce the run's arithmetic and fail on the previous adapter. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Register the Mac mover trial record and re-registered sources in the evidence manifest Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Add the mover trial's decision stream (events.jsonl is ignored by *.jsonl; force-added like the stop drill's) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Count the mover trial's rate-limit headers in the order-throughput evidence (1149 trading, 14 data) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Re-register the order-throughput evidence in the evidence manifest Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Resolve fills on the notional grid in one shared module, for the adapter and the ledger An independent pre-merge review (Codex, a different model family) found the first version too narrow: rounding assumed one price per snapshot delta, the tolerance came from the normalized string's exponent, an exactly representable derived price was accepted without an ambiguity check, a contradictory execution event was replaced by a derived price, and the ledger's limit check still halted on rounded averages at the limit (1 x 100.00 then 2 x 100.01 at 100.01 derives 100.0100005). fills.resolve_execution now accepts an execution event only when its price is on the grid and agrees with the average (else fill_event_price_requires_reconciliation), and otherwise requires the new shares' notional to be the only whole number of ticks strictly within filled x 0.000001 of the report, dividing into an on-grid price per share. It computes in its own decimal context. The ledger's limit check halts only on a violation that is certain within fills.incremental_notional_bound. Each counterexample from the review is a test; the ledger test fails on main's safety.py. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Re-register the fill-resolution sources and tests in the evidence manifest Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Keep the ledger's limit check unchanged; track its rounded-average false halt separately The delta review of the previous commit found that loosening the ledger's limit check by the rounding bound lets a real one-tick violation pass on large 4-decimal orders (buy limit 0.9354, 99 x 0.9354 then 1 x 0.9355, reported 0.935401). A correct check needs grid resolution of both cumulative notionals, fractional-share handling and a chosen trade-off between false halts and missed violations, which belongs in its own change. safety.py is back to main; the guard test that a certain violation halts stays (it passes on main). The adapter's fill resolution (fills.py) is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Re-register the reverted ledger sources in the evidence manifest Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Record mover trial C (Mac, 2026-09-24 14:52 ET): X1 blocked by stale quotes, needs_attention, not flat The second broker run of the mover mode (engine at d7a11b3, the first fill-fix version; no partial fills occurred): four entries filled at the quoted ask; GCTK was skipped. After a market-data websocket reconnect at 15:49, PFSA and SRZN quotes stayed stale, the transport's 3 s required-symbol freshness froze it, and X1 at 15:58 never sent. The hard flatten latched at 16:01:22 and GRML's sell was attempted but never reached Alpaca (client-ID 404). Recovery fails closed on that ambiguous intent ("owned intent absent from complete snapshot"), and after-hours quotes are too sparse for the freshness rule even at the 30 s maximum. Four paper positions remain open pending an operator decision. The verifier now separates integrity checks from reported outcomes, and the order-throughput evidence counts the new headers (1629 trading, 15 data). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Register mover trial C and the recounted order-throughput evidence in the evidence manifest Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Drop fills.py, its tests and the adapter hook; #221 books each execution #221 (8bd4ca7, merged 2026-09-25) books each trade_updates fill as its own execution and closes fill gaps from GET /v2/account/activities/FILL, so the adapter never derives a price from a cumulative average. That supersedes fills.py's inference (trading-lane proposal on PR #205, step 1). - Remove blueprints/us-equities/adaptive-paper/fills.py and tests/test_adaptive_paper_fills.py. - Restore native_adapter.py, tests/test_adaptive_paper_native.py and README-mover.md to the merge base, so the merge takes main's versions. The native test changes exercised fills.py's price recovery from rounded averages (dropped). The same-quantity average-correction test duplicates main's test_same_quantity_with_a_changed_average_still_freezes (dropped). - Keep tests/test_adaptive_paper_safety.py's test_a_certain_limit_violation_still_halts: main's ledger still books a cumulative-only observation from the averages, with a rounding tolerance, and this is the only test that a certain violation still halts there. - source-hashes.json: the base copy, re-pinned for the kept safety test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Count the 2026-09-24 mover trials' headers in the dated rate-limit record #501 (df41236) made rate_limit_evidence.py read a fixed DATED_TRIAL_FILES set, so that a trial committed later cannot move the 2026-09-24 totals. That set was built on main, where this branch's two mover trials were not yet merged. They also ran on 2026-09-24, and this branch's record already counts them (1693 trading and 16 data headers). After the merge, --check reported the record stale and test_rate_limit_evidence_is_current_and_matches_brief failed (705/14 built vs 1693/16 committed). - Append trials/mac-2026-09-24-mover-a/mover-paper.json and trials/mac-2026-09-24-mover-c/mover-paper.json to DATED_TRIAL_FILES. `--write` reproduces the committed record byte for byte, and `--check` passes. - test_a_later_trial_receipt_does_not_change_the_dated_evidence: expect the dated totals with the mover trials (16 and 1693). A later trial still does not move them. rate_limit_evidence.py is outside the brief's path list, so this change is a separate commit. To drop it, revert this commit and restore main's rate-limit-evidence-20260924.json, its order-throughput/README.md row and the test_order_throughput.py totals line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Re-register this branch's files in the evidence manifest (hot-file protocol) docs/lanes.md hot-file protocol, merge path. The merge took main's manifests/evidence.json unchanged. This commit registers, through scripts/host_receipts.register_file: - the changed files main's manifest already lists: adaptive-paper/source-hashes.json, order-throughput/rate_limit_evidence.py, tests/test_adaptive_paper_safety.py and tests/test_order_throughput.py; - the 37 new trial-record files this branch registered (trials/mac-2026-09-24-mover-a/ and trials/mac-2026-09-24-mover-c/). Not re-added: order-throughput/README.md and rate-limit-evidence-20260924.json. They are changed, not new, and main's manifest does not list them. fills.py and tests/test_adaptive_paper_fills.py are gone, and main's manifest never listed them. scripts/component_matrix.py --write and scripts/new_host_grand_list.py --write left their reports unchanged. scripts/validate.py passed (8669 hashed files), and scripts/evidence_manifest.py --check passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: seathatflowsinourveins <234074349+seathatflowsinourveins@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: Scout <scout@local>
Why
The 2026-09-24 RTH mover paper trial froze on
cumulative_fill_precision_requires_reconciliation. The adapter had derived a per-fill price from Alpaca's rounded cumulative average during a multi-price exit (APUS: 26 @ 5.62, 2 @ 5.61, 1 @ 5.61). The freeze left SRZN open until the engine'srecoversold it.The verified data-and-execution convergence record (2026-09-24) put three items at P0: this fix, a callback guard and halt/LULD awareness.
What (blueprints/us-equities/adaptive-paper)
trade_updatesfill and partial_fill events are booked as exactly those executions: TradeId =execution_id, last_px = the event price, last_qty = the event quantity.GET /v2/account/activities/FILL(on the read allowlist) gap-fills dropped events and builds_generate_fill_reports, so a restart with fills no longer raises.needs_attention. An AST test fails on any unwrapped handler, and a LiveNode test reproduces the upstream exception-swallowing behaviour it guards against.statusesandluldson the existing stream, with CTA and UTP codes per the CTS spec: CTA6is not a halt; E/F never clear a halt.The source-hashes and evidence pins are regenerated, and the READMEs describe the new behaviour.
Review trail
Checks
scripts/validate.py: passed.python3 -m unittest: 4,603 OK (509 skipped).Evidence classes: synthetic fixtures in the documented schemas, plus local integration on the real LiveNode.
Open before citing gates
The native-fault receipt (18:58Z) qualifies main's engine hashes before this release. The fault plan (C01, C02, C05, C04) must re-run on paper on this engine before
native-fault-behaviouris cited for it. A native paper mover session with at least 5 multi-fill orders should also showadapter_errors == [], and a 1:1 match between the booked fills and the FILL activities.🤖 Generated with Claude Code