Conversation
Seen live: the buddy drafted an answer to an escalation, the manager said "You can send it", and no confirm button appeared. The buddy claimed one existed and then denied having any such tool. Nothing was stored. Team mode mounts an area's tools only in the turn that opened it, the set of opened areas was rebuilt empty on every message, and the stored transcript is text only. So by the time the manager approved a draft, the tool that makes the change was gone and the model had nothing to call, and invented the confirmation. This hit every "discuss it, then approve it" flow, not just answering escalations. A reply now stores the areas it opened (buddy_team_messages.opened_areas, nullable), and the next message mounts them from its first hop. Only what the reply itself opened is stored, not what it inherited, so an area stays open for one further message and a conversation does not slowly mount every area's tools, which is the reason areas exist. A fold of old messages into the memory note does not close it, because the last reply is read from the whole transcript. Also describes each area in open_area's definition. The model chose an area from its name alone and opened arrival when asked about questions hires were waiting on, because "knowledge" says nothing. The definition now lists what is in each area, says an area stays open for one more message, and forbids saying something was offered for confirmation unless a tool of an opened area did it. The column is nullable, so Hibernate's ddl-auto update can add it to a populated table; V20 does the same by hand, idempotently. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Created my own steps to reproduce since none were given in this PR. In short, the commited changes do not fix the issue:
|
|
Update: I just noticed I didn't test the AI behaviour inside the new team mode environment. With team mode applied, however, I experienced problems similar to the Sprint 9 review demo, where the buddy wasn't able to access open escalations and gave nonsensical answers: |
| emitAgentReply(reply, citations) | ||
|
|
||
| buddyTeamMessageRepository.save( | ||
| BuddyTeamMessage(session = session, role = BuddyMessageRole.ASSISTANT, content = reply), | ||
| BuddyTeamMessage( | ||
| session = session, | ||
| role = BuddyMessageRole.ASSISTANT, | ||
| content = reply, | ||
| // Only what this reply opened, not what it inherited: an area stays open for one more | ||
| // message, so a conversation does not slowly mount every area's tools. | ||
| openedAreas = areas.openedThisTurn.encoded(), | ||
| ), | ||
| ) |
There was a problem hiding this comment.
This still makes the fix conditional on the model choosing to call open_area.
areas.openedThisTurn is populated only by an open_area tool call. The live reproduction shows that the model can instead return a draft or nonsensical final answer without opening KNOWLEDGE. This line then stores null, so the manager’s next message - such as “send that draft” - again has no escalation action tool mounted. The original bug therefore remains possible and has already reproduced against this head.
The new open_area description is helpful guidance, but prompt text is not a reliable state transition or enforcement mechanism.
Please make area continuation deterministic on the backend. For example, require a structured area-selection/tool step before accepting an area-dependent final response, or otherwise prevent an actionable workflow from finalizing until the relevant area has been opened or an action proposal has actually been emitted. A response must also never be allowed to claim that an action was completed unless the backend created/executed the corresponding proposal.
Related issue
No issue yet: found live on the dev deployment while preparing the team-mode demo. Follow-up to the team-mode area design from #215 / #230.
Short summary
Fixes team mode losing the tools that make a change between one message and the next. The buddy drafted an answer to an escalation, the manager said "You can send it", and no confirm button appeared: the buddy claimed one existed and then denied having any such tool. Nothing was stored.
buddy_team_messages.opened_areas, nullable), and the next message mounts them from its first hop. Only what the reply itself opened is stored, not what it inherited, so an area stays open for exactly one further message and a conversation does not slowly mount every area's tools. A fold of old messages does not close it.arrivalwhen asked about questions hires were waiting on.open_areanow lists what is in each area (TeamArea.summary), says an area stays open for one more message, and forbids saying something was offered for confirmation unless a tool of an opened area did it.Checks
Additional notes
buddy_team_messages.opened_areas VARCHAR(255), nullable, soddl-auto: updatecan add it to a populated table on startup (the NOT NULL columns are what failed to add on the dev database earlier).V20__add_buddy_team_message_opened_areas.sqldoes the same by hand and is idempotent. Existing messages haveNULL, which means "opened nothing"../gradlew clean checkgreen locally on top of currentdev: 3336 tests, 0 failures. New:OpenAreasTest, six cases inBuddyTeamServiceTest(carried into the first hop; stored with the reply; not carried twice; re-opening keeps it; nothing inherited from older replies, greetings or the manager's own message; a fold does not close it), two inBuddyTeamToolsTestfor the definition, andBuddyTeamMessageRepositoryTestfor the column round trip. No new controller, so no new WebMvcTest.🤖 Generated with Claude Code