Task: ores.shell: feed verbs for every asset class

Table of Contents

This page documents a task in the Feed lifecycle harmonization: asset-class-agnostic feed control-plane story. It captures the goal, current status, acceptance, and any notes or results.

Goal

ores.shell has feed verbs for every asset class: folder start/stop (one request, server-side cascade) and per-config start/stop/list keyed by config_id — including the IR curve commands that are missing today. No shell command enumerates asset classes; new asset classes are covered automatically via the factory.

Status

Field Value
State DONE
Parent story Feed lifecycle harmonization: asset-class-agnostic feed control-plane
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-08-11

Acceptance

  • synthetic start folder <token> and synthetic stop folder <token> cascade every feed kind under the folder.
  • synthetic start feed <config_id> / stop feed <config_id> / list feeds work for every asset class (IR curve start/stop/list were previously unreachable from the shell).
  • Feed lookup by name/token resolves to a config_id without the shell knowing the kind.
  • Command help and completion are kind-agnostic.

Plan

(Implementation strategy. Written when work starts; key decisions are distilled into the parent story's * Decisions at close, but the plan itself stays — it is the historical record of what we did.)

The folder cascade (task 9E2344CF) already covers both asset classes server-side; the shell's folder verbs need no change. The per-config verbs need a kind-agnostic token resolution and a list verb.

  • resolve_feed (synthetic_commands.cpp) becomes kind-agnostic: it probes the FX config family first, then the IR curve family — mirroring the server's own kind resolution in feed_config_handler, which probes the per-kind repositories by config_id with FX first. It returns a resolved_feed{config_id, source_name, optional ore_key}; the shell never knows the kind. UUID tokens match config ids across both families ("Feed not found" after both probes); name tokens match FX ore_key/source_name then IR source_name, with report_ambiguous per family and "No feed matching" after both.
  • start feed and stop feed send the resolved config_id in start_feed_request/stop_feed_request as before — the requests were already kind-agnostic. Only the token resolution changed.
  • New synthetic list feeds verb: process_list_feeds=/=list_feeds send list_feeds_request{} and print each running feed's source_name plus the running count. The response carries no message field, so failure prints a generic message.
  • validate-vintage stays FX-shaped: get_vintage_validity entries are keyed by fx config id, so only FX feeds can match one; IR curves report no entry. The ore key renders only when present.
  • Help and completion were already kind-agnostic: the start/stop usage string is "folder <folder-token> | feed <feed-token>" and cli::Menu completion completes command names only. The list feeds help text says "of every asset class".

Notes

Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario, run through the QA Validation Runner panel) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
     

PRs

PR Title
#1973 [shell] Feed verbs for every asset class

Review

# Comment summary File Decision Notes
1 resolve_feed skips the success check on the FX/IR list responses; a backend failure reads as "No feed matching" synthetic_commands.cpp Applied success guard added after each probe, mirroring list_folders/list_configs. Raised by both review passes.
2 The exact-match and ambiguity blocks are duplicated across the FX and IR probes synthetic_commands.cpp Applied factored into exact_feed_match and feed_by_id; try_uuid hoisted above both probes. Raised by both review passes.
3 try_uuid(token) parsed twice, once per probe synthetic_commands.cpp Applied hoisted in the same refactor as row 2.
4 Cross-family ambiguity unchecked for exact-name tokens; the FX match wins silently synthetic_commands.cpp Declined FX-first mirrors the server's kind resolution (documented in resolve_feed); the server resolves the same config_id to the FX feed, so the win is consistent. A guard would add an IR round-trip to every FX match for a collision the naming conventions make unreachable.

Result

The shell's feed verbs now cover every asset class. Folder start/stop already cascaded both kinds server-side (task 9E2344CF) and needed no change. Per-config verbs gained a kind-agnostic token resolution: resolve_feed probes the FX config family first, then the IR curve family — the server's own kind resolution in feed_config_handler probes the repositories in the same order — and returns a resolved_feed{config_id, source_name, optional ore_key}; the shell never knows the kind. start feed and stop feed send the resolved config_id; validate-vintage keeps its FX shape (entries are keyed by fx config id, IR curves report no entry, the ore key renders only when present). The new synthetic list feeds verb sends list_feeds_request{} and prints every running feed's source_name plus the running count — the IR curve start/stop/list verbs that were previously unreachable from the shell. Help text and completion were already kind-agnostic and remain so; the list feeds entry says "of every asset class".

Verification: full build green; no SQL change, so no DB recreate; compass build rat green (all suites pass, including the synthetic service feed_config_* cases).

Emacs 29.3 (Org mode 9.6.15)