Sprint 20 closed: tools that answer questions, and traces that prove they do

Until this sprint, Meronq's product tools introduced themselves the way connectors do: by naming the system they talk to. github_sync, memory_search, project_build. Accurate labels — and the wrong unit for a host assistant that is trying to finish a job.

Sprint 20 flips the surface to the question each tool answers, leaves a trace on every call, and finally writes into the two CEM layers that Sprint 19 left empty on purpose.

Tools by intent

Product tool descriptions in @meronq/mcp-core are now questions. Handshake next_steps name the tool to call next, not a vague suggestion. The ListTools payload grew — 12245 → 13285 bytes — because question-form copy is longer; consolidation stays deferred. ADR-0018 prices that trade explicitly: we measured before and after instead of guessing.

memory_search gained a layer filter so the closed axis from ADR-0019 is reachable from chat, not only from the Temperature Map chips.

The empty layers get writers

project_build and project_test used to throw their outcomes away. They now persist bounded CEM entities:

Tool Entity Layer
project_build build_result artifact
project_test test_run validation

Retention is the latest ten of each kind. Results survive CEM rebuild via extractRuntimeCem, and they are excluded from the archive sweep so a green build does not vanish because nothing touched it for a week.

Instrumentation that can prove it

Every product tool records an access event when a project is resolvable — not only handshake and memory_search. The MCP initialize clientInfo (name + version) is threaded into that context, so later focus-steering work can answer which assistant asked without inventing a side channel.

Scripts under scripts/ capture the cheap metrics this sprint owns: tool-list bytes and accessor / query histograms from the local memory DB.

Init and cold Connect

Two Desktop paths were lying by omission:

  • Initialize an empty folder now seeds docs/roadmap.md (Sprint 0), docs/product/vision.md, and an ADR stub, then scan/syncs so Tasks and the map show a sprint immediately — template CEM until Sprint 21 embeddings.
  • Cold Connect — a repo that already has docs but no .meronq store — materializes .meronq/local via ensureLocalStore and scan/syncs without inventing docs into a foreign tree. Connecting without a roadmap still creates the store and does not invent a sprint.

Dogfood in a throwaway subfolder covered Initialize, cold Connect, and the negative case; the folder was deleted after green.

Scanner fixes on the same train

Duplicate sprint numbers collapsing into one sprint:{n} entity, and conflicting dependency ranges silently keeping the first while declaredIn listed both, landed on main as #44 (sprintKeys, ranges / rangeByManifest). They ship with this sprint's closure story because they unblock honest intent and resource graphs.

Review notes

Code review on 9f63d3c (architecture focus): no medium+ defects blocking ship. Intentional double-counting remains for handshake / memory_search (richer in-handler rows plus the new tool-level row with client attribution). Tool-list bytes moved the wrong way for "cheaper context" — measured and accepted until a consolidation sprint. Focus steering stays out of scope until these access numbers exist in the wild.

Still open

Sprint 21 takes semantic retrieval (ADR-0020): keyword-first memory_search with a bundled embedding fallback for bilingual miss cases. Focus steering waits on real per-client access histograms from this sprint's substrate.

Principle

Name the question, leave a trace, and fill the layers you claimed were empty — then measure whether the surface got cheaper or just clearer.

← Back to blog