Review-first mode
Choose Review first under Application mode to require review of inferred dates, model metadata, and local archive matches. Explicit rules written by a user remain independent. Suchi checks the current document, matching text, field generations, access, and reviewer credentials before recording or applying a decision.Reviewing suggestions
The Approvals screen uses the same centered workspace card as Automations, Calendar, and Views. Its header keeps the page description, refresh action, and Show suggestion groups control together. Tabs below it show one kind of work at a time: All, Tags, Filing and Fields for metadata suggestions, which All counts, then Dates, and Decisions when workflow approvals are waiting. Administrators also get a Processing issues tab, set apart at the right end, when processing has failed. It names each affected document and offers Retry all when there is more than one issue. The open tab is kept in the address (#/tasks?tab=issues),
so the Dashboard’s Failed jobs card opens Processing issues directly. When
there are no metadata suggestions and no tab is named, the screen opens on the
first tab with work. The workspace is capped at 1,400 pixels so the change sentence
and its actions remain connected on very wide displays.
The suggestion tabs open with one By document table, keeping each
document’s current and proposed values together. Each document is one block: a
small thumbnail beside its title and its suggestions, with a hairline only
between documents. Each decision reads left to right as one change: the struck
current value, an arrow, and the emphasized new value. An added tag reads
+ tag because it replaces nothing, in both projections. Rows share fixed
action, change, reason, similar-document, and decision columns so different
suggestion types retain the same edges. The reason is a quiet chip; supporting
documents use a compact n similar disclosure.
Choose Show suggestion groups to open a 400-pixel sidecar inside the same
workspace card. The header control becomes Hide suggestion groups without
moving, and the By document and By suggestion captions appear only while
both projections are visible. Suggestion groups follow the document order: each
group appears where its first document does and lists its documents in that
order, so both projections read top to bottom together. Each projection shows at
most 100 entries and states how many remain; settling visible entries brings the
next queued entries into view. Long document names in a group are shortened so
each document number stays visible.
On wide screens the suggestion tabs fit the window: the header, tabs and both
captions stay in place while each projection scrolls on its own. On narrower
screens the sidecar stacks after the document table and the page scrolls as
one.
Applying or dismissing a decision updates both views immediately, and the item
fades out of both at once (instantly when reduced motion is requested). While
both projections are open, pointing at or focusing a suggestion group tints its
document cards, also marking the linked decisions in a document that has
several; pointing at a document tints its groups. Side by side, when no tinted
entry is visible, the other projection scrolls the first one level with the
entry you point at, so moving straight across lands on it. It waits until the
pointer rests for about 300 milliseconds, so sweeping across one projection
toward an entry does not scroll the other; keyboard focus scrolls at once. The
link icon in the By suggestion caption states the same relationship for
screen readers and on hover.
Each decision row has its own dismiss and approve controls; documents with
several decisions also offer Approve all and Dismiss all beside the
title. Suggestion cards apply or dismiss the grouped decision for every listed
document, as Apply to all n and Dismiss all n, or Approve and
Dismiss when the group holds one document. Expand a grouped card’s document
list before a bulk action when you need to inspect every affected item. A
partially failed bulk action removes only completed decisions, keeps failures
visible, and requires a refresh before retrying.
Model
- A definition stores a versioned JSON state machine under a stable slug.
- A run binds one definition version to a document and current state.
- A task asks one user or resolved role to choose from declared options.
- A transition records the previous state, next state, trigger, actor, and time.
running, done, failed, or cancelled. Tasks are open,
claimed, resolved, or expired.
Definition
user:<id>, document_owner, or a registered role:<name> resolver.
document_owner resolves when a document-bound run creates its task. The
shipped role:admin resolver assigns a shared task visible to administrators.
Built-in state kinds are:
system: emits a routing event without creating a taskapprove: creates a human task and waits for a choice or timeoutend: completes the run and expires remaining tasks
Engine.RegisterHandler.
Handlers can return a transactional effect with their routing event. Suchi
runs that effect in the same transaction as the transition, which keeps a
human-approved write retry-safe when the durable job is redelivered.
API flow
Register the example under
invoice-approval from an administrator’s browser
or OIDC session:
$TOKEN needs documents:write and change access to document 17.
A live browser/OIDC session or an API token with documents:write may resolve
routine reviews. The writer transaction reloads the user, token binding and
token scopes before accepting the decision.
The assignee resolves the resulting task from the Approvals screen or API. A
resolution enqueues the next advancement; the HTTP request does not run the
whole state machine inline.
GET /api/tasks/?include=approvals remains a generic mixed workflow feed.
Clients may render only the approval definitions and fields they understand;
unknown rows stay available to other clients and the web application.
Timeouts and recovery
Entering a state withtimeout_sec records a deadline. A recurring durable
timeout sweep enqueues a timeout advancement for due runs and expires their
open tasks. The same sweep cancels document-change reviews whose bound source,
field, destination or access state is no longer valid. The definition must map
timeout when timeout behavior is desired.
Interrupted jobs are reclaimed on startup. Each queued advancement and task is
bound to one visit to a state; stale retries cannot replay a choice on a later
visit or recreate a resolved task. Effects and task creation recheck that revision
inside the writer transaction. Cancellation records a transition and expires tasks;
accepted decisions clear their deadline before a later timeout sweep can act.
Accepting a decision or timeout increments the run revision immediately, so delayed
entry work cannot create another task or apply an effect while advancement waits.
Upgrading an archive created before v0.1.0 preserves pending decisions only when retained entry jobs and
the resolved task prove their state. Initial-state timeouts can resume; later-state
timeouts have ambiguous origins in the old implementation. Missing entry history
or ambiguous events leave affected jobs dead with a recovery message, preserving
the current review. Inspect the run and resolve a current task, or cancel and
restart a stalled run. Retrying an unbound old job cannot authorize it.
Run and task IDs are retained and no longer reused after deletion. The run allocator
also skips IDs retained in old jobs. Purged task IDs without pre-upgrade allocation
history cannot be reconstructed.
Approval jobs appear in /api/tasks/; filter by kind=approval: when
investigating a stalled run. Application logs use component=approvals.
Document suggestions
Archive matching, model metadata, detected-language suggestions, and fixed metadata actions selected by a classifier-backed automation question use the shippeddocument-change definition when review is required. The task is
assigned to the document owner. By default, Apply when confident lets
eligible model and local archive changes apply automatically. Choose Review
first to check every valid inferred change, even at 100% model confidence.
Below-threshold or otherwise review-required changes still appear here. A
document row states the current-to-proposed change once, followed by its reason
chip and any supporting-document disclosure. How this was suggested expands
model confidence and who suggested it on date-review cards. An
automation-question card names the automation as the reason for its proposed
fixed metadata effect, not the discarded question/answer transcript. Companion
presents title, filing-category and tag suggestions from this same feed; other
document-change fields, including typed custom fields, remain available in the
web review surface.
A title proposal is eligible only while the current title is automatically
owned. Accepting it makes the resulting title human-owned. A person renaming
the document, or a rule assigning a title before the queued effect runs,
invalidates the proposal rather than being overwritten.
The retained proposal binds the target’s immutable source and field generation,
plus any supporting documents. A custom-field proposal also binds a one-way
fingerprint of the prior typed display value; the value itself is shown through
the ordinary authorized projection, not copied into hidden model history. A
changed, cleared, or newly created prior value invalidates the proposal. Source,
membership, document ACL, destination and reviewer authority are checked at
resolution and again at the queued write. Creating new shared metadata also
requires its current administrative authority. Hidden supporting documents are
never exposed by review.
Apply records a decision and queues the effect; it does not promise the field
already changed. A later credential revocation, scope removal, source edit or
authority change can block that effect. After authorization expiry, a newly
requested identical inference can create a fresh review without reusing the old
decision. Duplicate live proposals and repeated resolution requests do not create
duplicate applications.
Dismiss closes the suggestion without applying it. Unknown actions are
read-only. Scoped API tokens may resolve these built-in suggestions, but the same
source, field, ACL, destination, vocabulary and policy checks still gate the write.
If the source or target changes before review, Suchi records a superseded
transition, expires the task and cancels the run. Human metadata edits do this
in their own transaction; startup and the existing approval sweep reconcile
changes from other paths. The obsolete card leaves Approvals without requiring
a dismissal. A later inference can create a fresh proposal bound to the current
document. An effect already queued after an accepted decision still repeats all
freshness and authorization checks before writing.
This remains the extension pattern for action workflows: a producer
starts an approval in its existing transaction, and a typed handler performs
the approved write. Reviewable extracted facts use the deliberately separate
document_intelligence ledger because they are bulk metadata decisions, not
state-machine runs.
Review dates
Start with Document dates for the complete user workflow. The Approvals screen hosts pendingdocument_intelligence suggestions in the
Dates tab; workflow approvals have a Decisions tab and dead jobs a
Processing issues tab. Each date is added or rejected with its own buttons,
and Add all N dates to Calendar above the dates accepts every addable date. Each action is one bounded API call over the affected IDs.
Dates and workflow approvals share the same card grid. More than two groups use
two desktop columns and one mobile column; one or two groups stay in a compact
single column.
This review does not create approval definitions, runs, transitions, or one
task row per date. See Document dates: Automatic and reviewed
dates for automatic policy,
legacy facts, review and rescan rules. Automatic acceptance never invents a
reviewer; startup and settings saves never bulk-accept pending dates.
Rescan proposals
Suchi ships arescan-proposal definition. A tagged release also carries
independent OCR, content and LLM recommendation thresholds, defaulting to zero.
When a positive recommendation makes stored processing results stale, Suchi
creates one admin review task per affected pipeline kind. The choices are:
- rescan every stale document
- rescan a random sample of 20 when more than 20 documents match
- dismiss the proposal
Current limits
- A run has one current state; parallel branches are not supported.
- Definitions are managed as JSON through the API rather than a visual editor or watched directory.
- A
role:admintask is shared by all administrators until one resolves it; assignment is not round-robin.