From 0f27b1251778349692d0e350f68c1e4734b559e0 Mon Sep 17 00:00:00 2001 From: TheCryptoDonkey Date: Wed, 23 Sep 2026 01:36:35 +0100 Subject: [PATCH] fix: clamp packet ranges and make handoff metadata optional in repository_packet Retrieval measured from 98 recorded cells without model calls shows every arm usually retrieves the required evidence; the Context arm's friction is tool errors (one call in five on DeepSeek). Most were whole-file reads with a guessed endLine and placeholder packet metadata. --- docs/WORKER-PACKETS.md | 7 +- .../retrieval-recall-20260923/RESULTS.md | 85 +++++++++++++++++++ .../retrieval-recall-20260923/analyse.mjs | 81 ++++++++++++++++++ .../src/repository-navigation-mcp.ts | 22 +++-- .../src/repository-packet-mcp.test.ts | 44 +++++++++- packages/context-tools/src/source-packet.mjs | 17 ++-- 6 files changed, 236 insertions(+), 20 deletions(-) create mode 100644 docs/experiments/retrieval-recall-20260923/RESULTS.md create mode 100644 docs/experiments/retrieval-recall-20260923/analyse.mjs diff --git a/docs/WORKER-PACKETS.md b/docs/WORKER-PACKETS.md index 8aeb5dd..942edcb 100644 --- a/docs/WORKER-PACKETS.md +++ b/docs/WORKER-PACKETS.md @@ -57,7 +57,12 @@ then call `repository_refresh` and retain its `generation`. Replace the example paths and anchors with located evidence. Use `mode: "build"` and `{path, startLine, endLine}` source entries for reviewed exact ranges, -including languages without syntax planning. The server accepts an inline spec; +including languages without syntax planning. Through MCP only `sources` is +required: omitted handoff metadata gets a neutral task and acceptance check, and +an `endLine` past the end of a file reads to its last line (the packet records +the range actually read). A range starting past the end is still rejected with +the file's line count. A plan anchor outside every supported block is rejected +with a pointer to `mode: "build"`. The CLI keeps the strict spec. The server accepts an inline spec; it cannot accept a different root, spec-file path, output path or shell command. The configured root must be a Git repository with a committed HEAD. Internal `git rev-parse` calls read provenance; the tool does not execute acceptance checks. diff --git a/docs/experiments/retrieval-recall-20260923/RESULTS.md b/docs/experiments/retrieval-recall-20260923/RESULTS.md new file mode 100644 index 0000000..bd96610 --- /dev/null +++ b/docs/experiments/retrieval-recall-20260923/RESULTS.md @@ -0,0 +1,85 @@ +# Retrieval measured from recorded transcripts + +No model calls. `analyse.mjs` reads the executor streams already recorded for +the v1, v2, S5, v3 coverage, Flash smoke and aborted Pro runs (98 cells; the +evidence stays private) and measures retrieval directly instead of through the +reviewer: + +- **recall**: the share of each task's `requiredEvidence` tokens + (`../d5-20260921/acceptance/`) that appear in any tool result. The Context + tools print `local-source-unsigned` in their own metadata, so that token is + excluded; counting it would credit the Context arm for reading its own + status output. +- **bytes to full recall**: cumulative tool-result bytes when the last required + token first appeared. +- **tool errors**: tool results flagged as errors. + +## Retrieval is not what fails the structured tasks + +Structured tasks only (code-change tasks have no required evidence), all runs +pooled: + +| Arm | Cells | Mean recall | Full recall | Accepted with full recall | Accepted without | +| --- | ---: | ---: | ---: | ---: | ---: | +| plain | 23 | 0.90 | 16 | 4 of 16 | 1 of 7 | +| graphify | 23 | 0.96 | 20 | 4 of 20 | 0 of 3 | +| context | 29 | 0.92 | 23 | 6 of 23 | 1 of 6 | + +Every arm usually retrieves everything the rubric needs, and three quarters of +full-recall answers are still rejected. On these tasks acceptance measures +synthesis and rubric fit; a retrieval tool can only show up as cost. The most +common miss in every arm is one test title in orientation-context +(`successfully used cursor is consumed`). Per task, Graphify and Context reach +full recall with fewer bytes than plain on the orientation tasks (median 63 to +70 KB against 97 KB on orientation-context) but not consistently elsewhere; +with three or four cells per task this is not a measured difference. + +## Tool errors: the Context arm's real friction + +| Run | plain | graphify | context | +| --- | ---: | ---: | ---: | +| v1 | 4 / 203 | 10 / 196 | 9 / 233 | +| v2 | 3 / 116 | 3 / 111 | 7 / 128 | +| S5 (DeepSeek Pro) | 3 / 206 | 4 / 152 | 37 / 179 | +| v3 coverage | | | 10 / 228 | +| Flash smoke | 0 / 60 | 0 / 36 | 8 / 68 | + +(errors / tool results). On DeepSeek the Context arm failed one call in five. +Grouped by message, the Context errors were: + +- `line range exceeds source length`: 31. Models ask for a whole file with a + guessed `endLine`. +- empty or placeholder packet metadata rejected by the schema + (`acceptanceChecks` empty, `allowedFiles` empty strings): 10, plus many + accepted calls padded with `"a"` or `"ok"`. +- `repository packet already in progress`: 10 (fixed in #26, calls now queue). +- `no supported syntax block contains :`: 7, mostly plan anchors on + imports. +- one-identifier search terms rejecting literals: 5 (fixed in #26), and one + literal passed to `repository_explore`. +- a coverage draft naming more than eight symbols: 1 (fixed in #26). +- harness permission prompts in v1: 3 (not the tool). +- stale navigation after the model's own edits: 3 (correct behaviour). + +## Changes made from this + +In `repository_packet` through MCP only (the CLI spec stays strict): + +- an `endLine` past the end of a file reads to its last line, and the packet's + `originalSpec` records the range read, so `verifyPacket` still rebuilds it + exactly; a range that starts past the end is still rejected; +- only `sources` is required; omitted or blank handoff metadata gets a neutral + task and acceptance check; +- a plan anchor outside every supported block now says to request an exact + range with `mode: "build"`. + +Together with #26 these remove 57 of the 71 recorded Context errors and +redirect 7 more; the rest are harness prompts, stale navigation and one +misused tool. +The served tool listing fell to 5,550 bytes. + +## What this does not show + +Recall is token presence in tool output, not understanding; a token can appear +in a search listing without the model reading its context. Runs differ in +model, build and rubric, so cells are pooled only for this model-free measure. diff --git a/docs/experiments/retrieval-recall-20260923/analyse.mjs b/docs/experiments/retrieval-recall-20260923/analyse.mjs new file mode 100644 index 0000000..fda70d6 --- /dev/null +++ b/docs/experiments/retrieval-recall-20260923/analyse.mjs @@ -0,0 +1,81 @@ +// Model-free retrieval measures from recorded executor streams. +// Usage: node analyse.mjs