Skip to content

Commit 981a74f

Browse files
jgravelleclaude
andcommitted
release: v1.108.138 — confidence provenance: every number states its basis
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 64a9ca9 commit 981a74f

12 files changed

Lines changed: 539 additions & 9 deletions

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,35 @@
22

33
All notable changes to jcodemunch-mcp are documented here.
44

5+
## [1.108.138] - 2026-07-18 - confidence provenance: every number states its basis
6+
7+
### Added
8+
- **Confidence provenance registry** (`retrieval/provenance.py`). Every
9+
confidence constant the suite emits now traces to a stated basis:
10+
`measured` — backed by a committed, reproducible benchmark artifact
11+
(`benchmarks/provenance/measured.json`: the tiktoken token-reduction
12+
methodology and the CI-gated replay retrieval-quality golden) — or
13+
`declared` — an engineering prior, honestly labeled as exactly that. The
14+
contract's load-bearing rule: **a prior is never presented as a
15+
measurement.** A `declared` value graduates to `measured` only when a
16+
gold-labeled corpus backs it, and `tests/test_provenance.py` fails the
17+
build otherwise. Drift guards run in three directions: registry values
18+
must equal the live constants in the emitting modules, registry `measured`
19+
entries must equal the committed artifact, and the artifact must equal the
20+
underlying benchmark results it cites (replay golden, methodology doc) —
21+
no number can silently diverge from its receipt.
22+
- **`find_implementations` responses carry `_meta.confidence_provenance`** —
23+
the per-channel basis for its resolution-confidence tiers (LSP/SCIP/AST/
24+
duck-typed/decorator), so a caller can see that today's tiers are declared
25+
priors, not measurements dressed up as ones.
26+
- **Published response JSON Schemas** in `schemas/`:
27+
`retrieval-verdict.schema.json` (the unified `_meta.verdict` contract),
28+
`confidence-provenance.schema.json`, and
29+
`ranked-context-response.schema.json` (the full `get_ranked_context` JSON
30+
surface, including `match_channel`/`_meta.query_shape` from v1.108.137).
31+
CI validates live responses against them; external pipelines and agents
32+
can do the same.
33+
534
## [1.108.137] - 2026-07-18 - source-shaped exact seeding in ranked context
635

736
### Added

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# jcodemunch-mcp — Project Brief
22

33
## Current State
4+
- **Version:** 1.108.138 — **Confidence provenance, Phase A of the self-attesting retrieval contract (F-15 #1 from the 2026-07-18 sweep; competitor unnamed in shipped artifacts).** New `retrieval/provenance.py`: `CONFIDENCE_PROVENANCE` registry — every confidence constant carries `basis` ∈ {`declared` (engineering prior, honestly labeled), `measured` (backed by committed artifact `benchmarks/provenance/measured.json`)}. Load-bearing rule: **a prior is NEVER presented as a measurement** — Phase B/C (graduating find_implementations tiers to measured) requires building a gold corpus FIRST (Loc-Bench feeds this); jjg accepted this phased order after my reservations (measurement-validity, fixture-decay drift-guard policy, jMRI-obligation optics). Registry entries: find_implementations 5 channels (all declared), negative_evidence_threshold 0.5, exact_seed_verdict_floor 1.0. `MEASURED` = the two artifacts jcm actually has: token_reduction 99.6%/15 runs/cl100k_base (METHODOLOGY.md) + replay retrieval quality (self_v1_75_0 golden, ndcg/mrr/recall 1.0, CI-gated). ⚠ The 0.992/0.895 Hit@10/MRR figure floated during the sweep is OCTOCODE'S benchmark (versus.php grid cell), NOT ours — never cite it as jcm's. `find_implementations` attaches `_meta.confidence_provenance` (via `channel_provenance()`). Published JSON Schemas in `schemas/` (retrieval-verdict, confidence-provenance, ranked-context-response); `tests/test_provenance.py` (14) drift-guards registry↔code↔artifact↔underlying-benchmark in all directions + jsonschema-validates live responses. README gains "Confidence provenance" subsection. NO new tool / INDEX_VERSION / schema-budget change (JSON-only `_meta` addition; no custom encoder for find_implementations so compact path unaffected). **Phase B next: surface measured munch-bench/methodology numbers as in-band provenance; Phase C: gold corpus per channel; jMRI normative section LAST (SHOULD-with-conformance-path, after suite parity is demonstrable).**
45
- **Version:** 1.108.137 — **Source-shaped exact seeding in `get_ranked_context` (clean-room F-15; competitor unnamed in shipped artifacts).** New `retrieval/query_shape.py` classifies query tokens into identifier shapes (qualified `A::B`/`a.b` w/ file-extension-tail exclusion, CamelCase, snake_case, dunders; ≤3 tokens, prose never matches); the DEFAULT ranking path resolves each shaped token via a cached `name_map` (built beside the BM25 corpus) to exact-name symbols (case-sensitive→insensitive; qualified parent narrows via id/parent substring; PageRank ranks ties; include_kinds/scope honored; caps 3/token, 5/query) and PINS them ahead of the ranked tail (`_exact_seed_symbols` + pinning block after `scored.sort`). Items carry `match_channel:"exact_name"`; `_meta.query_shape={source_shaped,exact_seeded}`; verdict best_score floored at 1.0 (raw-BM25 scale vs 0.5 threshold) when seeded, and a seeded result bypasses the negative-evidence early return (`if not raw_scores and not seeded`). **Pure-prose queries byte-identical; `fusion=True` path unchanged (its WRR identity channel already covers exact).** Motivation: the exact-lookup lane is our one measured weak spot (definition MRR 0.70 vs 0.87 in the fair rerun). ALSO: (1) **`openWorldHint` on every tool** — new `_OPEN_WORLD_TOOLS` frozenset (index_repo, index_folder/index_file/summarize_repo [cloud summarizer opt-in], embed_repo/check_embedding_drift/test_summarizer, order/route front door) annotated True, everything else False, in `_apply_readonly_annotations`; machine-checkable no-network claim beside readOnlyHint. (2) **`PRAGMA journal_size_limit=64MB`** in sqlite_store `_PRAGMAS` + embedding_store + parse_cache (WAL starvation under long-lived readers — a failure class three ecosystem peers patched the same month). New `tests/test_v1_108_137.py` (19). NO INDEX_VERSION / tool-count / schema change. Origin: 2026-07-18 top-15 competitor sweep (memory `project_competitor_sweep_2026_07_18`); F-15 #1 (measured-provenance receipts / self-attesting contract) NOT started.
56
- **Version:** 1.108.136 — **The savings meter records a per-day rollup (`daily` map in `_savings.json`).** The lifetime meter is the authoritative savings record but stored ONE number, so windowed views fell back to transcript scans — which on jjg's install prove ~2.2M tokens all-time vs the meter's 34.3B (4 orders of magnitude; jjg on the resulting Console panel: "\$7.73 this month next to \$171K = unhealthy disconnect", "\$0.11 today. Preposterous"). `_flush_locked` (`storage/token_tracker.py`) now also credits each flush batch to `daily[<local-iso-date>]` alongside `total_tokens_saved` — same file, same read-modify-write chokepoint (multi-process safe), `_DAILY_MAX_DAYS=750` cap, corrupt-shape tolerated, batch-across-midnight mis-dates ≤1 batch. **History accrues only from first flush under this version** — the lifetime total can't be back-distributed. **Long-running MCP servers keep pre-change code until restarted (editable install: new process = new code).** Consumer: console v0.8.81 draws window tiles from this book when it FULLY covers the window (today/yesterday immediately; week/month/year flip over as history accrues; `all` = lifetime total, closing the disconnect), transcript fallback + honest note otherwise; receipt scan remains sole source for per-tool breakdown + call counts. New `tests/test_v1_108_136.py` (6). NO INDEX_VERSION / wire change; file already README-disclosed.
67
- **Version:** 1.108.135 — **`receipt --rates` publishes the model price table (kills the duplicate-constant drift class).** The rate table lived only inside `receipt`, so any consumer pricing its own token counts kept a COPY — and a copy drifts silently: the jMunch Console's duplicate sat at the retired **\$15** Opus rate long after this table moved to **\$5**, so its two dollar tiles disagreed 3x with nothing to catch it. New `--rates` prints `{rates_usd_per_mtok, default_model}` as JSON and exits; **scans no transcripts** (instant, cacheable) so a consumer can poll it cheaply and offer every priced model — including ones added later — with no code change on its side. `--model`'s choices already derive from the same table (.131), so CLI and published rates can't disagree. New `render_rates()`; forwarded through the `server.py` receipt subparser (the duplicate-parser surface — edit BOTH). +3 tests in `tests/test_v1_108_134.py` (incl. a guard that `--rates` never calls `iter_calls`). NO INDEX_VERSION / tool-count / wire change. Consumer: console v0.8.80 pricing-model picker.

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ is a byte the agent doesn't pay to read.
128128
<!-- WHATSNEW:START -->
129129
#### What's new
130130

131+
- **[v1.108.138](https://github.com/jgravelle/jcodemunch-mcp/releases/tag/v1.108.138)** (2026-07-18) — confidence provenance: every number states its basis
131132
- **[v1.108.137](https://github.com/jgravelle/jcodemunch-mcp/releases/tag/v1.108.137)** (2026-07-18) — source-shaped exact seeding in ranked context
132133
- **[v1.108.136](https://github.com/jgravelle/jcodemunch-mcp/releases/tag/v1.108.136)** (2026-07-17) — the savings meter records a per-day rollup
133-
- **[v1.108.135](https://github.com/jgravelle/jcodemunch-mcp/releases/tag/v1.108.135)** (2026-07-17) — `receipt --rates` publishes the model price table
134134
<!-- WHATSNEW:END -->
135135

136136
![License](https://img.shields.io/badge/license-dual--use-blue)
@@ -325,6 +325,10 @@ The `tune_weights` tool reads the persistent ranking ledger and learns per-repo
325325

326326
The `suggest_corrections` tool (and the `reflect` CLI) close the loop: they mine the same ranking ledger for **retrieval regret** — where retrieval failed and the agent had to re-ask — and return a prioritized, explainable set of *suggested* fixes (a CLAUDE.md routing or glossary line as a unified-diff preview, an index-freshness hint, a stale-config finding, a dry-run weight proposal). It is read-only by design: it suggests a patch and shows you the diff; applying it is your keystroke, never the server's. Requires `perf_telemetry_enabled` (it has a ledger to read only then) and returns an honest hint when off.
327327

328+
### Confidence provenance — every number states its basis
329+
330+
Every confidence constant the suite emits traces to a stated basis: **`measured`** (backed by a committed, reproducible benchmark artifact — `benchmarks/provenance/measured.json`, drift-guarded in CI so the constants and the artifact can never silently diverge) or **`declared`** (an engineering prior, honestly labeled as exactly that). `find_implementations` responses carry the per-channel basis in `_meta.confidence_provenance`, and the response contracts themselves are published as JSON Schemas in [`schemas/`](schemas/) (`retrieval-verdict`, `confidence-provenance`, `ranked-context-response`) so CI pipelines and agents can validate responses mechanically. A prior is never presented as a measurement: a `declared` value graduates to `measured` only when a gold-labeled corpus backs it, and a build that claims otherwise fails.
331+
328332
### Local-first speed
329333

330334
Indexes are stored locally for fast repeated access.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"comment": "Committed measurement artifacts backing every basis='measured' entry in src/jcodemunch_mcp/retrieval/provenance.py. tests/test_provenance.py fails if the registry and this file diverge, and if this file diverges from the underlying artifacts it cites. Never hand-edit a number here without re-running the cited benchmark.",
3+
"token_reduction": {
4+
"average_pct": 99.6,
5+
"task_runs": 15,
6+
"baseline_tokens": 5122105,
7+
"jcodemunch_tokens": 19406,
8+
"tokenizer": "cl100k_base",
9+
"run_date": "2026-03-28",
10+
"methodology": "benchmarks/METHODOLOGY.md",
11+
"results": "benchmarks/results.md"
12+
},
13+
"replay_retrieval_quality": {
14+
"fixture": "self_v1_75_0",
15+
"k": 10,
16+
"queries": 10,
17+
"ndcg": 1.0,
18+
"mrr": 1.0,
19+
"recall": 1.0,
20+
"captured_at": "2026-07-06T01:03:32+00:00",
21+
"generator_version": "1.108.99",
22+
"source": "benchmarks/replay/results/self_v1_75_0-golden.json",
23+
"ci_gated": true
24+
}
25+
}

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "jcodemunch-mcp"
3-
version = "1.108.137"
3+
version = "1.108.138"
44
description = "Token-efficient MCP server for source code exploration via tree-sitter AST parsing"
55
readme = "README.md"
66
requires-python = ">=3.10"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "https://jcodemunch.com/schemas/confidence-provenance.schema.json",
4+
"title": "jCodeMunch confidence provenance",
5+
"description": "The _meta.confidence_provenance block: every confidence constant a tool emits states its basis. 'declared' = an engineering prior, honestly labeled; 'measured' = backed by a committed benchmark artifact (benchmarks/provenance/measured.json), drift-guarded in CI. A declared value graduates to measured only when a gold-labeled corpus exists for it — a prior is never presented as a measurement.",
6+
"type": "object",
7+
"required": ["channels", "contract"],
8+
"properties": {
9+
"channels": {
10+
"type": "object",
11+
"minProperties": 1,
12+
"additionalProperties": {
13+
"type": "object",
14+
"required": ["value", "basis"],
15+
"properties": {
16+
"value": {"type": "number", "minimum": 0, "maximum": 1},
17+
"basis": {"enum": ["declared", "measured"]},
18+
"source": {
19+
"type": "string",
20+
"description": "Repo-relative path of the committed measurement artifact; required in spirit when basis=measured."
21+
}
22+
},
23+
"additionalProperties": true
24+
}
25+
},
26+
"contract": {"type": "string"}
27+
},
28+
"additionalProperties": false
29+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "https://jcodemunch.com/schemas/ranked-context-response.schema.json",
4+
"title": "jCodeMunch get_ranked_context response",
5+
"description": "JSON response contract for get_ranked_context (the tool's JSON surface; the MUNCH compact encoding is a lossless-scalar/lossy-detail projection of this shape). The _meta.verdict block additionally conforms to retrieval-verdict.schema.json.",
6+
"type": "object",
7+
"required": ["context_items", "total_tokens", "budget_tokens", "items_included", "items_considered", "_meta"],
8+
"properties": {
9+
"context_items": {
10+
"type": "array",
11+
"items": {
12+
"type": "object",
13+
"required": ["symbol_id", "relevance_score", "centrality_score", "combined_score", "tokens", "source"],
14+
"properties": {
15+
"symbol_id": {"type": "string"},
16+
"match_channel": {
17+
"enum": ["exact_name"],
18+
"description": "Present when the item was pinned by source-shaped exact seeding rather than ranked scoring."
19+
},
20+
"relevance_score": {"type": "number", "minimum": 0, "maximum": 1},
21+
"centrality_score": {"type": "number", "minimum": 0, "maximum": 1},
22+
"combined_score": {"type": "number", "minimum": 0},
23+
"tokens": {"type": "integer", "minimum": 0},
24+
"source": {"type": "string"},
25+
"id": {"type": ["string", "null"]},
26+
"name": {"type": ["string", "null"]},
27+
"kind": {"type": ["string", "null"]},
28+
"file": {"type": ["string", "null"]},
29+
"line": {"type": ["integer", "null"]},
30+
"score": {"type": "number"},
31+
"token_cost": {"type": "integer"},
32+
"summary": {"type": "string"},
33+
"source_pruned": {"type": "boolean"},
34+
"source_kept_lines": {"type": "integer"},
35+
"source_elided_lines": {"type": "integer"},
36+
"source_total_lines": {"type": "integer"},
37+
"source_is_pruned_view": {"type": "boolean"}
38+
},
39+
"additionalProperties": true
40+
}
41+
},
42+
"total_tokens": {"type": "integer", "minimum": 0},
43+
"budget_tokens": {"type": "integer", "minimum": 1},
44+
"items_included": {"type": "integer", "minimum": 0},
45+
"items_considered": {"type": "integer", "minimum": 0},
46+
"negative_evidence": {
47+
"type": "object",
48+
"required": ["verdict", "scanned_symbols", "scanned_files", "best_match_score"],
49+
"properties": {
50+
"verdict": {"enum": ["no_implementation_found", "low_confidence_matches"]},
51+
"scanned_symbols": {"type": "integer", "minimum": 0},
52+
"scanned_files": {"type": "integer", "minimum": 0},
53+
"best_match_score": {"type": "number", "minimum": 0},
54+
"related_existing": {"type": "array", "items": {"type": "string"}}
55+
},
56+
"additionalProperties": true
57+
},
58+
"⚠ warning": {"type": "string"},
59+
"_meta": {
60+
"type": "object",
61+
"required": ["timing_ms", "tokens_saved", "total_tokens_saved"],
62+
"properties": {
63+
"timing_ms": {"type": "number", "minimum": 0},
64+
"tokens_saved": {"type": "integer", "minimum": 0},
65+
"total_tokens_saved": {"type": "integer", "minimum": 0},
66+
"verdict": {"type": "object", "description": "Conforms to retrieval-verdict.schema.json."},
67+
"freshness": {"type": "object"},
68+
"confidence": {},
69+
"query_shape": {
70+
"type": "object",
71+
"required": ["source_shaped", "exact_seeded"],
72+
"properties": {
73+
"source_shaped": {"type": "array", "items": {"type": "string"}, "minItems": 1},
74+
"exact_seeded": {"type": "integer", "minimum": 0}
75+
},
76+
"additionalProperties": false
77+
}
78+
},
79+
"additionalProperties": true
80+
}
81+
},
82+
"additionalProperties": true
83+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "https://jcodemunch.com/schemas/retrieval-verdict.schema.json",
4+
"title": "jCodeMunch retrieval verdict",
5+
"description": "The unified _meta.verdict block attached to retrieval responses (search_symbols, search_text, get_ranked_context). Grounded symbolic retrieval proves absence: an 'absent' state carries the scan counts that back the claim, and 'degraded' means the scan was partial so absence is NOT proven.",
6+
"type": "object",
7+
"required": ["state", "scanned", "channels", "note"],
8+
"properties": {
9+
"state": {
10+
"enum": ["ok", "low_confidence", "absent", "degraded"],
11+
"description": "ok = confident matches; low_confidence = non-empty but below threshold; absent = nothing matched and the scan was complete; degraded = partial scan (timeout, or semantic requested with no embedder) — absence not proven."
12+
},
13+
"scanned": {
14+
"type": "object",
15+
"required": ["symbols", "files"],
16+
"properties": {
17+
"symbols": {"type": "integer", "minimum": 0},
18+
"files": {"type": "integer", "minimum": 0}
19+
},
20+
"additionalProperties": false
21+
},
22+
"best_score": {
23+
"type": ["number", "null"],
24+
"description": "Best raw match score backing the state, null when no scoring ran."
25+
},
26+
"channels": {
27+
"type": "object",
28+
"required": ["lexical", "semantic", "index"],
29+
"properties": {
30+
"lexical": {"enum": ["ok"]},
31+
"semantic": {"enum": ["ok", "off", "unavailable"]},
32+
"index": {"enum": ["fresh", "stale"]}
33+
},
34+
"additionalProperties": false
35+
},
36+
"note": {"type": "string"},
37+
"did_you_mean": {
38+
"type": "array",
39+
"items": {"type": "string"},
40+
"description": "Near-miss suggestions when the state is absent/low_confidence."
41+
}
42+
},
43+
"additionalProperties": true
44+
}

0 commit comments

Comments
 (0)