From f57902f7cf429e9918a470ec2d2d23c0e19e62e1 Mon Sep 17 00:00:00 2001 From: ribdsp <113304041+ribdsp@users.noreply.github.com> Date: Mon, 31 Aug 2026 13:04:16 +0700 Subject: [PATCH] docs: correct claims the code does not support Three statements that were not true of the code: - CLAUDE.md said every stub from the original build had been implemented. `registerDynamicTool` is still a stub that throws, nothing calls it, and its marker is still on the line above it. Named, with the consequence stated: promoting a hypothesis does not grow a 17th tool. - CLAUDE.md said "All 285 tests pass". Measured: 25 files, 303 tests. - The `toolchange` comment in tool-status-banner.tsx presented the dynamic registration mechanism as something the app does. It is a stub; the only thing that can move that counter is the host changing its own tool list. No behaviour change. `registerDynamicTool` is left exactly as it is, marker included. --- CLAUDE.md | 6 ++++-- traces/src/components/ui/tool-status-banner.tsx | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index bc15532..7352853 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,7 +26,9 @@ than none. Whoever asked you to make this change will tell you your scope. ## `TODO(name), Day n:` markers are assignments -There are none left — every stub from the original build has been implemented. The convention is +One stub is left, and it still carries its marker. `registerDynamicTool` in +`traces/src/lib/webmcp/register-tools.ts:133` throws `registerDynamicTool: not implemented`, and nothing +in the codebase calls it — so promoting a hypothesis does not grow a 17th tool. The convention is documented here because the rule outlives the markers: a marker names the person who owned the work and the day it was due, so **deleting one while implementing around it destroys the only record of who owes what.** If you add a marker, name yourself in it. If you find one, either implement it or leave it @@ -34,7 +36,7 @@ exactly where it is. ## The tests are green, and two suites must stay honest -All 285 tests pass. That is worth stating because of how some of them got there: the `compress-dom`, +All 303 tests pass. That is worth stating because of how some of them got there: the `compress-dom`, `bisect` and `evaluatePredicate` suites were written first, as specifications, and were red for as long as it took the implementations to satisfy them. **Never** make a test in those suites pass by weakening an assertion, adding `.skip`, or deleting a case: that converts a specification into a lie, silently. A diff --git a/traces/src/components/ui/tool-status-banner.tsx b/traces/src/components/ui/tool-status-banner.tsx index 61c90da..808f5ec 100644 --- a/traces/src/components/ui/tool-status-banner.tsx +++ b/traces/src/components/ui/tool-status-banner.tsx @@ -136,8 +136,9 @@ export function ToolStatusBanner({ registration }: ToolStatusBannerProps) { }, []) /** - * `toolchange` is how a surface that grew a tool mid-investigation shows up here without a reload — - * the promoted-hypothesis tool from `registerDynamicTool` is the case worth demoing. The event fires + * `toolchange` is how a surface that grew a tool mid-investigation would show up here without a reload. + * Nothing in this app grows one: `registerDynamicTool` is a stub that throws and has no callers, so the + * only thing that can move this counter is the host changing its own tool list. The event fires * on `document.modelContext`, which is why the draft has it extend `EventTarget`. Not every host * honours that, and one of them is ChatGPT Desktop; `onToolChange` explains what subscribing there * used to cost. When the host has no events this counter simply never moves.