feat(decision): analyst options enablement phase 1 — chain tool + IV context + doctrine + premium validation (ALP-948) - #353
Conversation
…ontext, doctrine, premium validation (ALP-948) Make the analyst able to propose a valid long single-leg option in production. Every recorded invocation ran options-enabled, yet all 35 archived proposals were equity — the analyst had no contract-level options data, no doctrine, and no premium validation. Hybrid delivery per the 2026-06-10 design brief: - (A) src/alphamind/state/repository/options_chain_read.py: pure select_chain_slice over ContractQuote tuples (config-owned strike band / DTE window / OI floor / contract cap, drops named in ChainSlice.omitted), OptionsChainReader Protocol, SqlOptionsChainReader over options_contract_snapshots (latest snapshot per contract, sql_option_price_provider session conventions). - (B) retrieve_options_chain MCP tool (options_chain_tool_mcp.py), mounted for analyst + strategist: harness wiring + prefixes, runner tool-name tuples, AVAILABLE TOOLS render. Single required input: underlying. No-chain-data returns an explicit message. Subprocess transport via _OptionsChainReaderShim; the worker rehydrates a real reader against its own DATABASE_PATH session. - (C) TickerOptionsContext (IV rank via read-only q3 compute reuse — no baseline upsert — plus filter-surviving expirations) rendered into the analyst REFERENCE PRICES line as `TICKER: price | IVr NN | exp: MM-DD`; threaded from the orchestrator alongside the reader. - (D) analyst prompt: structural when-options doctrine (no numeric thresholds), NBBO anchoring rule, worked long single-leg example consistent with a chain-tool excerpt; strategist prompt: held-option current-marks note. - (E) validate_analyst_output gains an OptionsChainReader and three InstrumentOption rejections: option_contract_unknown, option_premium_staleness (entry limit vs NBBO midpoint, config tolerance), option_expiration_before_deadline. - (F) options_chain config section (models/YAML/resolver, 15/5/45/100/24/10) + resolved-config snapshot re-pin. Closes ALP-948. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Confirmed findings from the high-effort code-review pass: - Gate the options chain reader + context on the resolved profile's options_enabled flag (tool unmounted + validator quote checks inert when options are disabled, matching the prompt's Hard blocks signal), and skip the per-ticker context build in halt mode where the watchlist bundle never renders it. - latest_quote now selects the latest USABLE snapshot (SQL filter mirroring _quote_from_row) so a newer garbage row cannot mask the older usable quote the chain tool anchored against. - _quote_from_row and the chain_slice spot extraction read row fields by column label instead of position. - Reference-price render keeps the bare price line for a context with no surviving expirations (no dangling "exp:"). - options_context shares one session across the chain read and the IV-history read (halves per-ticker session count). - Dedup: shared decision/_shared.surface_tool_names replaces the per-runner _tool_names copies; _parse_snapshot_ts imported from sql_option_price_provider; ChainFilterParams.from_config replaces the orchestrator's manual field unpack; _build_decision_kwargs uses concrete types for the new params. Refuted (no action, evidence on file): options_context subprocess-drop claim (rendered into user_message in the parent), Z-suffix timestamp drift (mirrors the canonical q3 caller), strike>=100k OCC overflow (graceful rejection; no such strikes in universe), shim private-import fragility (established _SqlIvProviderShim convention), unconditional expiration check (pure data check), raw tool-name constant misuse (no such consumer), q3 IV-constant promotion (blocked by magic-number audit; documented restatement stands). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ALP-948 Analyst options enablement (phase 1, long single-leg): chain tool + IV context in reference prices + doctrine + premium validation
Analyst options enablement — phase 1: long single-legGoalMake the analyst able to propose a valid long single-leg option (call or put, net-debit) in production. The 2026-06-10 investigation established the gap end-to-end. Every recorded production invocation ran with Operator-decided design (2026-06-10 design brief): hybrid delivery — push per-ticker IV context into REFERENCE PRICES, pull contract detail via a new chain tool — and phase-1 scope of long single-leg only. The four touchpoints below deliver value only together: a chain tool without doctrine sits unused; doctrine without data invites fabricated premiums. Depends onNothing open. Merged substrate this builds on: ALP-856 (broker-enforced options capital floor), ALP-866 (options entries constrained to resting orders), distillation q3 ATM-IV baseline + rank compute. Reading
Scope(A) Chain-slice read + selection core. New module (B) MCP tool retrieve_options_chain. New module (C) Per-ticker options context in REFERENCE PRICES. Frozen slotted dataclass (D) Prompt doctrine. (E) Options validation closure. (F) Config. New Out of scopeMulti-leg strategies — InstrumentStrategy stays schema-supported but receives no doctrine, no validation, and no tool affordance in this issue. Mounting the chain tool for the PM. Live broker quotes at decision or dispatch time — the collector snapshot is the premium anchor; systematic non-fills would reopen this in the execution layer, not here. Short or net-credit options doctrine. Acceptance criteria
VerificationRun |
- [blocker] Restore the decision-not-execution import contract: inline _parse_snapshot_ts in options_chain_read instead of importing it from sql_option_price_provider, whose transitive sql_repository import reaches execution-layer aggregates (same kept-local rationale as the greeks_refresh iv_provider copy). lint-imports: 12 kept, 0 broken. - [suggested] The analyst/strategist prompts now state that retrieve_options_chain is mounted only when the active profile enables options and that the per-turn AVAILABLE TOOLS block is the authoritative surface — the static prompt no longer contradicts the tool list on options-disabled profiles (small/micro). Rejected nits with reason: non-OCC contract_ticker surfacing as option_contract_unknown (corner data-quality case; redraft guidance still actionable), no snapshot-staleness floor (phase-1 intentional — age is rendered per contract and the validator anchors to the same snapshot the tool showed), _NoChainReader duplicated across two test modules (reviewer-acknowledged acceptable). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
test_same_regime_in_window_is_not_superseded and test_reports_zero_when_nothing_supersedes watched the real prompts/decision/strategist.md path with repo_root unpinned, so detect_supersessions walked the LIVE repo's git log — any genuine commit to that prompt inside the hard-coded 2026-06-01..06-22 window fires concurrent_edit_on_watched_artifact and breaks both tests. ALP-948's prompt doctrine edits surfaced this: the full suite failed in the worktree and would have failed on main right after merge. Both tests now watch a never-tracked artifact path, so the trigger cannot fire spuriously regardless of real prompt activity; the other zero-marked tests are unaffected (their rows are filtered out before the git trigger evaluates). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
retrieve_options_chainMCP tool backed by a chain-slice read overoptions_contract_snapshots(config-owned strike band / DTE window / OI floor / contract cap; drops named in anomittednote), mounted for analyst and strategist; subprocess transport via a pickle shim rehydrated in the worker.validate_analyst_outputgains three InstrumentOption rejections (option_contract_unknown,option_premium_staleness,option_expiration_before_deadline) anchored to the same chain reader the tool mounts; newoptions_chainconfig section (15/5/45/100/24/10) with resolved-config snapshot re-pin. Reader + context are gated onoptions_enabledand pipeline mode.Closes https://linear.app/alphamind-jatassi/issue/ALP-948/analyst-options-enablement-phase-1-long-single-leg-chain-tool-iv
Test plan
.github/workflows/ci.yml) green on the PR — lint on Linux + full pytest on Windowsruff check,ruff format --check,mypy,lint-imports)🤖 Generated with Claude Code