Orchestrata Ultimate › Plans › context-injection-improvement-plan

Context-Injection Improvement Plan

Source: plans/context-injection-improvement-plan.md at 8a2cb42ad · last changed 2026-07-27 · first committed 2026-07-13 · 149 lines.

Prose pending.

Plan text

Context-Injection Improvement Plan

1. Current state

The repository has a layered context-injection architecture:

sources → UnifiedContextAssembler → ContextBudget/Usage → volk prompt

Live sources today:

Dead/unused sources today:

2. Problems to solve

  1. Session continuity is broken. Volks have no compact view of the active goal, pending work, latest handoff, or project state.
  2. Memory recall is O(N). RedisMemoryStore.retrieve_by_scope() can load up to 1000 entries and score them in Python.
  3. Rich data is not pulled automatically. Previous experiments showed models did not voluntarily use AST/graph data; it must be injected for them.
  4. Context budgets are not observed. ContextUsage.to_dict() exists but is not logged, so token spend per layer is invisible.
  5. Artifact store is in-memory only. Long runs lose artifacts if the process restarts, and digests are not paginated.
  6. Schema drift complicates KG queries (Volk vs Agent, Class vs CodeClass, etc.).

3. Plan of work (in order)

Phase 0 — Instrumentation and quick fixes

Goal: make the existing assembler observable and stop losing session context.

  1. Wire session context into the assembler

    • File: src/orchestrata_ultimate/kernel/pipeline_kg.py
    • Action: pass a real ContextData object into _assemble_context_for_subject instead of None.
    • Seams:
      • PipelineRunner already carries a session_controller; expose a method to load ContextData.
      • src/orchestrata_ultimate/session/cli/pipeline.py should pass controller context into the runner.
    • Test: add an observed test asserting the mission layer is non-empty when a session has active goals.
  2. Populate the plan layer

    • File: src/orchestrata_ultimate/context/assembler.py
    • Action: add a plan_context provider that renders the next planned stages / recent outcomes from the pipeline result.
    • Budget: use the existing 600-token plan reservation.
  3. Log context usage per call

    • File: src/orchestrata_ultimate/kernel/pipeline_kg.py
    • Action: after assembler.assemble(), log assembly.usage.to_dict() at INFO.
    • This creates the data needed to optimize budgets later.
  4. Cap memory recall cost

    • File: src/orchestrata_ultimate/memory/hot_store.py / memory_engine.py
    • Action: add a max_age_seconds / max_entries pre-filter before vector scoring; default to the most recent 200 entries or 24h.
    • Keep the existing similarity logic; just score fewer entries.

Phase 1 — Make AST and graph data reachable

Goal: stop expecting the model to pull data; push the right data into the prompt.

  1. Bridge AST serializer into Neo4j / KG context ✅

    • Files: scripts/serialize_codebase_ast.py, src/orchestrata_ultimate/knowledge_graph/kg_context.py
    • Action:
      • Added serialize_codebase_ast.py ast-to-kg subcommand that writes complexity, branch_count, and CALLS edges from plans/ast-ultimate.json onto existing :Function nodes.
      • Extended KGCodeContext with get_complexity_hotspots() and get_call_graph_neighborhood() to query these signals.
    • Injection: ast_context part already exists in ContextAssembly (budget 500 tokens).
  2. Wire semantic graph into context injection

    • Files: src/orchestrata_ultimate/semantic_graph/, src/orchestrata_ultimate/context/providers/
    • Action:
      • Create SemanticGraphContextProvider that calls semantic_graph.retrieve(query_embedding).
      • Add a semantic layer to ContextAssembly (budget 800 tokens) and enable it when subject is implement, fix_issues, or review_and_test.
    • This directly fixes the "model did not pull data" failure mode.
  3. Enable Prolog relevance refinement by default

    • File: src/orchestrata_ultimate/kernel/pipeline_kg.py
    • Action: construct a KgRelevanceRetriever when a PrologBridge is available and pass it to ContextInjector.

Phase 2 — Quality and scale

Goal: make context injection reliable for long-running sessions and large codebases.

  1. Adaptive pack trimming

    • File: src/orchestrata_ultimate/context/assembler.py
    • Action: when a layer exceeds its budget, truncate by sentence/paragraph boundaries rather than hard string slicing; prioritize mission/plan/user, then graph, then memory.
  2. Project-scoped context ✅

    • Files: knowledge_graph/project_resolver.py, context_injector.py, context_assembler.py, context_providers/ast_context.py, kernel/pipeline_kg.py
    • Action: centralize project-id resolution in resolve_project_id (KG Project-node lookup first, basename fallback); thread project_id through AST context rendering and the semantic-layer requirement/decision queries; replace repeated basename extractions in pipeline_kg.py.
  3. Incremental KG sync ✅

    • File: src/orchestrata_ultimate/knowledge_graph/synchronizer.py
    • Action: ensure_fresh and sync_project now load and save per-file hash state from .orchestrata/kg_sync_state.json, so incremental sync survives process restarts and only changed files are re-synced.

Phase 3 — Schema and unification

Goal: one canonical KG schema so context queries are simple and fast.

  1. Canonicalize KG labels

    • Pick one label per concept (Volk/Agent, Class/CodeClass, Spec/Specification, Requirement/RequirementItem).
    • Update sync.py, Neo4jSyncer, and all query modules.
    • Retire defensive coalescing in context_injector.py.
  2. Unify context under a single query interface

    • File: src/orchestrata_ultimate/knowledge_graph/query_engine.py
    • Action: make QueryEngine the one entry point used by ContextInjector; move volk_work_context, run_provenance, and semantic retrieval behind it.

Phase 4 — Artifact store refactor (user backlog)

Goal: durable, queryable artifacts that survive restarts and support richer digests.

  1. Persist artifacts to disk / Neo4j

    • File: src/orchestrata_ultimate/orchestrator/artifact_store.py
    • Action:
      • Add an output_dir constructor argument; write each artifact to a timestamped JSONL file.
      • On load, replay the JSONL into the in-memory index.
      • Keep the existing in-memory API unchanged.
  2. Paginated / ranked digest rendering

    • File: src/orchestrata_ultimate/context/providers/artifact_digest.py
    • Action:
      • Rank artifacts by recency and relevance to the current subject.
      • Render only the top-N within the artifact budget instead of dumping every prior artifact.
  3. Trace-aware artifact indexing

    • Add spec/reqs fields to PipelineArtifact.
    • Index by requirement so a volk working on REQ-025-091 can retrieve prior artifacts that trace to it.

4. Definition of done

5. Risks and blockers