Skip to content

Fix CPR AI true-up coordination and MCP retries - #122

Open
DoRmAmMu1997 wants to merge 3 commits into
mainfrom
codex/fix-cpr-ai-trueup-tool-retry
Open

Fix CPR AI true-up coordination and MCP retries#122
DoRmAmMu1997 wants to merge 3 commits into
mainfrom
codex/fix-cpr-ai-trueup-tool-retry

Conversation

@DoRmAmMu1997

Copy link
Copy Markdown
Owner

Summary

  • coordinate CPR AI five-minute inference with the official one-minute REST true-up watermark
  • wait until the final source minute of a completed five-minute bucket is officially confirmed before consuming that bar
  • retry missing or failed required MCP tool evidence once against the exact same frozen context and bar signature
  • keep both attempts inside the original inference deadline and fail closed for unexpected capabilities
  • record inference attempt counts and aggregate token usage in the decision JSONL
  • add beginner-friendly documentation and regression coverage for both failure modes

Root cause

The websocket snapshot could expose a provisional five-minute candle before the minute-close REST true-up. Codex inference then ran against that provisional snapshot, and the official true-up changed its signature before validation completed, producing stale_bar_signature.

Separately, an occasional Codex turn returned before completing all four required frozen MCP tools. The host correctly rejected that response, but it had no bounded recovery path, producing missing_tool_call or failed_tool_call outcomes.

Safety behavior

  • CPR AI now uses an atomic official-candle watermark instead of a guessed sleep interval.
  • A 09:55 five-minute bucket is eligible only after the official source covers 09:59.
  • A tool-evidence retry reuses the same frozen facts and signature and receives only the time remaining from the original timeout.
  • Duplicate, unexpected, or unallowlisted tools do not retry.
  • Existing stale-signature validation remains in place.
  • No authenticated Codex call or broker order was made during verification.

Verification

  • CPR AI: 72 passed
  • master: 513 passed
  • market health: 26 passed
  • repository suites: 1,144 passed
  • branch coverage: 72.1%; safety/broker threshold policy passed
  • Ruff, mypy, compileall, Bandit, and pre-commit passed
  • fake smoke: HOLD validation=accepted_hold NO ORDER

Co-authored by Codex.

Co-authored-by: Codex <codex@openai.com>
@DoRmAmMu1997
DoRmAmMu1997 marked this pull request as ready for review August 12, 2026 05:27
DoRmAmMu1997 and others added 2 commits August 12, 2026 14:20
Source: Intraday Hunter live session, 12 Aug 2026 (CV_Fs3TFF5I, 6:46).
A WIN taken from the SAME opening condition that produced the 11 Aug
loss, which is what makes it worth encoding.

Both days opened flat, sold off immediately, and had IH saying nobody was
positioned -- "neither many buyers nor many sellers". On 11 Aug he
predicted who would arrive and lost. On 12 Aug he waited for the market
to show him and won.

So v4e's rule needed reconciling rather than repeating. An empty book is
not simply a no-trade condition: it is a statement that the market MUST
manufacture a trap, because it has nothing else to work with. What it
does not tell you is which side the trap points at. The rule is now:
form the hypothesis, but wait for CONFIRMATION IN PRICE before acting.

Knowledge changes (all prose):
- OPENING_DRIVE: THE CHART DOES NOT REPEAT TWO DAYS RUNNING -- a shape
  everyone watched yesterday is one everyone is ready for today, so a
  second-day carbon copy argues for a reversal rather than the
  continuation; A MOVE THAT DENIED YOU ENTRY WAS NOT YOUR MOVE (v4d's
  gap logic at intraday scale -- "everything happened in ONE MINUTE");
  AN EMPTY BOOK MEANS A TRAP IS COMING, WAIT FOR IT TO REVEAL ITS
  DIRECTION; THE SHARPEST RECOVERY NAMES THE LEADING INDEX, AND SIZE
  FOLLOWS IT.
- RISK: BOOK WHEN THE PROFIT STOPS GROWING, NOT WHEN IT REVERSES -- the
  trigger is the rate of accrual, not a price level and not a loss.

Three test markers. The important one is
test_v4f_confirmation_rule_does_not_reopen_the_v4e_forecasting_hole:
v4e and v4f are a matched pair, and v4f read alone would license exactly
the forecast v4e forbids, so it asserts the confirmation requirement and
v4e's HOLD survive together.

Prompt 101,087 -> 105,933 chars (headroom 14,067).

The doc addendum also records how our agent traded the same tape. It
took ONE trade, on the wrong side: SHORT at 10:30 on
double_top_shooting_star_reversal, one minute after IH went long on the
recovery, cut at 10:31 by the v3y index-hierarchy rule. The hierarchy
rule worked; the entry was the error, and it is exactly what v4f is
meant to prevent -- repeated chart, a move that denied entry, and an
empty book all argued against selling that drop.

ADR-0012 gains the measured outcome of the durable/marks split, since
today is the first session running it: total slow-write warnings fell
from 281 to 22, and the supervisor path from 254 to 7 against a
threshold eight times looser. Recorded with both caveats -- the 12 Aug
figures are a partial session, and the worst marks write was 10.065s
with no fsync at all, so the disk contention is real and the split only
moved those seconds off the trading path.

Session P&L is provisional (runner live at 14:15): +13,519.25 across 39
legs, SL Hunting -1,034.25 cross-checked against its own Result summary.

Gates: SL Hunting + Dependencies pytest 875 passed, master 513 OK, ruff
clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The dhanhq utcfromtimestamp DeprecationWarning kept appearing despite
the master file installing a scoped ignore at import time. Reproduced,
and the filter itself was never the problem -- in a plain process it
suppresses the warning correctly.

The source is PYTEST. It wraps every test in catch_warnings() +
simplefilter("always"), which RESETS warnings.filters and discards
anything a module installed at import time; only its own -W /
[tool.pytest.ini_options] filterwarnings entries are re-applied inside
that context. The repo had no [tool.pytest.ini_options] section at all,
so nothing was re-applied and the warning surfaced in every run while
the runner's own console stayed silent -- the runner log contains zero
occurrences of it, which is what made this confusing.

Fixes:
- pyproject.toml gains [tool.pytest.ini_options] filterwarnings with the
  same narrow ignore. NOTE the format differs from the Python API: in
  -W/ini strings warnings._setoption re.escapes the message and module
  fields, so they are LITERALS, not regexes -- which is why the two
  dhanhq modules need one line each instead of an alternation. There is
  deliberately no leading "default"/"error" entry, so every other
  warning behaves exactly as before (verified: the dateutil
  utcfromtimestamp warning is still surfaced by the suite).
- the master file's filter now covers dhanhq.fulldepth as well as
  dhanhq.marketfeed. dhanhq/__init__ imports both and each ships the
  same utc_time helper (marketfeed.py:523, fulldepth.py:391). The runner
  only subscribes MarketFeed so the second site should never fire; it is
  one regex branch and removes a latent surprise.
- the comment claiming the import-time filter "wins over any blanket -W
  / PYTHONWARNINGS setting because filterwarnings PREPENDS" was wrong
  and is corrected: importing dhanhq alone pushes our entry to index 1,
  because urllib3 prepends its own. It now documents the pytest caveat
  instead.

Why the existing test did not catch this: it re-installs the filter by
hand inside simplefilter("always") -- exactly the step pytest does NOT
do for us -- so it proved the filter works while the bug was live. The
new TestPytestReappliesTheDhanhqWarningFilter asserts the ini entries
exist AND feeds the committed strings through warnings._setoption before
triggering the warning, so a plausible-looking entry that matches
nothing fails. Mutation-checked: breaking the module name in pyproject
fails both new tests.

Gates: master 516 OK, market-data-health 26 OK, pytest 1147 passed with
the dhanhq warning gone and only the unrelated dateutil one remaining,
ruff/mypy/compileall clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant