Skip to content

Support prefix matching for shortened thought IDs #32

Description

@timeleft--

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 01KKYAAC01KKYAACFAYFH7F727HVTNE9T3 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions