Market briefs
A brief is the structured output of one portfolio decision pass — the AI's full reasoning, target book and close list.
Briefs are the most important artifact in the app. Every order has a parent brief, and every brief has the inputs that produced it: window boundaries, signal count, event count, current open positions, AI model, and the raw model response. If you want to know why the agent did something, open the brief.
The 4-step cycle
- Read — pull fresh news + events in the window.
- Collate — combine them with the current open portfolio.
- Decide — ask the AI for a verdict on each open position + a target book + a close list.
- React — the executor opens, trims and closes positions accordingly.
Position verdicts
For every currently open ticker, the AI returns one of:
- hold — keep the position as-is.
- trim — reduce exposure but stay in the trade.
- close — exit the position.
The executor only closes positions the AI explicitly tells it to close. Silence on a ticker defaults to hold. This is intentional — it prevents accidental flushes when a new target book happens to omit an existing ticker.
Target book vs close list
- Target book — what the portfolio should look like after this pass. Drives new opens.
- Close list — explicit closes. Plus any position with a
closeverdict.
Rotation rules
The brief picks closes carefully. Three runtime guards sit on top of the AI's verdicts to keep the book stable:
- No rotation while the book isn't full — if open positions are below
portfolio_max_positions, any "rotate out for a better idea" close is demoted back tohold. Empty slots get filled with new ideas instead. - Rotation-cost guard (only when book is full) — to replace an incumbent, the new candidate's confidence must exceed the incumbent's entry confidence by at least
rotation_confidence_margin(default 0.10). - Loss-aversion guard — stale-but-not-negated theses sitting at a loss are not realised. Only thesis negation, direction flip, or locking a deteriorating winner counts as a valid close.
- Pyramiding — reinforcing news on an existing position increases its
target_weight_pctrather than opening a new slot.
Position sizing
portfolio_max_positions— single source of truth for how many concurrent positions the agent can hold (the oldermax_open_positionskey was retired).portfolio_session_budget_pct— share of the configured starting capital each pass may deploy into new exposure.
Key fields
| Field | Type | Description |
|---|---|---|
| trigger | — | What caused this pass: scheduled session, breaking news, event cluster, or imminent event. |
| window_start / window_end | — | Time range of news + events considered. |
| input_signal_count | — | How many fresh signals fed into this pass. |
| input_event_count | — | How many fresh events fed into this pass. |
| open_position_count | — | Positions open at the start of the pass. |
| target_book | — | Array of { ticker, direction, target_weight_pct }. |
| close_list | — | Tickers the AI explicitly wants closed. |
| position_verdicts | — | Array of { ticker, verdict, reason } — one per open position. |
| narrative_md | — | Free-form AI narrative explaining the overall stance. |
| ai_raw_response | — | Verbatim model response, kept for auditing. |