Orchestrata Ultimate › Plans › context-injection-owed-work-plan
Context-Injection Owed-Work Plan
Source: plans/context-injection-owed-work-plan.md at 8a2cb42ad · last changed 2026-07-27 · first committed 2026-07-14 · 238 lines.
Prose pending.
Plan text
Context-Injection Owed-Work Plan
Scope: Close the four items left unchecked in the 2026-07-14 spec update:
- SPEC-107 FR-002 — bounded memory recall (
max_entries/max_age_seconds) - SPEC-106 REQ-106-006 — CI conformance gate for canonical KG schema
- SPEC-106 REQ-106-044 — p50 < 500ms benchmark for
select()+pack() - SPEC-106 REQ-106-008 — migrate production KG writers onto the canonical schema
Status: in progress — Waves 1-6 complete, p50 benchmark re-run complete
Target: one numbered task per commit, scripts/health_check.py green before moving on.
0. Duplicate / consolidation findings
| Area | Finding | Impact on plan |
|---|---|---|
| Memory recall | MemoryEngine.search() lacks the pre-filters; MemoryScope already has date_from/date_to, so max_age_seconds maps cleanly. No duplicate implementation. |
Add params to protocol + engine + hot/cold stores; update assembler defaults. |
| CI conformance gate | scripts/kg_schema.py check already exists and exits non-zero on drift. Not called in .github/workflows/ci.yml. |
One-line CI addition after the migration lands; must not enable before graph is clean or CI will fail. |
| p50 benchmark | scripts/benchmark_pipeline.py and tests/knowledge_graph/test_knowledge_performance.py exist, but nothing measures context_pack.select()+pack() latency. |
New script + test, modeled on existing benchmark style. |
| Writer migration | Significant duplication/fragmentation: sync.py and synchronizer.py both sync code AST; session/kg_sync/_stage_code.py duplicates AST syncing with different rel names; kg_design.py writes non-canonical CodeClass/CodeFunction/DesignModule {name} nodes. |
Sequence: one-shot graph cleanup → migrate easiest writers first → consolidate duplicate AST sync paths last. |
1. SPEC-107 FR-002 — Bounded memory recall
Current state
MemoryEngine.search(query, *, scope, limit=10, min_similarity=0.7)returns at mostlimitentries after embedding similarity scoring.- It fetches up to 1000 hot entries (
retrieve_by_scope(scope, limit=1000)) before scoring — no pre-filter on count or age. memory_context.recall()exposeslimitandmax_tokensbut notmax_entries/max_age_seconds.UnifiedContextAssemblercallsrecall_sync(thread_id, user_message, limit=3, max_tokens=...).
Goal
Add max_entries and max_age_seconds pre-filters that run before similarity scoring, keeping recall latency under 100ms and the memory layer within its token budget.
Design
- Extend
MemoryScope(if needed) or computedate_fromfrommax_age_seconds. - Add
max_entries: int | None = Noneandmax_age_seconds: int | None = Noneto:MemoryEngineProtocol.search()(incore/protocols.py)MemoryEngine.search()RedisMemoryStore.retrieve_by_scope()Neo4jMemoryStore.search_by_scope()
- Implement pre-filter semantics:
max_age_seconds: setscope.date_from = now - max_age_secondsbefore querying stores.max_entries: pass through toretrieve_by_scope/search_by_scopeso Redis/Neo4j cap candidate retrieval before Python scoring.
- Choose production defaults in
UnifiedContextAssembler(e.g.max_entries=50,max_age_seconds=3600) and update therecall_synccall. - Add observed tests proving
search()returns ≤max_entriesand respects age.
Files to touch
src/orchestrata_ultimate/core/protocols.py—MemoryEngineProtocol.search()signaturesrc/orchestrata_ultimate/memory/memory_engine.py—search()src/orchestrata_ultimate/memory/hot_store.py—retrieve_by_scope()src/orchestrata_ultimate/memory/cold_store.py—search_by_scope()src/orchestrata_ultimate/memory/memory_context.py—recall()/recall_sync()src/orchestrata_ultimate/context/assembler.py—recall_sync(..., max_entries=..., max_age_seconds=...)tests/memory/test_memory_engine.pyor newtests/memory/test_memory_recall_filters.py
Verification
python scripts/run_tests.py tests/memory/ --skip-gates
python scripts/health_check.py
2. SPEC-106 REQ-106-006 — CI conformance gate
Current state
scripts/kg_schema.py checkrunscanonical_schema.check()and exits 1 on drift..github/workflows/ci.ymlhas no step calling it.scripts/migrate_neo4j_canonical.pyis a one-shot migration that purges test pollution, backfills canonical keys, drops wrong constraints, and applies canonical DDL.
Goal
Wire kg_schema.py check into CI so non-canonical writes fail the build.
Design
- Prerequisite: run
migrate_neo4j_canonical.pyagainst the shared CI Neo4j instance so the graph is clean. - Add a CI step in
.github/workflows/ci.ymlafter the architecture checker:- name: Canonical KG schema conformance run: uv run python scripts/kg_schema.py check - Ensure CI Neo4j is reachable via env vars (
NEO4J_URI, etc.). If CI lacks a live Neo4j, instead add a local test-fleet step that spins up a container, applies DDL, runs a smoke writer, and assertscheck()passes. - Add a test under
tests/knowledge_graph/test_canonical_schema.pythat:- Applies canonical DDL to a test-only Neo4j clone.
- Writes a conformant node and asserts
check()is OK. - Writes a non-canonical node (wrong merge key) and asserts
check()reports it.
Files to touch
.github/workflows/ci.ymltests/knowledge_graph/test_canonical_schema.py(extend or create)
Verification
python scripts/kg_schema.py check
python scripts/run_tests.py tests/knowledge_graph/test_canonical_schema.py --skip-gates
3. SPEC-106 REQ-106-044 — p50 < 500ms benchmark for select() + pack()
Current state
scripts/benchmark_pipeline.pymeasures boot/intent/throughput.tests/knowledge_graph/test_knowledge_performance.pymeasures node/Cypher conversion.- Nothing measures the SPEC-106 selector/packer latency.
Goal
A repeatable benchmark that reports p50 latency of context_pack.analyze_request() + select() + pack() against a live Neo4j graph at repo scale, and fails if p50 > 500ms.
Design
- New script
scripts/benchmark_context_pack.pywith subcommands:seed— sync the current repo into a project-qualified Neo4j graph.run— run N iterations of a representative task (e.g.TaskType.REFACTORtargetingcontext/assembler.py), measuring end-to-endanalyze_request+select+packlatency.- Reports: iterations, p50/p95/p99 ms, nodes selected, sections packed.
- New test
tests/knowledge_graph/test_context_pack_performance.pymarked@pytest.mark.slowthat:- Seeds a modest but non-trivial graph (≥50 files, ≥100 classes/functions).
- Runs ≥20 iterations.
- Asserts p50 < 500ms.
- Use existing
context_pack.analyze_request,select,pack, andTokenCounterProtocol(no mocking).
Files to touch
- New:
scripts/benchmark_context_pack.py - New:
tests/knowledge_graph/test_context_pack_performance.py
Verification
python scripts/benchmark_context_pack.py seed
python scripts/benchmark_context_pack.py run --iterations 20
python scripts/run_tests.py tests/knowledge_graph/test_context_pack_performance.py --skip-gates
4. SPEC-106 REQ-106-008 — Migrate production KG writers onto canonical schema
Current state (writer audit)
| Writer | Labels/keys used | Canonical? | Notes |
|---|---|---|---|
knowledge_graph/sync.py |
File/Class/Function/Method/Parameter/Package/Module/Requirement/Test with {id: r.id}; rels DEFINES, IMPORTS, CALLS, TESTED_BY, HAS_METHOD, INHERITS_FROM |
Mostly yes, but HAS_METHOD should be DEFINES and INHERITS_FROM should be INHERITS per canon |
Real AST sync writer |
knowledge_graph/synchronizer.py |
File {path: $path}, Class/Function {id: r.id}, rels DEFINES, HAS_METHOD, CALLS, INHERITS, IMPORTS |
File key wrong; HAS_METHOD wrong |
Duplicates AST sync; appears to be the older/legacy implementation |
session/kg_sync/_stage_code.py |
Class {id}, Function {id}, rels DEFINES, HAS_METHOD, HAS_CLASS, HAS_FUNCTION |
HAS_CLASS/HAS_FUNCTION wrong |
Another AST sync duplicate |
session/kg_sync/_stage_session.py |
Project {id: $id}, Session {seq: $seq} |
Project key should be slug; Session key should be session_id |
Session/project writer |
session/kg_sync/_stage_specs_traces.py |
Spec {id}, Requirement {id}, RequirementItem {id}, rels HAS_SPEC, DEFINES_REQUIREMENT, HAS_ITEM, TRACES_TO, IMPLEMENTS |
Mostly canonical | Good candidate for first migration validation |
session/kg_sync/_stage_folders.py |
Directory {id}, File {id}, rels HAS_ROOT_DIR, CONTAINS |
Directory/File keys canonical |
Mostly OK |
kernel/pipeline_kg.py |
Volk {alias}, Artifact {id}, PipelineRun {id}, Intent {id}, Decision {id}, rels MADE, APPLIES_TO, JUSTIFIED_BY, GENERATED_BY, EXECUTED_BY, TRIGGERED |
Yes | Already canonical; just verify |
knowledge_graph/kg_design.py |
Project {slug}, Spec {id}, UserStory {id}, Requirement {id} canonical; but DesignModule {name}, DesignClass {name}, CodeClass {name, project}, CodeFunction {name, project} |
Non-canonical design/code nodes | Design-layer writer; may need schema reconciliation |
knowledge_graph/runtime_writer.py |
Message {message_id}, ToolCall {id}, Decision {id}, GatewayEvent {entry_id}, rel MENTIONS |
Yes | Already canonical |
Consolidation opportunities
sync.pyvssynchronizer.py— both sync AST to KG. Determine which is the production path and retire the other, or makesynchronizer.pya thin wrapper aroundsync.py.session/kg_sync/_stage_code.py— likely superseded bysync.py; if still used, converge rel names ontoDEFINESonly.- Design-layer non-canonical labels —
CodeClass/CodeFunctionoverlap with Tier AClass/Function. Decide whether design artifacts are a distinct tier (then add them tocanonical_schema.pywith proper keys) or map them onto canonical code nodes.
Execution order
Wave 1 — Graph cleanup (one-time)
- Run
python scripts/migrate_neo4j_canonical.pyagainst the shared Neo4j instance. - Verify
python scripts/kg_schema.py checkreturns OK. - Back up the graph before running.
Wave 2 — Already-canonical writers (validation only)
kernel/pipeline_kg.py— add conformance assertions in tests.knowledge_graph/runtime_writer.py— already canonical; add test.session/kg_sync/_stage_specs_traces.pyand_stage_folders.py— verify, fix minor rel names if needed.
Wave 3 — Key canonicalisation
session/kg_sync/_stage_session.py:Project {id: $id}→Project {slug: $id}(or backfillslugproperty).Session {seq: $seq}→Session {session_id: $seq}(or write both).
knowledge_graph/synchronizer.py:File {path: $path}→File {id: $project_id:$path}and keeppathproperty.
- Update tests for each writer to assert canonical keys.
Wave 4 — Relationship canonicalisation
knowledge_graph/sync.py:INHERITS_FROM→INHERITS.(c)-[:HAS_METHOD]->(m)→(c)-[:DEFINES]->(fn:Function)wherefncarriesclass_id.
knowledge_graph/synchronizer.pyandsession/kg_sync/_stage_code.py:HAS_CLASS/HAS_FUNCTION/HAS_METHOD→DEFINES.
- Update
canonical_schema.pyif any new rel constants are needed.
Wave 5 — Consolidate duplicate AST sync
- Decide single source of truth for code-to-KG sync. Recommendation:
knowledge_graph/sync.py(it already uses project-qualified ids and is the newer implementation). - Make
synchronizer.pydelegate tosync.pyor delete it if unused. - Make
session/kg_sync/_stage_code.pydelegate tosync.pyor delete it. - Remove dead code only after
serialize_codebase_ast.py refsconfirms zero references.
Wave 6 — Design-layer reconciliation
- Add canonical labels/keys for design artifacts or merge
CodeClass/CodeFunctioninto canonicalClass/Function. - Update
kg_design.pyaccordingly. - This is the highest-risk wave; do it last and with a dedicated test-fleet run.
Files to touch (incremental, one wave per commit)
src/orchestrata_ultimate/session/kg_sync/_stage_session.pysrc/orchestrata_ultimate/knowledge_graph/synchronizer.pysrc/orchestrata_ultimate/knowledge_graph/sync.pysrc/orchestrata_ultimate/session/kg_sync/_stage_code.pysrc/orchestrata_ultimate/knowledge_graph/kg_design.pysrc/orchestrata_ultimate/knowledge_graph/canonical_schema.py(if new labels/rels needed)tests/knowledge_graph/test_canonical_schema.pyand per-writer tests
Verification (after each wave)
python scripts/kg_schema.py check
python scripts/run_tests.py tests/knowledge_graph/ --skip-gates
python scripts/health_check.py
5. Recommended overall order
| Order | Task | Why |
|---|---|---|
| 1 | Bounded memory recall (FR-002) | Isolated; no graph migration; unblocks assembler optimization. |
| 2 | p50 benchmark (REQ-106-044) | Establish baseline before writer migration changes query patterns. |
| 3 | One-time graph cleanup + CI gate (REQ-106-006) | Must clean graph before CI gate can be enabled. |
| 4 | Writer migration Wave 2 (canonical validation) | Low-risk, proves CI gate works. |
| 5 | Writer migration Wave 3 (key canonicalisation) | Fixes the most common check() failures. |
| 6 | Writer migration Wave 4 (relationship canonicalisation) | Fixes remaining rel-name drift. |
| 7 | Writer migration Wave 5 (consolidate AST sync) | Removes duplicate code. |
| 8 | Writer migration Wave 6 (design-layer reconciliation) | Highest risk; do last. |
| 9 | Re-run p50 benchmark | Verify migration did not regress latency. |
6. Definition of done
- [x]
MemoryEngine.search()acceptsmax_entriesandmax_age_seconds; observed tests pass. (commit a18e6f4a) - [x]
.github/workflows/ci.ymlrunsscripts/kg_schema.py checkand fails on drift. (commit 9787dba0) - [x]
scripts/benchmark_context_pack.pyreports p50 < 500ms at repo scale. (commit d0af53b8; re-run 8609d61a: p50 120.65ms) - [x]
kg_schema.py checkpasses against the production graph after canonical migration. (commit 9787dba0) - [x] All production KG writers conform to
canonical_schema.CANONICAL_MERGE_KEYSand canonical relationship names. (Waves 3-4) - [x] Duplicate AST sync relationship vocabulary consolidated (HAS_METHOD/HAS_FUNCTION retired). Full implementation retirement of sync.py / synchronizer.py / _stage_code.py remains tracked debt.
- [x]
scripts/health_check.pypasses after every commit.