Context
The fix lane for tonight's dup-test. Operator @tobiu broadcast a singular "one (not all!)" task → 4 agents raced → 3 dup tickets (#12851 canonical, #12852/#12853 closed) despite every agent running the mandatory ticket-create §1a GitHub dup-sweep AND two broadcasting [lane-claim]. Lead @neo-fable handed me this substrate-fix lane with the full empirical record; this ticket encodes the operator-calibrated immediate fix (the zero-infra discipline layer). The durable tool-side backstop is a separate higher-blast lane — see Related.
The Problem
ticket-create-workflow.md §1a mandates a live GitHub dup-sweep "before any create_issue call." Two structural gaps:
- Wrong substrate during the race window. Empirically (fable's record): for the first ~3 min of a thundering herd, the dups exist only as A2A
[lane-claim]s, not GitHub tickets. fable swept GitHub at 18:35Z, filed #12851 ~18:40Z — but both competing claims (18:37:48Z vega, 18:38:32Z claude) were already in the inbox, invisible to a GitHub sweep. §1a checks GitHub state — the wrong substrate for in-flight claims.
- Sweep runs too early (TOCTOU). Agents run §1a at the START of the create flow, then spend minutes drafting the Fat Ticket; by
create_issue time the sweep is stale (mine was ~3 min stale; #12851/#12852 existed by the time I filed #12853).
The empirical winner: @neo-opus-ada used a two-phase [lane-intent] → re-check → execute and filed 0. The two-phase re-check is the mechanism that works.
The Architectural Reality
.agents/skills/ticket-create/references/ticket-create-workflow.md §1a (Content Sweep / Live freshness sweep) — currently a single GitHub gh issue list sweep.
- A2A claims live in the Memory Core mailbox, queryable via
list_messages ([lane-claim]/[lane-intent]).
- Operator calibration (direct, relayed by @neo-fable): "use list_messages as the last step again before creating the ticket — if a turn takes 5-10m and we only check first, we're still stale for minutes. Mostly an issue at session start (team starts at the same time)."
- Skill-doc (
references/) amendment only — the ticket-create/SKILL.md router stays thin (Progressive Disclosure / ADR 0008 preserved). No new .mjs.
The Fix
Amend §1a Gate 0:
- Add an A2A claim sweep as the sibling of the GitHub live-sweep:
list_messages filtered for recent [lane-claim]/[lane-intent] on the same scope. GitHub sweep catches FILED dups; A2A sweep catches IN-FLIGHT dups. Same gate slot, two substrates.
- Reposition both sweeps as the LAST action immediately before
create_issue (not turn-start / pre-authoring). The turn-start mailbox check stays for general coordination but is not the dup gate.
- Deterministic tiebreak: when a competing claim is found, first-claim-timestamp-wins — the later claimant stands down (or closes its dup), no lead mediation needed. Makes simultaneous filings self-healing.
- Companion discipline: never
wakeSuppress a contested-lane resolution (the "do-not-re-file" signal must wake, or it reaches nobody — fable's 18:41Z miss tonight).
Decision Record impact
none — refines the ticket-create process substrate; no ADR governs §1a.
Acceptance Criteria
Out of Scope
- The durable sink-side semantic dedup gate on the
create_issue MCP tool (requireNoSimilarOpen + acknowledgedDuplicate, mirroring manage_issue_assignees) — higher-blast tool change, separate Ideation lane (Related). This ticket is the zero-infra discipline layer.
- Generalizing to
create_discussion (same hole likely exists) — noted for the Ideation lane.
Avoided Traps
- "Just re-run the GitHub sweep before create." Half-right: it catches later-mover dups (already-filed tickets) but MISSES the first ~3 min when dups are A2A-claims-only. The A2A sweep is the missing half.
- Relying on broadcast
[lane-claim] for mutual exclusion. Broadcasts deliver post-turn → concurrent responders are mutually blind. Discipline at the create-call gate + the deterministic tiebreak is what converges.
Related
#12851 — the ticket whose 4-way race is this lane's empirical anchor.
- Ideation (drafted, auto-mode-gated): sink-side semantic dedup gate on
create_issue — the durable tool-side backstop A; this ticket is the discipline layer C′.
#11536/#11537 — the lane-claim / pre-write coordination substrate this extends.
Handoff Retrieval Hints
query_raw_memories: "ticket-create A2A claim sweep last step before create_issue first-claim-wins"
- Empirical anchor: 2026-06-10 4-way sunset-ticket race (@neo-fable's data-handoff record).
Filed by @neo-opus-grace (Claude Opus 4.8); lane handed off by @neo-fable; operator-calibrated by @tobiu.
Context
The fix lane for tonight's dup-test. Operator @tobiu broadcast a singular "one (not all!)" task → 4 agents raced → 3 dup tickets (
#12851canonical,#12852/#12853closed) despite every agent running the mandatoryticket-create §1aGitHub dup-sweep AND two broadcasting[lane-claim]. Lead @neo-fable handed me this substrate-fix lane with the full empirical record; this ticket encodes the operator-calibrated immediate fix (the zero-infra discipline layer). The durable tool-side backstop is a separate higher-blast lane — see Related.The Problem
ticket-create-workflow.md §1amandates a live GitHub dup-sweep "before anycreate_issuecall." Two structural gaps:[lane-claim]s, not GitHub tickets. fable swept GitHub at 18:35Z, filed#12851~18:40Z — but both competing claims (18:37:48Z vega, 18:38:32Z claude) were already in the inbox, invisible to a GitHub sweep. §1a checks GitHub state — the wrong substrate for in-flight claims.create_issuetime the sweep is stale (mine was ~3 min stale;#12851/#12852existed by the time I filed#12853).The empirical winner: @neo-opus-ada used a two-phase
[lane-intent] → re-check → executeand filed 0. The two-phase re-check is the mechanism that works.The Architectural Reality
.agents/skills/ticket-create/references/ticket-create-workflow.md§1a (Content Sweep / Live freshness sweep) — currently a single GitHubgh issue listsweep.list_messages([lane-claim]/[lane-intent]).references/) amendment only — theticket-create/SKILL.mdrouter stays thin (Progressive Disclosure / ADR 0008 preserved). No new.mjs.The Fix
Amend §1a Gate 0:
list_messagesfiltered for recent[lane-claim]/[lane-intent]on the same scope. GitHub sweep catches FILED dups; A2A sweep catches IN-FLIGHT dups. Same gate slot, two substrates.create_issue(not turn-start / pre-authoring). The turn-start mailbox check stays for general coordination but is not the dup gate.wakeSuppressa contested-lane resolution (the "do-not-re-file" signal must wake, or it reaches nobody — fable's 18:41Z miss tonight).Decision Record impact
none— refines the ticket-create process substrate; no ADR governs §1a.Acceptance Criteria
list_messagesfor[lane-claim]/[lane-intent]on-scope) as a sibling to the GitHub live-sweep.create_issue(explicit "just-in-time, not turn-start" language).wakeSuppressed.references/ticket-create-workflow.mdonly;SKILL.mdrouter unchanged.create_issuesemantic dedup gate ships (the durable backstop), this discipline compresses to a trigger note.Out of Scope
create_issueMCP tool (requireNoSimilarOpen+acknowledgedDuplicate, mirroringmanage_issue_assignees) — higher-blast tool change, separate Ideation lane (Related). This ticket is the zero-infra discipline layer.create_discussion(same hole likely exists) — noted for the Ideation lane.Avoided Traps
[lane-claim]for mutual exclusion. Broadcasts deliver post-turn → concurrent responders are mutually blind. Discipline at the create-call gate + the deterministic tiebreak is what converges.Related
#12851— the ticket whose 4-way race is this lane's empirical anchor.create_issue— the durable tool-side backstop A; this ticket is the discipline layer C′.#11536/#11537— the lane-claim / pre-write coordination substrate this extends.Handoff Retrieval Hints
query_raw_memories: "ticket-create A2A claim sweep last step before create_issue first-claim-wins"Filed by @neo-opus-grace (Claude Opus 4.8); lane handed off by @neo-fable; operator-calibrated by @tobiu.