Repository navigation
Description
Is your feature request related to a problem? Please describe
The agent rule layer in this repo is good at three things: code style
(docs/ai/coding_conventions.md), the pre-done gate
(docs/ai/mandatory_checks.md), and post-mortem capture
(.agents/skills/mistake-reflection). What none of them state is which
surfaces a task-state write has to reach. That gap keeps producing the same
class of defect: a value that is correct on one surface and missing or stale
on another.
Recent instances, all in this class:
- v0.3 gRPC compat drops task status timestamp and three other fields #1276 (closed):
status.timestampwas mapped by
src/a2a/compat/v0_3/conversions.py(JSON-RPC/REST compat) but not by
src/a2a/compat/v0_3/proto_utils.py(gRPC compat) — the same field appeared
or disappeared depending on transport. - [Bug]: Framework-written FAILED status drops status.timestamp, persisting last_updated as NULL #1331 (open): a framework-written
FAILEDstatus carried no
status.timestamp, andsrc/a2a/server/tasks/database_task_store.py:152-157
deriveslast_updatedfrom it, so the row persistedNULLand dropped out
ofListTasksordering. - [Bug] DefaultRequestHandlerV2: ActiveTaskRegistry resumes from a stale task snapshot after input_required, silently overwriting store state (multi-replica deployments) #1188 (open) / [Bug]: Blocking continuation returns stale INPUT_REQUIRED when executor emits current task #1409 (open): the handler resumes or returns from a snapshot
that disagrees with what later reaches the store and the stream. - [Bug]:
taskIdwithoutcontextIdcreates a new context instead of inheriting it #1206 (closed as stale) → [Bug]: taskId-only continuation still fails required contextId inference in SDK 1.3.0 (follow-up to #1206) #1411 (open):contextIdinference makes events
disagree with the storedTask. - Review findings on fix(server): always stamp status.timestamp on terminal task states #1346: stamping the local copy after
task.status.CopyFrom(event.status)leaves the published event unstamped
(src/a2a/server/tasks/task_manager.py:285), and theCANCELEDpaths at
src/a2a/server/agent_execution/active_task.py:971-973keep the previous
state's timestamp. These were caught by review, not by any documented rule.
The same confusion shows up in the discussion forum, where it has no issue
tracker to land in: #248 ("Should Message events terminate…", 6 comments),
#435, #40 ("What's the purpose of EventQueue?"), and the multi-replica thread
#1224 / #336.
Describe the solution you'd like
A new skill, .agents/skills/task-state-invariants/SKILL.md, in the same
shape as mistake-reflection (trigger list → procedure → anti-patterns),
covering:
- the invariant set, each claim anchored to current
main(terminal states
need a timestamp; stamp the event beforeCopyFrom;CopyFrominherits
the old timestamp; push delivery is best-effort; zero events means a hung
caller; store and stream must agree; v0.3 compat has two independent
mappers; continuation identity is inferred per spec §3.4.3); - a sibling-surface checklist to run before declaring such a change done
(persisted store, streaming subscribers, push notification, cluster
task_eventstable, both compat mappers); - a test map naming the existing file per surface, so coverage lands where
the surface is; - the evidence a PR in this area should carry, consistent with
docs/ai/evidence_rules.md.
Plus a one-line pointer in AGENTS.md "Mandatory workflow". That pointer
matters: AGENTS.md is the only file in the repo that routes to
.agents/skills/, so a skill without a route is never loaded.
Describe alternatives you considered
- A
docs/ai/rules page. Rejected as the primary form:docs/ai/*is
read at task start, while this knowledge is only useful at the moment you
touch a status write — which is howmistake-reflectionis structured.
Happy to have both if maintainers prefer the rule text to live indocs/ai
with the skill as a thin pointer. - Encoding it only in tests. Partially useful, but tests cannot tell a
change agent which sibling surface they forgot. - Fixing each bug as it arrives. Six-plus in about six weeks suggests the
per-bug loop is not converging.
Additional context
Scouting the rule layer, .agents/skills/ has exactly one skill today and it
was introduced internally by #1059 — I found no precedent for an externally
contributed skill, so raising this first rather than assuming. A draft
implementation (skill + the one-line router pointer, markdown-only, no
runtime code) is ready and filed as a PR linked to this issue. Easy to trim:
drop the AGENTS.md line, or scope the skill to the compat-mapper and
timestamp rules only.
Code of Conduct
- I agree to follow this project's Code of Conduct
Activity
Linux2010 commentedon Nov 2, 2026
Draft PR with the concrete proposal is up: #1414
It is intentionally a draft — I did not find precedent for an externally contributed entry in
.agents/skills/(mistake-reflectionwas introduced internally in #1059), so I would rather confirm appetite here than have a PR land on the review queue uninvited.Two decisions I would like input on before marking it ready:
docs/ai/with the skill kept as a thin pointer? The repo currently uses both shapes —docs/ai/evidence_rules.mdcalls itself "graduated learnings promoted fromai_learnings.mdonce a rule has earned a permanent home", sodocs/ai/is a legitimate home for the rule set too.AGENTS.mdwelcome, or should the router stay three steps and rely ondocs/ai/for discovery?The skill body itself is ready either way — reshaping it is a copy edit, not a rewrite.
Linux2010 commentedon Nov 2, 2026
One scoping note: this pass actually surfaced a second skill candidate, which I deliberately did not bundle in.
.agents/skills/covers the reactive step of the mandatory workflow (mistakes) and this PR adds the missing domain invariant step, but the CI-enforced gate itself (docs/ai/mandatory_checks.md) still has no procedure for the part that costs contributors the most time: telling pre-existing diagnostics from newly introduced ones, and telling a real regression from an environment artifact. Two concrete examples from work in this area:-25%on a refactored module, which looked like a regression but was unreachable dead code introduced by the refactor itself;tests/integration/cross_version/...intermittently errors withServer ... HTTP failed to startin sandboxes that cannot bind the subprocess server — indistinguishable from a real failure unless you re-run against a stashed cleanmain.Both have a cheap, deterministic answer (stash-baseline diff for diagnostics; standalone re-run plus clean-checkout comparison for suite errors). If there is appetite for a second skill along those lines, I would rather land it as its own PR after this one is shaped, since it is the same rule layer and I do not want to make this review carry two decisions.
rohityan commentedon Nov 2, 2026
Hi @Linux2010, thanks for this proposal.
Regarding your design questions:
.agents/skills/task-state-invariants/SKILL.mdis the cleanest approach. It keeps initial agent context indexing lightweight while loading the full domain checklist on-demand.AGENTS.md: Adding the explicit numbered step toAGENTS.mdis welcome and preferred; passive discovery viadocs/ai/risks agents bypassing the checklist when modifying task mutations.EventQueue: Ina2aproject/a2a-python,EventQueueserves as the bounded, asynchronous buffer decoupling event publishers (TaskManager.save_task_event) from downstream consumers (ActiveTask, push notifications, and persistence) to ensure non-blocking dispatch and serialized updates.Draft PR #1414 looks architecturally sound. Please feel free to mark it ready for review. Assigning this issue to you till the PR gets reviewed.