Role Memory
Shadow-first, role-scoped reflection over settled manual trading cases
Role Memory stores success patterns and failure modes for a declared analysis role. In the unified Trading Memory architecture, a case becomes eligible for learning only after it is linked to an exact, consumed manual trade preview and the corresponding execution has a settled outcome.
This is not a generic prediction log and it is not an account-history mirror. Autopilot, Strategy Studio, XStrategy, workflow executions, and unknown-origin perps cannot produce a recallable role case.
For the user-facing audit page, see Trading Memory.
Admission boundary
A role case is scoring-eligible only when all of these conditions hold:
- The role ID is declared by a reasoning skill and exists in the role registry.
- A manual preview was consumed exactly once.
- The case and execution match the same decision ID, asset, direction, account, and market.
- The execution origin is
manual_agentor a verifiedmanual_external. - The outcome is settled and has sufficient evaluation data.
An automated marker overrides manual-looking evidence. An unknown role or trade origin is quarantined rather than admitted with a fallback. This fail-closed boundary prevents automated strategy behavior from being reinterpreted as a human preference or an analysis-role lesson.
Data model
role_cases stores the role, linked decision and evaluation run, situation,
decision text, outcome state, reflection, provenance, scoring eligibility, and
timestamps. FTS and optional vector indexes support retrieval, while the
relational decision/evaluation links remain the source of truth.
The surrounding unified chain is:
trading_decisions
→ trade_executions / trade_fills
→ position_lifecycles
→ evaluation_runs / evaluation_components
→ methodology_observations and role_casesCases are not independently allowed to claim that a trade happened. They inherit that fact from the linked execution chain.
Role declarations
Analysis-style skills declare stable role IDs and reflection policies. The role registry validates them at startup; duplicate or unknown IDs do not silently map to a generic role. A role definition controls its failure modes, maturity window, outcome probe, and reflection prompt.
The split between skill and role is intentional: a skill is a capability bundle, while a role names a decision context within that bundle. This keeps, for example, valuation lessons separate from momentum or cycle-analysis lessons.
Reflection
Once an eligible case matures, the reflector first classifies the outcome:
logic_error— reasoning contradicted available evidence; trainable.missing_data— required evidence should have been fetched; trainable.exogenous— the result depended on an unforeseeable event; retained for audit but not converted into guidance.variance— the result is indistinguishable from noise; no guidance produced.
Only trainable categories receive a concise role-specific lesson. Reflection is serialized per role to prevent duplicate LLM work, budget-gated, and cannot call fund-moving tools.
Runtime mode
ROLE_MEMORY_MODE is read at startup and fixed for the process:
| Mode | Write/evaluate | Recall/inject |
|---|---|---|
off | No new cases; existing data retained for audit | Disabled |
shadow (default) | Eligible manual cases are generated and reflected | Disabled |
active | Same as shadow | Reflected cases may enter matching analysis-role and Institution Trader / PM prompts |
Invalid values log a warning and fall back to shadow. Active mode does not
inject case text into execution tools. SOUL, static safety rules, permission
gates, and explicit user constraints always outrank retrieved cases.
The recall and manual-reflect tools are registered only in active mode; shadow exposes only the candidate-store path needed to generate cases. This is important: shadow is not “the model may ignore the case”; the model cannot retrieve or receive the case in its formal decision prompt at all.
Retrieval constraints
Active retrieval filters by the exact role and, where supplied, symbol and scenario. Only reflected, non-quarantined, scoring-eligible manual cases are eligible. Ranking may use FTS or embeddings, but semantic similarity never relaxes the origin, role, or decision-link constraints.
Evaluation relationship
Role Memory consumes versioned evaluation runs. Multiple benchmark profiles may
evaluate the same decision, and replay appends a new run. Only an explicitly
promoted primary run is eligible to update downstream statistics. Factor details
and missing-data quality remain on evaluation_components; Role Memory does not
collapse them into one hard-coded score.
Migration
Legacy role_memory rows migrate to role_cases. Known roles retain their
original text and provenance. Unknown roles go to quarantine. Legacy scores are
audit-only and cannot update new methodology or role statistics. Migration is
covered by the same checksummed backup and conservation report as the rest of
Trading Memory.
Operational checks
- Confirm
ROLE_MEMORY_MODE=shadowwhen evaluating behavior before injection. - Restart after changing the mode; it is not hot-switched.
- Use doctor/audit output to inspect old pending, failed, or quarantined cases.
- If a case is absent, verify the consumed manual preview and exact execution link before inspecting reflection scheduling.
- Never “repair” an automated or unknown trade by manually flipping its scoring eligibility.
Related implementation:
apps/agent/src/memory/role-memory-mode.tsapps/agent/src/memory/role-reflector.tsapps/agent/src/memory/prompt-injection.tsapps/agent/src/tools/role-memory.tsapps/agent/src/memory/trading-memory-migration.ts