How to approve with a signature
Use this guide when a protocol or report is in review and you are its approver. You start with a record in
status review (an agent-drafted one reads “Agent-generated draft, unsigned.”); you end with the record
approved, a signature row bound to its content, and the record page reading “Signature valid”. Approving a
protocol needs plans.protocols.approve; a report needs plans.reports.approve; both need a fresh
re-authentication.
Approval in the console (accepting an agent proposal) is not a signature. Signatures are reserved for the approve routes of protocols and reports and for requirement-set acceptance; the meaning is derived by the server from the route, never chosen by the client.
Prerequisites
- A protocol or report in
review(moved there withPOST .../transition, or an agent draft promoted from the canvas and transitioned by its author). - The
program_leadorprogram_ownerpersona, and an identity session that can re-authenticate.
Open the record and read its provenance
Plans › Protocols, select the protocol. An agent-drafted protocol shows the footer “Agent-generated draft,
unsigned.” with “Cites N sources.” and “Model configuration MC-n (recorded <date>)”, the link to its thread
(“From thread T-31” or “From a private thread”), the SOP versions it was drafted against
(sop_version_ids) and, when a person edited a section, a version with origin = human.
Choose Approve
Approve is shown only with plans.protocols.approve. The signature step expands inside the approval card (contract 12.10; no separate dialog) and is titled “Decision signature (non-GxP
pilot)” and shows the statement you will confirm: “I, Priya N., approve protocol <title> v1 (record
9f3a…). Decision signature (non-GxP pilot).” The sixteen hex characters are the start of the record hash of
{id, version, title, body_md, format, plan_id, sop_version_ids}.
Re-authenticate
Choose Re-authenticate. The card persists pending_signature in sessionStorage, the identity provider
prompts you to sign in again, and the card resumes on the signature step with the same statement and your typed
rationale restored under the line “Draft restored”, so nothing is asked twice. Fact (verified in
web/components/records/signature-step.tsx:13-14, 57-61, 102): the pending signature carries the rationale and
the step resumes with it | Consequence: the restore across the identity hop is built. From an e-mail deep link the
same thing happens after you land on the record.
Confirm and submit
Confirm the statement, write a rationale and submit. The web app calls
POST .../plans/protocols/{protocol_id}/approve with ApproveRequest {rationale, reauth_token, statement_ack}. The API verifies the token (oid and tid equal to your session, auth_time within 300 s,
single use), derives meaning = approved, recomputes the record hash, writes the signature and the audit row
in one transaction, and the record reads approved with “Signature valid”.
Read what changed
- The protocol carries
signature_id; furtherPATCHrequests answer409 record_signed, and a change creates a new version withsupersedes_id. - The record page reads “Agent-generated draft; approved by Priya N. on
<date>(approved). Signature valid.”; if the content ever differs from the signed hash the line becomes “Record changed since signature”. - Setup › Audit shows
protocol.approvewithactor_kind = human,signature_id, your rationale asreason, and, for an agent draft, theagent_run_idof the drafting run on the earlierprotocol.createrow.
Carrying the protocol into the notebook
Trovensa writes nothing into the ELN. When the approved text is copied into a notebook entry, copy the
provenance footer with it: a fenced JSON block {agent_id, agent_version_id, model_config_label, run_id, generated_at, citations[], statement: "agent-generated, unsigned"} plus one line of prose, so the notebook
shows where the text came from and that the approval lives in Trovensa.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Approve is disabled | you lack plans.protocols.approve or the record is not in review | the scientist persona drafts but does not approve; transition the record first |
401 reauth_required | no auth_time in the token, or older than 300 s | re-authenticate again |
409 record_signed | the record already carries a signature | create a new version that supersedes it |
| “Record changed since signature” | content differs from the signed hash | inspect the audit rows after signed_at; a signed record should only change through a new version |
Related
- Signatures.
- About records and signatures.
- How to request an approval for the approval-request record in Progress.