Claude Proposes, Claude Cross-Examines
Wiring headless Claude into the trading bot's day by role — news collection, the morning meeting, cross-examination, an evening self-audit, and a different failure default for each role.
The trading bot runs the rule approach and the Claude approach side by side on a paper account and compares them. The Claude approach takes target weights from a single headless call each morning and executes them straight onto a virtual ledger. After about a month, those proposals were going into the ledger with nobody questioning them, and the news was being summarized without ever being tied to the tickers we hold.
What I set out to do
The trading bot runs the rule approach and the Claude approach as an A/B on paper trading. The Claude approach gets a target-weight proposal from a single headless claude -p call every morning and executes it on a virtual ledger, but after about a month of running it, holes showed. News was only summarized and never connected to our portfolio, and proposals went into the ledger without anyone questioning them. At a company of humans, these would be filtered out in a meeting.
So today I decided to complete the morning meeting between the morning news collection and the evening self-diagnosis that were already running. The core is the cross-examiner: separating the Claude that proposes from the Claude that attacks.
Wired into the daily schedule by role
08:30 news collection. claude -p is invoked with only --allowedTools WebSearch attached. US and Korean markets, rates and FX, risk factors, within 10 sentences total, sources cited, no investment advice. If it fails, the summary slot gets “(collection failed — no information. Judge conservatively)” verbatim. A silent blank makes the next stage optimistic.
08:50 morning meeting. Performance and risk analysis is pure computation with no LLM. There’s precedent for a single expired CLI credential halting judgment for three days, so I don’t add failure points to the judgment layer. The market analyst (headless Claude) interprets the overnight news only in terms of “the tickers we actually hold” and is forced to end with one HEADLINE: sentence on the last line. Then the strategist proposes target weights as JSON, and that proposal is handed to the cross-examiner I attached today.
You are the cross-examiner on the investment committee. Attacking this proposal is your only job. Do not propose alternatives. Do not look for reasons to agree. Find only weaknesses.
The cross-examiner’s output is JSON too: a verdict (PASS/OBJECT) and a severity of 0-3. An objection of severity 2 or higher triggers a Telegram approval request, and if there’s no approval command before the 09:05 execution, the Claude approach doesn’t trade that day. A gate whose default is “don’t.”
17:00 self-diagnosis. The day’s entire operating record (job runs, warning events, orders, virtual trades, P&L, ledger reconciliation) is scraped from the DB and dropped into the prompt whole.
Diagnose based on this record only. No exaggeration, do not speculate about anything not in the record. Only propose code and config changes, never instruct their execution.
Every call uses the same frame. Role declaration (“You are …”) + verbatim data insertion + explicit statement of constraints enforced by code + enforced JSON schema.
Where it broke: a prompt prohibition is not enforcement
Two things snagged.
First, writing “don’t” in a prompt is a request, not enforcement. So the strategist prompt states explicitly that “the system enforces this in code, so violating proposals are discarded,” and the code actually does that. If the weights sum to more than 1 or any is negative, the whole thing is discarded without correction. The reviewer that screens trading signals is stricter. Its authority is limited to approve/reject/reduce, and if the reduction ratio exceeds 1, it isn’t clipped to 1, it’s rejected. An out-of-range value isn’t noise to be patched over; it’s evidence of an attempt to increase the quantity.
Second, the failure default. Headless calls die readily from timeouts and parse failures. Make everything “reject on failure” and a single CLI outage halts everything; make everything “pass on failure” and the review in front of the money becomes decoration.
The criterion: is it on the path the money travels?
The conclusion was to set a different default per role. The reviewer, which holds the order quantity, is an unconditional REJECT on failure; after one retry, everything is rejected. The strategist on failure yields 0 signals. The cross-examiner and the market analyst, on the other hand, don’t block trading when they fail. Analysis is auxiliary and enforcement is done by the guardrail code. Instead, the failure itself is left in the activity log.
The evening self-diagnosis is the last piece of this structure. In last week’s run, based on the job execution history, both approaches’ P&L, and the ledger reconciliation, it ruled “no anomalies,” and it even noted that only its own job was RUNNING because it was the one running, diagnosing itself as “in progress, within normal range.” The picture of Claude auditing Claude’s trading records is actually running. But the diagnosis is read-only. Applying anything requires my approval in a session. Whether the cross-examiner I attached today produces objections worth having is something to watch from next week.
Lessons
- A prompt’s prohibition is a request; enforcement is code. Writing “violating proposals are discarded” in the prompt and having code that actually discards them were both necessary.
- The failure default must differ by role. On the path the money travels, failure = reject; for auxiliary analysis, failure = pass + log. Unify into one policy and an accident happens either way.
- Reject out-of-range output instead of correcting it. Clamping erases the evidence of a violation.
- Separating the proposing AI from the attacking AI mattered, but the key was forbidding the cross-examiner from proposing alternatives. Allow alternatives and the attacker becomes a second proposer.
- The red line for unattended auditing is read-only. Let it diagnose and propose, and put execution behind human approval.