How must an instance attribute multi-agent contributions to a single factual conclusion?
**Date of Record:** 2026 October 26 **Scope:** Applies when multiple autonomous agents contribute partial evidence, reasoning, or verification to a single factual conclusion, and the orchestrator must persist attribution so future consumers can audit which agent contributed what. Does not apply to single-agent conclusions or cases where all contributions come from one source.
Core Distinction
The separation between **aggregate conclusion** (the final fact, e.g., "The API accepts HTTP/2") and **contributor attribution graph** (the cryptographic map of which agent contributed which piece of evidence, and which agents independently verified it). Failing to distinguish these creates the **Attribution Collapse**: when the conclusion is later found to be wrong or incomplete, no one can determine which agent's contribution was faulty, forcing a full re-derivation from scratch and preventing the system from quarantining the failing agent.
What Was Observed
In multi-agent reasoning and verification architectures, failing to attribute contributions produces three primary failure modes:
- **Silent Fault Propagation:** Agent A contributes a faulty premise, Agent B verifies it (incorrectly), Agent C builds a conclusion on it. When the conclusion fails, no one knows that Agent A was the root cause, so the entire swarm is retrained or quarantined.
- **Credit Erosion:** Agent A discovers a key insight, Agent B summarizes it, Agent C reports it. The successor sees only Agent C's name and cannot attribute the discovery correctly, leading to incorrect trust scoring over time.
- **Consensus Laundering:** A malicious agent contributes a wrong claim that gets absorbed into the aggregate conclusion. Without attribution, the malicious agent cannot be identified and removed from the swarm.
Recorded Elements
- **`contribution_manifest`:** The exact list of agents that contributed to the conclusion, with their specific evidence, reasoning, or verification payloads hashed and sealed.
- **`verification_independence_signature`:** The cryptographic proof that some agents verified the conclusion independently (not by copying each other), enabling the successor to weight their contributions correctly.
- **`provenance_dag_hash`:** The hash of the Directed Acyclic Graph representing which agent's contribution depended on which other agent's contribution, preserving the causal chain of evidence.
- **`fault_quarantine_directive`:** The fail-closed instruction if a contribution is later found to be faulty (e.g., "quarantine Agent A's future contributions, re-verify dependent conclusions").
Condition of Validity
* **Applies when:** Multiple agents contribute to a single conclusion, and the conclusion may later be invalidated, requiring root cause analysis and targeted remediation. * **Does not apply when:** All evidence comes from a single trusted source (no attribution needed), or the conclusion is trivially verifiable by direct ground truth without multi-agent aggregation.
Decision Boundary
- **Did multiple agents contribute to the conclusion?** If no, standard single-source attribution applies. If yes, proceed.
- **Is the `contribution_manifest` recorded with per-agent evidence hashes?** If no, attribution is impossible. The instance must reconstruct attribution before persisting the conclusion.
- **Is the `verification_independence_signature` present?** If no, the agents may have copied each other. The successor cannot weight their agreement correctly.
- **Conversely, when can an instance persist a conclusion without per-agent attribution?** Only when the conclusion is marked as `CONSENSUS_UNVERIFIED` and the successor is explicitly instructed to re-verify from scratch.
Operational Effect
- **Targeted Quarantine:** Allows the successor to quarantine the exact faulty agent rather than the entire swarm when a conclusion fails.
- **Trust Calibration:** Enables the system to weight agent contributions based on their historical accuracy, improving swarm-level reasoning quality over time.
- **Forensic Auditability:** Provides an audit trail of which agent said what, preventing consensus laundering by malicious agents.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class AttributionVerdict(Enum):
ATTRIBUTION_VERIFIED = auto()
MISSING_ATTRIBUTION = auto()
NON_INDEPENDENT_VERIFICATION = auto()
@dataclass(frozen=True)
class Contribution:
agent_id: str
contribution_type: str # "EVIDENCE", "REASONING", "VERIFICATION"
payload_hash: str
depends_on: frozenset[str]
@dataclass(frozen=True)
class AttributionContext:
independent_verifiers: frozenset[str]
required_min_verifiers: int
@dataclass(frozen=True)
class AttributionManifest:
verdict: AttributionVerdict
contributors: tuple[str, ...]
directive: str
manifest_digest: str
class ContributionAttributionGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_attribution(
cls, contributions: tuple[Contribution, ...], ctx: AttributionContext
) -> AttributionManifest:
if not contributions:
return AttributionManifest(
verdict=AttributionVerdict.MISSING_ATTRIBUTION,
contributors=tuple(),
directive="HALT: No contributions recorded. Cannot attribute conclusion.",
manifest_digest=cls._hash("NO_CONTRIBUTIONS")
)
contributor_ids = tuple(sorted({c.agent_id for c in contributions}))
# Gate 1: Independent verifiers check
verifiers = {c.agent_id for c in contributions if c.contribution_type == "VERIFICATION"}
independent = verifiers & ctx.independent_verifiers
if len(independent) < ctx.required_min_verifiers:
return AttributionManifest(
verdict=AttributionVerdict.NON_INDEPENDENT_VERIFICATION,
contributors=contributor_ids,
directive=f"HALT: {len(independent)} independent verifiers, minimum required {ctx.required_min_verifiers}.",
manifest_digest=cls._hash(f"INSUFFICIENT_VERIFIERS:{len(independent)}")
)
# Gate 2: Dependency DAG integrity
all_ids = {c.agent_id for c in contributions}
for contribution in contributions:
for dep in contribution.depends_on:
if dep not in all_ids and dep != contribution.agent_id:
return AttributionManifest(
verdict=AttributionVerdict.MISSING_ATTRIBUTION,
contributors=contributor_ids,
directive=f"HALT: Contribution {contribution.agent_id} depends on unknown agent {dep}.",
manifest_digest=cls._hash(f"BROKEN_DAG:{contribution.agent_id}")
)
# Gate 3: Verified
digest = cls._hash(json.dumps({
"contributors": contributor_ids,
"verifiers": tuple(sorted(independent)),
"count": str(len(contributions))
}, sort_keys=True))
return AttributionManifest(
verdict=AttributionVerdict.ATTRIBUTION_VERIFIED,
contributors=contributor_ids,
directive="PROCEED: Attribution graph is complete and independently verified.",
manifest_digest=digest
)