Skip to content

feat(agent): treat a Matrix thread as a conversation with Stacky - #66

Merged
arthware-dev merged 6 commits into
mainfrom
feat/agent-thread-addressing
Aug 4, 2026
Merged

feat(agent): treat a Matrix thread as a conversation with Stacky#66
arthware-dev merged 6 commits into
mainfrom
feat/agent-thread-addressing

Conversation

@arthware-dev

Copy link
Copy Markdown
Contributor

Answer Stacky in a thread and it knows you mean it. No name, no @-mention. Scoped to threads Stacky is actually part of, so the archivist's filing threads stay the archivist's.

Validating it on the rig surfaced two bugs underneath: the agent's stack shim lost argument boundaries, so every vault query longer than one word failed, and it exited 0 regardless, so the model read a usage error as results and retried forever.

A thread is a conversation, so a reply inside one the agent is part of
now counts as talking to it. Mention Stacky once, open a thread on its
answer, and the rest of the exchange needs no name and no @-mention.

Scoped to threads Stacky actually participates in (rooted at one of its
messages, or one it has posted in). The archivist and mail bot thread
their own replies in the same rooms, and those conversations stay
theirs.
`stack messages send --thread <event-id>` posts inside a thread, the way
a client's "Reply in thread" does, and `stack messages read --ids` prints
the event id under each message so you can thread onto one you did not
send -- a bot's own answer, say.

Neither was reachable before, which meant the agent's "a thread is a
conversation" behaviour could not be exercised or checked without a
Matrix client.
Every command Stacky runs travels to the CLI as one line of text. That
line was built by joining the arguments with a space, so a query like
"school run" arrived as two, and the CLI rejected the second one. The
agent's main way of reading the family vault failed on any question
longer than a single word.

The failure was also invisible: the shim exited 0 whatever happened, so
the tool handed the model a usage message as if it were search results,
and the model asked the same question again, and again. One turn ran
that loop for five minutes. Failures, refusals included, now come back
as failures.
`stack memory search` exits 1 when nothing matched, which is an answer,
not a failure. The tool read any non-zero exit as a broken search, so an
empty vault result would have reached the model as an error and invited
it to try the same question again.

Only bad arguments and an unreadable vault are failures now. This
surfaced because the shim only just started reporting real exit codes.
…und" plainly

Mounting the `stack` shim from the repo so it can be edited without a
rebuild replaced the image's copy along with its permissions, and the
repo file was not executable. Every vault tool failed at once with
"executable file not found". The file is executable now, and an audit
over every compose bind mount onto a PATH directory keeps it that way.

A search that matched nothing also reached the model as the host API's
generic "(no output)", which reads like a malfunction rather than an
answer. The exit status decides now, so it says so.
Ten shims over thirteen symbols, five of them private methods. ADR-012
records what that has cost, what a fork changes, and what to keep as it
is: the pure modules carry the decisions, the fork would only carry the
wiring.

Also notes why the agent finds nothing in the vault when the archivist
finds plenty. They disagree about what a query is, and the hop that
translates one into the other lives in the wrong stacklet.
@arthware-dev
arthware-dev merged commit a4d02e0 into main Aug 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant