# Workorder: Context Engine Plugin Boundary

## Objective

Extract context assembly, compaction, memory stitching, and completion framing behind a small orchestrator-owned interface. The current runner should remain behaviorally compatible, but future context strategies should be swappable without editing the main `AgenticRunner` loop.

## Problem Statement

`AgenticRunner` carries too many responsibilities:
- prompt assembly,
- Telegram-specific prompt differences,
- memory and retrieval context,
- completion contract framing,
- context compaction,
- tool-result triage,
- post-critique context injection.

Hermes separates the context subsystem through an explicit `ContextEngine` interface. Omnius already has good pieces in memory and retrieval packages, but the orchestration boundary is still tangled into the runner.

## Existing Code Anchors

Omnius:
- `packages/orchestrator/src/agenticRunner.ts:3200` builds mission completion contract text.
- `packages/orchestrator/src/agenticRunner.ts:18146` starts context-window trimming.
- `packages/orchestrator/src/agenticRunner.ts:18579` branches Telegram-specific system prompt text.
- `packages/orchestrator/src/completionContract.ts:294` formats completion contracts.
- `packages/memory/src/context-window.ts` contains context-window helpers.
- `packages/retrieval/src/contextAssembler.ts` assembles retrieval context.
- `packages/orchestrator/tests/context-fabric.test.ts` is a likely regression home.

Hermes:
- `/home/robit/Documents/repositories/hermes-agent/agent/context_engine.py:32` defines `ContextEngine`.
- `/home/robit/Documents/repositories/hermes-agent/agent/context_compressor.py:522` implements `ContextCompressor`.
- `/home/robit/Documents/repositories/hermes-agent/agent/context_compressor.py:754` prunes old tool results.
- `/home/robit/Documents/repositories/hermes-agent/agent/context_compressor.py:1572` cleans orphaned tool call/result pairs after compression.

## Target Architecture

Create `packages/orchestrator/src/contextEngine.ts` with a narrow interface:

```ts
export interface ContextEngineInput {
  goal: string;
  surface: "tui" | "telegram-public" | "telegram-admin" | "api" | "background";
  messages: AgentMessage[];
  toolEvents: ToolEvidenceEvent[];
  memoryHints: string[];
  runState: ContextRunState;
}

export interface ContextEngineOutput {
  systemMessages: AgentMessage[];
  conversationMessages: AgentMessage[];
  compacted: boolean;
  diagnostics: ContextEngineDiagnostics;
}

export interface ContextEngine {
  build(input: ContextEngineInput): Promise<ContextEngineOutput>;
  compact(input: ContextEngineInput): Promise<ContextEngineOutput>;
}
```

Default implementation:
- `DefaultContextEngine` wraps existing runner behavior without changing semantics.
- It exposes diagnostics for prompt token size, dropped tool results, retained evidence, and compaction reason.

Future extension point:
- Optional registration through config, but no plugin loader is required for the first cut.

## Phased Implementation

### Phase 0: Inventory and Golden Tests

Tasks:
- Add tests that snapshot key prompt fragments for:
  - normal TUI coding task,
  - public Telegram reply,
  - admin Telegram task,
  - API `/v1/run` task,
  - completion retry after critic feedback.
- Record current event/evidence fragments that must remain visible.

Completion metrics:
- Snapshot tests capture behavior before extraction.
- No new context logic exists yet.

### Phase 1: Define Context Types

Tasks:
- Add `contextEngine.ts` with input/output types and `DefaultContextEngine`.
- Define common message/event types, or import existing runner types if they are already exported safely.
- Add diagnostics:
  - `tokenEstimateBefore`
  - `tokenEstimateAfter`
  - `compactionStrategy`
  - `evidenceRetained`
  - `evidenceDropped`
  - `surface`

File-by-file notes:
- `packages/orchestrator/src/contextEngine.ts`: new boundary.
- `packages/orchestrator/src/index.ts`: export only if other packages need it.
- `packages/orchestrator/tests/contextEngine.test.ts`: unit tests for default no-op build.

Completion metrics:
- Types compile.
- Default engine can round-trip messages unchanged.

### Phase 2: Wrap Current Runner Assembly

Tasks:
- Move context construction code from `AgenticRunner` into default engine methods in small, reversible chunks.
- Do not change prompts while moving logic.
- Keep Telegram-specific content as input-selected surface policies, not scattered string checks.

Migration order:
1. Non-Telegram system prompt assembly.
2. Telegram prompt assembly.
3. Completion contract insertion.
4. Context trimming/compaction.
5. Tool-result pruning.

Completion metrics:
- Existing prompt snapshots remain stable.
- `AgenticRunner` delegates to `contextEngine.build` before backend calls.
- No behavior change for simple `task_complete` tests.

### Phase 3: Evidence-Aware Compaction

Tasks:
- Preserve recent tool evidence and critic reconciliation packets as first-class context items.
- Replace ad hoc retention rules with ranked evidence groups:
  - user goal and constraints,
  - final/proposed claims,
  - latest tool observations,
  - failed tool results,
  - modified artifacts,
  - critique feedback and reconciliation evidence.

Completion metrics:
- A repeated critic review sees evidence recorded after the prior critique.
- Tool call/result pairs remain paired after compaction.
- Orphaned tool results are removed or summarized with a diagnostic.

### Phase 4: Plugin Boundary

Tasks:
- Allow an optional configured engine name, defaulting to `default`.
- Keep plugin API internal until one alternate engine exists.
- Add a test fake engine that injects a diagnostic marker to prove selection works.

Completion metrics:
- Config can select default engine explicitly.
- Unknown engine fails closed with a clear error.
- Test fake engine runs without editing `AgenticRunner`.

### Phase 5: Documentation and Handoff

Tasks:
- Add an architecture note under `docs/architecture/` describing the context engine boundary.
- Document invariants:
  - context engine may reorder/summarize but not fabricate observations,
  - completion evidence must remain attributable,
  - surface-specific safety text is selected by surface, not by topic keywords.

Completion metrics:
- Docs include diagrams or tables for inputs and outputs.
- Future feature workorders can target `ContextEngine` rather than `AgenticRunner`.

## Required Tests

- `contextEngine.test.ts`: interface, diagnostics, no-op default round trip.
- `agenticRunner.test.ts`: runner still completes simple tasks.
- `telegram-bot-api-10.test.ts`: public/admin prompt behavior remains stable.
- `completionContract.test.ts`: completion contract still appears where expected.
- Compaction test: evidence after prior critique survives into the next critic prompt.

## Rollout Plan

1. Add boundary with no behavioral change.
2. Move non-Telegram assembly.
3. Move Telegram assembly.
4. Move compaction.
5. Enable diagnostics in TUI/admin surfaces.

## Risks

- Prompt drift can break fragile Telegram and tool-call behavior. Mitigation: golden prompt tests before migration.
- Over-generalized interface can freeze wrong abstractions. Mitigation: start with current runner data and only extract actual needs.
- Plugin loading can introduce untrusted code. Mitigation: internal registry only for first release.

## Definition of Done

- `AgenticRunner` no longer owns all prompt/context assembly directly.
- Existing behavior is preserved by tests.
- Context diagnostics expose what was retained and compacted.
- Completion evidence and critic reconciliation packets are protected through compaction.
