---
name: fomo-kernel
description: Review a user's trade CSV or position snapshot into one local review card and an append-only investment-thesis record, with at most one user-chosen next-time rule. Transaction history supports behavioral diagnosis; a position snapshot supports an opening structural check. Use for trade reviews, transaction postmortems, brokerage-statement reviews, position reviews, and equivalent requests in any supported language. Do not use for stock picks, market forecasts, or security research.
---

# fomo-kernel

Turn transaction history into one focused behavior-review card, or a position snapshot into one narrow opening portfolio check. Both routes preserve thesis continuity and at most one user-chosen rule.

## Non-negotiable rules

1. Use only numbers present in engine artifacts. Never calculate, fill in, or alter numeric facts.
2. Do not provide buy or sell recommendations. Review behavior, motives, thesis evolution, and process rules.
3. Obtain an answer for every `required:true` item in `question_queue` before preview.
4. A card has exactly one final commitment at most. The user may choose a candidate, provide a custom rule, or skip.
5. Keep trade data and engine state — the source CSV, session bundles, and the ledger — local and out of cloud memory. The review card itself is private to the user, not public: show `card-private.*` by default, following the delivery contract in `references/card-delivery.md`; local files, terminal output, and private-by-default in-client rendering (for example, a claude.ai Artifact) are all permitted. Never publish, post, or send it to a third party. `card-public.md` remains the one share-safe artifact the user may choose to share.
6. Treat `sessions/<session_id>/bundle.json` as the canonical completed result. Never hand-edit projections as if they were authoritative.
7. Invoke the engine only through the `engine/review.py` CLI (`prepare`, `resume`, `preview`, `finalize`, `capture`, `render`, `repair-projections`, `set-cap`, or `doctor`). Never call another `engine/*` script or import engine modules directly; those paths bypass lifecycle validation, required-question gates, and canonical session state.
8. For a position table or screenshot, transcribe only the broker-declared facts into the normalized snapshot JSON envelope and keep that temporary file outside the repository, such as under `/tmp`. Do not calculate weights, P&L, cycle IDs, metrics, or ETF classifications, and do not use a cloud OCR service.
9. An incomplete snapshot may produce a bounded review, but it must not become an accounting anchor. Later transaction files may unlock history-dependent diagnostics; ledger-derived current holdings remain canonical, and any claim about an unreconciled current broker view must fail closed.
10. When `review_plan.state_snapshot.cadence.tier == "light"`, the review is a capture-only action, not a full review: follow `flows/light-capture.md` instead of the route's normal flow. No card, no commitment, no `preview`/`finalize` — see the fixed lifecycle's light-tier note below.
11. Never invent, interpolate, or recall a market price. When a host blocks the engine's own price retrieval, `review_plan.input.price_feed.request` states what is unpriced; you may transcribe those closes from a recognized market-data source into the envelope in `references/price-feed.md` and rerun `prepare --prices`. A price you cannot find stays missing, and a missing price is never a delisting verdict or a zero return.

## Canonical entry point

Preflight once after install: the engine fail-soft degrades (silently dropping current prices, P&L, alpha/beta, and market context) when its optional runtime dependencies are missing, so install and verify them before first use.

```bash
cd skills/fomo-kernel
pip install -r requirements.txt   # runtime deps: yfinance + pandas + rich
python3 engine/review.py doctor   # verify; lists what each unlocks, exits non-zero if a full-experience dep is missing

python3 engine/review.py prepare <CSV...> --language en
python3 engine/review.py prepare --route snapshot_review \
  --snapshot-json /tmp/fomo-kernel-positions.json --language en
```

For transaction history, the agent must understand and normalize broker data locally into:
`Symbol / Action(BUY|SELL) / Quantity / Price / TradeDate / RecordType(Trade)`.
Add `Market / Currency` for non-US instruments when available. Do not ask the user to normalize the file. Symbol and cash-anchor rules (Taiwan `.TW`/`.TWO` suffixes, ROC dates, `--cash`) live in `references/data-contract.md`.

For a position table or screenshot, transcribe the displayed facts locally into the JSON envelope in `references/data-contract.md`, save that temporary file outside the repository, then pass it through `--snapshot-json`. The agent may map broker labels, normalize dates, and add the complete provider ticker suffix; it may not derive weights, returns, cycle IDs, or card/state artifacts. There is no engine OCR or cloud-upload path.

The engine prices the portfolio itself, so a normal review passes no prices. If the host blocks that retrieval, `prepare` still completes in a degraded mode and reports the gap in `review_plan.input.price_feed`; recovering it through `--prices` follows `references/price-feed.md`.

`prepare` creates a Review Plan; it does not create a conclusion card. Read only the flow selected by `review_plan.flow_path`:

- `flows/first-review.md`
- `flows/first-review-structural.md` (a first review the engine tiered `structural`/`empty`: an opening structural check, no question string, no forced commitment)
- `flows/weekly-review.md`
- `flows/snapshot-review.md`
- `flows/test-drive.md`

Then read the shared rules:

- `references/agent-boundaries.md`
- `references/interaction-delivery.md`
- `references/thesis-policy.md`
- `references/card-policy.md`
- `references/data-contract.md`

## Fixed lifecycle

1. `prepare`: run the engine, reconstruct active theses, deduplicate questions, and return a Review Plan.
2. Agent work: resolve the one host adapter in the local presentation trace. Unknown or unproven hosts use the first-class `plain_text` fallback; declare optional native controls or a rich widget only after the current host proves them. Then make only permitted qualitative judgments, ask every required question once using the selected adapter or fixed fallback in `references/interaction-delivery.md`, create inferred theses for uncovered positions, and write a narrative with no digits.
3. `preview`: validate answers, evidence, theses, and narrative; then render private and public previews.
4. Show the complete review-card preview inline, record the actual delivery mode, then ask the user to choose a candidate rule, provide a custom rule, or skip. Artifact generation alone is not card delivery.
5. `finalize`: validate the final commitment, atomically commit the canonical session bundle, then rebuild compatibility projections.

**Light-tier exception:** when `review_plan.state_snapshot.cadence.tier == "light"` (short span since the last review), steps 2–5 above do not apply. Follow `flows/light-capture.md` instead: ask at most one light question, then call `capture` to append the motive/emotion fact and stop. No preview, no card, no commitment.

```bash
python3 engine/review.py preview \
  --session-id <ID> --answers /tmp/answers.json --narrative /tmp/narrative.json

python3 engine/review.py finalize \
  --session-id <ID> --answers /tmp/answers.json --narrative /tmp/narrative.json
```

Do not rerun the engine after an interruption:

```bash
python3 engine/review.py resume
python3 engine/review.py resume --session-id <ID>
```

If finalization committed the canonical bundle but a projection failed, repair it without re-questioning the user:

```bash
python3 engine/review.py repair-projections
```

## Agent artifact contract

- For `add_thesis`, `headline_motive`, `initial_thesis`, and `exit_consistency` rows with `question_opportunity`, author only the private surface fields in `schemas/question-surface.schema.json`, bind them through `review.py resume --question-surfaces`, and present the returned `question_presentations`. Use the unchanged engine fallback on generation or validation failure. Other question kinds remain engine-rendered.
- Preserve the resolved option order and show its engine-owned semantic anchor and payload requirement copy. Native and text clients write the same canonical value and a content-free interaction receipt. A `none_of_above` response gets at most one clarification; unresolved wording becomes `skip` plus exact private provenance, never a forced classification.
- Validate `answers.json` against `schemas/answers.schema.json`.
- Validate `narrative.json` against `schemas/narrative.schema.json`; it may contain qualitative prose only and no digits.
- Write one sentence in `narrative.honesty` for every key in `card_plan.required_honesty_keys`, following the wording guidance in `card-spec.md`. Preview fails on a missing or untriggered key; the renderer collapses every sentence into the Block-1 footnote (output-contract.md §4).
- Add one `thesis_updates` entry for every missing-thesis `cycle_id`, following the field vocabulary in `review_plan.authoring_contract`: submit the unchanged `cycle_id` plus the qualitative fields, and the engine prefills the mechanical fields it owns. State the inference source; never present an inferred thesis as user-confirmed.
- Do not invent `thesis_id`, `event_id`, `revises`, or `decision_cursor`. The engine assigns stable identity and links each accepted event to the prior event for that cycle.
- A `new_evidence` decision requires `evidence_delta.claim` and `evidence_delta.source` or preview must fail.
- Treat confirmed evidence as "the user confirmed this was part of the decision," not as external fact verification. Do not invent `observed_at`; the engine preserves missing observation time separately from review capture time.
- `prepare` ranks eligible motive, recent-exit, matured 30/60/90 checkpoint, and first-review entry-thesis questions using engine-owned amount or P&L impact and returns a route-scoped count (a first review three to five, a weekly review one to three, a snapshot none), never fabricating filler to reach a minimum. Ask every returned question. `skip` semantics differ by kind: skipping an exit-reason capture is durable (that reason is never asked again), while skipping a `due_revisit` verdict is not saved and the same checkpoint legitimately returns next review.
- Do not guess ETF classes. Use a local `--instrument-map` for uncommon instruments. Unknown instruments receive no allocation exemption.
- A snapshot review is an opening portfolio check, not a transaction-history diagnosis. Discuss only engine-owned cost or value weights, single-position risk, driver concentration, ETF structure, and data integrity. Do not claim averaging-down counts, exit discipline, holding behavior, win rate, payoff ratio, alpha, or historical motives from a snapshot.
- Add an inferred thesis for every uncovered snapshot-origin cycle and label it as inferred. Invite the user to provide transaction history later; only that later history may unlock the historical behavior dimensions. Do not say that transaction import reconciles a newer broker view: ledger-derived current holdings stay canonical until an explicit snapshot reconciliation exists.
- A second complete snapshot routes through the same prepare call into reconciliation: show the engine-owned narrow diff from `engine_state.snapshot_reconciliation` before preview, state that finalize records the result (`reconciled` keeps the anchor; `adjusted` writes an adjustment event and adopts the newer declaration as the anchor), and never infer why values differ.

## Language and sharing

`--language zh-TW|en` controls user-visible questions, rules, and cards. Always pass the language the user is conversing in: a zh-TW conversation must run with `--language zh-TW`. The `en` values in this file's command examples are placeholders, not defaults to copy verbatim. Both locales use the same engine facts and policy; localization is a rendering concern, not a second analysis workflow.

Each completed session produces:

- `card-private.md` and `card-private.html`: the complete local review card, using the localized review-card name from copy assets.
- `card-public.md`: a separately rendered share-safe artifact. Transaction-history reviews may retain fixed behavior-pattern copy and engine-owned beta / benchmark-excess percentage points; snapshot reviews retain only fixed structural-baseline copy. Neither form includes amounts, dates, tickers, exact weights, session IDs, or agent-authored free text. It is not uploaded or published.

## Test drive

If the user has no data but wants to see the experience:

```bash
python3 engine/review.py prepare --test-drive --language en
```

Test drive follows the same lifecycle with `persist:false`. It runs in an isolated root directory: read `review_plan.state_root` from the prepare output and pass it as `--root <state_root>` to every later `preview`, `finalize`, and `resume` call, or they will not find the session. It must not project into the user's coach memory, and every conversation and card must be visibly labeled as demo data.
