research · v0.11 · living decision log — publication cut

Memory Tooling — Open Decisions & Measurement Log

The living decision log for the memory stack: what is adopted, what is still open, what is rejected — with evidence and measured results per record.

published 2026-07-11 · updated 2026-08-02
authors: Nexartis
tags: agents · memory · retrieval · decisions · benchmarks

Executive summary

Working with Large Codebases gives the current shape of the memory stack; this paper is the running log of what changes next, what is still an open call, and what we have already ruled out. Every entry carries evidence links and an empty Decision / Measured result slot that gets filled in when the call is made or the benchmark lands. This page is not a snapshot; it is the workspace's memory of how it makes memory decisions.

Console D1 datastore — status 2026-07-12

D1-database work is code-first as of 2026-07-12. Schema v0.3 locked (13 tables Q1–Q13 with matching ADR-006 amendments A1–A13, ULID PKs via ulidx, RFC 3339 UTC). Three Cloudflare D1 environments provisioned (local via better-sqlite3 · dev · prod). Stack: drizzle-orm@0.44 + drizzle-kit + zod@4 + ulidx. Runtime model: local-Node-primary — workers-dev deploys but classifies requires_local_runtime for anything touching node:fs / node:child_process (a loud, classified failure, not a fallback). 118 tests green; independent audit's 12 findings remediated. ADR-006 amended for fresh-start key re-entry. mcp_* telemetry tables deferred to D5; Phase-2 experiments schema (tool_benchmark_events, experiment_variants; see harness-bandit-experiments) locked but not yet migrated. Detail: docs/SCHEMA-DESIGN-console-d1.md.

Bottom line

Six low-effort adds queued (A1–A6). Twenty decisions tracked. Landed calls: D4 — chunkhound MCP re-enabled READ-ONLY (v5.2.0 auto-compaction + mcp --read-only); registry default flipped 2026-07-19 (dogfood-proven); write/index path gated on issue #365; router semantic expert = zilliztech/claude-context + Zilliz Cloud + voyage-code-3, fallback = self-hosted Sourcebot; fork-chunkhound / Greptile / Relace Repos rejected; Augment Context Engine rerouted to D19 (benchmark-only first — public API and SDK exist; blocker is string-only supported output shape). D5 — approved with expanded scope (MCP controller/manager as substrate for cloud ozzydev); serena on :24283, codesearch-serve on :39725 (LaunchAgent healthy after the EMFILE fix — SoftResourceLimits.NumberOfFiles=65536; the earlier TCC hypothesis is superseded). D6 — voyage-context-4 as default when the semantic layer returns. D8 — write-strategy rubric adopted as the AGENTS editing routing. D9 — Morph + Relace + Codemod + Anthropic Programmatic Tool Calling approved. D10 — single library + engine adapters (nexartis-parallel-waves-agent-harness). D12 — Letta MemFS conventions + pilot basic-memory MCP; full Letta / mem0 / khoj skipped. D13 — CoreGraph (workspace daemon) + dora (per-repo SCIP → SQLite → MCP) fed by scip-typescript as a package.json build step; routing rubric codified. D14 — mdsvex + mdsvex-shiki + remark-toc / rehype-slug + mermaid + pagefind for reading UX; Pandoc → Typst pipeline for PDF (single nexartis-brand.typ); Playwright page.pdf() as exact-render escape hatch. D15 — worktree-mcp for cross-worktree overlap detection. D16 — nexartis-agent-scripts pnpm monorepo with 5-step publish gate. D17 — SHIPPED: both native MCPs (ozzydev-write, ozzydev-search) enabled and production-dogfooded (search MCP canonical: ADR-007). D18 — (a) path-agnostic-where-guarded shipped 2026-07-16 (install.sh scaffolds + fd-limit plist migration; workspace move green: 592-test validate, live smokes, D1 row re-registered); (b) workspace-local registries approved direction — design rides D5. Still open: D1, D2, D3, D7, D11, D19. Three runaway-DB incidents on the log (~863 GB reclaimed). Canonical ADRs (ADR-005 serena backend, ADR-006 secrets vault, ADR-007 search MCP) live in nexartis-ozzydev/docs/DECISIONS/ — this page links, never duplicates. Benchmark-integrity note below on SWE-bench Verified vs Pro.

Benchmark integrity — what we trust

SWE-bench Verified was invalidated in February 2026: an independent audit found that 59.4% of the hardest failing cases were broken tests, not agent errors, which means every "SOTA on SWE-bench Verified" claim through that period is unsafe as a comparator. Our tracking now uses SWE-bench Pro (standardized-scaffold column) as the honest line — the standardized-scaffold column strips harness-specific advantages that made Verified numbers non-transferable in the first place. When a vendor cites Verified without pointing at Pro, that is a signal.

Incidents — live failure log

Three runaway ChunkHound DBs inside four days, sharing one upstream root-cause class (DuckDB HNSW churn) plus, in Incident #3, a CLI-path cap-bypass. Recorded so the reasoning behind the mitigations (and the D4 service-selection call) survives.

Incident #1 — 2026-07-09

Summary: 277 GB runaway ChunkHound DB during 46-repo onboarding. Write-heavy backfill × interrupted transactions × uncapped DuckDB HNSW churn.

Root cause: HNSW drop-recreate churn blocks DuckDB ART/row-group cleanup (duckdb#19468); the DB file never reclaims pages until compacted.

Mitigation shipped: Absolute database.path in the workspace .chunkhound.json scaffold, database.max_disk_usage_mb: 20000, fragmentation_threshold_pct: 30, bounded indexing knobs.

Upstream: chunkhound PR #339 (compaction, merged, unreleased post-5.1.0) will address the class; issue #340 (phased indexing + db_stop_pct) is the follow-up. Community tool it-bens/chunkhound-index-compactor exists as an interim.

Incident #2 — 2026-07-11

Summary: Second runaway DB — this time 412 GB inside nexartis-ozzydev, discovered during a parallel-wave run.

Root cause: Combined driver: (i) relative database.path resolved against CWD produced a repo-level DB that inherited none of the workspace cap; (ii) same DuckDB HNSW churn class as Incident #1; (iii) the pre-PR-#249 Voyage 429 retry death-loop amplified writes by looping on rate-limited batches.

Mitigation shipped: Absolute database.path everywhere, workspace-level 20 GB cap made mandatory in the scaffold, max_concurrent_batches lowered to 3 to stay well inside Voyage Tier 1 limits.

Upstream: Both incidents are known failure modes upstream and being actively fixed: PR #339 (compaction, post-5.1.0), issue #340 (phased indexing + db_stop_pct). PR #249 already shipped the Voyage 429 retry fix. See D4 for the mitigate-in-place vs migrate call.

Incident #3 — 2026-07-12

Summary: Third runaway DB — 202 GB accumulated in ~13 minutes during a throttled CLI re-index, with database.max_disk_usage_mb: 20000 configured. The cap was enforced on the daemon write path (stopped a parallel 24.9 GB daemon run cleanly) but NOT on the CLI bulk-indexing path; the CLI run terminated with SUCCESS despite the cap being blown by ~10×.

Root cause: The disk-cap enforcement lives on the daemon’s incremental write loop; the CLI bulk indexer takes a different code path that does not consult the same guard. Combined with the same DuckDB HNSW churn (duckdb#19468) as Incidents #1/#2, the CLI path is a cap bypass.

Mitigation shipped: Reclaimed ~863 GB across all three incidents. Disabled the chunkhound MCP in the workspace kilo.json until a release ships PR #339 (compaction) and the fix for the new upstream issue #365. Interim semantic layer = codesearch + serena; codesearch was healthy through all three incidents.

Upstream: Filed chunkhound/chunkhound#365 (CLI bulk path ignores max_disk_usage_mb; run reports SUCCESS with cap blown). D4 flipped to the service-selection call on the strength of this incident — the cap alone is no longer sufficient for on-by-default operation.

Adopt now — the low-effort queue (A1–A6)

These are obvious wins on published evidence, cheap enough to ship without a formal decision. Each earns its slot with a KPI delta in the benchmark harness.

  1. A1 — Repo-map MCP layer (Low)

    Aider-style tree-sitter + PageRank map per repo, ~1k tokens. Drop-in MCP; measurably cuts "let me grep" round-trips and hallucinated imports across every reference implementation we surveyed. Complements ChunkHound (semantic) and Serena (symbol) with a cheap file-level scaffold the planner reads once per repo.

  2. A2 — Embedding benchmark harness (100-query gold set from real agent traces) (Low)

    Score voyage-code-3 vs Qodo-Embed-1, jina-code-embeddings-1.5b, and SFR-Embedding-Code on our own queries. CoREB and CoIR both show code-specialised open-source challengers exist for our workload class; benching them beats faith. Also produces the honest baseline the whole decision log measures against.

  3. A3 — Reranker A/B in the same harness (Low)

    rerank-2.5 vs Qwen3-Reranker-4B on the code-to-code slice. CoREB is explicit that all rerankers are task-asymmetric; rerank-2.5 is unbenchmarked on cross-repo C2C in our stack. Cheap to run once the A2 harness exists.

  4. A4 — Verify ChunkHound AST chunking is structure-preserving on our tree (Trivial)

    ChunkHound advertises cAST-style chunking. Confirm no split-function pathology on our Svelte + TS + Python + Rust + Go mix — a 2–3% retrieval delta hides here per the cAST/AIRCoder findings, and we would rather see it in a fixture than in production.

  5. A5 — codesearch git post-checkout hooks on Agent Manager worktree repos (Trivial)

    Already-documented codesearch feature; installs freshness on branch switches so the index does not lag the checked-out ref inside a scratch worktree. Complements the "worktree audits use native tools" rule with a smaller freshness window when the tool IS the right one.

  6. A6 — Memory-review curation queue (Augment Memory Review pattern) (Low)

    Borrowed from Augment's Memory Review (2025-09-08): draft memories surface in a turn summary as "N pending" with per-item Approve / Edit / Discard. Our AGENTS.md self-maintenance loop is manual and end-of-session; a pending-items queue in the console is a better mechanism. Pair it with the mechanical trigger "same mistake twice → promote to a context file," which is automatable today because session_reports.wrong_tool_picks_json already exists in D1 — repeat detection can raise a queue item.

Open decisions (D1–D20)

Each decision below carries a problem statement, an options table, the evidence considered, the current recommendation, and a Decision / Measured result slot. That slot is the point of this page — when the decision is made or the benchmark comes back, it gets filled in here, not in a scratch document.

D1 — Cross-repo symbol intelligence

Problem: The one query class our stack cannot answer today: "who uses this SDK export across all 46 repos?" Serena is per-repo; codesearch fuses lexical + dense but has no cross-repo symbol graph; ChunkHound is semantic, not symbolic.

Options
  • (a) SCIP-in-CI — scip-typescript in every repo's CI + query layer (self-hosted Sourcegraph OSS or SCIP CLI + a thin custom MCP). Enterprise-proven, exact, cross-repo by package identity.
    Effort: MED–HIGH (CI job × 46 + upload pipeline). Highest ceiling. This is what Sourcegraph runs internally.
  • (b) Stack-graphs via CoreGraph — Single-binary MCP daemon, tree-sitter, no CI required. Syntactic (not type-precise) cross-repo symbol traversal.
    Effort: LOW. Less proven (single implementer) but near-zero cost to pilot.
  • (c) Status quo — chunkhound regex + codesearch group="nexartis" approximates the answer lexically; agents state the approximation in findings.
    Effort: Zero. Free but honest gap — what we ship today.

Evidence:

Recommendation: Pilot (b) CoreGraph for one week — near-zero cost. Commit to (a) SCIP-in-CI only if the pilot's answers are wrong often enough on our real "who calls this SDK export" queries to justify the CI investment.

Decision / Measured result: — (empty; to be filled when the decision lands or the benchmark result arrives)

D2 — Freshness architecture upgrade

Problem: Agent Manager worktrees are >90% similar to their parent; re-embedding everything on a fresh worktree is wasteful and, at workspace scale, the failure mode that produced the 277 GB runaway-DB incident. Cursor has a published answer (content-hash-keyed cache + Merkle diff + simhash worktree reuse); ChunkHound does not implement it yet.

Options
  • (a) Upstream feature request to ChunkHound — File the request with the 277 GB incident as the motivating case. Right answer, slow arrival.
    Effort: LOW (write the ticket). Preserves our position as a good upstream citizen.
  • (b) Fork ChunkHound and add the cache locally — Fast fix, maintenance debt, hard to unwind once shipped.
    Effort: HIGH. Only if D1 or a live incident forces the hand.
  • (c) Accept the disk cap as sufficient for now — The cap prevents the failure mode; wasted work on worktree spin-up remains a papercut, not an outage.
    Effort: Zero. Current state.

Evidence:

Recommendation: File the upstream request; accept the cap meanwhile. Revisit if worktree spin-up cost becomes a measured bottleneck. Upstream compaction (PR #339) is confirmed merged post-5.1.0 — this decision partially resolves the moment the release ships.

Decision / Measured result: — (empty; to be filled when the decision lands or the benchmark result arrives)

D3 — codesearch multi-signal fusion

Problem: AIRCoder shows that adding import-graph-existence and structural-hierarchy signals to the existing BM25 + dense RRF stack yields +4–6 EM in ablations. codesearch fuses two of three signal classes; the structural signal is missing.

Options
  • (a) Upstream feature request to codesearch — Add structural signals to the RRF fusion. Slow but right; codesearch has been receptive to prior requests.
    Effort: LOW (write the ticket). Best if D1 lands, because the symbol graph then feeds this fusion for free.
  • (b) Fork codesearch — Faster, high maintenance cost against a Rust codebase we do not own.
    Effort: HIGH. Not currently justified.
  • (c) Accept the current fusion — Two-signal RRF is already the strongest lexical+dense fusion we have measured; the +4–6 EM claim is on public benchmarks, not our workload.
    Effort: Zero. Current state.

Evidence:

Recommendation: File the upstream request; revisit after D1 lands so a symbol graph can feed the fusion its structural signal.

Decision / Measured result: — (empty; to be filled when the decision lands or the benchmark result arrives)

D4 — Semantic layer — service selection

Problem: The prior mitigate-in-place-vs-migrate call reopened once three runaway-DB incidents (see Incident log) exposed a class of failures the disk cap alone could not contain. Cost is not the primary constraint; upstream feature requests are not the fast path (fork-and-improve at workspace scale first, propose a PR only when world-class after auditing related issues); documented-best commercial service is preferred where one fits. The question: which service or fork delivers a world-class semantic layer, measured at workspace scale.

Options
  • (a) Fork chunkhound and fix cap + compaction ourselves — Own the cap-enforcement + CLI-path guard + compaction schedule + retry-loop fix in the fork. Test at full 46-repo scale. Audit related upstream issues. Propose a PR upstream only when world-class. Preserves the DuckDB + Voyage substrate.
    Effort: MED (Python + DuckDB knowledge; three known issue classes to close). Rejected — chunkhound PR #339 is 6,819 lines / 53 files and the upstream author is actively merging into the same surface area; forking would collide with in-flight upstream work. Pin to the pre-#339 release and wait instead.
  • (b) zilliztech/claude-context on Zilliz Cloud (hosted Milvus) + Voyage voyage-code-3 — Reference commercial implementation of the code-RAG paradigm. Native EMBEDDING_PROVIDER=VoyageAI (voyage-code-3), hybrid BM25 + dense retrieval, AST-based chunking, Merkle-tree incremental sync. Zilliz Cloud serverless starts at $0; dedicated clusters $16–63 per million vectors / month.
    Effort: MED (procure account, re-embed workspace, port doctor endpoints). Primary. Documented-best commercial path; matches every capability tuned for on chunkhound with a supervised, hosted substrate.
  • (c) Self-hosted Sourcebot + @sourcebot/mcp — Fallback layer. Sourcebot is a self-hosted regex/lexical + ask_codebase engine that fans out across all 46 repos. Runs alongside the primary as the regex escape hatch when hybrid retrieval misses.
    Effort: MED (docker deploy + MCP wire-up). Fallback. Complements the primary; not a replacement.
  • (d) Cloud-indexed alternatives (Greptile, Relace Repos) — Both viable and mature. Both index the workspace by cloning from GitHub cloud, which places the index outside the workspace-local memory plane.
    Effort: MED. Rejected — workspace-local memory is preferred. Held for revisit only if the primary + fallback stack fails at scale.
  • (e) Augment Context Engine — Augment shipped a Context Engine MCP on 2026-02-06 (GA) in two variants — local (`auggie --mcp [--mcp-auto-workspace]`, stdio, indexes the working directory in real time, `--wait-for-indexing` available) and remote (`https://api.augmentcode.com/mcp`, GitHub App onboarding, indexes default branches only, updates on push) — plus a Context Engine SDK (TS `@augmentcode/auggie-sdk`, Python `auggie-sdk`, marked Experimental — subject to breaking changes). Public API and SDK exist; the earlier "no public API" claim is factually obsolete.
    Effort: MED (benchmark-only) — M–L if adopted as a router arm. Rerouted to D19 for measurement. Real blocker is the supported OUTPUT SHAPE, not access: the documented retrieval contract is `async search(query, options?): Promise<string>` — Augment's API reference says verbatim "Formatted string containing the search results, ready for LLM consumption", "The format includes file paths, line numbers, and code content", with `maxOutputLength` default 20 000 / max 80 000. There is no documented ranked `chunks[]` and no per-item relevance score; `ctxc search --raw` returns pre-summarization text, still not JSON. An undocumented internal endpoint `agents/codebase-retrieval-raw` returns `chunks[{text, path, charStart, charEnd, lineStart, lengthInLines, blobName, score, origin}]` — structurally near-identical to our `ExpertHit` — but the CLI discards it and it is unsupported and liable to silent change. Cost ≈ $0.03–$0.06 per query (provider list price + 40% service fee); availability on our Legacy Developer Plan is undocumented and unverified (adjacent Auggie features — `--show-cost`, `context stats`, cloud agents — are server-side feature-flagged off for it, so this needs an account probe).

Evidence:

Recommendation: Primary = zilliztech/claude-context MCP + Zilliz Cloud (managed Milvus) + Voyage voyage-code-3 (native EMBEDDING_PROVIDER=VoyageAI; hybrid BM25+dense; AST chunking; Merkle incremental sync). Fallback = self-hosted Sourcebot + @sourcebot/mcp for regex + ask_codebase across the 46-repo workspace. Fork-chunkhound rejected; Greptile / Relace Repos rejected (GitHub-cloud-indexed); Augment Context Engine rerouted to D19 (public API and SDK now exist; real blocker is the string-only supported output shape — benchmark-only first, do not adopt as a router arm without numbers).

Decision / Measured result: Adopted 2026-07-12. Status: pending procurement of the Zilliz Cloud account. Primary = claude-context on Zilliz Cloud + voyage-code-3; fallback = self-hosted Sourcebot. chunkhound MCP is disabled in the workspace kilo.json until the primary lands. Signup and API-key wiring: see the Signup and setup links (D9) section; every key lands in the console Secrets panel per ADR-006. Amendment 2026-07-16 — upstream unblocked; scheduled bake-off. Both D4 pause conditions have shipped upstream: PR #339 (compaction) merged 2026-07-03 and released in v5.2.0 (2026-07-12, auto-compact via atomic swap on fragmentation_threshold_pct); the maintainer confirmed on chunkhound#365 that the CLI-path disk-cap bypass is fixed in the same version (not changelog-explicit — needs empirical verification). Local install 5.1.0 is behind v5.2.1. Action plan: (1) uv tool upgrade to v5.2.1, no MCP re-enable yet; (2) empirically verify #365 with one throttled CLI index run against a scratch DB under the 20 GB cap; (3) add a chunkhound expert to the ozzydev-search router behind enabled:false and bake off vs claude-context+zilliz on fixtures v1.4.0 (nDCG@10, selection F1, p95, cold/warm); (4) decide adopt/supplement/retire WITH NUMBERS. ChunkHound was never benchmarked in the IR harness — D4’s pause was operational-safety, not measured quality. What ChunkHound uniquely offers if it wins: workspace-local semantic (no Zilliz cluster dependency), live-watch incremental indexing (Zilliz arm is operator-run script today), code_research deep loop, git-diff semantic search (v5.2.0). Side-notes: rotate the plaintext Voyage key in .chunkhound.json through the Secrets panel (ADR-006) before re-enable; verify .svelte chunking directly in the bake-off (claude-context has the same gap, upstream #222). Bootstrap autostart stays opt-in; disk-cap + fragmentation settings stay mandatory. Amendment 2026-07-17 (dogfood session 2, homeport-release sprint) — D4 moves from paused to PARTIAL RE-ENABLE (read-only MCP). Upstream shipped both blockers: v5.2.0 (2026-07-12) automatic DuckDB compaction via atomic swap on database.fragmentation_threshold_pct (no indexing downtime) AND a new `chunkhound mcp --read-only` mode that opens the DB read-only and disables the indexer/watcher entirely; v5.2.1 is current. Issue #365 (max_disk_usage_mb not enforced during CLI bulk indexing — DB grew to 202 GB with a 20 GB cap configured, mirroring Incident #3) remains OPEN upstream. Measured on the 20260717-homeport workspace after upgrading 5.1.0 → 5.2.1: incremental reindex 23.55 s / 316 files / 0 errors; DB size 2.3 GB → 201 MB (compaction verified live); semantic search quality verified (top hit yanez-bls.ts at 0.812 for a BLS-verification query). New status: workspace kilo.json entry enabled with `--read-only`; indexing/watch remains explicit operator-run CLI only until #365 ships a fix. Amendment 2026-07-19 (dogfood session 3, 20260719-ocme workspace) — READ-ONLY DOGFOOD PROVEN and the registry default FLIPPED. Fresh-workspace measurement: `chunkhound index` discovered 751 files across 5 git repos; the DuckDB peaked ~657 MB during embedding then auto-compacted to 126 MB (0.6% of the 20 GB cap); the read-only MCP attached on VS Code window reload (query_ready true, watcher uninitialized as expected for --read-only) and a live semantic query returned the correct receipt-signing test (receipts-with-event.test.ts) at score 0.863. Executed the registry default flip: mcp/install.sh now scaffolds the chunkhound kilo.json entry enabled:true with `--read-only`, and bootstrap.sh §5c builds the one-time index by default (quiet, explicit `--max-disk-usage-gb 20`, opt out with --no-chunkhound-index) — superseding the earlier bootstrap-autostart-opt-in note now that compaction is proven live. The write/index path is never auto-run; chunkhound#365 (CLI bulk path ignores max_disk_usage_mb) remains the only gate on lifting the operator-run-CLI-only constraint. Lesson folded into the scripts: never index with --verbose (it emits a per-file/per-chunk DEBUG flood). Historical record above is preserved intact. Amendment 2026-07-27 — D4 option (e) rationale CORRECTED. The original "no public API" rejection is factually obsolete: Augment shipped a Context Engine MCP on 2026-02-06 (GA, local + remote variants) and an Experimental Context Engine SDK (@augmentcode/auggie-sdk / auggie-sdk). The REAL blocker is the supported OUTPUT SHAPE — `search()` returns a formatted string per Augment’s API reference ("Formatted string containing the search results, ready for LLM consumption"; `maxOutputLength` default 20 000 / max 80 000; no documented ranked `chunks[]`; no per-item relevance score; `ctxc search --raw` returns pre-summarization text, still not JSON). An undocumented `agents/codebase-retrieval-raw` endpoint returns `chunks[{text, path, charStart, charEnd, lineStart, lengthInLines, blobName, score, origin}]` structurally near-identical to our `ExpertHit`, but the CLI discards it and it is unsupported and liable to silent change. Cost ≈ $0.03–$0.06 per query (provider list + 40% service fee); Legacy Developer Plan availability is undocumented / unverified — adjacent Auggie features (`--show-cost`, `context stats`, cloud agents) are server-side feature-flagged off for it, so this needs an account probe. Adoption question moved to D19 (benchmark-only first; do not adopt as a router arm without numbers). D4’s own semantic-layer bakeoff (chunkhound vs claude-context+Zilliz, fixtures v1.4.0) still has an empty result slot — the Augment arm will be measured on the same fixtures so all three are comparable.

D5 — MCP transport hardening → world-class MCP controller/manager

Problem: stdio MCP fragility is a confirmed class-wide client bug (claude-code#43177): HTTP/SSE transports get auto-reconnect on the client side; stdio is explicitly excluded, and the one-line client fix is unmerged. In practice a stdio MCP that hiccups during a long wave stays broken until someone notices. codesearch sidesteps this by running as an HTTP daemon behind launchd; serena now does the same. Scope expanded: transport hardening is the foundation, and the deliverable is a world-class MCP controller/manager (supervision, health, restart, config) that becomes the substrate for cloud-deployed ozzydev ("My Cubicle Cube," a packaged dev-team-in-a-cubicle). Its architecture and data model feed the console D1 datastore (see status callout).

Options
  • (a) Move ChunkHound + Serena to Streamable HTTP behind supervisors — ChunkHound via an mcp-proxy HTTP shim, Serena via its documented --transport streamable-http, both supervised (launchd KeepAlive) the way codesearch already is. Clients pick them up over HTTP on :39725-style local ports.
    Effort: MED (shim + launchd plist per daemon). Recommended. codesearch is the proof this pattern survives real workloads.
  • (b) Wait for the claude-code#43177 client fix to land — The one-line fix restores stdio auto-reconnect at the client. Costs nothing but leaves the workspace exposed until it merges.
    Effort: Zero. Not chosen — indefinite timeline for a known-class bug.
  • (c) Keep stdio, add per-session health probes — Doctor endpoints re-probe MCP daemons every N seconds and surface stale ones. Detects the failure faster; does not prevent it.
    Effort: LOW. Complement, not replacement — worth doing anyway.

Evidence:

Recommendation: Approved with expanded scope. Ship the world-class MCP controller/manager as the foundation for cloud-deployed ozzydev. Its supervision/health/restart/config plane is the substrate every MCP daemon plugs into; codesearch is the reference pattern; serena is done; chunkhound depends on D4.

Decision / Measured result: Approved 2026-07-12 with expanded scope. Serena runs supervised streamable-HTTP on 127.0.0.1:24283 (LaunchAgent com.nexartis.serena-serve); codesearch-serve on 127.0.0.1:39725 is the reference pattern; ChunkHound pending D4. Next deliverable: promote the launchd-behind-HTTP pattern into an explicit MCP controller/manager (supervision, health, restart, config) as the substrate for cloud ozzydev ("My Cubicle Cube"). Codesearch-serve LaunchAgent wedge (listener RSTs ~15s after start while process alive) root-caused 2026-07-16 as fd exhaustion: launchd inherits the macOS 256-fd soft limit and serve needs ~1000 fds for 60 registered repos (LMDB + tantivy FTS + FSEvents per repo; "Too many open files" errno 24 / EMFILE in serve.log is the artifact). Fix: SoftResourceLimits.NumberOfFiles=65536 in the plist (documented launchd key; install.sh scaffolds it and migrates pre-existing plists every run). Verified sustained-healthy under launchd with live MCP handshakes. CORRECTED DIAGNOSIS: the earlier TCC-on-~/Documents hypothesis was a real probe result but not the wedge cause — the RCA is EMFILE; the Full Disk Access grant would not have fixed it. Upstream finding for the controller/manager design: serve should fail LOUD on EMFILE in the accept loop instead of wedging silently.

D6 — voyage-context-4 evaluation

Problem: Voyage shipped voyage-context-4 on 2026-06-29: chunk-context-aware embeddings that ingest surrounding chunks at embedding time ("stop worrying about chunking"). If it holds up on the workspace workload, it could obsolete a chunk of the chunking tuning done for voyage-code-3 + cAST, and possibly reduce the freshness surface area D2 addresses.

Options
  • (a) Benchmark voyage-context-4 vs voyage-code-3 in the A2 harness — Reuse the 100-query gold set. Same rerank-2.5 downstream. Score precision@1/5/10, cold/warm latency, token cost, and any change in coverage stability under churn.
    Effort: LOW (harness already exists as A2). Recommended.
  • (b) Adopt voyage-context-4 as the default — Skip the bench. Faster; premature on a brand refresh.
    Effort: LOW. Rejected — no switching embeddings on brand refresh; see the rejected list.
  • (c) Ignore for now — Revisit after chunkhound PR #339 compaction ships and the current substrate is stable.
    Effort: Zero. Fallback if bench capacity is spent on D7.

Evidence:

Recommendation: Approved as option (b) under the newest-first-evidence-checked principle: adopt voyage-context-4 as the default when the semantic layer returns (post D4). Bench remains scheduled as the evidence check; back off only if benchmarks show voyage-context-4 losing to voyage-code-3 on the workload.

Decision / Measured result: Approved 2026-07-12 as (b) — adopt voyage-context-4 as default when the semantic layer returns per D4. Newest-first, evidence-checked: bench is scheduled once the semantic layer is live; adoption backs off only if numbers say so.

D7 — RL-search subagents benchmark — WarpGrep v2 / Relace FAS vs codesearch group

Problem: The one query class our stack still cannot answer (D1: cross-repo symbol intelligence) is exactly the class the new RL-trained search subagents target. Morph WarpGrep v2 tops SWE-Bench Pro and advertises multi-repo + package + log search; Relace Fast Agentic Search claims 4× faster via parallel tool calls and now ships on OpenRouter. Whether either beats our codesearch group="nexartis" fusion on our own workload is unmeasured.

Options
  • (a) Bench WarpGrep v2, Relace FAS, and codesearch group on identical tasks — Reuse the D1 task set ("who uses this SDK export across the workspace?" + 20 similar). Score turns-to-first-relevant-file, precision, cost, and cross-repo recall.
    Effort: MED (dataset + adapter per engine). RECOMMENDED. Directly informs D1.
  • (b) Adopt one of the RL engines as the default subagent — Ship first, measure later. Reintroduces the "faith over evidence" failure mode.
    Effort: LOW. Rejected.
  • (c) Defer until D1 lands (SCIP or CoreGraph) — If D1 gives us exact cross-repo symbol answers, the RL search question narrows to "faster general search," which is less urgent.
    Effort: Zero. Reasonable if bench capacity is scarce.

Evidence:

Recommendation: Bench WarpGrep v2 and Relace FAS against codesearch group on the D1 task set. Adopt the winner (or stay put) with numbers, not vibes.

Decision / Measured result: — (empty; to be filled when the decision lands or the benchmark result arrives)

D8 — Adopt the write-strategy rubric into AGENTS editing-routing

Problem: The editing-routing table in the workspace AGENTS.md currently lists tools by category (weave / ast-grep / morph / serena / native) but does not route per-task. The new Write Strategies paper introduces a rubric (a–h) mapping each change class to a primary + fallback tool, backed by SWE-Edit (arXiv 2604.26102) evidence that per-task routing is a Pareto win.

Options
  • (a) Adopt the rubric as the routing table — Replace the current category-oriented table in AGENTS.md with the (a)–(h) rubric from /research/write-strategies. Cross-cutting rules (dry_run >3 files, no tool-mixing, git diff after batches) move to the same section.
    Effort: LOW (one AGENTS.md edit + docs cross-link). RECOMMENDED. Directly encodes the SWE-Edit Pareto finding.
  • (b) Adopt rubric as guidance only, keep category table — Cross-link the rubric from AGENTS.md but do not make it authoritative. Softer; risks the "which tool do I pick?" ambiguity persisting.
    Effort: TRIVIAL. Fallback if operator wants to wait for internal Morph-vs-Relace numbers.
  • (c) Reject — Keep the current category-oriented table.
    Effort: Zero. Reintroduces the failure mode the rubric was written to fix (sequential single edits).

Evidence:

Recommendation: (a) Adopt the rubric as the AGENTS editing-routing table.

Decision / Measured result: Approved and landed 2026-07-12 — the (a)–(h) rubric is the Write-strategy rubric block in the workspace AGENTS.md §1 (see /research/write-strategies). Cross-cutting rules (dry_run >3 files, no tool-mixing, git diff after batches) landed in the same section. Full rationale kept on the write-strategies page.

D9 — Commercial evaluation buy-list — Morph / Relace / Codemod

Problem: The write-strategies rubric leans on fast-apply and structural engines whose numbers are all vendor-reported. Two internal benchmarks (Morph-vs-Relace bakeoff; atomic-tool corruption bench) are cheap but not free; running them requires paid tiers of the vendor products.

Options
  • (a) Approve the buy-list and run the eval — Morph Enterprise + WarpGrep Pro, Relace hosted → VPC, Codemod BYOC, enable Anthropic Programmatic Tool Calling (free wherever the harness supports it). Numbers decide which becomes the default; the rest stay as options.
    Effort: MED (procurement + bench dataset build). RECOMMENDED. Programmatic Tool Calling is a free win regardless of the paid tiers.
  • (b) Approve Programmatic Tool Calling only, defer paid tiers — Take the free win now; hold on Morph/Relace/Codemod until the internal benchmarks are budgeted.
    Effort: LOW. Fallback if budget window is not open.
  • (c) Reject — Stay on native edit tools + weave + ast-grep + serena. No commercial engines.
    Effort: Zero. Leaves the fast-apply layer of the write stack empty.

Evidence:

Recommendation: (a) Approve. Enable Programmatic Tool Calling immediately (free); procure Morph/Relace/Codemod tiers scoped to the two internal benchmarks; adopt the winners on numbers.

Decision / Measured result: Approved 2026-07-12 — proceed on Morph + Relace + Codemod + Anthropic Programmatic Tool Calling. Signup / setup path per vendor is in the "Signup and setup links (D9)" section. Every key lands in the console Secrets panel per ADR-006 — never in tracked files, never in shell history.

D10 — Parallel-waves repo architecture — one-per-harness vs single library with engine adapters

Problem: nexartis-opencode-parallel-waves already ships two harness engines (claude-code, opencode) and needs to grow to at least five (add kilo, aider, augment auggie). It is also becoming a KYM developer-program library — a starter template external developers use to orchestrate their own agent workstreams. The architecture question is how the harness diversity is represented: one repo per harness, one library with engine adapters, or a plugin-package model.

Options
  • (a) Single library + engine adapters (RECOMMENDED) — v2 is already engine-adapter-shaped (scripts/engines/base.py). Absorb v1’s claude-code engine into v2 (already done), then add aider + auggie + kilo adapters against the same base. Retire v1. External developers get one install, one CLI, N engines.
    Effort: MED (write three new engine adapters; retire v1; harden the base contract). Best fit for the KYM developer-program library role: one artefact, uniform CLI, engine choice per wave.
  • (b) One repo per harness (current shape at 2) — Scales as 5+ repos with duplicated orchestrator/subagent template code; every improvement to the template has to land N times.
    Effort: HIGH (long-run maintenance). Rejected — obvious duplication debt as N grows past 3.
  • (c) Plugin packages against a core — Core parallel-waves package; each engine is an installable plugin. More ceremony than needed today; option to revisit if external contributors want to ship engines out-of-tree.
    Effort: HIGH. Overengineered for the current handful of engines.

Evidence:

Recommendation: (a) Single library + engine adapters. Use v2 as the base, absorb v1’s claude-code engine, then add aider + auggie + kilo. Retire v1. This is also the shape the KYM bandit workstream (harness-level A/B) needs — one CLI, N engines, receipts and votes as reward signal.

Decision / Measured result: Decided 2026-07-12 — (a) single library + engine adapters. Repo renamed nexartis-opencode-parallel-waves → nexartis-parallel-waves-agent-harness. v1 retires after claude-code parity is confirmed on v2. Two-tier adapter model: native adapters (per-engine) + generic ACP for anything speaking Agent Client Protocol. base.py follows the Terminal-Bench BaseAgent shape; mini-swe-agent is the control arm; the measured-result slot for the bakeoff lives on /research/harness-bandit-experiments.

D11 — KYM vs NANDA boundary — developer loop vs production publication

Problem: Working hypothesis under test: KYM (Know Your Model) is the developer optimization loop where variants are built, run, evaluated, and iterated; NANDA is the production publication layer where winning agents are exposed to the network and discoverable. If the boundary is clean, an end-to-end wizard in ozzydev looks like: select an agent batch → configure variance → publish to KYM → run/analyze → loop → publish winner to our NANDA node. If it is blurred in code, the wizard hits ambiguity and the code architecture needs a refactor.

Options
  • (a) Test the boundary E2E in ozzydev with the wizard workflow (RECOMMENDED) — Build the wizard: agent-batch selector → variance config → publish to KYM → run/analyze loop → publish winner to NANDA (discoverable on the network). Watch where the code resists the split; refactor until KYM = developer loop and NANDA = production publication with no leakage.
    Effort: MED (wizard UI + KYM/NANDA integration in the console). RECOMMENDED. Verifies the hypothesis by building the very product it implies.
  • (b) Documentation-only clarification, no wizard yet — Write the boundary down in canonical docs, defer the E2E test. Faster to publish; misses the code-architecture check that only the wizard build surfaces.
    Effort: LOW. Fallback; loses the empirical signal the wizard produces.

Evidence:

Recommendation: (a) Test the boundary E2E in ozzydev with the wizard workflow. Verify code architecture keeps the KYM/NANDA split clean; refactor if blurred.

Decision / Measured result: — (empty; to be filled when the decision lands or the benchmark result arrives)

D12 — Letta / MemGPT for canonical-doc memory — REVISIT

Problem: We previously rejected Letta as an agent memory system (rejected list below). The real problem it solves, however, is not agent memory — it is managing a large canonical markdown corpus (DRY, organised, searchable, lifecycle). Letta’s Context Repositories is a git-backed document-management framework that may give us document conventions + management primitives we should adopt for the canonical-doc corpus, independent of the rejected agent-system claim.

Options
  • (a) Evaluate Context Repositories for canonical-doc management — Read the Context Repositories spec, prototype a small corpus mapping (docs/, canonical architecture docs, ADRs) onto its conventions, score DRY/organisation/search/lifecycle wins vs our current markdown-in-git baseline.
    Effort: LOW (spec read + small prototype). Done. Verdict: adopt the pattern, not the product.
  • (b) Keep the rejection as-is — Stay on markdown-in-git without the Letta document-management framing.
    Effort: Zero. Rejected — the pattern is a clear win over vanilla markdown-in-git.

Evidence:

Recommendation: Adopt-pattern, not product. Transplant Letta MemFS conventions onto the canonical docs: YAML frontmatter with a MANDATORY description field (agents load-or-skip on it), a system/ folder for always-loaded content, memory-reorganization subagents run via worktrees (maps directly to the assess→refactor→compress loop), and a sleep-time "dream pass" at sprint end. Pilot basic-memory MCP (AGPL) as the query layer over the workspace docs corpus. Skip the full Letta runtime; skip mem0; skip khoj.

Decision / Measured result: Decided 2026-07-12. Adopt-pattern + pilot basic-memory MCP. Conventions to land: YAML frontmatter with mandatory description field; system/ folder for always-loaded content; memory-reorganization subagents via worktrees (assess→refactor→compress); sprint-end "dream pass". Full Letta runtime, mem0, and khoj skipped.

D13 — SCIP-in-CI + CoreGraph rubric — call-routing between exact and syntactic symbol layers

Problem: D1 (cross-repo symbol intelligence) had (a) SCIP-in-CI and (b) CoreGraph as competing options. The current direction: adopt SCIP as a package.json build step (freshness comes free with the existing build-before-commit gate — an instance of the general "index refresh as build step" pattern for any tool that supports it) AND pilot CoreGraph as an MCP. The open question is the call-routing rubric between them: which query class goes to SCIP (exact, type-precise, per-package), which to CoreGraph (syntactic, cross-repo traversal), and how agents pick.

Options
  • (a) Route on precision requirement + capability (RECOMMENDED) — Codified rubric across all four symbol/text layers: typed exact cross-repo refs & impact → SCIP (via dora, per-repo); live-edit navigation + zero-setup + config/YAML cross-language edges → CoreGraph (workspace-wide daemon); single-repo symbol ops → serena; text / regex → codesearch.
    Effort: LOW (routing-table edit + dora install + scip-typescript wire-up as a package.json build step). Adopted. Uses each engine on its strength; the four are complementary, not competing.
  • (b) Default to SCIP, fall back to CoreGraph on miss — Simple rule at the cost of taking the SCIP round-trip on queries CoreGraph would have answered directly.
    Effort: LOW. Rejected — simpler, but slower on the concept-search and config-edge classes.

Evidence:

Recommendation: Adopt both. CoreGraph as the workspace-wide daemon (polyglot stack-graphs, zero-setup, live, cross-language config edges) plus dora per-repo (SCIP → SQLite → MCP), fed by scip-typescript as a package.json build step so freshness is free from the build-before-commit gate. Routing rubric: typed exact cross-repo refs / impact → SCIP (dora); live-edit nav + zero-setup + config / YAML cross-language → CoreGraph; single-repo symbol ops → serena; text / regex → codesearch. scip-query (PlunderStruck) is documented as an alternate SCIP query layer.

Decision / Measured result: Decided 2026-07-12. Both engines adopted with the routing rubric above; scip-typescript wired as a package.json build step per the general "index refresh as build step" pattern; scip-query held as an alternate query layer.

D14 — Ozzydev document workbench — canonical-doc lifecycle UX

Problem: Ozzydev’s next phase treats document editing / viewing / exporting as a core function: canonical docs, ADRs, and roadmap artefacts need a first-class read, approve, and export lifecycle inside the console. The research question is which 2026 packages give us the best rich-markdown reading UX AND beautiful PDF export — because the document corpus is a product surface, not a side effect of writing code.

Options
  • (a) Reading UX: mdsvex + @mistweaverco/mdsvex-shiki + remark-toc + rehype-slug + mermaid + pagefind — SvelteKit-native. mdsvex compiles markdown-in-svelte; @mistweaverco/mdsvex-shiki gives Shiki syntax highlighting; remark-toc + rehype-slug yield linkable headings + auto TOC; mermaid renders diagrams inline; pagefind builds a static full-text index for the docs surface.
    Effort: LOW–MED. Adopted — reading UX stack.
  • (b) PDF export: Pandoc → Typst pipeline, with a Playwright page.pdf() escape hatch — Pandoc converts markdown to Typst; a single nexartis-brand.typ template renders it to PDF in 5–30 ms per doc, deterministically, with no Chromium in the loop. Playwright page.pdf() stays available as the exact-render escape hatch for docs that must match the console's browser rendering byte-for-byte.
    Effort: MED (template + build pipeline). Adopted — PDF export pipeline.
  • (c) paged.js / WeasyPrint / LaTeX — The other publish-to-PDF stacks considered. paged.js still runs Chromium; WeasyPrint is CSS-first but slow at scale; LaTeX is heavy and off-brand for markdown-native authoring.
    Effort: N/A. Rejected.
  • (d) Ship a plain markdown view + a PDF export via a print stylesheet — Cheapest; acceptable if the doc corpus stays small. Loses the "canonical docs are a product surface" ambition.
    Effort: TRIVIAL. Rejected — undersells the artefact.

Evidence:

Recommendation: Reading UX = mdsvex + @mistweaverco/mdsvex-shiki + remark-toc + rehype-slug + mermaid + pagefind. PDF export = Pandoc → Typst pipeline (5–30 ms per doc, deterministic, no Chromium; one nexartis-brand.typ template) with Playwright page.pdf() as the exact-render escape hatch. Skip paged.js, WeasyPrint, and LaTeX.

Decision / Measured result: Decided 2026-07-12. Reading UX and PDF pipeline as above; nexartis-brand.typ is the single Typst template; Playwright page.pdf() reserved for the exact-render escape hatch.

D15 — Multi-orchestrator file coordination — worktree overlap detection

Problem: Parallel implementation waves run multiple orchestrators against overlapping repos in git worktrees. Silent cross-worktree edits to the same files produce merge grief that surfaces late (at the wave PR) instead of at dispatch time. The research question is which coordination primitive prevents the collision without introducing OT/CRDT complexity we do not need.

Options
  • (a) worktree-mcp (RECOMMENDED) — File-overlap detection between worktrees, conflict preview, delegates to gwtm and git-status for the underlying worktree/status queries. Minimal surface area; MCP-native; fits the parallel-waves dispatcher directly.
    Effort: LOW. Adopted.
  • (b) coordinationhub — Heavier coordination layer; development currently paused upstream.
    Effort: MED. Rejected — dev paused.
  • (c) worktree-mcp-manager — Full 62-tool worktree management surface. Over-scoped for the current need (overlap detection).
    Effort: MED–HIGH. Rejected — scope mismatch.
  • (d) OT / CRDT-based coordination — Real-time collaborative-editing primitives. Overkill for wave-scale coordination where merges happen at PR boundaries.
    Effort: HIGH. Rejected — wrong tool for the problem class.

Evidence:

Recommendation: Adopt worktree-mcp. Add to the parallel-waves dispatcher so overlap is caught at dispatch, not at PR merge. Heavier options (coordinationhub — dev paused; worktree-mcp-manager — 62 tools) documented as rejected. Skip OT / CRDT.

Decision / Measured result: Decided 2026-07-12. Adopt worktree-mcp; land wire-up in the parallel-waves dispatcher; heavier alternatives rejected as noted.

D16 — nexartis-agent-scripts library — a curated skill monorepo

Problem: AGENTS §1 grants agents permission to write and execute scripts, but nothing curates them. Ad-hoc scripts evaporate at session end; the Voyager / CodeAct / Anthropic-PTC literature all point at a curated library as the compounding surface.

Options
  • (a) nexartis-agent-scripts monorepo (ADOPTED) — pnpm monorepo under _NEXARTIS-SDKs/nexartis-agent-scripts/. One skill per package (SKILL.md + scripts/ + test/ + references/). Extended frontmatter (runtime-portability, verify, receipts). ChunkHound-indexed frontmatter for progressive-disclosure discovery. 5-step publish gate: tsc · vitest · publint · attw · wintertc-check (ast-grep) · tri-runtime smoke (Node + Miniflare + JSDOM). scripts:sync mirror to ~/.config/kilo/skills/.
    Effort: MED. Adopted (round 4).
  • (b) Status quo (one-off scripts) — Agents keep authoring scripts inline; nothing persists across sessions. No publish gate; no portability contract; no discovery.
    Effort: Zero. Rejected — the literature is unambiguous.

Evidence:

Recommendation: Adopt nexartis-agent-scripts as architected in /research/scripts-as-tools. First 5–10 skills mirror the routing rubrics already codified (search-fanout, write-patch-batch, verify-typecheck-then-test).

Decision / Measured result: Decided 2026-07-12. Adopt; architecture per /research/scripts-as-tools; the next revision lands first published skills + publish gate.

D17 — ozzydev-native-write-mcp — experiment program (approved direction)

Problem: The write-strategy rubric (D8) codifies routing between native edit / weave-patch / morph / ast-grep / serena, but there is no MCP that multiplexes writes across parallel worktrees and pairs each with a verify step to run the sprints of pure write experiments we need to tune the rubric.

Options
  • (a) ozzydev-native-write-mcp (APPROVED DIRECTION) — Multiplexed write + verify across parallel worktrees. Experiment mode: the orchestrator runs sprints of pure write experiments measuring latency + accuracy against the rubric categories (a)–(h). Builds on worktree-mcp (D15) + sub-second sandboxes (Cloudflare Code Mode). Design pending.
    Effort: HIGH. APPROVED DIRECTION (round 4).
  • (b) Manual per-repo write experiments — Continue tuning the rubric by hand from sprint-end retrospectives. Works, but scales linearly with operator attention.
    Effort: LOW. Rejected — does not scale.

Evidence:

Recommendation: Approved direction; ship the write executor and pair it with the search executor under the same native-MCP program. The experimental framework (/research/experimental-framework) is the umbrella; core-workflow rule stands: experiments run out of band from user-visible work.

Decision / Measured result: Approved 2026-07-12; SHIPPED. Both native MCPs — ozzydev-write and ozzydev-search — are enabled in the workspace kilo.json and production-dogfooded (search MCP canonical spec: ADR-007). Experiments framed by /research/experimental-framework.

D18 — Workspace portability + workspace-local context (operator direction)

Problem: The 2026-07-16 workspace move (~/Documents → ~/Developer) required repairing ~160 absolute-path registrations across four machine-global surfaces: workspace kilo.json, ~/.codesearch/repos.json, ~/.serena/serena_config.yml, and the console D1 workspaces table. Operator direction: workspaces are periodically abandoned for clean restarts and moved at will, so the dev environment must survive relocation; it would be cleaner if all of a workspace’s context sat inside the workspace itself rather than in machine-global registries that track every workspace ever created.

Options
  • (a) Path-agnostic where guarded, absolute where load-bearing (SHIPPED) — kilo.json spawns for the native MCPs resolve via $PWD with a loud test -f guard (Kilo spawns local MCPs with the workspace as CWD — a wrong CWD fails with a classified message, never silently). chunkhound paths stay ABSOLUTE per the runaway-DB safety rule (relative resolves against process CWD). Global registries get repaired by re-running install.sh after a move.
    Effort: LOW. Shipped 2026-07-16 in install.sh scaffolds. The floor, not the ceiling.
  • (b) Workspace-local registries (APPROVED DIRECTION) — Each workspace carries its own codesearch registry (codesearch supports CODESEARCH_REPOS_CONFIG to point repos.json anywhere, e.g. <workspace>/.codesearch/repos.json) and serve instance scoped to that workspace’s repos only; serena projects are already per-repo (.serena/project.yml in-repo). A moved or archived workspace then carries or retires its own context with zero machine-global cleanup. Fits the MCP controller/manager (D5) as the supervisor of per-workspace daemons.
    Effort: MED (install.sh + controller design; port allocation per workspace). APPROVED DIRECTION (operator, 2026-07-16). Design rides the D5 controller/manager deliverable.
  • (c) Relocation self-healing only — Lean on codesearch’s built-in relocation detection (CODESEARCH_RELOCATE_MAX_DEPTH) and re-registration scripts. Heals moves but machine-global registries still accrete dead workspaces.
    Effort: LOW. Complement — does not deliver workspace-local context.

Evidence:

Recommendation: Adopt (a) now (shipped), design (b) into the D5 controller/manager: one supervised serve per workspace, workspace-local repos.json via CODESEARCH_REPOS_CONFIG, per-workspace port allocation, and a workspace manifest the console registers/retires atomically. A workspace becomes a self-contained, movable unit of context.

Decision / Measured result: (a) shipped 2026-07-16 (install.sh kilo.json scaffold + fd-limit plist migration; move executed and verified: 592-test validate green, live adapter smokes green, D1 workspace row re-registered, zero stale path refs). (b) approved direction — design pending with D5.

D19 — Augment Context Engine: adopt as a retrieval arm, or benchmark-only?

Problem: Augment's Context Engine is plausibly best-in-class at code retrieval, and Augment's own thesis is that downstream code-writing quality is downstream of retrieval quality. We have never measured it against our local stack (codesearch / serena / chunkhound / claude-context+Zilliz). Operator has approved indexing all workspace repos on Augment's tenant, so the measurement is now unblocked. Supersedes D4 option (e)'s original rejection rationale — public API and SDK now exist; the blocker is the supported output shape, not access.

Options
  • (a) Benchmark-only — Stand up a standalone retrieval arm on our BEIR-style fixtures, publish numbers, adopt nothing yet.
    Effort: MED. RECOMMENDED — gates any adoption on measured numbers, not vendor thesis.
  • (b) Adopt as a semantic-slot expert in the ADR-007 router — Replace or supplement claude-context+Zilliz with an Augment arm. Blocked on the supported output-shape problem (string-only `search()`; only the undocumented `agents/codebase-retrieval-raw` endpoint returns `chunks[…]` with per-item score) and on a hard dependency on a closed server-side index (no self-host, no air-gap, no export).
    Effort: MED–L. Deferred behind (a) until the bakeoff lands numbers.
  • (c) Inverted integration — Do not add Augment to our router; instead let external harnesses (auggie) consume OUR MCPs, and use Augment's engine only through its own harness.
    Effort: LOW. Kept as an option — decouples the two ecosystems and sidesteps the output-shape problem entirely.
  • (d) Reject on architecture — Server-side index, no self-host, no air-gap, no index export, closed embeddings, credit-priced. Incompatible with a local-first stack on principle.
    Effort: None. Kept explicit so the reasoning survives if the bakeoff numbers do not clear a high bar.

Evidence:

Recommendation: (a) benchmark-only first, explicitly gated on the retrieval bakeoff landing numbers. Revisit (b) only if Augment measurably beats our fused router by a margin that survives the hazards documented on /research/moe-search-router. No vendor retrieval-only IR numbers exist — their published lift is a downstream PR-quality benchmark (900 attempts, five subjective dimensions, vendor-run, unreplicated). Our own honest baseline to compare against: selection micro-F1 0.824 / macro 0.861, IR nDCG@10 0.821, MRR@10 0.857, Recall@10 0.830 on n=36 scored queries. Local MCP variant gives index parity by construction (real-time working-tree index); remote gives default-branch only. Arm design lives on /research/moe-search-router — cross-reference, do not duplicate. Supersedes D4 option (e)'s rejection rationale; D4's own semantic-layer bakeoff (chunkhound vs claude-context+Zilliz, fixtures v1.4.0) still has an empty result slot — measure the Augment arm on the same fixtures so all three are comparable. AMENDMENT 2026-07-31: gating condition RESOLVED with numbers. The bakeoff ran (Phase-1 pilot s13 + Phase-2 calibration batch calibration-20x3, prereg lock 4f3cce5, sonnet4.5 pinned); the Phase-2 de-saturation gate FAILED (three of four pre-stated criteria fail — all arms 100% resolve, per-task composites byte-identical across arms with 0.0 pp arm spread and sd 0.1646 identical; only criterion 4 at 8/20 divergent-output tasks hit threshold). Operator ruling: accept parity as the headline finding; Phase-2 full-n (~302–430 kcr) CANCELLED. No adoption trigger fired. See result field.

Decision / Measured result: MEASURED 2026-07-31 — parity. Calibration batch calibration-20x3 (20 hard-stratum tasks × 3 arms × 1 seed, sonnet4.5, prereg lock 4f3cce5): 60 runs, 13,675 cr, zero crashes. Retrieval stack does not change resolve/composite under sonnet4.5 on this deck at pilot+calibration scale (~56 kcr total spend); Phase-2 full-n cancelled. Exploratory (non-registered) cost signal: retrieval arms ~27% cheaper than arm-a (a=277 / b=202 / c=205 cr/run mean). Decision outcome: neither (a) adopt nor (b) adopt-as-router-arm fires — Augment Context Engine is NOT adopted as a retrieval arm on this deck under this model. Option (c) inverted integration remains available; option (d) reject-on-architecture is unchanged by parity. Evidence: nexartis-auggie-harness/probes/bakeoff/analysis/calibration-20x3/CALIBRATION-RESULT.md @ commit bb8b333 (+ ruling 8cc56b7).

D20 — Index staleness semantics: HEAD-pointer vs content-aware?

Problem: Two+ workspaces on one machine hold the SAME feature branch concurrently (ADR-014 era). Every commit from the peer workspace advanced HEAD and fired `expert_index_stale` in this workspace — even when the delta touched zero indexed content (measured: a one-line `.codesearchignore` commit false-dirtied a whole repo mid-session). On a shared branch the HEAD-pointer check forces constant reindexing of indexes whose content is still correct. Companion finding from the same probes: the hint-store GET cost 1.3–5.4 s per search (remote D1 round trips), often exceeding expert fan-out.

Options
  • (a) Diff-filter downgrade + auto-stamp — On head-mismatch with matching branch: `git diff --name-only indexed..HEAD`, filter ignored/unindexable paths; zero indexable delta ⇒ content-fresh — proceed, re-stamp the sidecar, mark the receipt (`content_fresh_verified`). Branch mismatch stays strict; git failure stays loud; computeFreshness stays pure (downgrade lives in the expert seam).
    Effort: MED. RECOMMENDED — matches the actual freshness question ("is the corpus content current?"), kills the churn, keeps every downgrade receipt-visible (§2 no hidden behavior).
  • (b) Tree-hash compare — Store indexed tree hash, compare at query time. Simpler, but git trees include ignored files — a `.codesearchignore` edit still false-dirties.
    Effort: MED. Less precise than (a) for the exact hazard that motivated this.
  • (c) Keep HEAD-strict — Status quo — every commit dirties; operators reindex constantly on shared branches.
    Effort: None. Untenable once two workspaces share a branch as the normal case.

Evidence:

Recommendation: (a) as ruled by the operator 2026-08-01 (option-picker Q1). Also shipped in the same ruling: hint-store in-process TTL memo (`hintCacheTtlMs`, default 300 s, 0 disables; errors never cached; config_version in the key self-invalidates on bump) and the repo-inventory schema (migration 0006: `repos` + `workspace_repos` + `GET /api/repos/inventory/cross` — one-PR-per-repo visibility across workspaces).

Decision / Measured result: DECIDED + SHIPPED 2026-08-01 — content-aware downgrade live in the codesearch expert (23 new tests; live smoke: aged sidecar → clean 31-item search with zero expert errors → sidecar auto-restamped to live HEAD at call time); hint memo live (10 new tests, hit <50 ms vs miss >80 ms at the seam); 0006 applied to shared D1 and cross endpoint verified returning TWO workspaces' checkouts of nexartis-ozzydev on the same branch. `expert_index_stale` now means real content staleness. Root validate EXIT 0 (console 417, search-mcp 349+2skip).

Signup and setup links (D9)

Vendor-by-vendor onboarding paths for the D9-approved buy-list. Reminder: every key lands in the console Secrets panel per ADR-006 — never in tracked files, never in shell history.

  • Morph — Pricing + plan selection at morphllm.com/pricing. Team creation + API key at the Morph dashboard. Enterprise contact via the calendar link on the site. WarpGrep Pro is under the same dashboard.
  • Relace — Sign up at relace.ai (Get Started → app.relace.ai), create a team + API key. Also available via OpenRouter as relace/relace-apply-3 for OpenAI-compatible clients.
  • Codemod — BYOC / enterprise onboarding via contact / demo form at codemod.com. OSS MCP is free per docs.codemod.com/model-context-protocol.
  • Anthropic Programmatic Tool Calling — Free. Enable in the harness config wherever the harness supports it. No signup; no key. Reference the advanced-tool-use engineering post for the enablement flag.
  • Zilliz Cloud (claude-context primary — D4) — Create an organization at cloud.zilliz.com, provision a serverless cluster in the closest region, mint an API key, and paste it into the console Secrets panel (/system → API Keys). The key is verified live and applied into the workspace claude-context config; the vector store lives in Zilliz, not on the developer machine.
  • zilliztech/claude-context (semantic-layer MCP — D4) — Install the MCP server via `npm i -g @zilliz/claude-context-mcp` (or clone zilliztech/claude-context and follow the repo README for the source-install path). The workspace kilo.json entry points at the local MCP; the Zilliz API key wires in from the Secrets panel — never in tracked files.
  • Sourcebot (semantic-layer fallback — D4) — Follow docs.sourcebot.dev to deploy Sourcebot locally (docker compose is the shipped path). Point it at the workspace repos and register the MCP endpoint in kilo.json. Sourcebot is the durable fallback when Zilliz is offline or credentials are unavailable.

Rejected — with evidence

These options came up in the survey and were ruled out. The point of naming them here is so the reasoning survives the moment: when a new voice re-proposes any of them, this section is the answer.

  • Full GraphRAG pipeline (offline KG build + graph-only retrieval) — RAGSearch (arXiv 2604.09666) shows agentic search over strong hybrid retrieval closes most of the gap that motivates a full GraphRAG build. Offline graph cost fits stable corpora; our PR-wave velocity produces continuous churn. High cost, low delta on our workload class.
  • Unified 46-repo embedding space for codesearch — BM25 statistics are per-corpus by definition; merging all repos into one lexical index blurs the signal. No published evidence that a unified space beats per-repo + RRF on cross-repo retrieval; SembleX validates the per-repo + fusion architecture independently.
  • Pre-emptive voyage-code-3 switch — voyage-4-large is Voyage's general flagship, but they ship no voyage-code-4. No head-to-head shows a dominator on our workload class. Bench first (A2); do not switch on brand refresh.
  • Adopting Letta / MemGPT as a memory system — Markdown-memories-in-git — the pattern Serena, Claude Code, and Letta all converged on, and what we already run — is the only approach with durability evidence for engineering work. Sleep-time consolidation has no external benchmark. Borrow the defrag idea when we need it; do not port the framework.

How this page works

Living decision log. When an adopt-now item ships, it moves out of A1–A6 and into a measurement row with the KPI delta. When an open decision lands, the recommendation is archived and the result slot records the actual call plus the numbers that justified it. When new benchmarks or SOTA papers arrive, they land in the sources list and any decision they affect is reopened in place. The version at the top bumps on every material change.