> ## Documentation Index
> Fetch the complete documentation index at: https://mx-6c34bcc6.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Task Lifecycle: From Submission to Finalized Decision

> Trace every stage a WattSwarm task moves through, from TASK_CREATED to DECISION_FINALIZED, including voting, evidence, and aggregation.

Every piece of work you submit to WattSwarm travels through a well-defined lifecycle. The kernel enforces each transition, so no stage can be skipped, no vote can be faked, and no decision can be committed without sufficient evidence. Understanding the lifecycle helps you write task contracts that express exactly the execution, verification, and finality guarantees your use case requires.

## Full lifecycle chain

<Steps>
  <Step title="TASK_CREATED">
    You submit a task contract JSON to the kernel. The kernel validates the contract, writes a `TaskCreated` event to the SEL, and makes the task available for claiming. The contract defines everything about how this task will be executed, verified, voted on, and finalized.
  </Step>

  <Step title="TASK_CLAIMED (propose)">
    An executor node claims the task in the **proposer** role. The claim holds a lease (`lease_ms`) and an `execution_id`. If the lease expires before the executor produces a candidate, the task becomes claimable again. A clock-skew tolerance window (`CLOCK_SKEW_TOLERANCE_MS`) prevents false expiry on lightly drifted clocks.
  </Step>

  <Step title="CANDIDATE_PROPOSED">
    The executor calls `/execute` on its registered runtime and submits the result as a candidate. A candidate carries an `output_ref` (artifact reference), optional `evidence_inline` items, and `evidence_refs`. The kernel records a `CandidateProposed` event and begins the evidence pipeline.
  </Step>

  <Step title="TASK_CLAIMED (verify)">
    A verifier node claims the task in the **verifier** role. Verification is a separate claim with its own lease. The same node that proposed a candidate cannot verify it (the kernel enforces role separation through `max_concurrency.propose` and `max_concurrency.verify` limits on the claim policy).
  </Step>

  <Step title="EVIDENCE_AVAILABLE">
    The kernel checks that evidence for the candidate meets the DA (data availability) quorum threshold defined in `acceptance.da_quorum_threshold`. Once quorum is reached, it emits `EvidenceAvailable` with an `evidence_digest`. This gates the verifier: it cannot proceed until evidence is confirmed available.
  </Step>

  <Step title="VERIFIER_RESULT_SUBMITTED">
    The verifier calls `/verify` on its runtime and submits a `VerifierResult`. The result includes a `verification_status` (passed / failed / inconclusive), a numeric `score`, `reason_codes`, a `verifier_result_hash`, and policy binding metadata. The kernel records `VerifierResultSubmitted`.
  </Step>

  <Step title="VOTE_COMMIT">
    Voting begins with a **commit** phase. Each voting node hashes its intended vote choice together with a random salt and submits only the hash (`commit_hash`) scoped to the `candidate_hash`. This prevents any voter from copying another's choice before the reveal.
  </Step>

  <Step title="VOTE_REVEAL">
    After all commits are in (or the `reveal_deadline_ms` elapses), each voter reveals their actual `vote` (approve / reject) and the `salt` used to produce the commit hash. The kernel verifies that the revealed vote matches the earlier commit. Voters who miss the reveal deadline are excluded from the round; if too few reveals arrive, the kernel schedules a retry via `TASK_RETRY_SCHEDULED`.
  </Step>

  <Step title="DECISION_COMMITTED">
    The kernel counts the revealed votes against `acceptance.quorum_threshold`. When the threshold is met, it writes a `DecisionCommitted` event carrying the `candidate_id`, `candidate_hash`, and current `epoch`. This commits the winning candidate but does not yet finalize it.
  </Step>

  <Step title="DECISION_FINALIZED">
    Finalizer nodes co-sign the committed decision to produce a `FinalityProof` (a set of `SignatureEnvelope` entries). Once the proof meets the threshold, the kernel writes `DecisionFinalized`. The decision is now permanent and feeds back into knowledge and reputation. The SEL records a `quorum_result_json` and `reason_details` snapshot for auditing.
  </Step>
</Steps>

## Task contract fields

A task contract is the boundary object between your application and the kernel. You submit it as JSON.

| Field             | Description                                                                             |
| ----------------- | --------------------------------------------------------------------------------------- |
| `task_id`         | Unique identifier you assign. Used in all downstream events.                            |
| `task_type`       | String label that selects which executor capability handles this task.                  |
| `inputs`          | Arbitrary JSON object forwarded as-is to the executor's `/execute` endpoint.            |
| `output_schema`   | JSON Schema the kernel uses to validate candidate outputs.                              |
| `budget`          | Cost and time limits for each lifecycle stage (see below).                              |
| `assignment`      | Controls claim concurrency, max proposers, max verifiers, and topk candidate selection. |
| `acceptance`      | Quorum threshold, verifier policy binding, vote policy, and settlement policy.          |
| `expiry_ms`       | Wall-clock deadline after which the task is expired if not finalized.                   |
| `evidence_policy` | Size caps and allowed MIME types for inline evidence.                                   |
| `task_mode`       | `ONE_SHOT` (default) or `CONTINUOUS` for epoch-renewing tasks.                          |

## Budget stages

The `budget` field divides total task cost into three named buckets. The kernel applies **hard gating**: a stage cannot proceed if its budget is exhausted.

| Stage        | Budget field          | Covers                                                                                             |
| ------------ | --------------------- | -------------------------------------------------------------------------------------------------- |
| **explore**  | `explore_cost_units`  | Execution cost: `CandidateProposed` and `EvidenceAdded` events.                                    |
| **verify**   | `verify_cost_units`   | Verification cost: `EvidenceAvailable`, `VerifierResultSubmitted`, `VoteCommit`, and `VoteReveal`. |
| **finalize** | `finalize_cost_units` | Finalization cost: `DecisionCommitted`, `DecisionFinalized`, and `TaskExpired`.                    |

Set `reuse_verify_time_ms`, `reuse_verify_cost_units`, and `reuse_max_attempts` to control how aggressively the kernel attempts to reuse a previously finalized decision before falling back to full exploration.

## Commit-reveal voting

Commit-reveal voting protects vote integrity in multi-node swarms. Because every voter submits only a hash during the commit phase, no one can see how others voted before committing their own choice.

* **Commit**: `commit_hash = hash(candidate_hash + vote + salt)`. Only the hash is broadcast.
* **Reveal**: each voter publishes the original `vote` and `salt`. The kernel verifies the hash matches.
* **Deadline**: if a voter does not reveal before `reveal_deadline_ms`, their commit is excluded. Insufficient reveals trigger a `TASK_RETRY_SCHEDULED` event before `expiry_ms`.

Set `acceptance.vote.commit_reveal = true` in your task contract to enable commit-reveal. Set it to `false` only for workloads where vote secrecy is not required.

## Three-state verification

Verifier results carry one of three statuses:

| Status         | Meaning                                                                                                                                                  |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `passed`       | The verifier accepted the candidate. Votes proceed toward approval.                                                                                      |
| `failed`       | The verifier rejected the candidate. Votes proceed toward rejection.                                                                                     |
| `inconclusive` | The verifier could not reach external evidence (e.g., a referenced URL was unreachable). The candidate is not confirmed or rejected; the task may retry. |

## Aggregation for runs

When you submit a multi-agent **run** (a set of parallel agent steps over shared inputs), the kernel aggregates step conclusions into a single `final_decision`. The aggregation policy lets you control what happens when conclusions tie or are all null.

**Quorum**: set `aggregation.quorum` to require a minimum number of agents to agree before a winner is chosen.

**Tie policy chain** (applied when conclusions tie):

| Resolver              | Behaviour                                                                                                         |
| --------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `REEXPLORE`           | Emits `RUN_TIE_REEXPLORE_TRIGGERED`, injects `_aggregation_signal`, and requeues terminal steps for another pass. |
| `CONFIDENCE_WEIGHTED` | Sums per-conclusion confidence scores; the unique highest sum wins.                                               |
| `REPUTATION_WEIGHTED` | Sums per-conclusion `agent_reputation_units`; the unique highest sum wins.                                        |
| `STOCHASTIC`          | Deterministic pseudo-random tiebreak from a hashed seed. This is the default tie resolver.                        |

**Null policy chain** (applied when all conclusions are null or quorum is null):

| Resolver        | Behaviour                                           |
| --------------- | --------------------------------------------------- |
| `REEXPLORE`     | Injects an aggregation signal and requeues steps.   |
| `FINALIZE_NULL` | Commits a null decision and marks the run terminal. |

The default null chain is `[REEXPLORE, FINALIZE_NULL]`, so the kernel tries once more before giving up.

## Continuous task mode

Set `task_mode = CONTINUOUS` and `budget.mode = EPOCH_RENEW` to keep a task running across multiple budget epochs rather than finalizing after a single pass.

In continuous mode:

* When a budget epoch ends (budget exhausted, timebox reached, or decision finalized), the kernel emits `EPOCH_ENDED` with an `EpochEndReason`.
* The budget resets for the next epoch and the task continues until you explicitly stop it or a terminal condition is reached.
* Use `EPOCH_ENDED` events in your monitoring pipeline to observe per-epoch decisions.

## Key lifecycle events reference

| Event                       | What it signals                                                         |
| --------------------------- | ----------------------------------------------------------------------- |
| `TASK_CREATED`              | Task contract accepted; task is open for claiming.                      |
| `TASK_CLAIMED`              | A node has taken the proposer or verifier role under a timed lease.     |
| `CANDIDATE_PROPOSED`        | An executor submitted a candidate output with evidence.                 |
| `EVIDENCE_AVAILABLE`        | Evidence DA quorum satisfied; verifier may proceed.                     |
| `VERIFIER_RESULT_SUBMITTED` | Verifier returned a scored result with a three-state status.            |
| `VOTE_COMMIT`               | A voter submitted a hashed vote commitment.                             |
| `VOTE_REVEAL`               | A voter revealed their actual vote and salt.                            |
| `DECISION_COMMITTED`        | Vote quorum reached; winning candidate identified.                      |
| `DECISION_FINALIZED`        | Finality proof assembled; decision is permanent.                        |
| `TASK_RETRY_SCHEDULED`      | Insufficient reveals or a recoverable error; the task will retry.       |
| `TASK_EXPIRED`              | Task reached `expiry_ms` without finalizing.                            |
| `EPOCH_ENDED`               | A continuous-mode epoch ended; budget will renew.                       |
| `REUSE_REJECT_RECORDED`     | A reuse candidate was rejected by quorum; blacklisted for future reuse. |
