Skip to Content
PlatformExplanationAbout stage playbooks

About stage playbooks

A program sits in one of four stages: 01Discovery 02Preclinical development 03Clinical development 04Manufacturing planning. A stage playbook says what a completed stage looks like in records, who does what to get there, and how the stage is closed. Everything on this page is designed (PRODUCT-PLAN.md Part 7 section 3, PRODUCT-CONTRACT.md section 11); today a program’s stage is changed with PATCH /programs/{program_id} under program.settings.update and nothing checks what the stage required.

Completion is defined in Trovensa records, never as a regulatory statement. The platform models manufacturing as a fourth sequential stage while real CMC work runs alongside preclinical and clinical work; CMC milestones inside earlier stages are ordinary Progress records in those stages.

What completion means, per stage

StageCompletion in records
Discovery -> preclinicalEvery open question has at least one accepted finding or a dismissed gap; at least one hypothesis approved; one research plan approved; open items closed or carried with a named owner; no undecided agent proposals older than the program’s escalation_days
Preclinical -> clinicalProtocols approved with valid signatures; experiments completed and linked to notebook entries; reports approved; every check bound to an effective SOP version or superseded by a re-check; review findings decided; deviations closed; gate-critical milestones completed; no approval requested
ClinicalObjects stay designed; the gate shape is the same and the checklist is Progress-only
ManufacturingObjects stay designed; the gate shape is the same and the checklist is Progress-only; twins in this stage do Progress and Plans work only

The sequence, discovery to preclinical

  1. The scientist’s twin proposes sources and findings weekly; the scientist accepts.
  2. The scientist’s twin proposes hypotheses; the scientist accepts the record; the lead decides it (evidence.hypotheses.approve).
  3. The lead’s twin proposes the plan change referencing the approved hypothesis; the lead approves the plan.
  4. The lead’s twin writes the readiness brief; the lead marks the gate ready; QA signs reviewed; the owner signs approved.

Hand-offs: scientist to lead (hypothesis ready, information); lead to scientist (question reassigned, decision).

The sequence, preclinical to clinical

  1. A hypothesis is approved; the scientist’s twin proposes a protocol draft bound to the SOP version in force; the scientist edits and requests approval.
  2. The lead’s twin attaches a reads-only pre-read (“Agent-generated draft, unsigned.”); the lead signs.
  3. Notebook entries close; the scientist’s twin proposes experiment records and a hand-off to QA; the scientist accepts both.
  4. QA accepts the hand-off, which opens a program-visible thread pinned to the entry; QA’s twin proposes the check bound to the effective SOP version; QA approves; findings open; QA’s twin triages; QA decides.
  5. All experiments complete; the scientist’s twin proposes a report draft; the lead signs.
  6. The manufacturing specialist’s twin watches dependencies throughout and proposes open items, milestone changes and plan changes for slips.
  7. Readiness brief, ready, QA reviewed, owner approved.

Hand-offs: scientist to QA (entry ready for check), QA to scientist (correction needed), QA to lead (major deviation, information), CMC to lead (supply slip), lead to CMC (decision: accept the new date).

Approval matrix

Fixed in PRODUCT-CONTRACT.md section 11 and, at R3, generated from BUILTIN_ROLES by a test so it cannot drift from the code. At persona version 3 the scientist bundle loses evidence.hypotheses.approve and plans.plans.approve (personas); today, at version 2, the scientist still holds both, which is why the matrix and the code disagree until R3 ships.

DecisionPermission exercisedSignature meaningPersonas
Finding, gap or source enters the recordevidence.findings.manage, evidence.gaps.manage, evidence.sources.managenonescientist, lead, owner
Hypothesis accepted or rejectedevidence.hypotheses.approvenonelead, owner
Plan approvedplans.plans.approvenonelead, owner
Protocol or report approvedplans.protocols.approve, plans.reports.approveapprovedlead, owner
Review finding decidedreview.findings.approvenonequality reviewer, lead, owner
Requirement set acceptedreview.sops.approveapprovedquality reviewer, lead, owner
Deviation recorded or classifiedreview.deviations.managenonequality reviewer, lead, owner
Approval request decidedprogress.approvals.approveas targetlead, owner
Hand-off sent, accepted, declined, completed, withdrawn (R3)program.handoffs.manage, scoped by partynonescientist, quality reviewer, manufacturing specialist, lead, owner
Twin enabled, paused, resumed, retired (own); standing plan approved (R3)program.twins.usenoneeveryone but viewer
Any twin paused with a reason (R3)program.twins.managenonelead, owner
Stage gate ready (R4)progress.stages.managenonelead, owner; manufacturing specialist for the manufacturing gate only
Stage gate reviewed (R4)review.stage_reviews.approve and the quality_reviewer personareviewedquality reviewer
Stage gate closed (R4)progress.stages.approveapprovedowner, lead (not the reviewed signer)

Twins appear in no row.

The stage gate (R4)

A stage is closed through a stage gate record (stage_gates): open -> ready -> reviewed -> closed. Once a program has any gate row, the gate is the only writer of programs.current_stage_id; the direct stage change is refused with 422 stage_via_gate, and the migration opens a gate for every program’s current stage so the rule holds from the day R4 ships.

StepWhoControl
Gate openssystem, on program creation and on close of the previous gaterequired_records is the stage checklist, recomputed hourly by stage_readiness_refresh only while the gate is open
Readiness briefthe lead’s twin (stage_readiness run, reads only)artifact readiness_brief, labelled “Agent-generated draft, unsigned.”: present and missing records, undecided proposals, open findings, unclosed deviations, checks bound to superseded SOP versions
Readyholder of progress.stages.managea human click; 409 gate_incomplete while any required record is missing; the checklist is frozen at this moment; a holder who is neither owner nor lead may mark only the manufacturing gate ready (409 gate_stage_restricted); a change to a frozen record reopens the gate, audited stage_gate.reopen
Reviewedreview.stage_reviews.approve and the quality_reviewer persona, resolved through groupssignature meaning reviewed with re-authentication; the statement stored verbatim is “I have reviewed the records listed in this gate’s checklist”; the dialog lists the checklist and shows the brief as an unsigned draft, so the signature attests records, not the brief (403 reviewer_role_required otherwise)
Closedprogress.stages.approve (owner or lead)an approvals row with target_type = stage_gate plus signature approved; reviewer and approver must differ (409 same_signer); current_stage_id advances and the next gate opens in the same transaction; audited stage_gate.close

stage_gate joins SIGNATURE_TARGET_TYPES (today protocol, report, requirement_set), APPROVAL_TARGET_TYPES (today milestone, plan, protocol, report, hypothesis), SIGNATURE_REQUIRED_TARGETS and RECORD_HASH_FIELDS; the closing hash includes the review signature id, so the approved signature binds to one specific quality review. After reviewed the gate is frozen; a late record supersedes it as a new version.

Why two signers

A single approver closing a stage leaves no independent quality review; free stage changes with an audit row leave the checklist unenforced. Two signatures with different meanings from two different people, over a checklist frozen before either signs, are the smallest design that makes “the stage is complete” a statement about records rather than about someone’s confidence. ADR 0024 records the alternatives.

Source: PRODUCT-PLAN.md Part 7 section 3 (3.1 to 3.5); PRODUCT-CONTRACT.md sections 11.4 and 3; api/app/db/models/signatures.py (SIGNATURE_TARGET_TYPES); api/app/db/models/progress.py (APPROVAL_TARGET_TYPES); api/app/auth/permissions.py (program.settings.update); decisions/0024-stage-gates.md