Problem
Thought IDs are 26-character ULIDs (e.g. 01KKYAACFAYFH7F727HVTNE9T3). Agents routinely shorten these to 8-character prefixes (e.g. 01KKYAAC) in their tool calls — this is natural behavior since agents display thoughts in tables with shortened IDs.
Currently, all thought-by-ID operations (get_thought, update_thought, supersede, propose_truth, change_scope) require an exact full ULID match via _find_thought_path(). When an agent passes a shortened ID, the operation fails with "not found".
Expected Behavior
- If a shortened ID prefix uniquely matches exactly one thought file, resolve it and proceed normally
- If a prefix matches multiple thought files, return an error listing all matching thought IDs with their YAML frontmatter metadata (source_type, created_at, content_preview, etc.) so the agent can disambiguate
- Exact full-ULID matches continue to work as before (fast path)
Example
Agent displays thoughts in a table:
│ 5 │ 01KKYAAC │ .gitignore template for builder worktree compatibility │ decision │
Then calls:
propose_truth(trail_name="mwai/eng/codev", thought_id="01KKYAAC")
This should resolve 01KKYAAC → 01KKYAACFAYFH7F727HVTNE9T3 and promote it.
Implementation Notes
- Core change is in
TrailManager._find_thought_path() (trail.py:104-109)
- Add an
AmbiguousThoughtID exception class with structured candidate info
- Tool handlers in
tools/thought.py and tools/navigation.py should catch AmbiguousThoughtID and return a helpful error response
- Add tests for: unique prefix match, ambiguous prefix match, exact match still works
Labels
bug
Problem
Thought IDs are 26-character ULIDs (e.g.
01KKYAACFAYFH7F727HVTNE9T3). Agents routinely shorten these to 8-character prefixes (e.g.01KKYAAC) in their tool calls — this is natural behavior since agents display thoughts in tables with shortened IDs.Currently, all thought-by-ID operations (
get_thought,update_thought,supersede,propose_truth,change_scope) require an exact full ULID match via_find_thought_path(). When an agent passes a shortened ID, the operation fails with "not found".Expected Behavior
Example
Agent displays thoughts in a table:
Then calls:
This should resolve
01KKYAAC→01KKYAACFAYFH7F727HVTNE9T3and promote it.Implementation Notes
TrailManager._find_thought_path()(trail.py:104-109)AmbiguousThoughtIDexception class with structured candidate infotools/thought.pyandtools/navigation.pyshould catchAmbiguousThoughtIDand return a helpful error responseLabels
bug