Phase 3.5 extraction & assembly

Phase 3.5 — Extraction & Context Assembly — Decision Log

Stack choices and ADR decisions for Extraction & Context Assembly.

Phase 3.5 — Decision Log

Quick decisions during Phase 3.5. Promote durable choices to docs/adr/ and the public ADR index when they affect multiple phases.

Python / service stack (Phase 3.5 deltas)

Phase 3 stack choices in Phase 3 decisions still apply. Phase 3.5 deltas:

ConcernChoiceReason
Context assembly runtimePython 3.12 (services/context/)Matches memory/worker ML-adjacent stack; gRPC + async
Worker serviceCelery 5 + Redis broker (services/worker/)At-least-once extraction; observability via ADR-0062
MCP serverFastMCP / MCP Python SDK Streamable HTTP + stdio (services/mcp-memory/)ADR-0050 transport; tools share memory HTTP substrate
Extraction enqueue from proxyWorker HTTP enqueue (not Celery Redis wire from Go)ADR-0072 — avoid Go/Celery protocol coupling
Token budgetsCapability catalog generate-and-diffADR-0067
PackingBounded DP knapsack (16-token buckets)ADR-0069
DegradationL0–L3 ladder with deadlineADR-0071; L3 is proxy fail-open

ADR register (Phase 3.5 — Accepted)

ADRTopicMilestoneStatus
ADR-0038Context assembly service design + gRPC contractPre-phase design (cited throughout C/D)Accepted
ADR-0050MCP transport, auth, audit skeleton2.5.G / Track E foundationAccepted
ADR-0062Worker task observability + dead-letter3.5.A.2Accepted
ADR-0063Extraction output schema v23.5.B.1Accepted
ADR-0064Extraction provider registry + batch execution3.5.B.2Accepted
ADR-0065Extraction batch idempotency + turn pointer3.5.B.3Accepted
ADR-0066Extraction quality evaluation harness3.5.B.4Accepted
ADR-0067Capability catalog generate-and-diff3.5.C.1Accepted
ADR-0068Composite scoring-time relevance gate3.5.C.3Accepted
ADR-0069Context packer bounded DP knapsack3.5.C.4Accepted
ADR-0070Formatter locked ordering + session nonce3.5.C.5Accepted
ADR-0071gRPC degradation ladder + retrieval deadline3.5.C.6Accepted
ADR-0072Extraction enqueue via worker HTTP3.5.D.4Accepted

Planning aliases not used

Early Phase 3.5 sketches reserved ADR-0043 / ADR-0044 for MCP / assembly topics. Those numbers already ship Phase 2.5 work — do not reuse them:

Planning aliasActual shipped ADR / note
“ADR-0043 context / MCP”Occupied — ADR-0043 tokenizer registry; MCP is ADR-0050
“ADR-0044 assembly / MCP tools”Occupied — ADR-0044 response pipeline; assembly is ADR-0038 / ADR-0071
“Move ADR-0038 Pending → Accepted”Stale — ADR-0038 has been Accepted since 2026-07-19; F.3 only re-indexes / cites it

Always assign the next free number from web/content/docs/adr/meta.json when publishing a new ADR.

Log pivots in findings. When an ADR merges, add it under docs/adr.

Architectural decisions

DecisionRationale
Separate Python context service (not inline Go)Ranking / packing / tiktoken stay in Python; proxy stays thin (ADR-0038)
gRPC AssembleContext with hard deadlineBound hot-path latency; degrade rather than block chat (ADR-0071)
Relevance gate before composite scoreFloor cosine excludes irrelevant-but-hot memories (ADR-0068)
DP packer over pure greedyRecover budget utilization on adversarial sets (ADR-0069)
Locked formatter order + nonceDeterministic injection; lost-in-the-middle mitigation (ADR-0070)
Batch extraction on session closeCross-turn awareness + cost (ADR-0064 / ADR-0065)
MCP tools call memory HTTP (one substrate)Same tenancy / write path as proxy-assembled memories (ADR-0050 + E.2)
MCP fail-closed on auth outage + org RPM budgetIndependent of proxy rate limits (E.4)
ISO-MCP matrix live auth + PostgresDefense-in-depth beyond unit mocks (F.2)

Pending decisions (post Phase 3.5)

  1. Published contextAssembly / mcpTool / extractionThroughput suites — contract columns exist (3.5.F.3); CI + site registry wiring deferred (exit-audit P2).
  2. Live 100K assemble_load CI gate — stub harness exists; live profile remains manual.
  3. Celery extraction throughput baseline — quality suite shipped (ADR-0066); throughput suite not started.
Edit on GitHub

Last updated on