LearnNewsExamplesServices
Frontmatter
id13411
titleA2A/wake lifecycle messages carry a mechanical PR-state echo
stateClosed
labels
enhancementaiarchitecture
assigneesneo-gpt
createdAtJun 16, 2026, 5:29 AM
updatedAtJun 16, 2026, 3:45 PM
githubUrlhttps://github.com/neomjs/neo/issues/13411
authorneo-opus-ada
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 16, 2026, 3:45 PM

A2A/wake lifecycle messages carry a mechanical PR-state echo

Closed v13.1.0/archive-v13-1-0-chunk-3 enhancementaiarchitecture
neo-opus-ada
neo-opus-ada commented on Jun 16, 2026, 5:29 AM

Context

Operator-asked, 2026-06-16: "how can we get better to check what is merged already before writing responses?" — after status / handoff responses repeatedly asserted stale merge-state (naming a PR "at the merge gate" / "awaiting merge" that had already merged seconds earlier; happened ~5× in one session). The pr-review audit pr-state-freshness.md already mandates a live gh pr view <N> --json state,mergedAt before any merge-eligibility relay — but it loads ONLY inside /pr-review, so general status / A2A / wake responses skip it and assert stale state from a signal that went stale "within seconds of being read" (that audit's own framing; empirical anchors #12950 / #12956).

This ticket implements that audit's named sunset condition: "if A2A lifecycle messages ever carry a mechanical state echo, compress this audit to its trigger line."

Release classification: post-release substrate / agent-MX (NOT v13-release-blocking) → boardless.

The Problem

Under merge-on-approval, every PR signal (A2A handoff, wake digest, comment) is stale within seconds. The current mitigation is discipline — the agent must remember to run the live state read before every merge-state claim — which (a) only fires in /pr-review, and (b) is a manual gate the agent silently skips under context pressure. The recurring, operator-visible result: responses confidently assert a merge-state the live tracker already contradicts.

Discipline doesn't scale; the fix is to make the signal itself carry live state, so the agent reads truth from the payload instead of reconstructing it (or failing to). This is the friction → gold shape — a repeated agent mistake becomes a substrate mechanization, not a louder rule.

The Architectural Reality

  • The wake payload already fetches + embeds GitHub context — the [WAKE] digest carries latest GitHub mention: "<title>" (<pull URL>). Adding the referenced PR's live state / mergedAt to that existing fetch is a small enrichment, not a new integration. (Wake driver: ai/daemons/wake/daemon.mjs — confirm the exact enrichment locus at implementation; this is the wake-daemon owner's territory.)
  • A2A lifecycle messages (add_message) already carry relatedTickets: [...]. When a related entry is a PR, the message read-path (or the digest renderer in the memory-core message layer) can resolve + attach its terminal/open state so the consuming agent sees it inline.
  • pr-state-freshness.md (.agents/skills/pr-review/audits/) is the discipline this mechanizes; its sunset condition explicitly anticipates this work and tells the skill how to compress once it lands.
  • Sibling #11829 (multi-strategy wake-driver substrate — content / delivery / skill / metadata layers): this PR-state echo is a concrete content/metadata-layer instance, but goal-distinct (freshness-of-relayed-state, not idle-out prevention).

The Fix

  • Enrich the wake digest: for each PR the wake references (the latest GitHub mention PR, and optionally the agent's own open PRs), attach live state + mergedAt so a status response reads merge-state from the payload, not a stale recollection.
  • Enrich A2A lifecycle messages: when relatedTickets names a PR, resolve + render its live state inline at READ time (or stamp at send time with an explicit as-of timestamp the reader treats as a floor).
  • Once the echo is live, compress pr-state-freshness.md to its trigger line in the pr-review guide (the audit's own sunset instruction).

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
[WAKE] digest PR-state echo pr-state-freshness.md sunset + the existing wake GitHub-mention fetch Each referenced PR carries live state / mergedAt inline in the digest Live fetch fails → omit the echo, keep the existing mention (never emit a stale-but-confident state) wake-driver JSDoc / @summary Unit test on the enrichment fn + a wake-digest render assertion
A2A message PR-state echo add_message relatedTickets + pr-state-freshness.md A PR in relatedTickets resolves to its live state at read time Fetch failure → no echo, message still delivers message-layer JSDoc Unit test: related-PR resolves to state; failure degrades safe
pr-state-freshness.md audit the audit's own sunset condition Compress to a single trigger line once the echo is live Echo partial (wake only, not A2A) → keep the audit for the uncovered path the audit file The compression PR cites the live echo

Decision Record impact

aligned-with the pr-state-freshness.md gate (implements its sunset). No ADR amendment. Related-to #11829 (wake-driver layers) and the fleet-freshness Discussion #13374 (distinct domain: agent/fleet freshness vs PR-merge-state freshness).

Acceptance Criteria

  • The [WAKE] digest carries live state / mergedAt for each PR it references (at minimum the latest GitHub mention PR).
  • A live-fetch failure degrades safe — the echo is omitted, never emitted stale; the existing mention / message still delivers.
  • A2A lifecycle messages whose relatedTickets name a PR surface that PR's live state to the reading agent.
  • Focused unit coverage: the enrichment resolves an open PR to OPEN and a merged PR to MERGED / mergedAt, and a fetch failure degrades safe.
  • Once the echo is live, pr-state-freshness.md is compressed to its trigger line in the pr-review guide (the sunset).

Out of Scope

  • The broader idle-out wake-driver layering (#11829) — this is one content/metadata layer, not the multi-strategy substrate.
  • Fleet / agent-state freshness (#13374 domain) — distinct.
  • Editing core AGENTS.md discipline — if a turn-loaded one-liner is also wanted (apply the live-state check to ALL responses, not just PR-review), that is an operator-directed substrate edit, tracked separately.
  • Non-PR ticket / issue state echoes (PRs first; issues later if the pattern proves out).

Avoided Traps

  • Louder rule instead of mechanization: rejected. The discipline already exists (pr-state-freshness.md) and still gets skipped; the gold is making the signal carry truth, not adding a sterner reminder.
  • Stamp-at-send only: insufficient alone — a send-time stamp is itself stale by read time; the echo must resolve (or re-note freshness) at READ time, or carry an explicit as-of timestamp the reader treats as a floor.

Related

  • pr-state-freshness.md (the discipline this mechanizes + sunsets)
  • #11829 (multi-strategy wake-driver substrate — sibling layer)
  • #13374 (fleet-freshness Discussion — distinct freshness domain)
  • Empirical: #12950 / #12956 (the freshness-failure anchors in pr-state-freshness.md)

Origin Session ID: 47b6dbc0-7673-4ad3-a9f5-bef3b606c56b

Retrieval Hint: "A2A wake PR-state echo freshness sunset pr-state-freshness mechanization"