An independent consistency check for a single Post Fiat Task Node task, built only from that task's public forensic events.
Task Node records every task's lifecycle as a chain of forensic events (offered, accepted, submitted, verification, reward outcome), each viewable under a task's Forensics tab. But the status shown on a task's Overview is derived separately from that event history — and the two can disagree. Publicly documented cases include tasks displaying "Refused" with no refusal event in their forensics at all.
pft-task-audit checks that a task's story is coherent: that its events form a valid
chain, that its displayed status is actually backed by an event, and that a rewarded
task's payout lines up. It turns a class of manual QA checks into a reusable, reproducible
tool.
It proves a task's lifecycle is internally coherent:
- the events form a valid, contiguous, correctly-ordered chain,
- the displayed status is backed by a real terminal event (catches "phantom" statuses),
- a terminal status is classified as user- or system-initiated,
- a rewarded task's reward outcome matches any supplied payment evidence.
It does not assert fraud, missing funds, or anything requiring backend access. Every finding is derived only from the pasted public forensic payloads, so anyone can re-run it and get the same receipt.
| Check | What it verifies |
|---|---|
| C1 events present | at least one valid forensic event payload was supplied |
| C2 single task | all events belong to the same task_id |
| C3 transition chain | each event's previous_status matches the prior event's status_after, and every transition is legal |
| C4 status backed | core check — the displayed status is backed by an event; a status with no matching event is flagged as PHANTOM |
| C5 terminal origin | a terminal status is recorded by an actual event, classified user- vs system-initiated |
| C6 reward linkage | for a rewarded task, the reward event is present and consistent with any supplied tx/amount |
Verdict is CONSISTENT, CONSISTENT_WITH_WARNINGS, or INCONSISTENT. The tool exits non-zero on an inconsistent task.
- Open a task's Forensics tab. For each event, expand Raw payload and copy the JSON.
- Paste the events into one file as a JSON array (
[ event1, event2, ... ]). - Run:
python3 pft_task_audit.py events.json --status refused
# rewarded task with payment cross-check:
python3 pft_task_audit.py events.json --status rewarded --reward-tx <hash> --reward-amount 3500It writes task-audit-<task_id>.md and .json — a human- and machine-readable receipt
with an SHA-256 fingerprint of the events audited.
Real receipts in examples/, generated from authentic task forensic data:
rewarded-CONSISTENT.md— a full 6-event rewarded lifecycle; all checks pass.real-refusal-CONSISTENT.md— a genuine user refusal (offer + refuse); consistent.phantom-refusal-INCONSISTENT.md— a task showing "Refused" with only an offer event; flagged INCONSISTENT (phantom status).
The fixtures/ directory holds the authentic event data behind these receipts so they can
be reproduced offline.
A verifier is only trustworthy if it fails when it should. tests/ contains fixtures that
each break one rule (chain gap, illegal transition, multi-task, phantom status) and a runner
that confirms the auditor catches each one:
python3 tests/run_tests.pyIt runs the auditor against the clean fixtures (expected CONSISTENT) and every broken one (expected INCONSISTENT, with the specific check that must fail), and exits non-zero if any case misbehaves.
Python 3.8+. Standard library only — no dependencies.
This tool audits whatever events you paste into it; it does not fetch from the network. It verifies internal consistency of public forensic data, not the correctness of the network's backend decisions. Related public QA reports: pft-qa-reports.
MIT — see LICENSE.