Orchestrata Ultimate › Plans › research › audit-03-context-injection
Audit 03 — Context Injection (SPEC-009) + Memory/KG Wiring into Volks
Source: plans/research/audit-03-context-injection.md at 8a2cb42ad · last changed 2026-07-27 · first committed 2026-07-04 · 63 lines.
Prose pending.
Plan text
Audit 03 — Context Injection (SPEC-009) + Memory/KG Wiring into Volks
Research audit for the completion mandate. Paths are repo-relative to
/home/mohamed/workspace/orchestrata-ultimate-architecture/.
Headline
Two context injectors exist; the SPEC-009-canonical one is dead code.
knowledge_graph/volk_context_injector.py::VolkContextInjector— SPEC-009 class (task-type dispatch BUILD/REFACTOR/DEBUG/DOCUMENT/TEST/REVIEW; injects Spec + Requirement + AST). Never called in production (only its file + 3 tests).knowledge_graph/context_injector.py::ContextInjector— subject-gated, injects only KG code structure (files/classes/functions/rels/tests). This is wired.
What a volk actually receives today
- Intent text — first stage (Concierge U:Cx) only.
kernel/pipeline.py:219. - Prior-stage artifacts — YES, via manual per-volk payload key-copying (choreography).
- KG code-structure facts — only when
subject ∈ INJECT_SUBJECTS(implement, fix_issues, review_and_test, design_review, scope_review, ux_design), capped MAX_ENTITIES=50 / MAX_CONTEXT_CHARS=8000. - Specs / Requirement nodes — NO (only in the unused VolkContextInjector).
- Relevant memories — NO (zero retrieval anywhere in the execution path).
- Session / goal / project state — NO.
Injection mechanism: graph context is prepended to the user message, not the
system prompt — llm/client.py:545-547 (effective_message = graph_context + "---" + user_message).
System prompts are hardcoded static per volk (e.g. pm/volk.py:16 PM_SYSTEM_PROMPT).
GraphContextValidator (knowledge_graph/graph_context_validator.py, client.py:575-602)
checks the response references injected entities and can retry.
Wired injection path
- Init:
kernel/pipeline.py:73 _init_context_injector→kernel/pipeline_kg.py:48buildsContextInjector(driver)(sync neo4j driver) orContextInjector(None). - Per hop:
kernel/pipeline_escalation.py:58 _maybe_inject_context→kernel/pipeline_kg.py:107(should_inject(subject)→inject(payload)setspayload["graph_context"]). - Volk extraction:
core/graph_directives.py:26 extract_graph_context(payload).
Memory (SPEC-010) — standalone, write-only, different runtime
memory/memory_engine.pyhas store/retrieve/search/summarize (139/183/197/232).- Only consumer:
agents/kernel_handler.py(_rememberwrites each turn, 69-79) — the gRPC agent-runtime path (runtime_main.py:45-49 CXPServer), NOT the productionPipelineRunner.retrieve/searchare never called by any volk.
Prior-stage artifacts
Flow via manual key-copying, not an ArtifactStore feedback:
- Cx→BA
concierge/volk.py:388-390; BA→PManalyst/agent.py:213-226; PM→UX/Arpm/volk.py:292-332 _build_forward_packet; Ar→Cd/QApipeline_escalation.py:262-332 _build_escalation. kernel/pipeline_artifacts.py::ArtifactStore+orchestrator/artifact_store.pyare collect/persist-only (pipeline_output/<thread_id>/), never re-injected.
Two parallel runners
kernel/pipeline.py— choreographed, HAS injection.orchestrator/pipeline_runner.py— orchestrated loop,_run_stage:238just forwards payload, NO graph/memory injection at all.
Gaps + insertion points (central chokepoint = kernel/pipeline_kg.py:_maybe_inject_context L107)
- A SPEC-009 injector unwired → call
VolkContextInjector.inject_for_task(needs async Neo4jClient), map subject→TaskType, merge into payload. - B No spec/requirement facts → extend
context_injector.py:320 _query_contextwith BUILD Cypher (volk_context_injector.py:212-248). - C No memory retrieval → after graph_context,
memory_engine.search(ctx)→payload["memory_context"]; addextra_contextkwarg tocall_llm(client.py:502). - D No session/goal/project → inject goal/session block (PM
goal_registry.pyexists, unused in prompts). - E ArtifactStore not fed back → query
artifacts.by_thread(thread_id)→ compact prior-artifacts summary, replacing brittle key-copying. - F Two injectors + two runners + two ArtifactStores → pick ONE canonical of each before wiring.