Claims by paste or import

Who this is for: whoever builds or reviews how Attest gets an agent’s claims now that it reads no agent’s site. What you’ll know after: why claims come from a log the person pastes, what Attest does with the pasted text, and the tasks that build it.

Status: v1 design (8 October 2026; Decisions [3.11]). It replaces Sprint 3’s live reading of agent pages, which Meta’s, OpenAI’s and Anthropic’s terms forbid (Decisions [3.10]), with a path that needs no vendor’s permission. If a vendor permits reading later, its reader is still in extension/src/adapters/ and can be switched on beside this path.

1. The idea

An agent shows the person what it did: Muse keeps an activity log beside every chat, ChatGPT’s agent mode lists its steps, and Claude shows each connector action in the thread. The person selects that log, copies it, and pastes it into Attest. Attest turns each reported action into a claim, checks it against the person’s own Gmail Sent folder and Google Calendar as it does today, and issues receipts.

Attest never visits, reads or loads the agent’s site: it has no host permission and no content script for any agent (AGENT_READERS in extension/src/config-agents.ts). Copying from a page you are reading and pasting into another app is ordinary use of your own screen. This is not legal advice; the vendors’ terms and the reading of them are in Decisions.md [3.10].

2. The flow

  1. In the side panel, the person chooses Add agent activity, picks the agent (Muse, ChatGPT, Dots or Claude) and pastes.
  2. Attest parses the text in the side panel itself, nowhere else (§3).
  3. It shows a preview: each claim it read (type, who or what, time), and each entry it does not import as a claim and why: no day, no time Attest can use, nothing Attest checks, or unreadable. A proposal (“Shall I book the dentist?”) is imported as an other claim, which Attest lists but has nothing to check. The preview also says how many entry times it keeps: the minute of every timed entry, a claim or not, is kept as a time the agent was working, the evidence UNASKED reads (§5).
  4. The person confirms. The side panel sends the claims and the entries’ minutes, never the text, to the service worker as a claims.import message; the service worker stores and grades them (§5).
  5. The pasted text is dropped as soon as the preview closes. It is never stored, logged or sent anywhere (Hard Rules 1, 2 and 10).

3. Parsing a pasted log

The parser is pure and has no DOM: text in, an AgentRead out, the same shape an agent adapter returns (extension/src/adapters/types.ts). From there the existing claim builder (claims.ts) and pattern tables (patterns.ts) do what they already do: one claim per reported action of an ActionType, at most one other for an entry that reports none, ids and rawHash per docs/grading.md §10. So pasting the same log twice adds nothing new.

4. Privacy and security

5. Storing and grading

The service worker stores each claim (upsertClaim), builds candidates from the Gmail and Calendar observations already in the ledger, grades with gradeBatch and stores the receipts. A PENDING receipt is finalised by the grace alarm, and orphan observations become UNASKED receipts (attribution.ts). This is the background wiring Sprint 3.6 planned, now fed by imports instead of a content script. Attest sees no agent’s session without reading its site, so the pasted log stands in: each timed entry, a claim or not, is a moment the agent’s own log says it worked, stored as a session ping (3.14). The person’s idle time comes from Chrome only if they turn it on (3.14, an optional permission). Until both are recorded, UNASKED rests on the activity log’s own entries.

6. What this path does not do (yet)

7. Tasks

Task What Done when
3.11 The paste parser: text → AgentRead → claims, with the rules of §3 Unit and property tests over invented logs of each agent’s shape: entries, headers, times, proposals and chatter; re-pasting adds no claim; a time after the paste and a log over the limit are refused
3.12 The side panel’s Add agent activity: paste, preview, confirm Component tests for every preview state; keyboard and screen-reader labels; the text is gone once the preview closes
3.13 claims.import and the service worker: store, grade, receipts, grace alarm, UNASKED Unit tests per step; a service worker stopped mid-grace still finalises (the 3.6 rule)
3.14 The UNASKED signals: the pasted log’s timed entries as session pings, and opt-in idle detection The §2 demo graded through the ledger with its log’s sessions and a recorded idle interval gives UNASKED; nothing records idle without the person’s opt-in
3.15 Event times from pasted claims: “Thu 2pm”, “Friday at noon”, “Oct 8 at 2:00 pm” as the calendar claim’s targetAt, read forward from the claim’s time, only when a day and a time are both named Tests over invented sentences, ambiguous ones giving none; the §2 demo’s calendar claim grades NOT_FOUND through the ledger
3.16 End to end In the built extension, pasting the §2 demo’s log with the Gmail Sent and Calendar fixtures gives exactly VERIFIED, NOT_FOUND (after a simulated grace) and UNASKED