What
Every postless toAgent child of one caller session is keyed <platform>:a2a:<callerId>:<callerThread>:<childId> — the synthetic channel (a2a:<caller>) and thread segments are caller-derived and identical across children, so all pairwise sessions of one caller write into ONE shared transcript thread (transcriptChannelKey(a2a:<caller>) + <callerThread>). Only the agent segment differs.
A child's turn-context refresh reads that shared thread. Measured (webchat Werewolf eval artifacts, #941): a player's night prompt contained context rows with the referee's role-assignment deliveries to its siblings — including the private canaries — and the siblings' replies:
(thread context you may have missed)
[<caller id>] From referee: Werewolf role assignment. Your alias: player-2. Your role: werewolf. … (private canary: …)
[<sibling id>] reported.
[<sibling id>] We kill player-1 tonight.
Why it matters
- General privacy defect, not a games problem: an orchestrator that privately delegates DIFFERENT subtasks to several agents (
toAgent + needsReply fan-out) leaks each delegation and each report to every other delegate through ordinary context refresh. Cross-agent information barriers (per-agent credentials, per-tenant work) cannot rely on postless calls being pairwise-private.
- Hidden-information games are unplayable fairly: role deliveries are cross-visible by construction.
Expected
A pairwise a2a session's transcript should be per (caller, child) pair, not per caller: sibling children of one caller must not see each other's deliveries or replies in any context refresh.
The eval suite already carries the measurement seam: the webchat Werewolf scripted players had to be explicitly hardened to ignore sibling context rows (evals/games/webchat-werewolf.ts), and a canary cross-visibility regression test can pin the fix.
Refs #854 (a2a pairwise sessions), #941 (measurement).
What
Every postless
toAgentchild of one caller session is keyed<platform>:a2a:<callerId>:<callerThread>:<childId>— the synthetic channel (a2a:<caller>) and thread segments are caller-derived and identical across children, so all pairwise sessions of one caller write into ONE shared transcript thread (transcriptChannelKey(a2a:<caller>) + <callerThread>). Only the agent segment differs.A child's turn-context refresh reads that shared thread. Measured (webchat Werewolf eval artifacts, #941): a player's night prompt contained context rows with the referee's role-assignment deliveries to its siblings — including the private canaries — and the siblings' replies:
Why it matters
toAgent + needsReplyfan-out) leaks each delegation and each report to every other delegate through ordinary context refresh. Cross-agent information barriers (per-agent credentials, per-tenant work) cannot rely on postless calls being pairwise-private.Expected
A pairwise a2a session's transcript should be per (caller, child) pair, not per caller: sibling children of one caller must not see each other's deliveries or replies in any context refresh.
The eval suite already carries the measurement seam: the webchat Werewolf scripted players had to be explicitly hardened to ignore sibling context rows (
evals/games/webchat-werewolf.ts), and a canary cross-visibility regression test can pin the fix.Refs #854 (a2a pairwise sessions), #941 (measurement).