MINARA

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:

  1. The role ID is declared by a reasoning skill and exists in the role registry.
  2. A manual preview was consumed exactly once.
  3. The case and execution match the same decision ID, asset, direction, account, and market.
  4. The execution origin is manual_agent or a verified manual_external.
  5. 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_cases

Cases 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:

ModeWrite/evaluateRecall/inject
offNo new cases; existing data retained for auditDisabled
shadow (default)Eligible manual cases are generated and reflectedDisabled
activeSame as shadowReflected 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=shadow when 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.ts
  • apps/agent/src/memory/role-reflector.ts
  • apps/agent/src/memory/prompt-injection.ts
  • apps/agent/src/tools/role-memory.ts
  • apps/agent/src/memory/trading-memory-migration.ts

On this page