# TraceVero local verification runner Python 3.11+ on macOS or Linux; standard library only. Runs use **dedicated test accounts**, create a synthetic email **draft**, download its XML attachment, save and read back a file, extract the amount, and write and read back a spreadsheet. No email is sent. The migration scenario also copies the file and spreadsheet between Google and Microsoft, repeats destination writes, checks for duplicate rows and verifies that the source stayed unchanged. Cleanup runs on success and failure and deletes only the run's identified test objects. ## Install and configure Download and unpack [the runner](https://tracevero.com/automatisieren/sdk/tracevero-runner.zip). The adjacent [SHA-256 file](https://tracevero.com/automatisieren/sdk/tracevero-runner.sha256) identifies the download. Start with `example-google.json`; for migrations use `example-migration.json`. A private project on [TraceVero](https://tracevero.com/automatisieren/monitor) also provides a matching configuration and a project key. Credentials remain local; never paste provider tokens into TraceVero or commit token files. ```sh python3 verify-workflow.py --config example-google.json python3 verify-workflow.py --config tracevero-runner.json --watch ``` Supply the Google access token through `TRACEVERO_GOOGLE_TEST_TOKEN`, Microsoft through `TRACEVERO_MICROSOFT_TEST_TOKEN`, and (only for private reporting) the project key through `TRACEVERO_PROJECT_KEY`. Populate these variables through your local secret manager or a concealed shell prompt. Do not put token values in command arguments. The downloaded JSON contains variable names, never tokens. For automatic refresh replace `access_token_env` for that provider with `"token_file": "/absolute/private/path/google.json"`. Create the file with mode 0600. Supported fields are `client_id`, `refresh_token`, optional `client_secret`, and optionally a still-valid `access_token` with numeric Unix `expires_at`. Microsoft additionally accepts `tenant` (tenant ID/domain; default organizations). Refresh tokens are obtained through your registered OAuth app and are kept on this computer. Updated tokens are written atomically. Access-token-only mode cannot renew expired credentials. Google: enable Gmail, Drive and Sheets APIs, register a desktop OAuth client and add your dedicated account as a test user. Obtain delegated consent using [Google's desktop OAuth flow](https://developers.google.com/identity/protocols/oauth2/native-app) with offline access. Microsoft: register a public client, use your dedicated Microsoft 365 tenant and obtain delegated consent using the [device authorization flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-device-code). Conditional access, admin consent and provider test-app expiry may require action in the provider console. A service-account key alone is not Gmail user consent. The runner refreshes existing grants; it does not register OAuth apps or perform initial consent for you. ## Rights, versions, costs and limits Documentation checked 2026-09-08. The runner uses Gmail v1, Drive v3, Sheets v4 and Microsoft Graph v1.0. These are **direct API tests**, not tests of a particular MCP connector or assistant client. A private submitted report is attributed to its runner, never automatically published as independently verified by TraceVero. | Test access | Delegated permissions | Why | | --- | --- | --- | | Google | `https://www.googleapis.com/auth/gmail.modify`, `https://www.googleapis.com/auth/drive.file` | Create/read/delete draft and attachment; create/read/write/delete files created by this app, including its spreadsheets | | Microsoft | `Mail.ReadWrite`, `Files.ReadWrite` | Draft and attachment operations; OneDrive and Excel reads, writes and deletion | | Microsoft renewal | `offline_access` | Refresh the delegated grant | Google scope evidence: [draft creation](https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.drafts/create), [message search](https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.messages/list), [spreadsheet creation](https://developers.google.com/workspace/sheets/api/reference/rest/v4/spreadsheets/create), [range update](https://developers.google.com/workspace/sheets/api/reference/rest/v4/spreadsheets.values/update). Microsoft: [draft creation](https://learn.microsoft.com/en-us/graph/api/user-post-messages?view=graph-rest-1.0), [file upload](https://learn.microsoft.com/en-us/graph/api/driveitem-put-content?view=graph-rest-1.0), [range update](https://learn.microsoft.com/en-us/graph/api/range-update?view=graph-rest-1.0). Excel range updates require delegated access; application-only access is not supported according to that operation's documentation. The start configuration uses an organizational tenant; personal-account compatibility is not tested. Provider subscriptions, storage capacity and API quotas remain prerequisites. The runner makes no price or free-quota guarantee. Check your selected account's plan and the official [Google limits](https://developers.google.com/workspace/gmail/api/reference/quota) and [Microsoft throttling guidance](https://learn.microsoft.com/en-us/graph/throttling). 401/403, 429 and unavailable Excel workbooks are reported as failed prerequisites or operation errors, never as evidence that a product lacks a feature. The fixture is a bounded UBL monetary summary with a fixed expected amount. It is not a legally valid invoice or a PDF/OCR test. Spreadsheet writes target the run's own `Sheet1!A1:D2`; readback includes row 3 to detect extra data. This does not test appending to existing tables, formulas, permissions migration, folder hierarchies or all of a user's documents. It does not establish full coverage of a catalog task merely because the sample succeeds. ## Interrupted runs and cleanup State is under `~/.local/state/tracevero-runner//` (override with `--state-dir`). `journal.json` records operation states and resource IDs before writes. `report.json` contains sanitized results. Keep the journal until cleanup succeeds. Never edit its IDs or point it at production objects. ```sh python3 verify-workflow.py --config tracevero-runner.json --resume RUN_DIRECTORY ``` Use the actual UUID directory name. Resume retains the operation IDs; it does not blindly create a second draft or upload. Missing responses are reconciled against exact names/IDs and readback. An uncertain write that cannot be found remains uncertain. A failed cleanup stops `--watch`; resolve the provider error and resume. Ctrl-C runs cleanup for created objects before exit; abrupt process termination leaves the durable journal for resumption. If some objects were already deleted, a resumed workflow can fail while still completing cleanup of the remaining ones. No 24/7 execution is implied by downloading a file: `--watch` must remain running on your computer or supervised service. Configure a restart policy and secret access appropriate to that machine. One hour is the minimum interval. Pausing a TraceVero project pauses source monitoring; stop the local runner separately. The runner intentionally never retries an ambiguous non-idempotent create blindly. ## Monitoring and privacy Without a `monitoring` section no report is uploaded. With it, only fixed check names, statuses, timings, HTTP status/error codes, provider names, version, scenario and cleanup outcome are sent to the exact TraceVero API host. Bodies, addresses, resource IDs and tokens stay local. Reports distinguish `protocol_fixture` from `provider_test_account`; the latter alone is not an independent TraceVero attestation. The server checks catalog-owned sources and missing reports on a persistent schedule. A changed document means review is required, not that an operation was removed. The project page shows events and worker failures; no email/push alert is sent. A duplicate report does not refresh its measurement time. A stopped runner becomes stale after twice the configured interval. Local reports survive an upload failure; a later new run can submit a new report. Old reports outside the one-hour submission window cannot turn a stale project green. ## Reproduce protocol tests In the repository, `python3 portal/test/workflow_runner_test.py` starts a local HTTP fixture for both provider protocols and deliberately loses write responses, corrupts data and rejects deletion. These are protocol tests, **not practical provider-account verification**. No live tokens can be sent to that fixture.