Use when multiple agents have completed a round and the user asks to reconcile outputs, compare Codex and Gemini, synthesize run results, identify conflicts, or decide what should be retried.
Resources
1Install
npx skillscat add wenyuchiou/agent-collab-skills/agent-output-reconciler Install via the SkillsCat registry.
agent-output-reconciler
Cross-agent diff + synthesizer. After agent-task-splitter plans a
round and the delegate skills have run their tasks, this skill reads
everything they produced and reports:
- Did each task succeed?
- Where do agents agree (same files changed similarly, same
conclusions)? - Where do they conflict (same files changed differently, contradictory
recommendations)? - What's the recommended next move (merge / retry / escalate)?
When to use
Trigger phrases:
- "Reconcile these N agent outputs."
- "Did Codex and Gemini agree on this round?"
- "Synthesize the multi-agent run results."
- "What did the agents do this round? Any conflicts?"
- "Round N is done — give me the reconciliation report."
Not for:
- Running the agents — that's
codex-delegate(Claude lanes run via the Agent tool;gemini-delegateis deprecated, fails closed). - Final accept-or-reject gate before merging — that's
agent-acceptance-gate. The reconciler describes; the
acceptance gate decides. - Single-agent runs — if only one task in
.coord/plan.yml, there's
nothing to reconcile.
Inputs (auto-discovered)
.coord/plan.yml— the round's plan. Use theroundfield
to identify which task files are in scope..ai/<agent>_log_<NNN>_<slug>.txt.result.json— one per
non-Claude task. Schema (fromcodex-delegate's contract):
Each entry in{ "status": "success|fallback|error", "delegate": "codex|gemini", "model": "...", "log_file": "...", "output_file": "...", "summary": "...", "risks": [], "files_changed": [], "tests_run": [], "timestamp_utc": "...", // v0.2.2+ optional fields — see §2.6 promise/delivery contract: "promised": [], // artifacts this task surfaces for downstream consumers "consumed": [] // artifacts this task used from upstream tasks }risksmust be a single sentence (≤ 30 words).
Long-form analysis belongs inoutput_file, not here — verboserisksentries are a context-contract violation and the
reconciler should flag them..ai/<agent>_result_<NNN>_<slug>.md— agent-written summary
(referenced from each task file'sAcceptancesection)..ai/<agent>_log_<NNN>_<slug>.txt— full log path; read only
the configured tail for error context ifstatus: error.- For
agent: claudetasks — read the Claude session's
in-conversation output (whatever Claude said in the chat for that
task, treated as the equivalent ofresult.md). .coord/context_<NNN>.md(optional, ifagent-context-budget
ran) — declared per-task context budgets. Reconciler uses these
to flag oversized summaries / unboundedrisksarrays at the
per-task granularity, not just the plan-wide default. Absence is OK.
If the user passes specific paths, use those instead of
auto-discovery.
Workflow
1. Identify round + tasks
Read .coord/plan.yml. If multiple rounds exist, default to the
highest round number unless the user specifies. Collect the list
of (task_id, agent, slug).
2. Read each task's outputs
For each task:
- Codex / Gemini: load
result.json+result_<NNN>_<slug>.md+
log tail only whenstatus: error(default max: last 50 lines). - Claude: pull from current conversation history.
Flag any task where:
result.jsonis missing → run never completed.status: "error"→ run failed.status: "fallback"→ run completed but in degraded mode.result_<NNN>_<slug>.mdmissing → agent didn't write the
required summary (acceptance criterion violated).result_<NNN>_<slug>.mdexceedscontext_policy.result_summary_word_budget
(default 250 words) → context contract violated.
2.4. Multi-locale lockstep check (catches Gemini drop / merge)
When the round's outputs include ≥ 2 locale variants of the same
file stem (e.g., 06-memory-rag.md + 06-memory-rag.en.md +06-memory-rag.zh-Hans.md), verify they actually stayed in lockstep:
- Line count parity — each mirror within ±3% of canonical's
line count. Larger delta usually means Gemini dropped or
duplicated a section. - H2 count parity —
grep -c '^## 'returns identical count
across all locales. - Per-table column count parity — for each markdown table at
position N in canonical, verify table N in each mirror has the
same column count. (F2 incident indocs/observed-failure-modes.md:
Gemini merged a 5-column Projects table's rows into a 3-column
Tools table.) - Required headline-term cross-presence — if
plan.ymldeclaresrequired_termsfor this round, each must appear in every locale
variant. Missing in one locale = mirror sync dropped content. - Anchor strict — if repo has an anchor validator script,
run it. Broken cross-stage links are a common drop-side-effect.
If any of these fail, defer to the multi-locale-mirror-sync
preset of agent-acceptance-gate rather than computing it
manually — it's already codified there.
Surface each lockstep failure as HIGH in "Aggregated risks":
the gate will demand a re-run before merging.
2.5. Cross-task ID / slug consistency check (catches agent drift)
Real multi-agent runs sometimes produce outputs that claim to be
about different tasks than they actually were. Common cause:
gemini under inline-prompt mode (no file-system access) hallucinates
plausible-but-wrong task slugs and agent assignments because it
doesn't have plan.yml loaded.
For each agent's result.md summary, verify:
- Task IDs in the summary match plan.yml's IDs. If the agent
ran forT2per plan.yml, but its summary references "T1, T2,
T3, T4" as if doing all of them, that's drift — the agent
restated the entire plan instead of reporting on its own task. - Slugs match plan.yml's slugs. If plan.yml says T2's slug is
scaffold-provider-corebut the result.md mentionsimplement-auth-middleware(a slug not in the plan), the agent
invented context. - Agent assignments match plan.yml. If the agent's summary
claims "all 4 tasks were claude" but plan.yml has mixed
routing, the agent is treating its inline prompt as a
stand-alone planning exercise rather than a single-task report.
Surface each drift as a HIGH severity item in the
"Aggregated risks" section. Don't quietly ignore it; the gate
needs to see it.
If drift is severe (entire summary is about a different task /
scenario), recommend re-running that task with file-system access
or with the prompt body itself containing all critical context
(rather than just paths to read).
2.6. Promise vs delivery contract check (W2 — sequential hand-off integrity)
When tasks form a sequential chain (e.g., research-agent → write-agent →
verify-agent), each task's result.json MAY declare a promised field
listing artifacts the downstream consumer is expected to use:
{
"status": "ok",
"summary": "...",
"promised": [
{"kind": "video_url", "count": 5,
"detail": ["lVdajtNpaGI", "M2Yg1kwPpts", "bJFtcwLSNxI", "abc123", "def456"]},
{"kind": "concept_mapping", "count": 19}
]
}The downstream consumer's result.json MAY declare a matching consumed field:
{
"consumed": [
{"kind": "video_url", "count": 3,
"detail": ["lVdajtNpaGI", "M2Yg1kwPpts", "bJFtcwLSNxI"]}
]
}The reconciler computes the diff:
- Promised but not consumed → soft WARN (downstream agent ignored part of upstream contract — may be intentional / out of scope for this round)
- Consumed but not promised → HIGH (downstream agent invented artifacts not in any upstream
promisedlist — likely hallucination) - Counts mismatch → WARN
Severity asymmetry rationale: dropped artifacts (promised but not
consumed) are common in real workflows — research surfaces 10 facts,
write pass uses 7 because 3 weren't relevant. Invented artifacts
(consumed but not promised) are a different signal entirely — the
agent claims to use something nobody surfaced, which strongly
indicates fabrication. WARN vs HIGH reflects this difference in
expected legitimacy.
This is the contract-driven hand-off check. It catches the common
case where upstream research surfaces N facts, but downstream write
pass only uses M < N. Without this check, the contract is implicit
and silently breakable.
Backward compatibility: promised / consumed are optional fields.
Tasks without them skip this check (no FAIL). Adoption is incremental —
agents that opt-in benefit from the contract verification.
3. Compute cross-task analysis
Build three views:
(a) Agreement table — per task pair, did agents converge?
| T1 (codex) | T2 (codex) | T3 (gemini) | |
|---|---|---|---|
| T1 | — | overlap: src/auth/providers.py | no overlap |
| T2 | overlap | — | no overlap |
| T3 | no overlap | no overlap | — |
Two tasks "overlap" if their files_changed lists share any path.
Two tasks "agree" if they overlap AND their changes don't
contradict (heuristic: same file changed by two agents → flag for
manual review unless one is git mv-style and the other is content
edit).
(b) Conflict heatmap — which files were touched by multiple
tasks?
src/auth/providers.py [T1, T2] ⚠ conflict — both edit same file
src/auth/interfaces.py [T1] ok
docs/auth.md [T3] ok
tests/test_auth.py [T2] okFor conflicts, read the actual diffs and either:
- Confirm changes are independent (T1 added imports, T2 added a
function — likely mergeable). - Flag genuine collision (both rewrote the same function differently
— needs human merge).
(c) Aggregated risks — concat all risks arrays from
result.json + risks mentioned in the .md summaries.
4. Suggest a recommended action
Based on the analysis:
| Situation | Recommendation |
|---|---|
All tasks status: success, no conflicts, no risks |
"Merge all in dependency order (T1 → T2 → T3 → T4)." |
| All success but one conflict on file X | "Merge T1, T3, T4. Manually merge T2's edits to X with T1's." |
One task status: error |
"Retry T2 (failure reason: ). Don't merge other tasks until T2 succeeds, since T4 depends on T2." |
One task status: fallback |
"Review T3's degraded output before merging. Acceptance criteria may not have been met." |
| Risks flagged | "Address risks before merging: ..." |
| Cross-agent contradiction (e.g., Codex says X, Gemini's review says X is wrong) | "Escalate: invoke agent-debate on the contested point before deciding." |
5. Write .coord/reconciliation_<NNN>.md
Format (full template: references/reconciliation_template.md):
# Multi-agent reconciliation — round 1
**Goal:** Refactor the auth module into plugin-based architecture
**Created:** 2026-04-28T10:30:00Z
**Tasks:** 4 (2 codex, 1 gemini, 1 claude)
## Per-task summary
### T1 — codex — extract-interfaces ✅ success
Files: src/auth/interfaces.py (+47 lines)
Tests: pytest tests/auth/test_interfaces.py PASS
Risks: none reported.
### T2 — codex — refactor-providers ⚠ fallback
Files: src/auth/providers/google.py, src/auth/providers/saml.py (+93 / -41)
Tests: pytest tests/auth/test_providers.py — 1 FAIL (test_legacy_compat)
Risks:
- Backwards compat with legacy.py possibly broken; test_legacy_compat is failing.
### T3 — gemini — review-doc-coverage ✅ success
Output: 12 docstrings flagged as outdated (still mention legacy class).
Risks: none reported.
### T4 — claude — design-review ✅ success
Verdict: YES, the refactor is sound. Specific concerns: the
test_legacy_compat failure suggests we may need a deprecation
shim before removing legacy.py.
## Cross-task analysis
### Agreement
- T1 and T2 share scope on src/auth/* — both touched only files in
their declared in-scope globs. ✅
- T3's doc review aligns with T2's implementation: T3 flagged the
same legacy references that T2 should have removed.
- T4's design review confirms T1's interface choice.
### Conflicts
- None on file paths.
- One contradiction: T2 succeeded with a fallback (legacy compat
test failing), T4 said design is sound; T4 didn't see T2's test
failure. Flag for user decision.
### Aggregated risks
1. test_legacy_compat is failing — backwards compat possibly broken.
## Recommended action
⚠ **Don't merge yet.** Two paths:
1. **Keep legacy.py as deprecation shim** (T4's suggestion). Re-run T2
with this constraint, retry, then re-reconcile.
2. **Accept the breaking change.** Update test_legacy_compat to
reflect the new architecture, then merge T1 + T2 + T3 (and treat
T4's verdict as conditional-pass).
If you want a third opinion, invoke `agent-debate` on "should we
keep a deprecation shim for legacy auth?" before deciding.6. Hand off
End with:
[agent-output-reconciler]
Round: 1
Tasks reconciled: 4 (2 success, 1 fallback, 1 success-claude)
Conflicts: 0 file-level, 1 cross-agent contradiction (T2 failure ↔ T4 verdict)
Risks: 1 (legacy compat)
Report: .coord/reconciliation_001.md
Recommended next: review the report and either retry T2 with shim,
or accept breaking change. After deciding, run agent-acceptance-gate
for the merge decision.What NOT to do
- Don't merge anything. Reconciler describes; acceptance gate
decides; user merges. - Don't make up agreement. If two agents touched different files
on different topics, they didn't "agree" — they ran independently. - Don't suppress conflicts. If two agents edited the same
function, surface that even if both edits are syntactically valid. - Don't read the agent log files in full — tail of last 50 lines
is enough for error context, and only when status iserror. The
summary.mdfiles andresult.jsonare the primary inputs. - Don't paste raw logs into reconciliation reports. Record log
paths and compact failure summaries only. - Don't compute aggregate token cost — that's the acceptance
gate's job (it reads the same result.json files).
Subagent review (keep main session lean)
When: ≥ 3 agent outputs to reconcile, OR any agent'sresult_*.md exceeds 200 words.
Why: Reading 4 × full result.md files inline costs ~10 KB of
main session context. A per-agent subagent can pre-digest each
output and return only a structured ≤ 150-word verdict so the
reconciler works from compact digests, not raw summaries.
Pattern (parallel, one subagent per agent output):
For each task in plan.yml round:
Spawn `code-reviewer` subagent with:
- Read .ai/<agent>_result_<NNN>_<slug>.md
- Read .ai/<agent>_log_<NNN>_<slug>.txt.result.json (status,
risks, files_changed)
- Return: ≤ 150-word digest = { status, key claim, risks,
slug consistency vs plan.yml, missing-output flags }
Main session reads only the digests and writes reconciliation_<NNN>.md
from them. Never inlines the original result.md / result.json content.This is the canonical pattern for "fan-out / fan-in" multi-agent
reconciliation. It keeps the main session linear in N (number of
agents) instead of quadratic in (N × avg result size).
Commit Boundary
Every agent boundary is a commit boundary (see global rule:
~/.claude/CLAUDE.md → "Commit Discipline for Multi-Agent Work"). This
makes multi-agent work auditable (commit log = agent log) and enables
surgical rollback via git revert <hash> of just one agent's commit.
Specific to this skill: the reconciler reads each agent's output as a separate commit. If agents share an uncommitted working tree, the reconciler cannot disentangle which change came from which agent. Always commit each agent's output before invoking the reconciler.