Foundry — Architecture Use Case Walk¶
A use-case walk of the Foundry architecture. Each walk traces a realistic scenario end to end, tags where every step happens, and records what holds, what's missing, and what still needs a decision.
The purpose is to pressure-test the architecture against reality — confirm the shape holds where it should, and surface gaps where it doesn't.
Template¶
Keep each walk to one page. Four sections.
1. Scenario One sentence. Concrete, realistic, no architecture jargon.
2. Flow Numbered steps. Tag every step with where it happens:
[F]— Foundry (a pure-platform component)[E]— Ecosystem component (name it)[C]— Consumer (applies its own domain logic)
Don't list contracts, substrates, or lineage unless one needs a decision — those belong in Findings.
3. Findings Three buckets:
- Works — what holds cleanly
- Missing — gaps or undefined behaviour
- Decide — questions that need answering
4. Decisions captured What the room agreed during the walk. Empty until walked.
Notes on running a walk¶
- Findings drive the walk, not template completeness. If a UC has nothing in Missing or Decide, it's a confirmation walk — that's a valid outcome.
- The location tags are the discipline. Forcing every step to be tagged
[F]/[E]/[C]is what surfaces boundary disagreements. If two people tag the same step differently, that's the conversation to have. - Collapse shared paths. If two use cases follow the exact same Foundry path, walk them once and note both consumer variants. Split them only where the path diverges.
- Flag the unclear. Where a step isn't settled, draw both options and put the fork in Decide rather than picking silently.
Walk 1 — Live structured event → canonical → push consumer¶
Covers UC1 (content) and UC2 (fantasy). Identical Foundry path; the consumer differs.
Scenario A live NFL play is published as canonical and reaches push consumers within seconds.
Flow
1. Stats Perform / Opta feed sends event [E]
2. Game Feed Ingester accepts (one per feed provider) [F]
3. Ingest Game Feed → Canonicalizer (resolves against Internal Entity Store) [F]
4. Stored in Canonical Game State Store; emitted to Canonical Game Feed [F]
5. Consumer Contract Projector → External Canonical Consumer Feed [F]
6. Fantasy Feed Consumer (or content consumer) consumes [C]
7. Consumer applies own logic — scoring (Fantasy) / presentation (content) [C]
Findings - Works: matches the Sport Management Module pattern end to end. - Missing: the store→feed mechanism (Canonical Game State Store → Canonical Game Feed) is not drawn — CDC / outbox / projection? - Decide: substrate per consumer (push feed vs query vs the consumer's own replica)?
Decisions captured - (filled during walk)
Walk 2 — Live event → orchestrator → model → outcome¶
Covers UC3.
Scenario A live play changes win probability; the model re-runs; the updated outcome is available on demand.
Flow
1. Event ingested → canonicalised → Canonical Game State Store [F]
2. Model Orchestrator consumes game state + reads Internal Entity Store [F]
3. Luckbox Model runs; Accumulators → Outcome Context Generator [F]
4. Written to Outcome Context Store (Model Config Store holds version/config) [F]
5. ExternalOutcome Query Service exposes outcomes — pull only [F]
6. Consumer queries when it needs an outcome (e.g. Fantasy Query Service →
ExternalOutcome Query Service) [C]
Findings - Works: the orchestrator is a bounded Foundry subsystem with its own config store; it writes outcomes directly. - Resolved: no push feed for outcomes. Outcomes are pull-only by design. - Decide: ExternalOutcome Query Service latency target; model versioning surfacing (Model Config Store).
Decisions captured - Outcomes are query-only. No Consumer Contract Projector / push feed for outcomes. - Rationale: separate the live-data path from the query-load path. Game state is pushed (discrete events, every consumer wants the same thing); outcomes are pulled (combinatorial, large, consumer asks a specific question). The natural pattern is game-state push is the trigger; outcome query is the response — the live feed wakes the consumer, the query answers the specific question, and query load can never degrade live delivery.
Walk 3 — Foreign / acquired model output via ingestion¶
Covers UC3b. A foreign model is an external producer.
Scenario An acquired model produces outputs in its own shape; Foundry consumes them as a source.
Flow
1. Foreign model produces output [E]
2. Ingester accepts (treated as a feed) [F]
3. Canonicalizer resolves entity references against Internal Entity Store [F]
4. Stored in Outcome Context Store [F]
5. Exposed via ExternalOutcome Query Service [F]
6. Consumer queries [C]
Findings - Works: confirms the structured/unstructured rule — a foreign model enters through ingestion like any feed, not as a Foundry-internal component. - Missing: not drawn on the diagram. One generic foreign-output ingester vs a per-model adapter is undecided. - Decide: are foreign outputs distinguishable from Luckbox Model outputs in the Outcome Context Store, or treated identically?
Decisions captured - (filled during walk)
Walk 4 — Trading inputs / signals¶
Covers UC4 (signal-driven model) and UC5 (trading input).
Open architectural fork. The diagram and the earlier decision disagree. This is the last genuine architectural question.
Scenario A trading input / market signal enters and is made available to the system (e.g. to drive a model adjustment).
Flow — Option A (as drawn on the diagram)
1. Trading Inputs UI Module [F-internal]
2. → Core Module → Command API [F]
3. Internal structured write — no canonicalizer, no signal feed [F]
Flow — Option B (per the earlier walk)
1. Signal source produces signal [E]
2. Signal Ingester → Signal Canonicalizer (vs Internal Entity Store) [F]
3. Canonical Signal Store → Signal Feed [F]
4. Model Orchestrator / consumers subscribe [F/C]
Findings - Works: either option is internally consistent. - Missing: the diagram routes trading inputs through the Command API as commands; the agreed pattern was a signal canonicalizer producing a subscribable canonical signal feed. No signal canonicalizer is drawn. - Decide: are signals canonicalised data (subscribable feed) or API commands (internal writes)? Pick one.
Decisions captured - (filled during walk)
Walk 5 — Prediction market RFQ (Kalshi)¶
Covers UC6.
Scenario Kalshi sends an RFQ; a canonically-backed bid response is returned.
Flow
1. Kalshi RFQ Source sends request [E]
2. RFQ Feed Ingester receives [E — Kalshi PM Domain]
3. RFQ Feed Mapper → RFQ Responder; PM Query Service queries Foundry [E]
4. ExternalOutcome Query Service returns canonical outcomes [F]
5. RFQ Responder assembles response (RFQ Response Catalog, Canonical RFQ
Catalog) [E]
6. Kalshi RFQ Response returned [E]
Findings - Works: confirms the query-layer split — Foundry exposes the ExternalOutcome Query Service; the Kalshi/RFQ translation domain is a consumer-side component, correctly outside Foundry. - Missing: PM Query Service and one internal path are marked "Complete Unknown" on the diagram — flagged honestly. - Decide: ExternalOutcome Query Service latency commitment; auth pattern for the PM domain calling Foundry.
Decisions captured - (filled during walk)
Walk 6 — Result context → multiple consumers¶
Covers UC7. Settlement is downstream / consumer-side.
Scenario A play resolves to a final result; the canonical result/game state is published; multiple consumers consume for their own purposes (betting settles, content finalises, fantasy finalises, archive stores).
Flow
1. Result event ingested → canonicalised → Canonical Game State Store [F]
2. Consumer Contract Projector → External Canonical Consumer Feed [F]
3. Betting consumes → applies settlement logic [C]
4. Content consumes → finalises [C]
5. Fantasy consumes → finalises scores [C]
Findings - Works: fan-out is just multiple consumers on the projected feed; settlement correctly sits in Betting, not Foundry. - Missing: "result context" vs "game state" — is a final result a distinct category or a state within game state? Not distinguished on the diagram. - Decide: durability tier for result-bearing events (commercially material)?
Decisions captured - Settlement is a downstream concern of the external betting consumers. Foundry produces game state and result context that enable consumers to derive their own results for outcomes.
Walk 7 — Unstructured content → canonical structured content¶
Covers UC8. Content Processing Module.
Scenario A news article / social post is ingested, structured, classified, stored, and published.
Flow
1. YouTube / Twitter / Reddit / NewsSources produce unstructured content [E]
2. Ingester accepts [F]
3. Content Canonicalisation extracts structured fields, resolves entities [F]
4. Canonical Content Store; Classifier adds categorisation [F]
5. Consumer Contract Projector → External Canonical Content Feed [F]
6. Content consumer presents [C]
Findings - Works: confirms Foundry imparts structure to unstructured input via the same module pattern. - Missing: the Classifier output path is not drawn (writes back to store? tags the feed?). Structured-content schema and classification vocabulary undefined. - Decide: Classifier ownership; are classification rules config (editable) or code?
Decisions captured - (filled during walk)
Not walked¶
- UC9 — Two truths. Deferred. The architecture commits to a single canonical truth (Foundry's truth). No path to walk. Revisit if a use case lands that materially requires plural truths; source identity is preserved in lineage so migration stays possible.
- UC10 — Foundry per VIP / B2B client. Resolved without a walk. Handled via a dedicated read replica / specialised B2B output (per the consumer-domain caption on the diagram). A substrate-provisioning decision, not a flow.
Summary¶
| Walk | Covers | Diagram status | Flag |
|---|---|---|---|
| 1 | UC1, UC2 | Drawn, holds | store→feed mechanism implicit |
| 2 | UC3 | Drawn | outcomes pull-only (resolved) |
| 3 | UC3b | Not drawn | foreign-output ingester undecided |
| 4 | UC4, UC5 | Partial / conflicting | signals: canonical feed vs API command |
| 5 | UC6 | Drawn (Kalshi) | PM Query Service "Complete Unknown" |
| 6 | UC7 | Drawn | result context as category vs state |
| 7 | UC8 | Drawn | classifier path / vocabulary undefined |
Open architectural decisions¶
| Decision | Status |
|---|---|
| Outcomes push vs pull | Resolved — pull only |
| Signals — canonical feed vs API command (Walk 4) | Open |
Walk 4 is the last genuine architectural fork. Everything else is drawn-and-holds or operational detail to be designed when the capability is built.