Currently HydrationConfig has three hardcoded named slots: hcTemporalSource :: Maybe (ContextSource TemporalResult) hcSemanticSource :: Maybe (ContextSource SemanticResult) hcKnowledgeSource :: Maybe (ContextSource KnowledgeResult)
This prevents plugging in arbitrary hydration sources (e.g. per-repo coding memory, git log, docs-RAG).
Replace the three named slots with a stacked list: hcSources :: [HydrationSource]
Where HydrationSource is self-rendering: data HydrationSource = HydrationSource { hsName :: Text , hsPriority :: Priority -- or Int ordering , hsBudget :: Maybe Int -- token budget , hsRun :: SourceParams -> IO [Section] }
The hydrator (Omni/Agent/Prompt/Hydrate.hs) runs each source in order, enforces per-source token budgets, and merges the resulting Section list.
1. HydrationSource — the universal stacking interface (name, priority, budget, IO [Section]) 2. Typed source builders (temporalSource, semanticSource, knowledgeSource) remain as helper functions that produce a HydrationSource — preserving typed ergonomics without hardcoded slots
The existing passiveTemporalSource, passiveSemanticSource, passiveSemanticKnowledgeSource in Context.hs become builders that produce HydrationSource values.
This is the second step in proving out a pluggable/stacked hydration architecture (follows t-821 which adds graph traversal). The goal is to make 'any (temporal x semantic) data source' pluggable as a hydration source — essentially generalized RAG with budget enforcement on top. See also: Ben's adaptive context framing (passive/active x temporal/semantic quadrants) which maps to source tags, not structure.
Depends on t-821 (graph traversal in passive hydration) — implement t-821 first.