epic-12: after epic audit and init commit

This commit is contained in:
2026-05-16 11:42:00 +04:00
commit c77277af0b
461 changed files with 28958 additions and 0 deletions
+203
View File
@@ -0,0 +1,203 @@
# 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 L0L2; 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.