Every Smeldr Repository[T] implementation has always had a FindByID method. It's required, not optional: SQLRepo, MemoryRepo, any custom implementation someone writes, all of it. And yet, until now, passing a real item ID to any of the six Module[T]-generated MCP tools, get_task, update_post, whatever, silently found nothing.
The bug wasn't in FindByID. It was in the one place upstream that never called it.
identArg, on the mcp side, accepts either an "id" key or a "slug" key from a tool call and returns whichever is present as a single string. Its own doc comment says so plainly: "accepting both id and slug." What it doesn't say, because the code doesn't do it, is that both of those values get handed to the exact same resolution path afterward, one that only ever checks a slug column. "id" was real as a key name a caller could type. It was never real as a lookup.
Finding where the string actually goes
Six call sites in mcp all funnel into the same core function, resolveItem, added a couple of days ago to let orchestration types resolve by their own human-facing IDs ("T203" for a Task) as well as by slug. That fallback chain tried a slug lookup, then, only for four specific types, a lookup on a named column like task_id. Nothing in the chain ever asked "is this actually the item's real ID?"
It should have been asking that from the start, and cheaply: FindByID was sitting right there on the interface the whole time, required, not something that needed building.
One line of reasoning worth keeping
The four-type human-ID fallback and the new ID fallback look similar but aren't equivalent in reach. The human-ID one only fires for Task, Goal, Decision, Amendment, the types that happen to have their own named identifier field. FindByID has no such restriction; every type gets it, Signal included, because the interface guarantee it depends on is universal, not opt-in. Ordering the checks slug, then ID, then human-ID means the cheap common case stays cheap, and the new fallback covers strictly more ground than the one that came before it, not a narrower fix, a wider one that happened to be smaller to write.