Skip to content

Persist applied command status across reload (CS-11736)#5367

Open
FadhlanR wants to merge 2 commits into
mainfrom
cs-11736-auto-executed-command-reverts-to-ready-after-reload
Open

Persist applied command status across reload (CS-11736)#5367
FadhlanR wants to merge 2 commits into
mainfrom
cs-11736-auto-executed-command-reverts-to-ready-after-reload

Conversation

@FadhlanR

@FadhlanR FadhlanR commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Problem

After a command is applied in the AI assistant (most visibly an auto-executed command in act mode), it shows applied during the session but reverts to ready after a page reload — the applied state isn't persisted.

Root cause. command-service.run stamps the commandResult event's m.relates_to.event_id with the latest m.replace edit id Y of the streamed bot message (intentional — CS-11045 — so the ai-bot's normalized /messages view correlates correctly). On reload the timeline filter strips all m.replace edits, so only the original event X is loaded (with aggregated content) and Y no longer exists as a distinct event. The host's two reload-side matchers still keyed off event_id, so the dangling Y link broke and the status fell back to the literal default 'ready'.

Fix

Correlate both reload-side matchers by the stable, globally-unique commandRequestId (the LLM tool-call id) instead of the drifting event_id — mirroring the correlation the ai-bot already uses:

  • MessageBuilder.buildMessageCommand — drop the event_id condition; match on type + rel_type + commandRequestId.
  • RoomResource.updateMessageCommandResult — locate the owning bot message by "result's commandRequestId ∈ message's command-request ids" instead of event_id equality.

The wire format (event_id = Y) is unchanged, so ai-bot prompt construction / checkCorrectness behavior is untouched. The downstream _messageCache key still resolves to X on both the live and reload paths.

Screen Recording

Screen.Recording.2026-06-30.at.18.33.10.mov

Test

Adds a host regression test that reproduces the post-reload state directly (original message X carrying the command request + a commandResult linked to a stripped edit id Y) and asserts the command still renders [data-test-apply-state="applied"]. Fails on main, passes with this change.

Note: the host integration suite couldn't be run locally (no Docker for Postgres/Synapse in this environment); relying on CI. Type-check (ember-tsc) and eslint pass on the changed files.

Linear: CS-11736

🤖 Generated with Claude Code

An applied/invalid command on a streamed bot message reverted to "ready"
after a page reload. The commandResult event links to the latest m.replace
edit id (CS-11045 wire format), but reload strips all m.replace edits so
only the original event survives — the host's two reload-side matchers keyed
off the now-dangling event_id and the status flip was lost.

Correlate both matchers (MessageBuilder.buildMessageCommand and
RoomResource.updateMessageCommandResult) by the stable, globally-unique
commandRequestId instead of the drifting event_id. The wire format is
unchanged, so ai-bot prompt construction is untouched. Adds a host
regression test that reproduces the post-reload state and asserts the
command still renders applied.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Preview deployments

Host Test Results

    1 files  ±0      1 suites  ±0   2h 32m 49s ⏱️ + 16m 37s
3 322 tests +1  3 307 ✅ +1  15 💤 ±0  0 ❌ ±0 
3 341 runs  +1  3 326 ✅ +1  15 💤 ±0  0 ❌ ±0 

Results for commit 065a27f. ± Comparison against earlier commit 44b5f16.

Realm Server Test Results

    1 files  ±0      1 suites  ±0   8m 56s ⏱️ - 1m 48s
1 679 tests ±0  1 679 ✅ ±0  0 💤 ±0  0 ❌ ±0 
1 758 runs  ±0  1 758 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 065a27f. ± Comparison against earlier commit 44b5f16.

@FadhlanR FadhlanR marked this pull request as ready for review June 30, 2026 11:34
@FadhlanR FadhlanR requested a review from a team June 30, 2026 11:34
In updateMessageCommandResult, the commandRequestId lookup now fully
determines the owning bot message, so the effectiveEventId fallback was
unreachable. Hoist the missing-message early return and derive the cache
key unconditionally from the located message.

Add a regression test asserting an applied commandResult flips only its
own bot message: a sibling message that also carries a command stays
ready, confirming correlation by commandRequestId does not bleed across
messages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@lukemelia lukemelia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need the /evergreen-comments skill applied

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.

2 participants