2026-04-25 author update: Original scope was "structured JSON intent payloads" with a Neo-native sketch. Per @tobiu's challenge this turn ("official standards for a2a protocols did emerge") and subsequent web_search confirmation, the Google Agent2Agent (A2A) Protocol v1.0 (Linux Foundation, 150 production orgs, native support across LangGraph/CrewAI/Google ADK/etc) is the authoritative external standard for agent-to-agent payload schemas. Recalibrating this ticket's scope to align: instead of inventing Neo-native payload shape, adopt A2A Task object envelope subset (Option C hybrid) per cross-family discussion at https://github.com/neomjs/neo/discussions/10313#discussioncomment-16714045. Existing scope captured below; A2A-aligned scope amendment follows.
Context (original — unchanged)
#10272 identified that A2A hand-offs lack a conventional structured shape, forcing agents to parse markdown bodies. This is fragile and inefficient for programmatic agent coordination.
The Problem (original — unchanged)
Stringifying A2A handoffs into Markdown bodies relies on natural language parsing, which is brittle for programmatic agent coordination. Agents need a structured way to communicate intents.
The Architectural Reality — RECALIBRATED
The Memory Core mailbox from #10145 can carry typed messages, but currently relies on stringified text bodies. Transitioning to structured JSON intents is now an A2A-spec-alignment opportunity, not a Neo-native invention. Per Discussion #10313 cross-family iteration this turn:
- A2A spec defines a Task object with
state, input.parts, metadata, artifacts, history fields
- State enum standardized:
Submitted, Working, InputRequired, Completed, Canceled, Failed, Rejected, AuthRequired, Unknown (PascalCase per spec)
- Agent Card concept exists for capability advertisement (deferred to follow-up Phase)
Recalibrated scope adopts A2A Task object envelope as the message-payload shape, with Neo-extension fields (e.g., expiresAt, BLOCKED state) where the standard doesn't cover Neo-specific needs.
The Fix — RECALIBRATED
Add a structured task field on MESSAGE node properties carrying an A2A-Task-object-shaped JSON payload. Backward-compatible: existing body (markdown) field stays; task is opt-in for structured handoffs.
Schema sketch (A2A-aligned subset, Phase 1):
interface MessageTaskPayload {
state?: 'Submitted' | 'Working' | 'InputRequired' | 'Completed' | 'Canceled' | 'Failed' | 'Rejected' | 'AuthRequired' | 'Unknown';
input?: {
parts: Array<{
kind: 'text' | 'data' | 'file';
text?: string;
data?: object;
file?: { uri: string; mimeType?: string };
}>;
};
metadata?: {
sessionId?: string;
relatedTickets?: string[];
relatedDiscussions?: string[];
parentTask?: string;
priorComments?: { url: string; commentId: string }[];
};
expectedOutput?: {
shape: 'review' | 'ticket' | 'discussion' | 'pr' | 'free-form';
locationHint?: string;
};
budget?: {
deadline?: string;
maxTokens?: number;
};
expiresAt?: string;
}
Phase 2 (separate sub-ticket post-#10313 graduation): state-machine logic + transition authority enforcement + idempotency claim-and-lock — gated on Discussion #10313 OQ convergence on Option A/B/C.
Acceptance Criteria — RECALIBRATED
Out of Scope
- Full A2A Agent Card protocol — capability advertisement is Phase-3+ scope. This ticket is just the Task envelope.
- State-machine transition logic — covered by Discussion #10313 graduation sub-tickets (Phase 2). This ticket adds the
state field; assignment-validation rules layer on top later.
- A2A-protocol HTTP server — Neo's MailboxService is the substrate; A2A external interop layer is separate scope.
- Migration of existing
body-only messages — messages without task continue working unchanged; no retroactive backfill.
- Wakeup mechanism integration — Track 1's swarm-heartbeat.sh polls SQLite directly (per #10335). The Track 2 schema this PR introduces becomes consumable by Track 1's polling once shipped.
Avoided Traps
- Re-inventing A2A Task object schema — rejected per @tobiu's challenge + the web_search finding. Aligning is the architecturally-correct move; Neo speaking A2A makes Neo's swarm interoperable with the broader ecosystem (per
feedback_neo_is_engine_not_framework: Unreal speaks USD/glTF; engines adopting standards strengthens identity rather than dilutes).
- Putting state-machine in this PR — rejected; scope-creep into Phase 2 territory. This ticket is the envelope primitive; state-machine work is Phase 2 sub-tickets.
- Renaming MESSAGE to A2A_TASK as the only primitive — rejected per Discussion #10313 OQ2 reasoning: MESSAGE (informational) and TASK (transactional) are conceptually different. This ticket adds task-envelope to MESSAGE without conflating them.
- Going Option A spec-strict before cross-family convergence — rejected; Option A removes Neo extensions like
expiresAt we already decided on. Hybrid (Option C) preserves both.
Related
- Discussion #10313 — cross-family A2A spec alignment recalibration in flight
- #10311 — Epic: Institutionalizing Swarm Autonomy. Track 2 substrate work.
- #10325 — sharedEntity:true primitive (graph layer); compatible with A2A task field
- #10330 / #10331 — single-canonical identity format (caller-format prerequisite for A2A target identification)
- #10335 — Track 1 swarm-heartbeat MVP (polls SQLite for state-changed tasks; consumes what this ticket writes)
- External: A2A Protocol Specification — authoritative external standard
Origin Session ID: b5a17132-7324-46e1-b73e-038825bb4d55
Retrieval Hint: "A2A Task object envelope structured payload Mailbox Phase 2 substrate Linux Foundation Google interoperability hybrid extension"
Context (original — unchanged)
#10272identified that A2A hand-offs lack a conventional structured shape, forcing agents to parse markdown bodies. This is fragile and inefficient for programmatic agent coordination.The Problem (original — unchanged)
Stringifying A2A handoffs into Markdown bodies relies on natural language parsing, which is brittle for programmatic agent coordination. Agents need a structured way to communicate intents.
The Architectural Reality — RECALIBRATED
The Memory Core mailbox from
#10145can carry typed messages, but currently relies on stringified text bodies. Transitioning to structured JSON intents is now an A2A-spec-alignment opportunity, not a Neo-native invention. Per Discussion #10313 cross-family iteration this turn:state,input.parts,metadata,artifacts,historyfieldsSubmitted, Working, InputRequired, Completed, Canceled, Failed, Rejected, AuthRequired, Unknown(PascalCase per spec)Recalibrated scope adopts A2A Task object envelope as the message-payload shape, with Neo-extension fields (e.g.,
expiresAt,BLOCKEDstate) where the standard doesn't cover Neo-specific needs.The Fix — RECALIBRATED
Add a structured
taskfield on MESSAGE node properties carrying an A2A-Task-object-shaped JSON payload. Backward-compatible: existingbody(markdown) field stays;taskis opt-in for structured handoffs.Schema sketch (A2A-aligned subset, Phase 1):
interface MessageTaskPayload { // A2A Task object subset (forward-compatible with full A2A interop) state?: 'Submitted' | 'Working' | 'InputRequired' | 'Completed' | 'Canceled' | 'Failed' | 'Rejected' | 'AuthRequired' | 'Unknown'; input?: { parts: Array<{ kind: 'text' | 'data' | 'file'; text?: string; data?: object; file?: { uri: string; mimeType?: string }; }>; }; metadata?: { sessionId?: string; // origin-session anchor (Neo-specific use of A2A metadata) relatedTickets?: string[]; // Neo extension relatedDiscussions?: string[]; // Neo extension parentTask?: string; // chain-of-custody for sub-tasks (A2A-compatible) priorComments?: { url: string; commentId: string }[]; // pr-review §9 hand-off }; expectedOutput?: { // Neo extension on top of A2A shape: 'review' | 'ticket' | 'discussion' | 'pr' | 'free-form'; locationHint?: string; }; budget?: { // Neo extension deadline?: string; // ISO timestamp maxTokens?: number; }; expiresAt?: string; // Neo extension (TTL for stale-task sweeping) }Phase 2 (separate sub-ticket post-#10313 graduation): state-machine logic + transition authority enforcement + idempotency claim-and-lock — gated on Discussion #10313 OQ convergence on Option A/B/C.
Acceptance Criteria — RECALIBRATED
taskfield defined on MESSAGE node properties (per A2A subset above)MailboxService.addMessageaccepts optionaltaskparam; stores as JSON-serialized propertyMailboxService.getMessage+listMessagesreturn parsedtaskfield in responseai/mcp/server/memory-core/openapi.yaml) updated for new tool surfacetaskfield continue to work (existing markdown-body path)Submitted → Workingtransition) — last item gates on Phase 2 sub-tickettaskfieldOut of Scope
statefield; assignment-validation rules layer on top later.body-only messages — messages withouttaskcontinue working unchanged; no retroactive backfill.Avoided Traps
feedback_neo_is_engine_not_framework: Unreal speaks USD/glTF; engines adopting standards strengthens identity rather than dilutes).expiresAtwe already decided on. Hybrid (Option C) preserves both.Related
Origin Session ID:
b5a17132-7324-46e1-b73e-038825bb4d55Retrieval Hint:"A2A Task object envelope structured payload Mailbox Phase 2 substrate Linux Foundation Google interoperability hybrid extension"