Skip to content

[feat·M2] DecisionIntent memory — automatically record a live trade intent, then resolve it from execution evidence or one follow-up #636

Description

@atomchung

Status

Owner-approved product/implementation issue — separate owner, not an extension of #597. Not on the current M1 correctness critical path.

Owner ruling, 2026-07-30:

  • A user who explicitly brings a live trade decision to FOMO Kernel has created an intent worth recording.
  • The kernel should record that intent automatically; do not ask a separate “save this?” confirmation.
  • A later transaction record is evidence that the action occurred.
  • If no transaction evidence arrives, a later relevant interaction may ask once whether the user bought, did not buy, changed the plan, or is still considering it.

This issue owns that intent lifecycle. #597 continues to own the no-book conversational framing only. #490 continues to own execution-qualified decision memory and trade-event linkage truth.

Milestone

M2 — Recall and Compare My Reasons.

The write begins at the Phase-1 decision moment, but its value is longitudinal memory and later intent-versus-action reconciliation. Do not start this automatically while the current M1 correctness/answer-quality queue is active.

User outcome

A user can begin with no holdings snapshot or transaction history, discuss one real trade, and later return without reconstructing what they meant at the time.

The product can truthfully distinguish:

  1. what the user intended / considered;
  2. whether the user later reported acting;
  3. whether a canonical transaction record proves an action occurred;
  4. whether that transaction can be linked unambiguously to this specific intent.

Example progression:

“I am considering buying X as a small test because Y; I would exit if Z.”
→ DecisionIntent recorded automatically
→ later transaction import proves a buy occurred
→ unique compatible intent is linked, or one bounded mapping question is asked
→ later review can compare intended size/reason/exit with actual book and action

If no transaction evidence appears, the next relevant interaction may ask one bounded question:

“你上次考虑买入 X,后来有执行吗?”

The answer resolves the intent without pretending that a missing trade record exists.

Current behavior / evidence

Verified against main@dabf709 / PR #616:

  • no-book DecisionFraming is host-side only;
  • it has no engine call, session, route value, artifact or durable write;
  • its three answers disappear with the conversation;
  • a later snapshot or transaction import cannot recover the original intended importance, why_now, or exit condition.

Nearby owners do not cover this lifecycle:

Problem and consequence

The current stage-1 route creates useful decision context and immediately discards it.

Consequences:

  • the next conversation repeats the same three questions;
  • a later holdings snapshot cannot compare declared importance with actual weight;
  • a later transaction cannot be tied back to the earliest reason and exit condition;
  • “considered”, “reported executed” and “transaction-proven executed” remain indistinguishable outside the transient host chat;
  • FOMO Kernel loses the first and often most decision-proximate memory supplied by a new user.

This is not primarily a storage shortage. It is a missing product/domain contract.

Decision

1. Automatic intent capture; no per-intent save confirmation

Explicitly invoking FOMO Kernel for one live trade decision is the product moment that authorizes local decision-memory capture. The host does not ask a second “save this?” question.

User control remains at the local data layer through status/export/reset/deletion mechanisms. Public GitHub evidence remains synthetic.

Only a deliberate trade-decision conversation qualifies. A ticker mention, news question, watchlist scan, or generic company research does not.

2. The stored truth is DecisionIntent, not profile or execution

The first record says only:

The user was considering this action and said these things at this time.

It does not say:

  • the user executed;
  • the declared target is an actual portfolio weight;
  • the exit condition is an adopted permanent rule;
  • the user has a stable investor style;
  • the agent’s generated challenge is a user fact.

3. Minimum append-only contract

Use one versioned append-only stream with stable intent_id and event types such as opened, resolved, and superseded; do not mutate an original intent in place.

An opened intent minimally carries:

  • intent_id;
  • proposed instrument/action;
  • exact user wording for intended importance/target size, why_now, and exit/invalidation where supplied;
  • source route (decision_framing initially; do not duplicate an existing [feat·M1] Bounded TradeEvaluation with visible two-sided challenge #479 TradeEvaluation row);
  • recorded_at and producing host/run provenance;
  • bounded evidence references when explicitly supplied;
  • status projection initially open;
  • idempotency fingerprint so retries cannot append duplicates.

Agent-authored challenge prose is not canonical intent truth. It may be reproduced from source facts or stored separately as labelled judgment only after a concrete reader exists.

4. Resolution sources remain distinct

A resolution event records both status and authority:

  • executed_trade_record — a canonical TradeEvent proves an action occurred and is linked to this intent;
  • executed_user_reported — the user says they acted, but no canonical TradeEvent currently proves quantity/date/book consequence;
  • not_executed_user_reported;
  • modified — the original intent is superseded by a new one rather than rewritten;
  • still_considering — remains open;
  • unknown — no answer; never infer decline or expiry from silence.

A user-reported execution must not create a fabricated TradeEvent, holding, quantity, price or actual portfolio consequence. Later transaction evidence may upgrade the relation.

5. Transaction evidence proves action, but intent linkage may still be ambiguous

A transaction record is sufficient evidence that the recorded buy/sell occurred.

It does not always prove which prior intent or exact reason it realizes when there are multiple same-instrument intents, modified plans, partial executions or different quantities.

First-version rule:

6. Follow-up is relevant-event triggered, not a background scheduler

When no transaction evidence resolves an open intent, ask at most one resolution question at the next relevant product moment, for example:

  • the user returns to the same instrument;
  • a new holdings snapshot or transaction file is ingested;
  • a later review selects the unresolved intent as decision-relevant.

Do not create a timer, notification service, 30-day missed-return queue or broad watchlist sweep in the first version. Silence leaves the intent open.

7. First reader ships with the writer

Do not repeat #429’s write-only-memory defect.

The first implementation must include a visible reader that, on the next relevant interaction:

  • retrieves the bounded open intent;
  • avoids re-asking already captured facts;
  • either upgrades the answer with actual book/transaction evidence or asks the single resolution question;
  • clearly labels intent versus execution evidence.

A writer without this reader is incomplete.

Scope

This issue owns:

  1. the DecisionIntent append contract and stable identity;
  2. automatic no-book intent capture after a completed [research·product] Philosophy bootstrap: decision guidance before transaction history #597 framing;
  3. bounded open-intent query;
  4. one relevant-event-triggered resolution question;
  5. intent resolution states and authority labels;
  6. the handoff into [feat·M2] Explicit execution link promotes an evaluation into durable decision memory #490 when canonical TradeEvent evidence exists;
  7. status/export/reset/replay and corruption/idempotency gates for the new stream;
  8. same-session upgrade when a holdings view or transaction record arrives after the initial framing.

Non-goals

  • No InvestorProfile, style label or personality inference.
  • No automatic capture from every ticker mention, watchlist, news query or idea scan.
  • No 30-day counterfactual P&L or “missed gain” judgment from [Phase 2] Not-Buy Tracker:沒買的決策也要記,30天後驗「不買對嗎」 #35.
  • No shadow portfolio or assumed unexecuted position.
  • No automatic broker matching when multiple intents are compatible.
  • No claim that user-reported execution has canonical quantity, price or book consequence.
  • No background scheduler, push notification or resident app.
  • No permanent rule creation from an exit answer.
  • No rewriting [feat·M1] Bounded TradeEvaluation with visible two-sided challenge #479 TradeEvaluation; avoid duplicate intent records for the same source decision.
  • No use of unresolved intents as canonical M2 “why I acted” history.

Acceptance criteria

  • A completed no-book DecisionFraming appends exactly one DecisionIntent without asking a save-confirmation question.
  • Exact retry is idempotent; a materially different why_now, action or final premise receives a distinct identity.
  • The original user statements remain byte-for-byte readable and are not rewritten by the reader.
  • Intended size is labelled declared input and never emitted as actual weight.
  • The next relevant same-instrument interaction reads the intent and does not repeat already answered questions.
  • One unique compatible canonical TradeEvent automatically resolves and links the intent as executed_trade_record.
  • Multiple compatible intents fail closed to one mapping question; no link is guessed.
  • A user answer “yes, I bought” without a TradeEvent resolves as executed_user_reported and creates no trade/holding/quantity/price fact.
  • “No”, “changed”, “still considering”, and no answer produce the distinct states above; silence never becomes not_executed or expired.
  • A later canonical TradeEvent can upgrade a prior user-reported execution without rewriting the original events.
  • An open intent is never surfaced as “why I acted” by [arch·M2] Canonical bounded execution-qualified self-report history #450 or profile input by [design·P1] The distillation layer: bounded profile memory over the append-only ledger (scoping) #446.
  • Writer and first bounded reader land together; removing the reader makes a production-shaped test fail.
  • Stream registration covers status/export/reset/replay; corruption and duplicate/conflicting resolution fail closed.
  • Public fixtures and receipts use only fictional instruments, statements, dates and amounts.
  • Existing [feat·M1] Bounded TradeEvaluation with visible two-sided challenge #479/[feat·M2] Explicit execution link promotes an evaluation into durable decision memory #490 identity, TradeEvaluation, review and book-truth tests remain green.

Dependencies and relations

Privacy boundary

Local-first durable memory. Real intents, reasons, exit conditions, transaction records and mappings remain in the user’s local data root.

Public repository issues, tests, PRs and QA receipts use fictional/generic data only. No private decision text, instrument, amount, date, source or reconstructable combination is posted to GitHub.

Rollout / compatibility / recovery

  1. Slice A — no-book intent writer + bounded reader: append-only record, idempotency, same-instrument recall and one resolution prompt. No execution promotion yet beyond authority-labelled user response.
  2. Slice B — canonical TradeEvent handoff through [feat·M2] Explicit execution link promotes an evaluation into durable decision memory #490: unique-match automatic link, ambiguity question, replay-stable resolution.
  3. Later only if proven useful: a shared bounded “what I considered” query spanning no-book intents and existing TradeEvaluations without copying either source.

Legacy roots without the stream remain valid. Rebuilding the status projection from events must be deterministic. A failed append or resolution leaves the prior projection intact; partial files and conflicting resolutions fail closed. Rollback of Slice A removes the new reader/writer without mutating existing ledger, TradeEvaluation or execution-link records.

Stop condition

Stop after the smallest writer+reader slice and one owner-live trajectory prove that the next interaction is materially better: no repeated explanation, intent/execution truth stays separate, and the user can resolve or upgrade the intent in one bounded turn. Do not continue into profile distillation, rule learning, counterfactual P&L or background reminders.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions