## ADDED Requirements ### Requirement: Provider-agnostic analysis-agent interface The system SHALL define an `AnalysisAgent` interface that accepts a structured evaluation object and returns a written analysis. Consumers MUST depend only on this interface so the underlying model provider can change without affecting the evaluation engine or UI. #### Scenario: Agent invoked through the interface - **WHEN** an evaluation object is passed to the configured analysis agent - **THEN** the agent returns a written analysis produced through the interface #### Scenario: Alternate implementation can be registered - **WHEN** a different agent implementation is configured - **THEN** the system uses it without changes to evaluation or UI code ### Requirement: Default agent via Claude Code CLI; API as swappable alternate The system SHALL ship a default `AnalysisAgent` that invokes the local **Claude Code CLI** in headless mode (`claude -p --output-format json`), which runs on the operator's existing Claude authentication (e.g. subscription) rather than a metered API key. The system SHALL also ship an alternate implementation backed by the Anthropic API (`@anthropic-ai/sdk`), selectable via configuration without changes in consumers. Either way, the default model SHALL be **Claude Opus 4.8** (CLI alias `opus`) and a per-request "deep dive" option SHALL escalate to **Claude Fable 5** (CLI alias `fable`); the model SHALL be selectable per evaluation. Structured narrative output SHALL be requested via the CLI `--json-schema` option (or the equivalent structured-output mechanism on the API alternate). Any API key used by the alternate SHALL be loaded from configuration and never hard-coded or committed. #### Scenario: Claude Code CLI produces the written thesis - **WHEN** the CLI agent is configured and an evaluation is submitted - **THEN** the system runs `claude -p` with model alias `opus` and returns the written thesis parsed from the CLI JSON output #### Scenario: Deep-dive escalates to Fable 5 - **WHEN** an evaluation is requested with the deep-dive option enabled - **THEN** the agent runs the CLI with model alias `fable` for that request - **AND** requests without the option continue to use `opus` #### Scenario: API alternate selected via configuration - **WHEN** the agent transport is configured to the API alternate with a valid key - **THEN** evaluations are served through `@anthropic-ai/sdk` instead of the CLI - **AND** no changes to evaluation or UI code are required #### Scenario: Secrets sourced from configuration - **WHEN** the API alternate reads its configuration - **THEN** the Anthropic API key is loaded from environment/config, not source code ### Requirement: Live web grounding The agent SHALL be able to retrieve current information via its web search and web fetch capability — the Claude Code CLI's `WebSearch`/`WebFetch` tools for the default transport, or Anthropic's server-side web tools for the API alternate — to source macro and news-driven facts the structured data layer does not provide: tariff/rate developments, analyst rating and price-target changes, management commentary, peer read-throughs, and dated catalysts. Facts drawn from the web SHALL carry their source so the output can attribute them, and grounding SHALL be scoped to the ticker under evaluation. #### Scenario: Web-sourced facts are attributed - **WHEN** the agent uses a web-sourced fact in the analysis (e.g. an analyst target change or a catalyst date) - **THEN** the output attributes that fact to its source #### Scenario: Grounding degrades gracefully - **WHEN** web search or fetch is unavailable or returns an error - **THEN** the agent still produces the analysis from the structured evaluation - **AND** notes that live macro/news grounding was unavailable ### Requirement: Grounded, structured written analysis The agent SHALL base its narrative on the supplied evaluation data plus attributed web-sourced facts, and SHALL NOT invent figures. It SHALL produce the narrative sections reflected in the example evaluation: current standing, earnings recap and quality-of-earnings caveats, valuation with explicit over/undervalued reasoning, macro factors, timing, entry/exit/stop-loss rationale, bull-versus-bear, and an actionable plan. When a data caveat or discrepancy is present in the input, the agent SHALL preserve it. #### Scenario: Narrative grounded in provided data - **WHEN** the agent writes the analysis - **THEN** every figure it cites is either present in the supplied evaluation object or attributed to a web source it retrieved #### Scenario: Data caveats preserved - **WHEN** the evaluation object flags a discrepancy or one-time item - **THEN** the written analysis surfaces that caveat rather than omitting it #### Scenario: Disclaimer preserved in narrative - **WHEN** the agent returns its analysis - **THEN** the analysis-not-advice disclaimer is present ### Requirement: Graceful degradation without an available agent The system SHALL, when no analysis agent is available (the Claude Code CLI is not installed or not authenticated, or the configured API alternate has no key), still return the full structured evaluation and clearly indicate that the written narrative is unavailable and how to enable it. #### Scenario: Agent unavailable - **WHEN** an evaluation is requested and no agent transport is available - **THEN** the structured evaluation is returned - **AND** the response indicates the written analysis is unavailable and how to enable it (authenticate the CLI, or configure an API key) ### Requirement: Agent error handling The system SHALL handle agent failures (auth errors, rate limits, timeouts) by returning a typed error and the underlying structured evaluation, without losing the data already computed. #### Scenario: Agent call fails - **WHEN** the agent call errors after retries - **THEN** the system returns the structured evaluation plus a typed agent error - **AND** the computed data is not discarded