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.