What did my AI agent do? Four questions to answer with proof
For every AI agent task you should see who did it, what changed, what was skipped and why, with evidence you can check instead of a comment saying done.
Weft is the AI task manager for solo founders and small teams.
By Andrei Finogeev ·
To know what your AI agent did, don't start with its summary. Check four things: which connection did the work, what changed (shown by something you can open yourself), what was left undone, and what was decided and why. If any of the four rests on the agent's word alone, you have narration, not a record.
We make Weft. Facts about other products come from their official pages, checked on 27 October 2026.
Why isn't a comment that says "done" enough?
A comment is the agent describing its own work. It may well be accurate, but the comment cannot show that, because the author is the party you are trying to check. Knowing that an agent touched a task answers who. It does not answer whether the work is what you think it is.
Hypertask's article on AI work attribution makes a fair point: agent work should land on the same board as human work, not in a terminal log nobody reads. Hypertask also gives agents their own identity as service accounts, so writes are attributed to the agent instead of to you, and it has task evidence and leases, though its docs say these are REST endpoints only, not MCP tools, by design. Where we differ is what the record should contain. A comment thread with the agent's output is a log of what the agent said. We want the record to hold proof.
There are no survey numbers in this guide. You can test the four questions on your own board this afternoon, and that tells you more than an industry average.
What are the four questions?
Pick any task an agent finished last week. You should be able to answer each of these in under a minute without asking the agent or opening its chat:
- Who did it? Which client, on which connection, claimed and finished the task.
- What changed? The outcome, plus artifacts you can check without trusting the agent: a commit hash, a URL, a file, a message id.
- What was not done? The parts it skipped, and the things it was unsure about.
- What was decided, and why? Any choice made along the way, with the options weighed, and any time you sent the work back.
| Question | Weak answer: a comment saying "done" | Strong answer: evidence you can check |
|---|---|---|
| Who did it? | "Agent" or your own name on every change, because all tools share one key | The connection that claimed and finished the task, by the name the client registered, with each journal event tagged person or MCP and the client id |
| What changed? | "Refactored the auth module, tests pass" | A commit hash, a PR or page URL, a file with its sha256, a message id: something you open yourself |
| What was not done? | Nothing said, so you assume nothing was skipped | A notDone list ("did not run the migration on staging") and an unknowns list ("not sure the old endpoint has no other callers") |
| What was decided, and why? | Buried in a chat that has since scrolled away | A decision record with the options weighed and the condition to revisit, plus the task's decision history, including why it was sent back |
How do I know which agent did it?
Weft connects to AI clients over the Model Context Protocol at one endpoint, https://letsweft.com/api/mcp. Each OAuth client and each personal access token is its own actor. A task records which client created it, and the board shows the name that client registered with at sign-in, plus an icon. Every event in the task's journal stores whether it came from a person or over MCP, and which client sent it.
The full journal (get_task_history in full mode) shows the raw client id for each event: an OAuth client id, or mcp-token followed by the token's id. It is not a friendly name, but it is exact, and it separates two connections even when they come from the same product.
Ownership during the work is explicit too. An agent calls start_task, which claims the task with a 20-minute lease and moves it to Doing. report_progress renews the lease. A second agent that tries the same task gets already_claimed, and a lease that lapses frees the task for someone else. The claim loop guide covers this step by step, and running several agents on one board covers the multi-client case.
One practical rule: give every tool its own connection. If two clients share one access token, the board sees one actor, and the who question loses its answer.
What changed, and can I check it without asking the agent?
When an agent finishes, it calls complete_task. Only the task id is required; everything else is optional, and the call never fails for missing evidence. That is deliberate: losing finished work is worse than recording it unverified. What a receipt can carry:
- outcome: up to 1,000 characters on what was done and where the result lives.
- artifacts: up to 20 entries, each a kind (url, file, message, commit, and so on), a location, and optionally a sha256 digest.
- claims: what the agent asserts it did, stored as claims rather than verified facts.
- notDone and unknowns: covered in the next section.
- nextStep: what the agent would do next if you accept.
complete_task({
"id": "<task id>",
"runId": "<from start_task>",
"leaseToken": "<from start_task>",
"outcome": "Rate limiting added to /login; PR open, not merged.",
"artifacts": [
{ "kind": "commit", "uri": "<repo>/commit/<hash>" },
{ "kind": "url", "uri": "<repo>/pull/<number>" }
],
"notDone": ["Did not change the signup endpoint"],
"unknowns": ["Limit of 5 per minute is a guess; no traffic data"],
"nextStep": "Merge the PR to main"
})The outcome line is still narration. The artifacts are the part you can check. A commit hash either exists in your repository or it doesn't. A URL loads or it doesn't. A file's sha256 matches or it doesn't. If a receipt has an outcome and no artifacts, treat it as agent-reported work, because that is what it is. On the web, Done cards show whether a task is Verified or Agent-reported.
What did the agent not do?
This is the question most records skip, and the one that bites two weeks later. complete_task has two lists for it, each up to 20 entries of 500 characters: notDone for what the agent left out on purpose, and unknowns for what it is unsure about. The tool's own description asks agents to state what they did not do, out loud. That is what separates a result you can rely on from one you have to re-derive.
Read these lists first. "Did not run the tests against the staging database" changes what you do next. A receipt with no notDone entries on a large task is itself worth a question.
What was decided, and why?
Decisions made in chat vanish when the chat scrolls away. record_decision keeps them in two ways:
- A standalone decision record: a title, the outcome, the context, the options actually weighed, the consequences, and the condition under which to revisit it. Records are immutable; changing one means recording a new decision that supersedes it, and the old one stays, marked superseded.
- A verdict relay: when you tell an agent in conversation "accepted", "redo it with X", "drop it" or "not now", it records that verdict on the task, with your note.
get_task_history reads it back in three modes: summary (the card, its latest receipt and counts), decisions (every decision about the task, including why it was sent back, which survives even after a later accept) and full (the raw journal, capped at 100 events). get_context hands the live decisions to the next agent within a token budget, so the next run starts from what was decided rather than from scratch. More on this in why AI chat decisions get lost.
Where do I review it, and what do I click?
By default a completed task goes straight to Done. It stops in your Inbox when the task needs review or when a verification check fails. There you see the receipt and four buttons: Accept, Rework, Later and Drop. Rework asks for a note, and that note goes back to the agent.
If the agent passed a nextStep, it appears above the Accept button, and accepting approves exactly that step. The approval is good for 72 hours and comes back to the agent through get_my_work or start_task as the one step to do next. Questions an agent asks with request_input land in the same Inbox, on the web and in the iOS and Android apps, with a mobile push.
The Inbox has a limit on purpose: 5 waiting items for a one-person workspace, 10 for a team, or 45 minutes of estimated review time, whichever comes first. When it is full, start_task refuses with attention_queue_full, so agents finish or clarify work instead of piling up more for you to check.
What evidence should I ask for by task type?
Write these into the task description so the agent knows what proof you expect:
- Code: the commit hash and the PR URL as artifacts. notDone should name the tests not run, migrations not applied and files deliberately left alone.
- Content: the published URL, or the draft file with its sha256 if it isn't live yet. unknowns should list facts the agent could not confirm.
- Research: a source URL for each key claim, and the notes file. unknowns should separate what a source says from what the agent inferred.
- Outreach: the message id of each sent message, and the recipient list as a file. notDone should list who was not contacted and why.
How do I control what an agent can do in the first place?
Attribution after the fact works best with limits before it. In Weft, each OAuth connection has one of three permission levels, set on the consent screen or later in Settings, Connected AI clients:
- full (the default): all 32 tools.
- write: everything except the three destructive tools (trash_task, archive_done_tasks, complete_sprint).
- read: only the 11 read-only tools.
The check runs on every call. Disconnect revokes the connection's refresh tokens and refuses any token issued before the cut on its next call. Personal access tokens, for clients without OAuth, have no scopes: one token reaches all 32 tools, and revoking it takes effect on the next call. Agents can move tasks to a 30-day trash but cannot delete them for good; restoring from trash is a Pro feature.
What doesn't Weft do here?
- It has no GitHub or Slack integration, so Weft does not look up your commits or messages for you. You open the artifact.
- It has no public REST API, webhooks or CLI to push receipts into other systems. There is a JSON and Markdown export.
- It doesn't trace model steps. Tools that log prompts, tokens and latency at the model layer do a different job, and you may want one as well.
- Agents write their own receipts. Weft makes the gap between claim and evidence visible; it cannot make an agent honest.
If you want agents managed as service accounts over a REST API, a CLI for CI scripts, or built-in AI features like task writing and triage, Hypertask fits that better. Our Hypertask alternative page compares the two side by side.
- Isn't git history enough to know what my agent did?
- Git shows what changed in the code. It doesn't show what the agent skipped, what it was unsure of, or which choice it made between two options. Use the commit hash as an artifact on the task, and keep the rest in the receipt and decision record.
- Can't an agent just make up an artifact?
- It can send any string. The point of an artifact is that you can open it: a hash you can look up, a URL you can load, a message id you can find. A made-up one fails the moment you check, which a comment never does. When a task carries a verification check and a blocking check fails, the task stays out of Done.
- Does every finished task wait for my review?
- No. By default a completed task goes to Done. It waits in your Inbox for Accept, Rework, Later or Drop only when the task needs review or a verification check fails.
- Which AI clients can write receipts to Weft?
- Any MCP client. ChatGPT has Weft as a published plugin on every plan, including Free. Claude Code connects with
claude mcp add --transport http weft https://letsweft.com/api/mcp. Claude.ai and Claude Desktop use a custom connector. There are setup pages for 33 clients, such as Claude Code, ChatGPT, Cursor and Codex. - What does this cost?
- Free covers 50 tasks and 200 AI calls a month. Pro is $7 per seat a month or $60 per seat a year. Weft has no AI credits: the thinking happens in your own AI client. See pricing.