204 lines
7.7 KiB
Markdown
204 lines
7.7 KiB
Markdown
# Epic 7 — Context Engine (Deterministic Context Synthesis Layer)
|
||
|
||
## completed deliverables
|
||
|
||
### 1. context identity
|
||
|
||
introduced `ContextPackId` and `ContextEntryId` as type aliases to `TypeId` in `core:events`.
|
||
|
||
* lives alongside other shared vocabulary types (`SessionId`, `ArtifactId`, etc.)
|
||
* available to all modules depending on `:core:events`
|
||
|
||
---
|
||
|
||
### 2. context lifecycle events
|
||
|
||
introduced five context lifecycle events in `core:events`, covering the full pack building pipeline.
|
||
|
||
events:
|
||
|
||
* `ContextBuildingStartedEvent(sessionId, stageId)`
|
||
* `ContextPackBuiltEvent(contextPackId, sessionId, stageId, budgetUsed, budgetLimit)`
|
||
* `CompressionAppliedEvent(contextPackId, layer, entriesRemoved, strategyApplied)`
|
||
* `LayerTruncatedEvent(contextPackId, layer, entriesDropped, reason)`
|
||
* `ContextBuildingFailedEvent(sessionId, stageId, reason)`
|
||
|
||
properties:
|
||
|
||
* all registered in `eventModule` polymorphic block
|
||
* emitted during pack assembly — enables deterministic replay of compression decisions
|
||
* `layer` and `strategyApplied` carried as `String` — avoids circular dependency with `core:context`
|
||
|
||
---
|
||
|
||
### 3. context layer model
|
||
|
||
introduced `ContextLayer` as a serializable enum with five distinct layers.
|
||
|
||
```text
|
||
L0 live execution [active request, current tool output, pending approval]
|
||
L1 stage-local context [artifacts and receipts from the current stage]
|
||
L2 compressed session [summaries of completed stages; kept under a token cap]
|
||
L3 project memory [persistent facts, architecture decisions, key outputs]
|
||
L4 archival history [full event log; not used for inference]
|
||
```
|
||
|
||
models receive a `ContextPack` built from L0–L2; L3 optionally injected if relevant. L4 is archival only.
|
||
|
||
---
|
||
|
||
### 4. context pack contract types
|
||
|
||
introduced the core domain types for context synthesis.
|
||
|
||
final structures:
|
||
|
||
* `ContextEntry(id, layer, content, sourceType, sourceId, tokenEstimate)` — typed reference to an event, artifact excerpt, summary, or policy snippet
|
||
* `CompressionMetadata(appliedStrategies, truncatedLayers, entriesDropped)` — audit trail of compression decisions
|
||
* `ContextPack(id, sessionId, stageId, layers, budgetUsed, budgetLimit, compressionMetadata)` — the final assembled context artifact
|
||
* `TokenBudget(limit, used)` — transient computation value with `remaining`, `consume()`, and `canFit()` helpers; intentionally not serializable
|
||
|
||
---
|
||
|
||
### 5. compression pipeline
|
||
|
||
introduced a content-type-specific, rule-based, deterministic compression pipeline. zero model calls.
|
||
|
||
final structure:
|
||
|
||
* `CompressionStrategy` (sealed interface, five content-type-specific implementations):
|
||
* `ToolLog` — deduplicate identical content, drop oldest when over budget
|
||
* `Conversation` — keep last N verbatim, drop oldest first under budget pressure
|
||
* `Artifact` — keep most recent entry per `sourceId`
|
||
* `SteeringNote` — always retained verbatim, never dropped
|
||
* `EventHistory` — always retained; already-compressed DecisionPoints from prior stages
|
||
* `ContextCompressor` (interface)
|
||
* `DefaultContextCompressor` — applies strategies deterministically; drop order: L2 first, then L1; L0 is never dropped
|
||
|
||
key invariant:
|
||
|
||
> same input always produces the same output — compression is replay-safe
|
||
|
||
---
|
||
|
||
### 6. context state and projection
|
||
|
||
introduced the standard event-sourced pattern for context state.
|
||
|
||
final structures:
|
||
|
||
* `ContextState(builtPackIds, buildingInProgress)` — fully rebuildable from events; no external data
|
||
* `ContextReducer` (interface)
|
||
* `DefaultContextReducer` — handles `ContextBuildingStartedEvent`, `ContextPackBuiltEvent`, `ContextBuildingFailedEvent`; passes all others through unchanged
|
||
* `ContextProjector` — implements `Projection<ContextState>`; delegates to reducer
|
||
|
||
---
|
||
|
||
### 7. context pack builder
|
||
|
||
introduced a pure, side-effect-free context pack assembly pipeline.
|
||
|
||
final structures:
|
||
|
||
* `ContextPackBuilder` (interface)
|
||
* `DefaultContextPackBuilder` — compresses entries, groups by layer, tracks budget usage and truncation metadata
|
||
|
||
key invariant enforced:
|
||
|
||
> entries with `sourceType` of `"steeringNote"` or `"eventHistory"` are partitioned before compression and always retained, regardless of budget pressure
|
||
|
||
* `DecisionPointBuilder` (interface)
|
||
* `DefaultDecisionPointBuilder` — extracts only L0 and L1 entries from a pack for model inference calls
|
||
|
||
---
|
||
|
||
### 8. context repository
|
||
|
||
introduced `DefaultContextRepository` over `EventReplayer<ContextState>`, following the established repository pattern.
|
||
|
||
* single method: `getContextState(sessionId): ContextState`
|
||
* delegates to `replayer.rebuild(sessionId)`
|
||
* no business logic — thin wiring layer
|
||
|
||
---
|
||
|
||
### 9. context serialization module
|
||
|
||
introduced `contextModule: SerializersModule` in `core:context`.
|
||
|
||
* polymorphic block scaffolded for future extension
|
||
* follows the same pattern as `eventModule` and `artifactModule`
|
||
|
||
---
|
||
|
||
### 10. test coverage
|
||
|
||
implemented deterministic and projection tests covering all core behaviors.
|
||
|
||
deterministic tests (27):
|
||
|
||
* compression strategies: determinism, layer drop order, never-drop invariants (SteeringNote, EventHistory), artifact deduplication, tool log deduplication
|
||
* token budget: arithmetic correctness, immutability, exhaustion, canFit semantics
|
||
* pack builder: layer grouping, budget tracking, budget enforcement, decision point filtering, steering note retention under budget pressure, empty entries
|
||
|
||
projection tests (22):
|
||
|
||
* reducer: all three context event transitions, pass-through for unrelated events
|
||
* projector: initial state, deterministic replay
|
||
|
||
---
|
||
|
||
# final architecture after Epic 7
|
||
|
||
```text
|
||
ContextBuildingStartedEvent → ContextPackBuiltEvent (via core:events)
|
||
↓
|
||
ContextState (rebuilt from events via DefaultContextReducer + ContextProjector)
|
||
↓
|
||
DefaultContextPackBuilder (pure function)
|
||
├── pins: SteeringNote + EventHistory entries (never dropped)
|
||
├── compresses: remaining entries via DefaultContextCompressor
|
||
│ └── strategy dispatch: ToolLog / Conversation / Artifact / SteeringNote / EventHistory
|
||
│ └── drop order: L2 → L1 (L0 never dropped)
|
||
└── assembles: ContextPack with layer map + budget metadata
|
||
↓
|
||
DefaultDecisionPointBuilder → L0 + L1 entries (sent to model for inference)
|
||
```
|
||
|
||
---
|
||
|
||
# major architectural outcomes
|
||
|
||
Epic 7 established:
|
||
|
||
* deterministic, rule-based context synthesis — zero model calls for compression
|
||
* five-layer context model separating live execution from compressed history
|
||
* content-type-specific compression strategies with never-drop invariants for critical entries
|
||
* token budget enforcement with correct layer eviction priority
|
||
* event-sourced context state fully rebuildable from the event log
|
||
* pack builder as a pure function — no IO, no side effects, replay-safe
|
||
|
||
---
|
||
|
||
# what Epic 7 intentionally does NOT include
|
||
|
||
not implemented:
|
||
|
||
* policy injection into context packs (step 5 of the pipeline — deferred)
|
||
* event retrieval and projection wiring for pack building (caller provides entries)
|
||
* L3/L4 storage and retrieval (infrastructure concern)
|
||
* router context isolation (separate L2 memory for the router — deferred)
|
||
* semantic summarization — no model-assisted compression of any kind
|
||
* cross-session context leaking prevention (enforced structurally by session scoping)
|
||
* observability hooks beyond event emission
|
||
|
||
those are explicitly deferred to later epics.
|
||
|
||
---
|
||
|
||
# final state
|
||
|
||
Correx now has:
|
||
|
||
> a deterministic, rule-based context synthesis engine that assembles token-budgeted, layered context packs from events and artifacts — with content-type-specific compression strategies, strict never-drop invariants for steering notes and decision history, and full event-sourced state tracking — ensuring models always receive minimal, relevant, reproducible context without any model calls in the compression path.
|