unbridled-41 opened a new issue, #4753:
URL: https://github.com/apache/rocketmq-dashboard/issues/4753
### Studio Version
branch: rocketmq-studio
git commit id: cd448e17f14b4bd6e6d4ade87300caf19ca91bc2
### Problem
The AI conversation retention pass deletes the conversation, its runs and
its events, but leaves the conversation's agent workspace on disk. The
workspace holds the child's `HOME`
(`home/.claude/projects/<cwd>/<session-id>.jsonl`), i.e. the full agent
transcript, plus `rmqctl.yaml`, `mcp.json` and the appended system prompt; the
on-request delete removes it, the retention pass does not, so "expired"
conversations keep their transcript under an id nothing refers to any more.
Chain:
-
`server/src/main/java/org/apache/rocketmq/studio/ops/ai/conversation/AiConversationService.java:509-515`
(`deleteCascade`) deletes events, then runs, then the conversations - and
nothing else; it is called only by `deleteExpiredConversations` (`:480-497`),
reached from the scheduled `purgeExpired` (`:412-426`,
`@Scheduled(fixedDelayString =
"${studio.ai.conversation.cleanup-interval:PT24H}")`).
- The on-request delete does remove it: `AiConversationService.java:290`
(`workspace.delete(conversationId)`).
- The workspace is documented as tied to the conversation's lifetime:
`RmqctlWorkspace.java:212-216` ("while {@code home/} and whatever {@code
claude} persisted inside it are left alone", i.e. they persist per
conversation), the layout at `:61-70` (`home/ 0700, the child's HOME, per
conversation and persistent`), and `delete(long)` at `:277-299`, whose javadoc
says it is "called by `DELETE /api/ai/conversations/{id}` after the rows are
gone". Nothing else ever calls it - `AiConversationService.java:290` was the
only production caller.
Trigger (deterministic): set `studio.ai.conversation.retention-days=1` and
`cleanup-interval=PT1M` (or wait out the 90-day default,
`AiConversationProperties.java:37`), let a conversation with an agent run age
out, and let the sweep run. The conversation disappears from the UI and its
rows are gone, while
`${studio.ai.conversation.workspace-dir}/conv-<id>/home/.claude/...` is still
there.
### Evidence
- Defect: `AiConversationService.java:509-515` (retention cascade without
the workspace).
- Contrast: `AiConversationService.java:290` (the delete path that does it)
and the pinned order in
`AiConversationServiceTest.deleteShouldCascadeChildrenFirstAndRemoveTheWorkspaceTest`,
which asserts `workspace.delete(CONVERSATION_ID)` for that path.
- Retention contract: `AiConversationProperties.java:37` (`retentionDays =
90`), `server/src/main/resources/application.yml:119` (`workspace-dir:
${STUDIO_AI_CONVERSATION_WORKSPACE_DIR:/tmp/rocketmq-studio-ai}`).
- Regression test added with this report
(`AiConversationServiceTest.retentionShouldRemoveTheWorkspaceOfEveryPurgedConversationTest`),
failing on cd448e17:
```
[ERROR] ...retentionShouldRemoveTheWorkspaceOfEveryPurgedConversationTest --
Time elapsed: 0.028 s <<< FAILURE!
Wanted but not invoked:
[ERROR] Tests run: 19, Failures: 1, Errors: 0, Skipped: 0
```
### Impact
The retention setting is not honoured for the most sensitive artefact the
feature writes: the agent transcript, which contains the operator's prompts,
the tool arguments and the tool results, survives the purge. With the workspace
on a persistent volume (what `STUDIO_AI_CONVERSATION_WORKSPACE_DIR` exists for)
the directory accumulates without bound, one `conv-<id>` per purged
conversation; with the default `/tmp` location it is only cleared by a
container restart. Either way the two deletion paths disagree about what
deleting a conversation means, and the retention job is the one that is
supposed to run unattended.
### Expected behavior
Purging an expired conversation removes its workspace as well, in the same
order the on-request delete uses (rows first, then the directory), so a crash
in between leaves a directory that is still reachable instead of a transcript
removed under a conversation that is still visible.
### Related work
- #4647/#4648 (open) — the same scheduler family: malformed
snapshot-retention configuration.
- The alert-silence/alert-event retention work (`AlertSilenceSchedule`,
`NotificationOutboxService`) is unrelated to the AI subsystem.
- The AI items open today (#4685, #4693, #4696, #4707, #4715, #4631, #4665,
#4738, #4740) are all about the run/stream lifecycle in the browser or the CLI
session, none about the workspace lifecycle.
#
## PR
Fix: #4754.
This PR targets the development trunk `rocketmq-studio`. GitHub interprets
closing keywords only for pull requests that target the repository default
branch, and this repository default branch is still `master`, so merging the PR
will not close this issue automatically — it needs to be closed by hand.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]