Context
Empirical observation from session aaf22f06-cc5c-4dff-aa2f-7d5efb3a6343: cross-family agent (@neo-opus-ada) missed inbound A2A messages from @neo-gemini-pro 6+ times in a single session. In each instance, @tobiu had to nudge explicitly ("gemini sent you a message" / "gemini sent you 2 messages" / "gemini replied") before the messages were read. The discipline gap is structural — there is currently no per-turn-start mandate to check list_messages({status: 'unread'}) before proceeding with the user's prompt.
The Problem
AGENTS.md §0.5 + §4.2 codify the outgoing persistence discipline at turn-end (add_memory consolidates the turn before yielding). The symmetric primitive for incoming state ingestion at turn-start is missing. Without it, the persistence loop is asymmetric — agents save outgoing state but don't reflexively ingest incoming substrate state.
This creates four observable failure modes:
- Cross-family review drift — reviewer responses not seen until prompted; coordination cycles run on stale mental model
- Missed coordination signals — pause-requests, work-split changes, scope-renegotiations land in inbox but don't get acted on
- State-mismatch propagation — when reviewer state-mismatch findings (e.g., "your claim doesn't match repo state") aren't read, follow-up cycles compound the divergence
- Cross-cycle continuity break — when a turn yields and a new turn starts, all in-flight A2A correspondence becomes invisible unless explicitly queried
The Architectural Reality
Per-turn-loaded discipline docs:
AGENTS.md §0 Critical Gates — invariants, no conditional exceptions
AGENTS.md §4 Memory Core Protocol — add_memory at turn-end (§4.2 Consolidate-Then-Save)
AGENTS.md §3 Pre-Commit Hard Gates — Pre-Flight Check pattern with explicit reasoning-statement
AGENTS.md §19 Working with Sub-Agents — delegation discipline (different concern: out-going to spawned sub-agents, not in-coming from peers)
Current per-turn-start coverage: none. Both Claude Code (AGENTS.md per-turn-loaded) and Antigravity (per ~/.gemini/antigravity/mcp_config.json context.fileName) load AGENTS.md per turn, so a single addition to AGENTS.md fixes both harnesses symmetrically.
The empirically-strongest reflex primitive in this codebase is the Pre-Flight Check pattern (§3 / §4.2): mandate the agent state in their reasoning before yielding. The same shape applied to inbox-check would be:
"Pre-Flight: I called list_messages({status: 'unread'}) and observed [N unread / none]. [If unread: I will read the most relevant before yielding the turn / queued for processing context.]"
Architectural relationship to Phase 3 wake substrate (#10357)
Once the wake substrate ships (Shape A/B/C), auto-wake events PRIME the next turn with mailbox context. The mailbox-check Pre-Flight does NOT become obsolete — it changes role from "primary delivery" to "verification primitive." Wake substrate is push-based and has structural blind spots:
| Failure mode |
Auto-wake |
Mailbox-check Pre-Flight |
| Message arrives during prior turn's processing |
Wake fires AFTER turn ends; next turn must still query |
✅ catches |
| Subscriber's filter excluded a relevant trigger |
No wake; agent unaware |
✅ catches |
| Transport delivery failure (network, harness) |
Silent miss |
✅ catches |
| Cold-cache (fresh session bootstrap) |
No prior subscription state |
✅ catches |
| In-flight turn arrival (the pause-coordination-physics issue surfaced this session) |
Wake queues but turn already running |
✅ catches |
Same verify-effect-not-just-success discipline we apply to PR review state-mismatch: wake substrate primes the context; turn-start check verifies delivery.
The Fix
Single new section in AGENTS.md, parallel to §4 Memory Core Protocol. Suggested as §22 (or wherever fits between #10380's proposed §22 and the existing §21):
<h2 class="neo-h2" data-record-id="7">§22. The Mailbox Check Protocol (Pre-Flight at Turn Start)</h2>
Symmetric companion to §4.2 (Consolidate-Then-Save at turn end): at turn start, you MUST check your A2A mailbox for unread messages before proceeding with the user's request.
<h3 class="neo-h3" data-record-id="8">Pre-Flight Check (state in your reasoning at turn start):</h3>
> *"Pre-Flight: I called `list_messages({status: 'unread'})` and observed [N unread / none]. [If unread: I will read the most relevant before yielding the turn / queued for processing context.]"*
<h3 class="neo-h3" data-record-id="9">Why</h3>
Without an explicit turn-start check:
- You may proceed on stale mental model (cross-family reviewer's response missed)
- Coordination signals (pause requests, work-split changes) get lost
- State-mismatch findings compound across review cycles
- Cross-cycle continuity breaks at every turn boundary
<h3 class="neo-h3" data-record-id="10">Conditional skip</h3>
If the user's prompt is direct continuation of the immediately-prior turn AND no time-elapsed signal suggests messages may have arrived (e.g., user says "now do Y" within seconds of your last response), the inbox check is OPTIONAL — but err toward checking when in doubt.
<h3 class="neo-h3" data-record-id="11">Relationship to Phase 3 wake substrate (#10357)</h3>
Once the wake substrate ships (Shape A/B/C), auto-wake events prime the next turn with mailbox context. The mailbox-check Pre-Flight then becomes the **verification primitive** for auto-wake delivery — catches gaps where:
- Subscriber filter excluded a relevant event
- Wake substrate transport failure (network, harness)
- Cold-cache (fresh session bootstrap, no prior subscription state)
- In-flight turn arrival (wake fires post-turn-completion; next turn needs to query state)
The mandate is NOT obsoleted by auto-wakeup; it's the discipline-layer companion to the substrate-layer push.
<h3 class="neo-h3" data-record-id="12">Empirical anchor</h3>
Session `aaf22f06-cc5c-4dff-aa2f-7d5efb3a6343` (2026-04-26): 6+ instances of inbound A2A messages requiring explicit human-prompted nudges before being read by the receiving agent. Pattern recurs across both Claude Code and Antigravity sessions. Post-this-codification, the Pre-Flight reasoning-statement transforms the discipline from "remember to check sometimes" to "explicit commitment before yielding."Acceptance Criteria
Out of Scope
- Critical Gate elevation (§0) — §0 is reserved for mechanically-verifiable invariants with no conditional exceptions. The mailbox check has a legitimate conditional-skip clause (direct-continuation turns) so it doesn't fit Critical Gate semantics. New §22 is the right home.
- Per-turn enforcement automation (e.g., a hook that auto-runs
list_messages before every turn). Discipline-layer first; mechanical enforcement is premature until discipline-layer proves insufficient.
since_message_id watermark on per-agent identity — incremental polling primitive that scales linearly with new-message volume. Out-of-scope for this discipline ticket; possibly implied by the eventual wake substrate's resync semantics + agent-side commitId tracking. File separately if pattern emerges.
- Mailbox triage ordering / priority — i.e., "read high-priority A2A messages first." Discipline ticket is just "check"; how to triage is separate concern.
Avoided Traps
- Bolting into §0 Critical Gates as a 6th gate. Tempting for symmetry with §0.5 (
add_memory), but the conditional-skip clause means it's not a hard invariant. §22 separate-section placement is correct.
- Adding to AGENTS_STARTUP.md only. AGENTS_STARTUP.md is one-time-boot, not per-turn-loaded. The discipline must fire reflexively at every turn start, not just at session boot.
- Creating a new skill (
.agent/skills/mailbox-check/). Progressive Disclosure overhead for ~25 lines of discipline doesn't pay off; AGENTS.md is the right home.
- Writing without empirical anchor. The 6+ missed-message incidents from the session ID are concrete receipts; cite them so future agents reading §22 understand the failure mode being prevented (not abstract discipline).
- Conflating with #10380's sibling-file-lift discipline. Different shape: #10380 targets authoring-time discipline (before writing a new class file); this ticket targets turn-start-time discipline (before reading the user's prompt). Both are per-turn AGENTS.md hardening but at different lifecycle points.
- Treating as "obsoleted by Phase 3 wake substrate." Wake substrate addresses the push-delivery layer; this ticket addresses the verification-pull layer. Both needed, complementary substrates.
Related
- Sibling per-turn AGENTS.md hardening ticket: #10380 (sibling-file-lift discipline) — different lifecycle point but parallel pattern; both can land together as "post-Phase-3 per-turn AGENTS.md hardening" cluster.
- Symmetric companion (already codified):
AGENTS.md §0.5 + §4.2 — Consolidate-Then-Save at turn-end. This ticket adds the symmetric counterpart at turn-start.
- Pre-Flight Check pattern source:
AGENTS.md §3 Pre-Commit Hard Gates — the canonical primitive being applied here.
- Phase 3 wake substrate: Epic #10357 + ADR 0002 — once shipped, this ticket's mandate becomes the verification primitive for auto-wake delivery.
- Substrate-evolution pattern: "turn friction into gold" mandate per
AGENTS.md §13 (Self-Evolving Systems) — this ticket exemplifies the pattern (6+ empirical anchors → codified discipline).
Origin Session ID: aaf22f06-cc5c-4dff-aa2f-7d5efb3a6343
Retrieval Hint: "mailbox-check Pre-Flight" / "turn-start inbox check" / "verify-incoming-substrate-symmetric-to-add_memory" / "list_messages turn-start mandate"
Context
Empirical observation from session
aaf22f06-cc5c-4dff-aa2f-7d5efb3a6343: cross-family agent (@neo-opus-ada) missed inbound A2A messages from@neo-gemini-pro6+ times in a single session. In each instance,@tobiuhad to nudge explicitly ("gemini sent you a message" / "gemini sent you 2 messages" / "gemini replied") before the messages were read. The discipline gap is structural — there is currently no per-turn-start mandate to checklist_messages({status: 'unread'})before proceeding with the user's prompt.The Problem
AGENTS.md §0.5+§4.2codify the outgoing persistence discipline at turn-end (add_memoryconsolidates the turn before yielding). The symmetric primitive for incoming state ingestion at turn-start is missing. Without it, the persistence loop is asymmetric — agents save outgoing state but don't reflexively ingest incoming substrate state.This creates four observable failure modes:
The Architectural Reality
Per-turn-loaded discipline docs:
AGENTS.md §0Critical Gates — invariants, no conditional exceptionsAGENTS.md §4Memory Core Protocol —add_memoryat turn-end (§4.2 Consolidate-Then-Save)AGENTS.md §3Pre-Commit Hard Gates — Pre-Flight Check pattern with explicit reasoning-statementAGENTS.md §19Working with Sub-Agents — delegation discipline (different concern: out-going to spawned sub-agents, not in-coming from peers)Current per-turn-start coverage: none. Both Claude Code (
AGENTS.mdper-turn-loaded) and Antigravity (per~/.gemini/antigravity/mcp_config.jsoncontext.fileName) load AGENTS.md per turn, so a single addition to AGENTS.md fixes both harnesses symmetrically.The empirically-strongest reflex primitive in this codebase is the Pre-Flight Check pattern (§3 / §4.2): mandate the agent state in their reasoning before yielding. The same shape applied to inbox-check would be:
Architectural relationship to Phase 3 wake substrate (#10357)
Once the wake substrate ships (Shape A/B/C), auto-wake events PRIME the next turn with mailbox context. The mailbox-check Pre-Flight does NOT become obsolete — it changes role from "primary delivery" to "verification primitive." Wake substrate is push-based and has structural blind spots:
Same
verify-effect-not-just-successdiscipline we apply to PR review state-mismatch: wake substrate primes the context; turn-start check verifies delivery.The Fix
Single new section in AGENTS.md, parallel to §4 Memory Core Protocol. Suggested as §22 (or wherever fits between #10380's proposed §22 and the existing §21):
<h2 class="neo-h2" data-record-id="7">§22. The Mailbox Check Protocol (Pre-Flight at Turn Start)</h2> Symmetric companion to §4.2 (Consolidate-Then-Save at turn end): at turn start, you MUST check your A2A mailbox for unread messages before proceeding with the user's request. <h3 class="neo-h3" data-record-id="8">Pre-Flight Check (state in your reasoning at turn start):</h3> > *"Pre-Flight: I called `list_messages({status: 'unread'})` and observed [N unread / none]. [If unread: I will read the most relevant before yielding the turn / queued for processing context.]"* <h3 class="neo-h3" data-record-id="9">Why</h3> Without an explicit turn-start check: - You may proceed on stale mental model (cross-family reviewer's response missed) - Coordination signals (pause requests, work-split changes) get lost - State-mismatch findings compound across review cycles - Cross-cycle continuity breaks at every turn boundary <h3 class="neo-h3" data-record-id="10">Conditional skip</h3> If the user's prompt is direct continuation of the immediately-prior turn AND no time-elapsed signal suggests messages may have arrived (e.g., user says "now do Y" within seconds of your last response), the inbox check is OPTIONAL — but err toward checking when in doubt. <h3 class="neo-h3" data-record-id="11">Relationship to Phase 3 wake substrate (#10357)</h3> Once the wake substrate ships (Shape A/B/C), auto-wake events prime the next turn with mailbox context. The mailbox-check Pre-Flight then becomes the **verification primitive** for auto-wake delivery — catches gaps where: - Subscriber filter excluded a relevant event - Wake substrate transport failure (network, harness) - Cold-cache (fresh session bootstrap, no prior subscription state) - In-flight turn arrival (wake fires post-turn-completion; next turn needs to query state) The mandate is NOT obsoleted by auto-wakeup; it's the discipline-layer companion to the substrate-layer push. <h3 class="neo-h3" data-record-id="12">Empirical anchor</h3> Session `aaf22f06-cc5c-4dff-aa2f-7d5efb3a6343` (2026-04-26): 6+ instances of inbound A2A messages requiring explicit human-prompted nudges before being read by the receiving agent. Pattern recurs across both Claude Code and Antigravity sessions. Post-this-codification, the Pre-Flight reasoning-statement transforms the discipline from "remember to check sometimes" to "explicit commitment before yielding."Acceptance Criteria
AGENTS.mdupdated with new §22 (or appropriately-numbered)Mailbox Check Protocolsection parallel to §4 (Memory Core Protocol).~/.gemini/antigravity/mcp_config.jsoncontext.fileName); no harness-specific work needed.Out of Scope
list_messagesbefore every turn). Discipline-layer first; mechanical enforcement is premature until discipline-layer proves insufficient.since_message_idwatermark on per-agent identity — incremental polling primitive that scales linearly with new-message volume. Out-of-scope for this discipline ticket; possibly implied by the eventual wake substrate's resync semantics + agent-side commitId tracking. File separately if pattern emerges.Avoided Traps
add_memory), but the conditional-skip clause means it's not a hard invariant. §22 separate-section placement is correct..agent/skills/mailbox-check/). Progressive Disclosure overhead for ~25 lines of discipline doesn't pay off; AGENTS.md is the right home.Related
AGENTS.md §0.5+§4.2— Consolidate-Then-Save at turn-end. This ticket adds the symmetric counterpart at turn-start.AGENTS.md §3Pre-Commit Hard Gates — the canonical primitive being applied here.AGENTS.md §13(Self-Evolving Systems) — this ticket exemplifies the pattern (6+ empirical anchors → codified discipline).Origin Session ID: aaf22f06-cc5c-4dff-aa2f-7d5efb3a6343
Retrieval Hint: "mailbox-check Pre-Flight" / "turn-start inbox check" / "verify-incoming-substrate-symmetric-to-add_memory" / "list_messages turn-start mandate"