# pmat v3.15.0 — DRAFT Release Notes

> Status: DRAFT — pending final merges and `make validate-book` green after R17 wave.
> Scope: the R17 "fix-wave" of five merged PRs (#355–#359) that remediate a cluster of
> MCP and HTTP defects surfaced by rounds 15 and 16 of the dogfood bench matrix.

## R17 Fix Wave — MCP and HTTP Correctness

This release lands **five correctness fixes** to the MCP and HTTP surfaces. Every fix
is "honest-first": failure over silent-success, accurate metadata over stubs,
correct dispatch over misleading aliases. Nothing here changes CLI semantics.

### #355 — `pmat serve` fails loudly instead of stubbing silently (R17-4 / KAIZEN-0191)

- **Before.** `pmat serve --transport http --port N` printed a `Server ready!` banner
  and blocked on `ctrl_c().await` *without binding a socket*. `curl localhost:N`
  returned connection-refused; the process exit code (once killed) was 0.
  Documented as **D72** in pmat-book ch69.
- **After.** Every transport (`http`, `web-socket`, `http-sse`, `both`, `all`) prints
  a clear "not yet implemented" diagnostic to **stderr**, echoes the host/port/transport
  for visibility, points at the working stdio transport (`PMAT_PMCP_MCP=1 pmat`),
  and **exits with code 2** (misuse convention).
- **Follow-up.** Path-B HTTP wiring (via `pmcp::StreamableHttpServer`) is tracked as
  **KAIZEN-0191**; scope exceeded 300 LOC for this PR.

### #356 — 16 core MCP tools now advertise real inputSchema and description (KAIZEN-0189)

- **Before.** `ToolHandler::metadata()` defaulted to `None`, so `ServerCoreBuilder::tool`
  fell back to `ToolInfo::new(name, None, json!({}))` — every `tools/list` entry collapsed
  to an **empty schema and missing description**. MCP clients could not render forms.
- **After.** Each of the 16 core tools (`analyze_complexity`, `analyze_satd`,
  `analyze_dead_code`, `analyze_dag`, `analyze_deep_context`, `analyze_big_o`,
  `refactor.*`, `quality_gate`, `quality_proxy`, `pdmt_deterministic_todos`,
  `git_operation`, `generate_context`, `scaffold_project`) plus the 6 TDG-system tools
  now returns a hand-written JSON-Schema alongside a human-readable description.
- **Verification.** Live stdio smoke: 16 tools, 0 non-object schemas, 0 missing
  descriptions, only the 3 no-arg `refactor.*` tools have zero properties (correct).

### #357 — pv contract gate: 432 violations → 0 (KAIZEN-0175 / KAIZEN-0190)

- **Before.** `pv` (aprender-contracts-cli) reported 432 schema / metadata violations
  in the repo's work-contract YAMLs. Mix of missing `metadata` fields (KAIZEN-0175)
  and SCHEMA-003 violations (KAIZEN-0190).
- **After.** Every contract YAML under `.pmat-work/` now emits a well-formed
  `metadata` block and passes `pv check` with zero findings. The pre-push hook
  stays O(1) because contract enforcement is the canonical path — no more adhoc bash.

### #358 — D82 authoritative-zero fix on 4 MCP analyze handlers (R17-2)

- **Before.** `analyze_complexity`, `analyze_satd`, `analyze_dead_code`, and
  `generate_context` over MCP required `path.is_file()` for every input and silently
  skipped directories. A caller that passed `src/` (a directory) got back an empty
  payload — an *authoritative zero*: the payload looked valid but carried no data.
- **After.** A new `expand_paths_to_source_files()` helper walks any directory input
  to its constituent source files (extensions `rs/py/js/ts/tsx/jsx/java/cpp/c/h/hpp/go/rb/php/swift/kt/lua/sh`;
  skips hidden dirs, `target/`, `node_modules/`). A 9-file fixture path now returns
  9 files / 216 complexity via MCP — identical to the CLI.
- **Regression guard.** `analyze_dead_code` output now includes `total_functions` and
  `languages` so clients can distinguish "ran, found nothing" from "didn't run."

### #359 — MCP wrong-dispatch fix on 3 tools (R17-1)

- **Before.** Misleading type aliases in `analyze_handlers.rs` routed three MCP tools
  to the wrong analyzers:
  - `analyze_dag` → `LintHotspotTool` (returned lint hotspots)
  - `analyze_big_o` → `CouplingTool` (returned coupling metrics)
  - `analyze_deep_context` → `ChurnTool` (returned git churn)
- **After.** Each tool now has a distinct handler dispatching to the correct
  `services::deep_context::analysis_functions::*` implementation, matching the CLI.
  MCP output now matches CLI output: **7178/181 DAG nodes/edges**, **8854** Big-O
  functions, **1362** deep-context files — identical to `pmat analyze dag/big-o`
  and `pmat context`.
- **Static guard.** A `TypeId` assertion prevents re-aliasing the three tools in
  future refactors.

---

## Upgrade notes

- CI or scripts that relied on `pmat serve --transport http` exiting 0 while not
  binding a port **will now fail with exit 2**. This is intentional — the previous
  behavior was the D72 silent-hang footgun. If you need an HTTP MCP transport,
  track KAIZEN-0191 or use stdio (`PMAT_PMCP_MCP=1 pmat`).
- MCP clients that worked around the empty-schema bug by ignoring `inputSchema`
  can now render accurate forms; no action required, but better UX is available.
- Agents that treated empty MCP `analyze_*` responses as "clean code" should
  re-run against their projects — previously-hidden findings will surface.

## Internal

Discovered by R15 #3 bench matrix (`/tmp/pmat-dogfood/round15/r15-3-bench-matrix.md`).
Follow-up tickets: KAIZEN-0191 (HTTP transport wiring), KAIZEN-0193 (examples audit
for R17 semantics — this doc's companion work).
