Maintained work
Source reports, source-version checks, stale results, and repair review.
The Work screen creates a report from approved local text and Markdown sources. It uses keyword retrieval and quotes source passages. It does not call a model, execute source instructions or independently prove the statements in a source.
Work also offers source-linked briefs, which use an explicitly selected local model and a separate citation checker. Excerpt reports keep the behavior described below. Both result types use the same durable revisions, source-access checks, repair approval and restore rules.
Create a report
Complete local setup and approve a folder. Open Work, enter a query and create a source report. The worker searches at most 2,000 files for up to 30 seconds. It reads at most 256 KiB per file and keeps up to six matching excerpts. The result records whether the scan reached a limit. A scan with no matches fails clearly.
The status Sources checked means that the stored source versions matched when checked. It does not mean that all claims in the report are true.
The local worker stores tasks and reports in work.sqlite under the instance
directory. A task continues when the page closes. After a process crash, an
expired worker lease allows another process to resume this read-only task. An
old worker cannot publish after its lease expires or after cancellation.
Respond to a source change
The worker checks tracked sources at intervals and when the result is opened. A changed or missing source marks dependent reports stale. Other reports keep their status. Removed access hides the cached content from the API.
Choose Prepare repair to repeat the query against current approved sources. The proposal shows the accepted result, proposed result and difference. It does not change the accepted result. Apply repair approves that exact proposal. The server checks the content fingerprint, current revision, source versions, expiry and prior use in one database transaction. A proposal expires after one hour. A changed result or source requires a new proposal.
Restore an earlier result
Open Sources & history and select an earlier revision to compare its saved body with the accepted result. The server captures both bodies and the accepted revision number in one database transaction. The selected revision's source state is calculated from the latest observed source versions.
Choose Prepare restore, review the exact difference and evidence state, then
apply the proposal. If revision 2 is accepted and revision 1 is selected, applying
the restore creates revision 3 with restored_from: 1. It copies revision 1's
content, source dependencies and original checks, including the original check
timestamp. All existing revisions remain in storage. Restoring a result does
not change source files or run the query again.
An accessible source that differs from the historical version permits a stale restore. Restoring old text does not make its old evidence current. If the historical versions match the latest observations, the result is Sources checked; the original check timestamp and verification limits still remain. Missing evidence or removed access prevents restore. In that case the revision comparison and restore proposal hide the saved body, references, checks and difference. This includes inaccessible sources required by the accepted body shown in the comparison, even when the selected revision's sources remain accessible.
The approval binds the proposal ID, local workspace and owner, exact accepted revision and body, chosen historical revision, copied content, source dependencies, checks, observed source versions and one-hour expiry. The server checks the same fields again when applying. A changed accepted result, changed observations, expired approval or reused fingerprint produces a conflict and leaves the accepted revision intact. Applying, recording the new revision, consuming the approval and writing its audit event share one SQLite transaction. A storage failure rolls back that transaction.
Retrying the same restore returns its existing pending proposal and original expiry. Preparing a different restore or preparing again after observed sources change supersedes the earlier pending restore for that result. Its approval metadata remains in storage, but its fingerprint can no longer be applied. There is at most one pending restore per result and 20 unexpired pending restores per workspace. Used or expired approvals are never reused.
Source refresh happens before the transaction. It is a bounded series of file reads, not an atomic filesystem snapshot: files can change after they were read. The transaction binds the recorded observations and stored revisions; it cannot lock source files or establish independent truth. Later refreshes update the result's source state.
History responses include the latest 100 revision entries with restored_from
metadata. Earlier stored revisions remain addressable by revision number. This
increment has no erasure workflow.
Export saves a JSON source-report record with the result, source versions, verification limits and revision metadata. The export is not digitally signed. It does not establish authenticity or independent verification on another system.
Inspect Work relationships
The maintained Work graph projects the existing SQLite records into sources, source versions, results, revisions, saved verification records, runs and repair/restore proposals. Edges name recorded dependencies and lifecycle transitions. They do not infer semantic relationships or add claim verification. No graph indexer, model, remote service or source-file mutation runs to produce this view. Code-index exploration remains a separate graph capability.
Source-version nodes include versions cited by saved revisions and the currently
observed version. This is not an archive of every earlier source file. Check
nodes represent saved verification records and retain their original
checked_at. Equivalent records can share a node when a restore copies the old
evidence. A restore does not become a new check execution. Missing, malformed or
oversized verification metadata produces no check node; the revision/proposal
has details.verification_available: false, while valid dependencies remain.
The service refreshes only the registered sources in the selected scope. It uses guarded local reads, updates their existing version/access observations, then projects one read-only SQLite transaction. Results, revisions, tasks, proposals and approvals are not changed. Source access is checked again before delivery; a detected loss of access causes redaction and a bounded rebuild. There is no permission cache. These checks cannot lock the filesystem or interrupt every blocked operating-system call. An empty, malformed or oversized saved source location is unavailable in the projection; it cannot inherit cached read authority. Projecting such a record does not replace or repair its saved location.
The response has version: 1, kind: "maintained_work_graph", scope: "local",
snapshot, filters, typed nodes and edges, visible summary counts,
limits, truncated and omitted. snapshot.id hashes the visible projection;
it is stable for unchanged projected records and states. captured_at and
observed_at are epoch seconds and are distinct from a saved check's timestamp.
The snapshot is neither a filesystem transaction nor signed proof. Node and edge
IDs are opaque and ordered deterministically. Every returned edge has both
endpoints in the response. Node ref values link to existing result, revision,
proposal or run actions. A Work source ID is not a Files API source handle.
Use GET /api/v1/work/graph, optionally focused by one artifact_id or
source_id returned by Work. view=attention selects results needing attention
and their related records; the default is all. limit accepts integers from
50 to 500, default 250. Duplicate, unknown, malformed or path-like focus
parameters are refused with HTTP 400. The encoded query is capped at 1 KiB.
Local search and display filters operate on the returned scope.
The projection selects at most 20 results, 128 revisions (16 per result),
64 proposals (16 per result), 100 runs and 128 sources. A source read is capped
at 256 KiB. Refresh has the existing cooperative 30-second budget; each SQLite
snapshot has a three-second progress/deadline budget and a one-second lock
wait. Saved dependency JSON is capped at 16 KiB and verification JSON at 8 KiB,
with 64 nesting levels. Larger approval/base/selected records are not passed to
the approval validator by this view: their availability requires opening the
existing proposal review. The final response contains at most 500 nodes,
1,500 edges and 512 KiB of JSON. The limits object declares these ceilings.
summary counts only the visible selected scope. omitted.bounds and
truncated distinguish bounded selection from omitted.inaccessible evidence.
An inaccessible result may remain as a generic owned-result stub, but source
names, identifiers, digests, cached check details and dependency edges are
removed. A revoked current result also hides its revision history. A source
focus that is missing, revoked or unknown returns the same empty visible
records, counts and omission hints, so focus cannot reveal which reports used a
removed source. Graph apply eligibility is informational; the existing exact
proposal review and fingerprint-only apply remain the approval boundary.
Run the real-record, migration, permission, transition and HTTP boundary tests
with python -m unittest discover -s tests -p "test_work_graph*.py" -v.
See managed graphs for the product scope and qualification
criteria.
Access boundary
This increment is available only through the authenticated local application.
The relay explicitly refuses all /api/v1/work paths. Local handlers also check
the socket, origin and relay marker. Browser writes require their local Origin.
There is no remote work authorization model in this increment.
Only the worker records source checks. The HTTP API does not accept a client field that declares a report verified. Model output and documents do not grant permissions. Reports are stored artifacts; applying a repair or restore does not overwrite the user's source files or send an external message.
Version 1 API
All responses use Cache-Control: no-store. JSON requests have a 16 KiB body
limit and a five-second body deadline. Queries have a 4,000-character limit.
The per-workspace pending queue holds at most 20 tasks. Lists return at most 100
entries. The local HTTP workspace is selected by the service, never by a client
workspace field.
| Method and path | Input | Result |
|---|---|---|
GET /api/v1/work |
None | Capabilities, worker status, runs, artifacts and recent events |
GET /api/v1/work/graph |
Optional artifact_id or source_id, view, limit |
Bounded typed Work relationships, source state, saved checks and snapshot metadata |
POST /api/v1/work |
query |
Queued run; HTTP 202 |
POST /api/v1/work/runs/{id}/cancel |
Empty object | Cancelled run |
GET /api/v1/work/artifacts/{id} |
None | Result, source references, check limits and revision history |
GET /api/v1/work/artifacts/{id}/revisions/{revision} |
Positive integer revision in path | Selected revision, captured before, base_revision, before_state, difference, can_restore and restore_problem |
GET /api/v1/work/artifacts/{id}/export |
None | Downloadable version 1 JSON report record |
POST /api/v1/work/artifacts/{id}/repair |
Empty object | Queued repair; HTTP 202 |
POST /api/v1/work/artifacts/{id}/restore |
revision, base_revision as positive integers |
Stored restore proposal; HTTP 201 |
GET /api/v1/work/proposals/{id} |
None | Difference, expiry, fingerprint and apply eligibility |
POST /api/v1/work/proposals/{id}/apply |
fingerprint |
New accepted revision |
Restore proposals have kind: "restore", restore_revision, result_state,
can_apply and a safe rejection_reason. A source denial returns a redacted
revision or proposal with state: "access_removed" or
state: "evidence_unavailable". A valid comparison with unavailable evidence
returns HTTP 200 and can_restore: false; attempting the restore returns 409.
The API accepts no client content, source checks, actor or workspace on restore.
HTTP 400 means invalid input; 401 means missing authentication; 403 means the local access boundary refused the request; 404 means no visible result; 409 means the requested transition is no longer valid; 413 means an oversized body; and 503 means setup or local storage is unavailable.
At most four work requests run concurrently. Excess requests receive HTTP 503. Refresh has a cooperative 30-second budget and fails closed if that budget is exceeded. It cannot interrupt an operating-system file read that is blocked.
The local database uses schema version 2. Opening a version 1 database migrates it in a transaction and preserves its revisions, tasks and events. Existing pending repair fingerprints are rebound to the accepted body and approval actor; review those proposals again after upgrading before applying them. A failed migration leaves version 1 intact for retry. A database created by a newer unsupported application is refused instead of rewritten.
Limits and qualification
This is the first working part of maintained results. It does not implement general autonomous tasks, cloud inference, workflow promotion, independent semantic verification or arbitrary file repairs. Local administrator or same-user operating-system compromise is outside the credential boundary. Database content is private local data and needs a user-approved backup policy.
Remote source reports use a separate explicit folder grant, worker queue and versioned API. The local Work routes above remain local-only.
Tests cover real HTTP execution and restart, cancellation, leases, exact repair approval, revision restore, migration, competing approvals, atomic failure, source invalidation, exclusions and removed access. Fixture tests are not a substitute for clean-device qualification or independent security review.
See the architecture and the release status.