About agent actions and records
Agents in Trovensa prepare, compare, propose and flag. A person reviews and decides. An agent action is
therefore never a mutation of an existing record: it is an agent run that ends in new records marked
origin = agent, plus an event log a reader can follow, plus a decision that stays with the person.
The problem
Research agents that examine authorised sources, compare findings, draft protocols and reports and run review checks need durable state, an event log, cancellation, redaction of every output and an attribution lint. They must not commit anything, approve anything or rewrite an approved record, and the model they use must never be a literal in code or documentation.
How it works
- Kinds:
evidence_compare,evidence_gaps,evidence_hypotheses(started from a question withevidence.agents.use),plans_draft_protocol,plans_draft_report(from a plan withplans.agents.use),review_check(from an SOP version and a target withreview.agents.use). Phase 2 addsconsole_turn(one per message in a console thread),progress_propose,review_extract_requirements,review_sop_impactandreview_check_batch; the six phase-1 kinds stay callable as canned prompts from the console. - Run record (
AgentRunOut):kind,statusinqueued,running,awaiting_input,succeeded,failed,cancelled,input,result_summary,requested_by,started_at,finished_at,error,last_event_seq, plusthread_id,mode(interactive,background),lane,agent_version_id,plan_hash,usageandtrace_id. - Events (
AgentEventOut):run_id,seq,ts,kind,level(debug,info,warning,error),message,payload; read underSetup › Agent runswithprogram.agent_runs.read. - The submit result:
{items[], drafts[], review_findings[], lint}. Items are findings, hypotheses or gaps with anassertion_kindandorigin: agent; drafts are protocols or reports created in statusdraft; review findings are filed with decisionopen. Everything passes redaction and the attribution lint first; a lint hit yields the public errorattribution_leakand a null result that is discarded. - Public error codes:
runtime_unavailable,session_lost,budget_exhausted,timed_out,cancelled_by_user,attribution_leak,internal_error, and from phase 2gate_expired,policy_denied,plan_violation,config_mismatch,runtime_updating,rate_limited. A gate that waits for a person is the container stateinterrupted_input_required, stored as the run statusawaiting_input. - Worker rules: claims
agent_runs,sync_runsandtool_invocationswithFOR UPDATE SKIP LOCKEDin two lanes (interactive turns never queue behind background jobs); refresheslocked_atevery 60 s and re-queuesrunningrows whose heartbeat is older than 5 minutes; honours SIGTERM with a 120 s grace. Locally the runtime is a fake (AGENT_RUNTIME_URLempty) that returns canned, illustrative results. The model id comes only fromAGENT_MODEL_IDand is verified at run start against the recorded model configuration.
What a person decides
| Agent output | Arrives as | The person’s decision | Permission |
|---|---|---|---|
| Finding | origin = agent, kind printed | edit or keep; cite in a hypothesis | evidence.findings.manage |
| Hypothesis | status proposed | accepted or rejected, with rationale | evidence.hypotheses.approve |
| Gap | status open | addressed or dismissed | evidence.gaps.manage |
| Protocol or report draft | status draft | transition to review, then /approve | plans.protocols.*, plans.reports.* |
| Review finding | decision open | accepted, dismissed or resolved, with note | review.findings.approve |
| Console proposal (any write) | tool_calls row proposed with proposal_hash | approve, edit then approve, or decline with a reason | the write’s own permission, recorded as permission_exercised |
| Any run | queued or running | cancel | program.agent_runs.manage |
Why this design
- New records instead of edits: the trail from a decision back to the run that proposed it stays intact, and an approved record is never changed by software.
- A separate runtime with durable sessions instead of calling a model from the API worker: interrupt and resume, a separate execution role, and redaction on both sides of the wire (ADR 0008).
- No git actions: the reference runtime’s
push,run_testsandsquashwere removed; the research agent has nothing to commit. - In the console the same rule becomes plan-first: every run starts with a plan artifact, every write is a proposal a person approves with the write’s own permission, and agents hold no approve, sign or notify tools (About the console).
Consequences and limits
- Agent runs are only as useful as the sources the program authorised; a run over an empty question returns an empty result.
- The fake runtime proves the protocol, not the science; every result it returns is labelled illustrative.
- A
failedrun leaves its events and error code; nothing is written to the product tables.
Related
- How to run an evidence comparison.
- Statuses for the run lifecycle.
- ADR 0008 and ADR 0013.
Last updated on