Specification: review domain and versioning¶
Planning specification (prefix RD; tracker row T-RD-00). Feature implementation remains on hold
(Chris, 5 October 2026). The owner decisions cited here are planning approval only. Brief approval
and implementation authorisation are separate, per gate (D1-04), and are still on hold. Nothing on
this page says that work has started, that a gate has passed or that anything is enabled in
production. Storage shapes and names are PROPOSALs until the F1a storage and naming ADRs fix them.
Thresholds quoted from earlier documents are proposed and not approved.
Sources. "Consolidation" is the
owner-session consolidation,
which wins over older text. "Register" is the
74-entry session register,
including its appended owner amendments. "Condensed" is the
condensed packages. The
owner ledger is review-form-owner-decisions-2026-10-02.md.
Package context: domain model, versioning model,
consistency model, contracts C1 to C5 and C9.
Neighbouring specifications: duplicate merge (DM),
stage pools, steps and history (SP),
reconciliation and screening (RS),
baseline conversion (BC),
UX, devices and work discovery (UX) and
access, communications and deletion (AC). Owner-session
amendments outside the register count are cited by short name; their OS-A IDs are in the
owner-session integration.
Labels. OWNER (a decision ID or a consolidation section), PROPOSAL (this specification's
recommendation for the brief), OPEN (an owner decision not yet taken), BRIEF (an alignment,
engineering or validation entry that the workstream brief settles).
1. Summary in plain English¶
The Study stays the thing a project reviews. A form session, a screening decision, a reviewer target override and an accepted result always belong to one Study. Each imported reference (a citation) and each source document (a report, for example a PDF) stays its own record. SyRF never fuses two imported references into one invented original. A conference abstract and the journal article that followed it may stay as two Studies.
One reviewer, one session, one place. A reviewer has one session per Study and form. Every stage, browser tab and device that reaches that form opens the same session. It holds one place in the capacity count. The form decides how long an inactive session keeps its place and how many studies a reviewer may have in progress. When the place expires, the draft stays.
Three ways of writing. Autosave keeps a recoverable draft by sending only the changes; it never submits anything. Save creates an immutable version checkpoint, which may be incomplete. Complete checks the whole form and creates a completed checkpoint. Only explicit versions count towards targets. Saving a completed session as incomplete stops it counting, and SyRF warns the reviewer first about any reconciliation or other work that depends on it.
Definitions change through published versions. Questions, forms and screening profiles each have immutable versions. The form's standard reviewer target is part of the form version, so changing it is a publication with an impact preview, even when no question changes. A single Study can have its own target through an override with its own version history. A request for additional reviews, for one Study or many, raises those Studies' targets openly and counts each reviewer once.
Publishing is previewed, chosen and rechecked. The admin sees which existing and active work is affected and how, chooses the treatment, and SyRF rechecks at commit. Publication may now create session versions that record the chosen treatment, each attributed to the publication and the publishing admin (D2-01 reversed). Reviewers' drafts are kept. The publisher declares whether a changed question is compatible with its previous version and whether old answers may be mapped to new options. That declaration never changes afterwards; a mistake is corrected by a guided rollback and a new publication.
Several people can draft at once. Designers see who else is viewing or editing, changes appear in every open view, and a conflicting edit is kept for recovery. Only one publication per form runs at a time.
Every question gets an answer by default (Chris, 6 October 2026). New questions are required unless a designer deliberately makes one optional in advanced settings. A reviewer who cannot give a value says so by choosing a reason no value is provided, such as "Not reported" or "Unable to assess", so it is clear that every question was considered. Designers choose which reasons each question offers, and which comments, units, quotes or other notes an answer allows or needs. An "Other, please specify" choice is a value, not a reason: its text is recorded with the value. Chris decided these terms later the same day (DQ-46): Answer status names the overall state of a question (Unanswered, answered with a value, or answered with a reason no value is provided), and "no-value answer" is retired (§3.16, §12).
One question editor for every project (Chris, 6 October 2026; DQ-01 and DQ-03). Classic projects (not yet converted) and Versioned projects use the same refreshed question editor, each with its own saving and assignment behaviour; the editor does not silently introduce versioned publication, draft or assignment semantics into an unconverted project. In a Versioned project each accepted field change is saved automatically into the unpublished design draft, with a clear save status, safe conflict handling and per-question discard; saving a draft never publishes anything to reviewers (§3.7, §4.7).
No owner decision is open. Of the 89 owner decisions open before the session, D2-09 was the only one the session left open. It concerns how accepted answers to a question shared by two forms are revised. Chris answered it on 5 October 2026, agreeing with the recommendation and adding two points: the second form's reconciler may revise them in their own final submission, producing a new snapshot with provenance; they are prompted for a reason, which is never required; and they may also raise a query on the accepted answer (§4.14). Update (6 October 2026): Chris's answers about answers left two owner items open: the naming of what was then called a no-value answer, and how clearing an answer is recorded (§12). Update (6 October 2026, design-handoff answers; decision register §1.18): the naming is decided (DQ-46); how clearing an answer is recorded stays open (DQ-50). DQ-01 also answers QMI-04 in part (§12). Recording these answers neither sends the design pack nor lifts the implementation hold.
2. Decisions covered¶
| ID | Decision in one line | Status | Section |
|---|---|---|---|
| Consolidation §1 (Study unit) | The Study is the reviewable item; forms, sessions and targets attach to Study × form across stages | Decided | §3.1, §3.3 |
| Consolidation §1 (references and reports) | References and source documents stay distinct records; storage is chosen deliberately; grouping distinct reports is deferred | Decided | §3.2, §3.3 |
| Consolidation §1 (shared session) | One session and place per reviewer per Study × form across stages, tabs and devices; route provenance stays on versions | Decided | §3.9, §3.11, §4.1 |
| Consolidation §1 (autosave, Save, Complete) | Autosave is a diff-based recoverable draft; Save is a checkpoint that may be incomplete; Complete is a validated checkpoint | Decided | §3.10, §4.2 to §4.4 |
| Q-27 | Readiness from current evidence; warn the actor before commit; inform affected authors; never rewrite dependent work automatically | Decided | §4.5, §7 |
| Q-20 | Admin impact preview; alerts to affected reviewers; in-form warnings for a reviewer's own edits; deduplicated notices | Decided | §4.8, §5, §7 |
| Q-34 | The publisher explicitly declares compatibility and whether mapping applies; mapping writes attributable revisions | Decided-amended | §3.4, §4.8 |
| Q-26 | Immutable profile versions; mismatches with existing decisions and outcomes detected and treated before publication | Decided | §3.6, §4.12 |
| D2-11 | Many drafts; one publication operation per form; the next publication rechecks against the resulting state | Decided | §3.7, §4.7 |
| Collaborative question drafts (owner-session amendment) | Presence, live updates, preserved local edits, base checks, recoverable conflicts, attributed changes | Decided | §3.7, §4.7 |
| Target-versions-form (owner-session amendment) | The standard reviewer target is part of the immutable form version | Decided | §3.5, §4.9 |
| Overrides and additional-review requests (consolidation §1; D3-13 clause) | Study × form overrides keep their own history; requests raise the effective target explicitly and count reviewers once | Decided (the D3-13 entry itself stays a brief item owned by SP) | §3.12, §4.10, §4.11 |
| D2-01 | Publication may create attributable generated session versions (reverses the round-2 proposal) | Decided-amended | §3.15, §4.8 |
| D2-02 | Compatibility belongs to immutable question versions; the publisher declares it; corrections use guided rollback and republication | Decided-amended | §3.4, §4.13 |
| D2-03 | A data-type or multiplicity change is an incompatible version of the same question | Engineering contract (no owner question) | RD-R30 |
| D2-04 | A stage binds the form identity; the live route presents the session's resolved version | Engineering contract (no owner question) | RD-R31 |
| D2-05 | The standard target versions the form; every other setting is classified in the brief | Decided-amended (in part) | §3.5 |
| D2-06 | System questions stored as versioned data and adopted only through a form publication | Engineering contract (no owner question) | RD-R32 |
| D2-07 | Form-owned inactivity timeout and per-reviewer in-progress limit; one place across tabs and routes; expiry keeps the draft | Decided | §3.11, §4.6 |
| D2-08 | One shared session and place across tabs and devices; connections tracked separately; base-version checks | Decided | §3.10, §3.11 |
| D2-09 | Shared-question accepted answers across two forms: the second form's reconciler may revise them as a new snapshot with provenance; an optional reason is prompted for; a query may also be raised | Decided-amended (Chris, 5 October 2026, status page) | §4.14, §12 |
| D2-10 | Tested publication active-work protection; measured pause and operation limits | Brief item | §7, §12 |
| D2-16 | No size-based exclusion; the largest project is an acceptance case | Replaced | RD-R33, §11 |
| Q-29 (target-change part) | A new target may lead to a new accepted-result version; history kept (owned by RS) | Decided-amended (owned by RS) | §4.9 |
| D3-03 (status meaning) | Draft auto-saved, version checkpoint saved and completed stay distinct (wording owned by UX) | Decided-amended (owned by UX) | §4.2, §9.1 |
| Required by default (owner answer, 6 October 2026) | New questions are required by default; optional sits under advanced settings; each question version declares its allowed reasons no value is provided (defaults, designer-added, catalogue sets); Complete needs an answer for every applicable required question; converted forms keep the legacy Optional flag |
Decided-amended (Chris, 6 October 2026) | §3.16; RD-R49 to RD-R51 |
| Configurable answer metadata (owner direction, 6 October 2026) | Each question version declares metadata fields, each hidden, allowed or required per answer state | Decided as Chris's direction (6 October 2026); field shapes and validation timing PROPOSAL |
§3.16; RD-R52 |
| DQ-46: naming of answers (owner question, 6 October 2026) | Answer status names the overall state; "reason no value is provided" names the configured reasons (noValueReasonId, PROPOSAL) and replaces "no-value answer"; "Other, please specify" is a value; "No value to enter" is illustrative action wording |
Decided with revised terminology (Chris, 6 October 2026; decision register §1.18) | §3.16; RD-R50 to RD-R54; §12 |
| Recording unanswered and cleared answers (6 October 2026) | Clearing writes an explicit Unanswered revision; nothing is pre-written at Complete | PROPOSAL (open as DQ-50) |
§3.16; RD-R53; §12 |
| DQ-01: question editor for Classic projects | One refreshed editor for Classic and Versioned projects, with each mode's saving and assignment behaviour; no versioned publication, draft or assignment semantics in unconverted projects. QMI-04 is answered in part; the retirement timing (T-RD-17) is not addressed |
Decided, option (a) (Chris, 6 October 2026) | §4.7; RD-R48; §10; §12 |
| DQ-03: how design edits are kept in a draft | Accepted field changes save automatically into the unpublished design draft, with save status, safe conflict handling and per-question discard; saving a draft never publishes | Decided, option (a) (Chris, 6 October 2026) | §3.7; §4.7; RD-R55 |
3. Concepts, entities and storage¶
Each entity below says what it is, how it is identified, which versions and pointers it has, what may change, where it is proposed to live, and what it is not. Storage follows two package rules: immutable records live where an append-only repository can enforce insert-only writes (versioning model §12.2), and a new collection is proposed only when that rule or a measured need requires it, never merely because a record is a distinct domain concept (consolidation §1).
3.1 Study¶
- What it is. The item a project screens and annotates. Forms, sessions, targets, decisions and accepted results attach to a Study.
- Identity. The existing Study GUID (CSUUID). It is never re-keyed.
- Versions and pointers. A mutable parent with
state(CurrentorTombstoned) andcurrentVersionId, which points to the currentStudyVersion(§3.2). A tombstone records its reason and operation (DM §3.1). - Mutability. The parent changes by compare-and-set on its
Audit.Version, as every planned canonical command does under CR-1. Content versions never change. - Proposed storage (
PROPOSAL). The existingpmStudydocument gainsstate,currentVersionId,tombstoneand thecurrentEvidenceprojection (DM §3.6). Its existing top-level bibliographic fields stay as the projection of the currentStudyVersion, so legacy readers keep working. A missingstatereads asCurrent. - What it is not. It is not a citation, a report or an investigation. It does not belong to a stage. A stage's pool is computed from Studies (SP).
3.2 StudyVersion¶
- What it is. An immutable snapshot of a Study's content: the displayed bibliographic fields with per-field provenance, the links to its references, and the links to its source documents.
- Identity.
(studyId, seq)with a GUID. - Versions and pointers.
Study.currentVersionIdpoints to one. Earlier versions stay readable. - Mutability. None. A bibliographic edit, a merge and an unmerge each append a version (DM §4).
- Proposed storage (
PROPOSAL). An append-onlypmStudyVersioncollection, chosen for enforcement. Older binaries replace the Study document whole, so immutable content inside it cannot be proven unchanged. A P1 import writes version 1 from its single reference. A Study created before P1 gets version 1 on first need (a bibliographic edit, a merge or baseline conversion), labelledCurrentSnapshotOnlybecause its earlier history was not recorded (BC). - What it is not. It is not a citation and not a FEAT-011
Publication. Cross-projectPublicationenrichment never changes a Study's displayed fields silently (DM-R17).
The rules for field provenance and overrides are in DM §3.2.
3.3 Reference (citation) and source document (report)¶
- Reference. A citation is the bibliographic reference and import record: the raw imported
fields, the search and import job, the importer, the import time and the original identifiers. It is
immutable. Its identity is
citationId. Its home Study is the Study created for it at import, and it never moves. - Proposed storage for references (
PROPOSAL). Keep citations as immutable entries in the home Study'scitations[]array, the FEAT-011 shape. Because citations never move, a Study usually holds exactly one. A consolidated Study links its inputs' citations by ID throughStudyVersion.referenceLinks[]({citationId, homeStudyId, linkedBy, linkedAt, reason}), so no chain of merges is ever walked to find a reference. This deliberately adds no collection. F-P revisits it only if measured document sizes require it. - Source document. A file that reports the work: a full text, a supplement or an abstract. The
existing PDF and file records stay as they are.
StudyVersion.sourceDocumentLinks[]({documentRef, kind, linkedBy, linkedAt, sourceStudyId}) can hold several documents, which is the prepared multi-source link (D4-08, carry-forward). Which distinct report a reference or file belongs to is RI'ssourceDocumentKeywith its basis (RI §3.1): it sits onreferenceLinks[]entries, and asourceDocumentLinks[]entry may carry the same key (PROPOSAL, added in the 5 October harmonisation). The workflow for grouping distinct reports into one investigation is deferred (RI owns Q-23 and D4-08). - What they are not. Two imported citations are never collapsed into one fabricated original. A report is not a Study. Linking a source document never merges review evidence. A conference abstract and a journal article may remain separate Studies under the protocol (consolidation §1).
3.4 Question definition and question version¶
- What it is. A question's stable identity (versioning model §3.1) and its immutable content versions.
- Identity.
QuestionRefplus structural identity; a version is(QuestionRef, seq). - Versions and pointers. Form and profile versions pin exact question versions.
- Compatibility declaration (D2-02 amended, Q-34;
OWNER). Each version carriescompatibility {suggestedBySyrf, declared, declaredBy, declaredAt, rationale}and, where the publisher allows it,optionMapping {oldOptionId → newOptionId, declaredBy, declaredAt}. SyRF suggests a default from the change (versioning model §3.5 table). The authorised publisher confirms or changes it explicitly. A version is normally committed as part of publishing the first form or profile version that pins it, so the declaration is made by the publisher at that moment. - Mutability. None after commit, including the declaration and the mapping. This replaces the versioning model's rule that a declaration may change until a revision pins the version. A wrong declaration is corrected by a guided rollback and republication (§4.13).
- Proposed storage.
pmQuestionDefinitionandpmQuestionDefinitionVersion, as in the versioning model §12.1. - Answer labels (
PROPOSAL).main's answer label (#2739, #2772; M-20) is question-version presentation content. Changing it is a compatible change, and conversion carries it into v1 (RD-R42). - Options and filtered options (
PROPOSAL). Every option keeps a stable option ID. A child question's filtered options (which of its options are offered after each parent answer) are version content keyed by parent option IDs. They are new authoring: neithermain's new editor nor the legacy designer saves them today (both writeparentFilter: null), schema-v0 options cannot hold them, andParentFilter.Validate()is never called (M-15, M-23). The server validates them against the pinned parent version, and a schema-v0 project gets an explained refusal (RD-R38). - System questions (
PROPOSAL). The global seed'sseq 1for each productionSystemQuestionVersionequalsmain's code-built system questions (18 GUIDs, with their text and structure). The parity test reads a frozen copy, because the code's creator collection can change at runtime (M-24, H-DOM-07, X-49; RD-R43). - Reference questions (
PROPOSAL, 6 October 2026). Reference questions carry a target contract as version content (CPR §3.4.2). - What it is not. A pending edit is not a version. Pending edits live in a design draft (§3.7).
3.5 Form and form version¶
- What it is. An annotation form is a project-level evidence and requirement owner (SF1). A form version is its immutable published requirement.
- Identity.
(projectId, formId); a version is(formId, seq). - Versions and pointers. The form head holds
currentPublishedSeq,publicationSeq,policyGenerationand the active publication marker. Sessions, accepted results, tasks and stage bindings pin form versions. - Content of a form version. The ordered question-version pins with ancestors, requiredness,
minimum instance counts, the validated applicability graph and the renderability result
(versioning model §4.1), plus
FormVersion.standardTarget(OWNER, target-versions-form) andReconciliationPolicy(targetOneHandling∈AutoAccept,RequireHumanReconciliation,OWNERR1; baseline conversion alone may also setNoAcceptance, RS-R04aPROPOSAL; the other members are classified below). - Proposed storage.
pmAnnotationForm,pmAnnotationFormVersion, and the audited operational settings record on the form head with entries inpmDefinitionSettingsAudit. - What it is not. A stage does not own a form's target, timeout, limits, blinding or hint availability (consolidation §4; SP and RS).
- Composition validation (
PROPOSAL). A form version is composable only when its pins pass one C4 composition rule set with one code namespace.main's rule corpus (16 rules: FL001 to FL009, NQ001 to NQ005, CPA001 and CPA002) and its placement fixtures (16 valid, 96 invalid) become the shared fixture set FX-COMPOSE.main's placement validator runs it now, and the canonical composition validator runs it from R2a. NQ005 (cycles), CPA001 and CPA002 are not built yet; they join the set re-keyed to option IDs of pinned parent versions, with ancestor closure. The formal specification's AQ001 to AQ016 and QM v2's AQ001 to AQ017 are folded into the same namespace (M-02, M-03, M-25; RD-R41).
Setting classification (D2-05 amended in part). The owner fixed one row: the standard target is
inside the version. Every other row is a PROPOSAL for the brief. A setting goes inside the version
when it changes what counts as valid evidence, how evidence is produced or how an
accepted result is formed, because the records it affects must pin it. A setting stays operational
when it changes only who is offered work and when; operational changes are audited, read live and
recorded on the events that use them.
| Setting | Owner | Classification | Basis |
|---|---|---|---|
| Question pins with ancestors, requiredness, minimum instances, applicability graph, renderability result | Form | Inside the form version | FV1; versioning model §4.1 |
Standard reviewer target (FormVersion.standardTarget) |
Form | Inside the form version | OWNER (target-versions-form) |
Target-one handling (AutoAccept or RequireHumanReconciliation; conversion-only NoAcceptance, RS-R04a) |
Form | Inside the form version | OWNER (R1: "publish the relevant versioned form policy"); NoAcceptance is PROPOSAL |
| Accepted-answer completeness override | Form | Inside the form version (PROPOSAL) |
Q-04: it changes what an accepted result must contain |
| Reconciliation identity blinding | Form; the profile for screening reconciliation | Inside the version (PROPOSAL); profiles already version it (naming registry) |
Q-28, Q-30 |
| Reconciled-answer hint availability baseline | Form | Inside the form version (PROPOSAL) |
Q-28: it changes exposure, which the session version records |
| Outdated-answer completion mode (warn or block) | Form | Inside the form version (PROPOSAL) |
D4-17 (O3): "record the policy and evidence versions used" |
| Inactivity timeout; per-reviewer in-progress limit | Form | Audited operational setting (PROPOSAL) |
D2-07; Q-28 |
| Capacity cap (separate from the target) | Form | Audited operational setting, off by default (PROPOSAL) |
D3-17 (SP) |
| Unstarted reconciliation-assignment expiry | Form (reconciliation tasks); the profile for adjudication tasks (RS §3.12); admin-configured | Audited operational setting, optional, off by default | Q-30 |
| Bulk acceptance of agreeing candidates | Form | Audited operational setting, off by default | Q-11 (RS) |
| Comparison display settings; guidance text | Form | Audited operational setting | D2-05 |
3.6 Screening profile and profile version¶
- What it is. A screening profile owns eligibility questions, decision rules and its reconciliation and adjudication policies. A profile version is its immutable published content.
- Identity.
(projectId, profileId); a version is(profileId, seq). - Versions and pointers. Decisions, profile-owned answers, outcomes, adjudications and stage filter clauses pin profile versions.
- Mutability. None after publication (Q-26,
OWNER). Changes publish a new version through the impact process in §4.12. - Proposed storage.
pmScreeningProfile,pmScreeningProfileVersion,pmProfileVersionIssue. - What it is not. This page covers how profiles version and publish. RS covers what a profile
version contains (Unsure, tie policy, discussion, rationale, blinding, sufficiency and source
policies,
ScreeningProfileVersionin the naming registry).
3.7 Design drafts, draft changes and presence¶
- What they are. A
DesignDraftis a named, unpublished proposal for the next version of one form or one profile, including pending question edits. Several drafts may exist for one form (D2-11). ADesignDraftChangeis one accepted edit to a draft.DesignPresencesays who is viewing or editing which draft or question right now. - Identity. A draft has a GUID and a scope (form F or profile P). Each change has
(draftId, draftRevision). - Versions and pointers. A draft records the published version it is based on and its current
draftRevision. Each change records its actor, time, the item it changed (question, option, form composition element or policy field), the item revision it was based on, and the before and after values. - Mutability. A draft's working state changes only by appending a change. A change is never edited. Discarding a draft is an audited status change.
- Saving into the draft (
OWNERDQ-03, option (a), Chris, 6 October 2026; mechanicsPROPOSAL). Each accepted field change is saved automatically into the unpublished design draft as oneDesignDraftChange; there is no per-question Save or "Keep changes" step. The editor shows a clear save status for the draft (for example "Unpublished · saved 14:03", illustrative; design wording never uses the reviewer's "Draft auto-saved", DH-C105), handles a same-item conflict safely (§4.7: the local edit is kept beside the current value, never overwritten silently) and offers Discard changes per question, as recommended. A per-question discard appends changes that return that question's items to the draft's base values, so the change log keeps the discarded edits (PROPOSAL). Saving a design draft never publishes to reviewers: only a publication (§3.8, §4.8) changes what reviewers see. This applies to Versioned (canonical) projects; a Classic project has no design draft and keeps today's save semantics (DQ-01; §4.7). - Proposed storage (
PROPOSAL).pmDesignDraft(head) and an append-onlypmDesignDraftChange. The earlier sentence "Presence is not stored: it lives in connection state on the existing hub" is superseded by the next bullet. - Presence (
PROPOSAL, pending owner question QMI-01). Presence is never an audit record (collaborative question drafts amendment: "presence is not a substitute for an audit record"), and only users who may view the design see it. Connection state on one hub cannot carry it: production runs 3 to 10 API pods with no SignalR backplane (realtime server plan D4), and the realtime hub contract v2 has no design topic and no groups (X-02, X-03). Recommended: an ephemeral, TTL-bounded presence record per viewer and draft (pmDesignPresence,PROPOSALname), refreshed by heartbeat and expiring on its own, read by the realtime v2 change-feed reader and pushed on an additive v2 topicdesign:{scope}. Alternatives: per-pod bus fan-out of presence changes, or a Valkey backplane (the realtime plan's D4 revisit trigger). No audit, history or export path ever reads the record (RD-R45). - What it is not. A draft never changes a published requirement or a reviewer's form. Editing a draft never starts an impact flow (Q-20). Presence never grants or blocks an edit.
3.8 Publication operation¶
- What it is. The operation that publishes a form version (
FormVersionIssue) or a profile version (ProfileVersionIssue), with its recorded policy and its impact. - Identity. An operation GUID; at most one active per form or profile (D2-11).
- Versions and pointers. An append-only policy record per generation (FV4 adds generations), the preview digest, the generated-version plan, progress, and the impact manifest built after commit.
- Proposed storage.
pmFormVersionIssuewith chunks, andpmProfileVersionIssue, as in the domain model §4.5. - Operation driver (
PROPOSAL; ADR-021). The phase-2 driver and its watchdog are host-neutral: a lease scan in a hosted service, or a host-neutral handler class, guarded by the operation's generation. They never rely on cancelling a scheduled message, which Wolverine does not document, and use no MassTransit-only feature, so they run unchanged before and after the Wolverine switch-over. The switch-over's drain and rollback runbooks (ADR-021 S2.10 and S4) quiesce programme operations: no new publication starts, a running phase 2 finishes or stalls, and work resumes by lease takeover (X-17, X-18; RD-R46). - P9 class (
PROPOSAL, pending owner question QMI-02). The queued-work ledger's P9 rule says data-changing jobs are atomic and roll back, tidy-up and consistency jobs finish, and obligations exist only by approval. Recommended: phase 1 is delegated and atomic and rechecks the publisher; phase 2 would be an approved system obligation (QMI-02) that runs to completion once phase 1 has committed (X-41). - What it is not. It is not the draft and not the version it publishes.
3.9 Review session and session version¶
- What it is. A reviewer's work on one Study for one form (
FormSession) or one profile (ProfileSession), shared by every stage, tab and device (SF1, consolidation §1). - Identity. Deterministic ID from
(project, study, form or profile, reviewer). It is created by the first autosave; opening a study creates nothing. - Versions and pointers. The session head points to its latest explicit version. Each version is
(sessionId, seq)with its kind, declared form version, route (stage, step, settings version), the full pin map, the resolved question set, exposure state, actor, effective author, operation, command ID, clock stamp and digest. - Mutability. Versions are immutable. The head moves by compare-and-set.
- Proposed storage.
pmFormSessionandpmFormSessionVersion(versioning model §12.1). - What it is not. A session does not belong to a stage. A draft is not a version. A reconciliation session is a separate entity of the reconciliation task (RS).
- Typed answer payload (
PROPOSAL). A revision's payload is a typed value (option IDs, response mode, metadata andunmappedLegacyValue), adapted from QM v2'sAnnotationAnswerrecords (H-DOM-02). Amended 6 October 2026: the payload is exactly one of a value (option IDs for a choice; for an "Other, please specify" option, its option ID with the specified text), a reason no value is provided (noValueReasonId,PROPOSAL; the term decided by DQ-46 replaces the working term "no-value answer" andnoValueAnswerId, which had replaced "response mode") or the explicitUnansweredrecord (PROPOSAL; DQ-50 is open), each with metadata validated for its state, plus the conversion-onlyunmappedLegacyValue(§3.16). It takes a distinct name, for exampleAnswerValue, becausemainalready has anAnnotationAnswertype that only RoB-AI BSON uses. Under the System.Text.Json plan it carries an explicitkindwith a custom discriminator converter (no[JsonPolymorphic]until that plan's R4), keeps decimals exact, compares lists structurally and has round-trip goldens. Digests run over explicit, versioned projections, never whole objects (X-20, X-23; RD-R44).
| Version kind | Created by | Becomes current | Counts towards targets |
|---|---|---|---|
Save |
Reviewer | Yes | Never as completed |
Complete |
Reviewer, after whole-form validation | Yes | Yes, once per reviewer per Study × form, while its standing qualifies |
Fix |
Reviewer, from an outdated flag (SF5) | Yes | No (incomplete) |
Upgrade |
Reviewer (re-pins to the current form version) | Yes | As its status and standing allow |
Withdraw |
Reviewer or admin (C5 ADR) | Yes | No |
PublicationGenerated |
A publication operation, attributed to the publisher (D2-01 amended) | Yes; it is computed against the latest head and never overwrites a newer reviewer version | As its status and standing allow; never a Complete that fails validation |
MergeResolved, MergeCarriedForward, UnmergeCarriedForward |
A merge or unmerge operation (DM §3.5) | Yes, on the Study the operation targets | As their status and standing allow |
3.10 Session draft and draft change log¶
- What it is. The reviewer's unsaved work over the session's current explicit version (SL1).
- Identity. One draft per session.
- Versions and pointers. The draft head records the base explicit version, the base form version
and an increasing
draftVersion. Each accepted autosave appends aSessionDraftChange:{draftVersion, basedOnDraftVersion, per-answer base, patch, connectionId, tabId, actor, at}. - Mutability. The head moves by compare-and-set; changes are append-only. Save and Complete consume the draft atomically and link its changes to the version they produced.
- Proposed storage (
PROPOSAL).pmSessionDraft(head, with the materialised current draft as a cache) and an append-onlypmSessionDraftChange. The change log is kept with the session's history so the draft history is fully reconstructable (consolidation §1). This replaces the earlier rule of no autosave trail beyond the current draft (PH-33). Retention and any compaction are a brief item (§12); compaction never removes an explicit version. - What it is not. A draft never counts, never qualifies, is never shown to reconcilers and never appears in exports (AC-R2a-08). It never writes Study.
3.11 Connections and the shared place¶
- Connection. One record per tab or device (
ReviewSessionConnection), with the session it serves, the route it came through and its last activity. Connections are tracked separately (D2-08,OWNER). - Place. One capacity claim per reviewer per Study × form (claim contract v2), however many
connections or stages use it. The form owns the inactivity timeout and the per-reviewer in-progress
limit (D2-07, Q-28,
OWNER). - Release rule (
OWNER). One idle or closed tab never releases the place while another connection remains active. The place is released only when every connection has been idle beyond the form's timeout or has closed. Release keeps the draft. - What it is not. The place is not the target and not the capacity cap (SP owns D3-17 and D3-18). The in-progress limit counts sessions, never connections.
3.12 Study target override, effective target and additional-review request¶
- StudyTargetOverride (
OWNER, consolidation §1). An immutable, versioned requirement decision for one Study and one form, applying across every route. Identity: deterministic from(project, study, form); versions(overrideId, seq). Each version recordsvalue,basis(SetByAdmin,AdditionalReviewRequest(requestId, raiseBy),MergeConfirmation(mergeId)orRemoved),madeAgainst {formVersionSeq, standardTarget}, reason, actor, time and clock stamp. Proposed storage (PROPOSAL): an append-onlypmStudyTargetOverride, with the current value projected into the Study'scurrentEvidence. There is no step-level override (OWNER). - EffectiveTarget (derived). The current override's value if one exists and is not
Removed, otherwise the current published form version'sstandardTarget. It is computed, never stored as a fact, and it is projected for fast reads. Accepted results and readiness snapshots record both the form version and the override version they used (target-versions-form amendment). - AdditionalReviewRequest (
OWNER, consolidation §1; D3-13 clause). A request record naming one form, one or many Studies, the number of additional reviews, optional assignees (members or groups), a reason and the requester. Each Study item writes an override version with basisAdditionalReviewRequestand, where assignees are named, a scoped assignment for that Study × form. Proposed storage: the existingpmAdditionalReviewRequest, reshaped as a batch with per-Study items. TheRequest an additional reviewcapability (RA5) is still required. An assignment never grants a permission. - What they are not. An override is not a capacity cap. A request is not an invisible bypass that leaves the target unchanged; that earlier behaviour is superseded (§14).
3.13 Accepted-result version (as targets affect it)¶
RS owns AcceptedResultVersion and its authority values (SingleAnnotator, HumanReconciled,
Adjudicated, MergeResolved). This page fixes only what a target change does to it: applying a new
form version or override may lead to a new result version under the agreed authority rules, it never
rewrites an old result, never invents a missing review and never invalidates a recorded answer
(target-versions-form amendment; Q-29). Automatic acceptance of several agreeing candidates is not
approved (T-POL-03).
3.14 Derived values and where they live¶
| Value | Derived from | Kept where | Currentness |
|---|---|---|---|
| Per-answer state and session standing | Latest explicit version, pin map, current form version, recorded policy generations, validity | Computed on read; projected for lists | Projection carries its definition-version vector; gates fail closed when stale |
| Qualifying contribution | Status completed and qualifying standing and eligibility |
Computed on read; projected | As above |
| Effective target | Override or standard target | Projected in currentEvidence |
Written in the same transaction as the override or publication item |
| Reconciliation readiness | Qualifying contributions against the effective target | Computed at query time, or read from a projection guaranteed current for its input versions (Q-27) | A stale projection never authorises work |
| Current evidence of a Study | Its sessions, decisions, accepted results and targets | currentEvidence on Study (DM §3.6) |
Written in every study-scoped canonical transaction (CR-1) |
3.15 What D2-01's reversal changes¶
The decision. The round-2 proposal said publication writes no evidence, so a published policy
would change only what readers derive. Chris rejected it. Publication may create attributable
generated session versions (OWNER; register "Decisions already fixed"; consolidation §1). SF6
already anticipated this ("an applicable recorded admin update treatment creates a new incomplete
session version"), so SF6 now applies literally.
When publication generates a version (PROPOSAL for the brief). For each affected session whose
latest explicit version pins an older form version and falls in a category the admin chose to treat:
| Outcome of the recorded treatment for the session | Generated version? | What the generated version holds | Resulting status |
|---|---|---|---|
Every changed question is doNothing, or no question changed (a target-only or policy-only version) |
No | Nothing | Standing derived: pinned to the older version, counted or not as the admin chose; unchanged questions satisfy the new version |
autoUpdate on compatible changes and every pinned answer is valid |
Yes, PublicationGenerated |
The same revision pins, re-pinned to the new form version | Completed stays completed only if the pin map validates under the new version |
| Option mapping (Q-34) | Yes | New revisions for mapped answers with provenance {sourceRevisionId, mappingRef, operationId, generation}; pins moved to them |
As validated |
requireReanswer on an answered question |
Yes | Pins kept; the answer shows Needs updating; re-pinned to the new version | Incomplete; a completed session stops qualifying |
New required question with requireAnswerBeforeCounting |
Yes | Re-pinned to the new version; the new question needs an answer | Incomplete |
New required question with countEarlierCompletes |
No | Nothing | Standing derived: pinned older and counted |
| Category outside the admin's chosen scope | No | Nothing | Standing derived |
| Draft-only session (no explicit version) | Never | The draft is rebased (RD-R24) | Not applicable |
One session gets at most one generated version per publication generation, combining all its questions' treatments. Generated versions are attributed to the publication operation and the publishing admin; the reviewer stays the effective author of the answers. A generated version never records a Complete that fails validation under its declared form version.
Changes to the versioning model.
| Versioning model | Before | After |
|---|---|---|
| §1.1 model paragraph; §2 rule 4 | Publication is a recorded policy and never writes evidence, with option mapping as the only exception | Publication records a policy and may write attributable generated session versions and mapped revisions under the table above; where it writes none, effects stay derived |
| §2 rule 6; §4.4 | Operational settings never version; the minimum target is an operational setting | The standard target is inside the form version; other settings follow §3.5 |
| §3.5 | A declaration may change until a revision pins the version | Immutable from commit; declared by the publisher; corrected by guided rollback and republication |
| §3.9 | One designer pending record with a lease and take-over | Collaborative design drafts with per-item base checks (§3.7) |
| §7.2, §7.3 | Kinds Save, Complete, Withdraw; "there is no publication-written transition" | Kinds include PublicationGenerated (and DM's merge kinds); generated transitions follow the table above |
| §7.5 | SF6 read as "changes the effective standing" | SF6 applies literally when a version is generated; derived standing remains for the no-generation rows |
| §7.6 | No autosave trail; second tab read-only with take-over | Draft change log kept; concurrent tabs reconciled by base checks; the take-over presentation is a brief detail |
| §8.1, §8.4 | "Nothing is applied to a session" | Generated versions apply the chosen treatment explicitly |
| §8.5 | Phase 2 rewrites projections only | Phase 2 also writes generated versions and mapped revisions, per Study, idempotently |
| §8.7 | FV4 appends a policy generation | Unchanged, and a new generation may generate further versions; earlier generated versions stay in history |
| §8.8 | A late Save on a superseded version is accepted pinned to it | Still true where no version was generated; where one was, the Save is refused as stale and the draft is rebased (RD-R24) |
| §8.9 | Option mapping as the only derived-revision writer, OPEN |
Q-34 decided; mapping is one of the generated-version cases |
| §9.3 | Any candidate version change drifts the task | A generated version drifts only the questions whose pinned revision or class changed, or a candidate that stopped qualifying |
Changes to the consistency model.
| Consistency model | Before | After |
|---|---|---|
| §4.2 publication phase 2 item | Rewrites the Study summary; writes no evidence | Per Study, one short transaction: generated versions by compare-and-set on each session head, mapped revisions, Study (version CAS, summary, currentEvidence), notice intents; deterministic version ID per (sessionId, operationId, generation) |
| §7.4 | "It writes no evidence (D2-01)" | Writes generated versions; the admission and readiness pause for the form stays; the operation limit is measured (D2-10) |
| §4.4 drafts | A stale autosave after a newer explicit version is rejected and discarded by the client | A draft or autosave whose base was superseded, by a generated version or by the reviewer's own Save in another tab, is rebased onto the new version at the next autosave or Save; non-overlapping changes apply; overlapping ones are kept as a conflict copy; nothing is discarded silently |
| §15 conflict map | No row | New row: a generated version never overwrites a newer reviewer version (session head CAS; recompute against the new head) |
| §16 failure modes | Phase 2 crash rewrites projections again | Phase 2 crash resumes; replays return existing generated versions |
| §19.3 | D2-01 "publication writes no evidence" | D2-01 decided as amended; D2-07 and D2-08 decided; D2-12 and D2-16 replaced |
What does not change. Phase 1 still does constant work (fence, drain, digest recheck, head compare-and-set, policy and operation records). One publication per form. Policy records are append-only generations. The impact manifest is built after commit and is never an input to an effect. Admission and readiness for the form pause while phase 2 runs.
3.16 Answers, requiredness and metadata¶
Added 6 October 2026. Chris made one decision and gave one direction about what a reviewer
records; the decision register section "Owner answers, 6 October 2026"
records them. Updated the same day: Chris then decided the terminology (DQ-46; Chris, 6 October
2026, Codex discussion; record archived at
owner-session-2026-10-05/syrf-design-decisions-2026-10-06.md.txt;
decision register §1.18).
Nothing here authorises implementation, and feature implementation remains on hold.
- Required by default, with reasons no value is provided (decided-amended). Chris proposed: "strongly encourage question designers to make all questions required to be answered but then optionally allow a 'unable to asses' (or something similar) option in order to be explicit. the ability to make a question optional (i.e. not required) could be hidden in advanced menu and discouraged but only made available for backwards compatability with questions created before these features. On completion all applicable questions would generally require some form of annotation response. And it will be clear reviewers have actively considered every question rather than accidentally missing a non-required question." After the coordinator recommended adjustments, he replied: "I agree except the no value options could maybe be configurable beyond the defaults , so question designers can configure them and add specific options (or indeed potentially select them from templates in libraries like SYRCLE etc...)."
- Configurable answer metadata (Chris's direction). "acceptable and/or required annotation metadata should be configurable with several different options being configurable with the question design and these can be associated with different response modes. These include things like comments, units, quotes/evidence, freetext values for other when value is not included in multiple choice options etc. Perhaps this could include potentially configurations that allow or require certain metadata responses for no answer?"
Terms (decided, DQ-46, "Approved with revised terminology"). The archived record of Chris's final clarification reads: "Use Answer status for the overall state, covering Unanswered, answered with a listed or other specified value, and a configured explicit reason no value is provided. Use Reason no value is provided for that reason set, with No value to enter as the proposed reviewer action. … Other, please specify is a value-bearing answer with configured free text, not a missing-value reason. Preserve distinctions and configured stable identities in versions and exports." The terms are used exactly as follows.
- Answer status is the overall state of a question in a session version: Unanswered; answered with a value (a listed option, "Other, please specify" with its text, a number, text, a date or a reference); or answered with a reason no value is provided.
- Reason no value is provided names the designer-configured set of explicit reasons: the defaults
(Not reported, Not applicable, Unable to assess), custom reasons and catalogue sets such as SYRCLE,
each with a stable identity and reason-specific metadata requirements. It replaces the working term
"no-value answer" everywhere, in user-facing copy and in specification prose. Dense tables may use
the short form "no-value reason". The code identifier is
noValueReasonId(PROPOSAL), replacingnoValueAnswerId. - No value to enter is the proposed reviewer action that opens the reasons. It is illustrative wording, not a fixed label, unless separately confirmed.
- Other, please specify is a value-bearing answer: the listed "Other" option plus its configured free text, recorded as the answer's value. It is never a reason no value is provided. Its stable option identity and the specified text are preserved in versions and exports (below).
- Carried from the recommendation; not separately discussed: Unanswered means nothing recorded; Option means only a predefined choice; Not compared (unanswered) is the comparison label for a missing answer in agreement (RS-R14).
- Retired from user-facing language: "no-value answer", "blank", "response mode", "response option", "missing-data code" and "answer exception".
How unanswered and cleared answers are recorded stays a PROPOSAL and an open owner item (DQ-50,
§12).
Answer status and the recorded payload (terms decided; payload shape PROPOSAL):
| Answer status | Recorded payload | Meaning | Satisfies Complete |
|---|---|---|---|
| Answered with a value | value: a value of the question's data type; option IDs for a choice; for an "Other, please specify" option, its option ID with specifiedText |
A value, listed or specified | Yes |
| Answered with a reason no value is provided | noValueReasonId |
An explicit, configured reason that no value is provided | Yes |
| Unanswered (explicit record) | The Unanswered record (PROPOSAL, DQ-50 open). Sources: a clear; a metadata-only answer where the version allows metadata in the unanswered state (below); empty or whitespace-only text or an empty selection, normalised on the server (below); a converted legacy record with no value (BC-R49) |
Explicitly recorded as unanswered | No |
| Unanswered (absent) | No revision | Nothing was ever recorded | No |
The first three payloads carry metadata validated for their state. unmappedLegacyValue stays a
conversion-only payload (versioning model §11).
Requiredness (OWNER, decided-amended; the mechanisms marked are PROPOSALs).
Chris agreed these adjustments to his proposal with "I agree except…" on 6 October 2026: "only … for backwards compatability" became "mainly for backward compatibility", with Optional still usable on new questions under advanced settings, behind a warning, and its use tracked; requiredness stays form-owned; and Complete reads as every applicable required question, which is generally every question.
- Requiredness stays form-owned (SF1, SF3; versioning model §4.1). The form-level default for a newly pinned question is required.
- Optional stays available under advanced settings, with the warning "reviewers can skip this
without saying why". It is discouraged and exists mainly for backward compatibility. Its use is
tracked: each published form version records requiredness per pin, so SyRF counts optional pins
per form and per project from published versions, with no separate tracking store (
PROPOSAL). - Complete requires an answer, a value or a reason no value is provided, for every applicable question that the declared form version pins as required. Because new questions are required by default, this generally means every applicable question, which is Chris's aim: reviewers have visibly considered every question. An applicable optional question may stay unanswered. Save never requires an answer. Applicability is still derived per ancestor instance by the E23 evaluator, so a required child question needs an answer under each applicable instance, and a suppressed one needs none.
- Repeatable groups (
PROPOSAL; Chris did not mention a group-level answer). A required repeatable question (one that creates instances, such as cohorts) needs its minimum instance count, or the explicit group-level reason no value is provided "None reported" (RD-R51). The minimum defaults to 1 for a required repeatable question; "None reported" is offered by default on repeatable questions; it is recorded on a head keyed by the repeatable question and its parent path with no instance element; Save refuses "None reported" while an active instance exists; adding an instance after it asks the reviewer and clears it in the same Save. - Baseline conversion keeps today's per-question
Optionalflag as each converted form's requiredness (faithful conversion). The redesign wizard (RW1) offers to upgrade optional questions (BC-R49). - Agreement methods must say how reasons no value is provided count (
T-SI-02, specialist input).
Reasons no value is provided (OWNER; terms decided by DQ-46; identity and shape PROPOSAL).
- Each question version declares which reasons no value is provided it allows. The defaults are Not reported, Not applicable and Unable to assess. Designers may add custom reasons, or select sets from catalogue templates (for example SYRCLE). The word is "catalogue", not "library", which Q-13 reserves for Study Management. Which defaults a new question starts with is a designer brief detail (§12).
- Each reason has a stable
noValueReasonId(PROPOSAL), minted once and never reused, with a label, a description, its reason-specific metadata requirements and an active or retired state, exactly like an option (versioning model §3.3). A set copied from the catalogue recordscopiedFromand never changes with the catalogue (versioning model §4.5). - Recording a reason answers the question: its answer status is "answered with a reason no value is provided". Two candidates who record the same reason agree; a reason against a value disagrees (Q-04; RS-R14, RS-R15).
- Risk-of-bias "Unclear" values are values, never reasons no value is provided (for example the "Unclear" judgement in SYRCLE). Templates and guidance keep the two apart.
- The reason Not applicable is the reviewer's explicit answer. It is not the derived
NotApplicablestate, which means that an ancestor's answer suppressed the question (versioning model §7.4). An unanswered question is never Not applicable (UA1). - A reason may require metadata, for example a comment for Unable to assess (below).
- In the reviewer form the reasons open from an action whose proposed wording is No value to enter (illustrative, not a fixed label).
"Other, please specify" (value-bearing; decided by DQ-46; shape PROPOSAL).
- A designer may configure a listed option as an "Other, please specify" option: the option asks for
free text. Choosing it records a value: the option's stable
optionIdtogether with the reviewer's text (specifiedText,PROPOSAL). The text belongs to the value, never to metadata. - It is never a reason no value is provided, and it never counts as one in validation, agreement or exports. Its answer status is "answered with a value".
- The option version says whether the text is required when the option is chosen (
PROPOSAL: required by default). Save accepts the option without its text; Complete requires the text where the option requires it. Empty or whitespace-only text is never stored, as for any text (below), so the value then holds the option alone. - Versions and exports keep the option identity and the specified text together as the value (versioning model §10.2; RI §3.9).
- Re-modelled 6 October 2026 (DQ-46): this replaces the earlier "Other: specify" text metadata field; no metadata field of that type exists.
Answer metadata (OWNER direction; field shapes and validation timing PROPOSAL).
- Each question version declares metadata fields, each of one closed field type: comment, unit (aligned with C14's unit vocabulary), evidence quote with a source location (a source document and a position in it, shape fixed with E37) and reason (a free-text explanation, for example why a judgement was made; it is not the configured reason no value is provided, which is the answer itself). A designer may declare several fields of one type; a new field type is an engineering change to the closed set. 6 October 2026 (DQ-46): the "Other: specify" text type is removed from the set; that text is part of the value (above).
- For each field and each recorded answer state, the version says whether the field is hidden, allowed or required. The answer states are: a value; a specific option, which overrides the value row for that option (for example an evidence quote required only when "Yes" is chosen); each allowed reason no value is provided; and unanswered, which applies only where the form pins the question optional.
- Save accepts only fields that are allowed or required for the payload's state, refuses hidden or undeclared ones, and never requires one. Complete requires every field that the state actually chosen requires, on every applicable answer the session pins. Changing the state changes the requirement: a reviewer who replaces Unable to assess with a value no longer needs its comment, and fields hidden in the new state are not carried to the new revision (the earlier revision keeps them in history).
- An applicable optional question left unanswered whose version requires a field in the unanswered state blocks Complete until the reviewer records that field, which writes an explicit Unanswered revision. The designer warns that this makes the question "answer or explain" and suggests a required question that offers a reason no value is provided instead.
- This settles V-D3 from the harvest map: metadata with neither a value nor a reason no value is provided is allowed only where the question version permits metadata in the unanswered state.
Recording unanswered and cleared answers (PROPOSAL; open as DQ-50, §12).
- A question that was never touched stays an absent answer. Nothing is written for it, at Save or at Complete.
- Clearing an answer writes an explicit Unanswered revision, so history shows "answered, then cleared". It may carry metadata allowed for the unanswered state. It differs from a withdrawal revision, which keeps its role for deleting an entity instance and for the versioned clear (versioning model §6.5, §7.3); whether the versioned clear should write Unanswered revisions instead is a brief confirmation (§12).
- Empty or whitespace-only text is normalised to Unanswered on the server, and empty strings are
never stored. An empty selection is normalised the same way (
PROPOSAL, by the same reasoning). - Nothing is pre-written at Complete. Chris asked why. A pre-written record adds no information, because absence already means never answered and each session version stores its resolved question set (versioning model §7.2). Applicability is derived per ancestor instance and changes later, after an ancestor answer or a form version changes, so pre-written records would go stale. They would cost one revision per untouched applicable question on forms of up to 2,023 questions. And every reader would have to ignore them.
- Suppressed descendants stay preserved and are derived
NotApplicableper ancestor instance (versioning model §3.4).
Compatibility (PROPOSAL; versioning model §3.5). Adding a reason no value is provided or a
metadata field, or loosening a field for an answer state, is compatible. Removing or retiring a reason
is incompatible unless the publisher maps it one-to-one to another reason whose meaning is unchanged,
under Q-34's rules. Removing a metadata field, changing its type, or making it required or hidden for
an answer state is incompatible. For an "Other, please specify" option, adding an optional text
request or making a required text optional is compatible, and requiring the text or removing the
request is incompatible; these carry over the rows of the retired "Other: specify" metadata field.
Mapping an option to a reason no value is provided, or the reverse, is a brief item and is not
offered in MVP (§12); an "Other, please specify" value is never mapped to a reason.
4. What loads and writes when¶
Each action lists what is read, what is written, the transaction boundary, and what is derived
afterwards with how it stays current. "Study write" means the per-study compare-and-set with the
canonical summary and currentEvidence (CR-1).
4.1 Open a Study and form from any stage, tab or device¶
| Aspect | Detail |
|---|---|
| Reads | Admission (permissions, allocation, availability, step rules; SP); the session head and its latest explicit version; the draft head and materialised draft; the form versions pinned and current; applicable reconciled-answer hints and their provenance (RS); the reviewer's own answers on other forms (SF5) |
| Writes | A connection record. A capacity claim if the reviewer has no place yet and capacity allows (SP). Nothing else: opening creates no session |
| Transaction boundary | The claim is one atomic conditional update on Study; the connection is its own write |
| Derived afterwards | The form host shows the status (draft auto-saved, version checkpoint saved, completed), any Needs-updating or outdated marks, and any alert left by a publication since the reviewer's base |
4.2 Autosave¶
| Aspect | Detail |
|---|---|
| Trigger | A debounce after edits (the earlier 2-second figure is proposed, not approved) |
| Reads | Draft head (draftVersion, base explicit version, base form version) |
| Writes | One SessionDraftChange holding only the changed answers, each with its per-answer base; the draft head (draftVersion + 1, materialised draft). The first autosave also creates the session by upsert on its deterministic ID |
| Transaction boundary | Draft head compare-and-set on draftVersion; never Study |
| Concurrency | Two tabs or devices may autosave. A change whose answers did not change since its per-answer base is applied. A change to an answer that moved since its base is kept as a recoverable conflict copy and both values are shown (D2-08; the take-over or read-only presentation is a brief detail) |
| Derived afterwards | Status "Draft auto-saved" (illustrative wording; UX). Status, current explicit version and qualification are unchanged |
4.3 Save (version checkpoint)¶
| Aspect | Detail |
|---|---|
| Reads | Session head, draft etag and changes, declared form version, form head (fence), admission, dependent work for the warning in §4.5 when the session was completed |
| Writes | Revisions for changed answers; one immutable Save version with the full pin map; session head CAS; draft consumed; Study write (member savedIncomplete); on the first explicit version, the slot claim is released and presence replaced exactly once (RT-05). 6 October 2026: each payload is validated for its recorded answer state (no hidden or undeclared metadata; empty text normalised to Unanswered), and no answer or metadata field is required (RD-R52, RD-R53) |
| Transaction boundary | One interactive transaction with the command-bearing record |
| Derived afterwards | Status "Version checkpoint saved". A Save after Complete removes the completed qualification at once (SL3). Readiness and sufficiency are re-derived at query time |
4.4 Complete¶
| Aspect | Detail |
|---|---|
| Reads | As Save, plus the applicability evaluator over the whole form under the declared version, independent of which questions are rendered (virtual scrolling) |
| Writes | As Save, with kind Complete; member completed with its standing |
| Transaction boundary | One interactive transaction |
| Refusals | ValidationFailed naming the blocking question and context; StaleBase keeps the draft; OutcomeUnknown is retried with the same command ID. 6 October 2026: ValidationFailed also names a required applicable question with neither a value nor a reason no value is provided, an "Other, please specify" value missing its required text, a required repeatable group below its minimum without "None reported", and a metadata field that the chosen answer state requires (RD-R51, RD-R52) |
| Derived afterwards | One qualifying contribution per reviewer per Study × form, whichever route was used (SF2). Readiness and automatic stage completion re-derive (SP) |
4.5 Save as incomplete after Complete, with dependent work (Q-27)¶
| Aspect | Detail |
|---|---|
| Reads before commit | The session's current completed version; reconciliation tasks whose input set pins it; accepted results that used it; dependent steps whose readiness it supports; all shaped by blinding |
| Shown before commit | "Saving this as incomplete removes your completed review from S-101, Risk of bias. A reconciliation in progress for this study uses it and will need re-checking. Accepted answers published on 3 October used it; they stay as they are and may be reconsidered." No reconciler name or other candidate is shown to a blinded reviewer |
| Writes | As Save. Nothing is written to the dependent records |
| Recheck at commit | The dependency set is recomputed in the commit snapshot; if it grew, the reviewer confirms again |
| Notified after | Each affected author once (the reconciler holding the task; the reconciler who published the accepted answers), through a deduplicated in-app notice explaining the change at their level of access |
| Derived afterwards | Readiness from current evidence; the task shows "inputs changed · re-check"; accepted results stay effective until someone explicitly reconsiders them, which creates a new immutable result version (RS); automatic stages re-evaluate remaining work, manually completed stages stay complete (SP) |
4.6 Inactivity timeout and expiry¶
| Aspect | Detail |
|---|---|
| Trigger | Every connection to the session idle beyond the form's timeout, or closed |
| Reads | All connections' last activity; the draft's last activity; the claim |
| Writes | Claim released on Study through the claim release path. No history event is written; claims and their releases are not retained as history (SP §3.14, §4.9). The draft is kept |
| On return | Admission and capacity are rechecked. If a place is available the reviewer continues with the draft. If not, SyRF says so honestly and keeps the draft; the reviewer may discard it or wait (SP owns capacity behaviour) |
4.7 Edit a design draft with others present; publish from one of several drafts¶
| Aspect | Detail |
|---|---|
Editor modes (OWNER DQ-01, option (a), Chris, 6 October 2026; mechanisms PROPOSAL) |
One refreshed question editor, main's Design/Assign/Preview editor (M-09), serves Classic (older) and converted (Versioned) projects, with the saving and assignment behaviour appropriate to each project mode. In legacy API mode (Classic projects, not yet converted) it writes through the legacy endpoints, which R0's writer inventory lists and refuses on canonical scopes, with today's save semantics and per-stage Assign (UX-AE32, UX-AE33); there is no draft, presence or version, and the editor does not silently introduce versioned publication, draft or assignment semantics into an unconverted project. In canonical mode every write is a DesignDraftChange append with a base revision; the editor's direct, project-wide writes are never used for a canonical scope (RD-R48). QMI-04 is answered in part (the same editor serves every project); the retirement timing of the legacy designer and newQuestionManagement (T-RD-17, after R1a acceptance and one staging soak) is not addressed and stays the recommendation (§12) |
| Open | Reads the current published version, open drafts and a presence snapshot; subscribes to the design topic for that form or profile on realtime hub v2, and the ack carries the current draftRevision (PROPOSAL, X-02). Only users with design access may subscribe. The earlier "joins the presence group" is superseded, because hub contract v2 has no groups |
| Edit | Each accepted field change is sent automatically, with no per-question Save (OWNER DQ-03, option (a), 6 October 2026; the debounce is a brief detail). The client sends {draftId, itemPath, baseItemRevision, value, clientChangeId}. The server appends a DesignDraftChange and bumps draftRevision by compare-and-set when the item's revision equals the base. A duplicate clientChangeId returns the original result. The editor shows the draft's save status (for example "Unpublished · saved 14:03", illustrative). Nothing reaches reviewers until a publication |
Discard (OWNER DQ-03, per question as recommended; mechanism PROPOSAL) |
"Discard changes" on one question appends changes that return that question's items to the draft's base values; earlier changes stay in the log. Discarding the whole draft is an audited status change (§3.7) |
| Conflict | A stale base is refused. The client keeps the local edit beside the current value and offers "keep mine" (a new change on the current base) or "discard mine". Nothing is overwritten silently |
| Live updates | Accepted changes publish a DesignDraftChanged invalidation carrying draftRevision, a class © hint that never carries correctness. Other open views fetch the changes after their revision and merge per item while keeping their unsaved local edits. On ResyncRequired or a new connection the page reloads the draft head (X-04, X-05) |
Client state (PROPOSAL) |
The canonical stores follow the state-management plan: a root store for definitions and versions and a route-scoped draft store, with httpResource reads, ordered writes keyed by clientChangeId, signal forms per item and one debounce stream per item (X-08, X-09; RD-R47) |
| Publish | Starts the publication in §4.8 from one draft. The unique active-publication index refuses a second publication (PublicationInProgress). If another draft published since this draft's base, the draft is rebased item by item, conflicting items are resolved, and the impact preview is recomputed against the resulting state (D2-11) |
| Derived afterwards | Every published version and its history keep the actor, time and base revision of each change |
4.8 Publish a form version with question changes¶
- Preview (no authoritative writes). Reads the diff between the draft and the current published version; each changed question's change class and SyRF's compatibility suggestion; usage evidence at the protected boundary (C8; draft-only counts from drafts); sessions by category (completed, saved incomplete, draft only), prior form version and route; active connections; reconciliation tasks in progress; accepted results built on affected answers; dependent steps; any Study overrides if the target also changes. Stores a preview digest.
- Declarations and treatments. The publisher declares compatibility for each changed question, allows or refuses option mapping per option, and chooses treatments per question and per category, as attributed draft changes. Meaning changes must be declared incompatible; mapping never bypasses option or type validation or a mandatory re-review (Q-34).
- Phase 1 (constant work). Fence the form; drain; recompute the digest in a pinned snapshot; on a
change return
PreviewDigestChangedfor re-confirmation. Otherwise, in one short transaction: commit the new question versions with their declarations and mappings, insert the form version, compare-and-set the form head, write policy generation 1 and the operation record, write the notice fan-out intent, and record aFormVersionPublishedhistory event. Release the fence. Phase 1 is delegated and atomic: it rechecks the publisher's authority on execution and retry (P9 classPROPOSAL, QMI-02; X-41, X-42). - Phase 2 (per Study item). Phase 2 would be an approved system obligation (QMI-02) that runs
to completion once phase 1 has committed, under the host-neutral driver of §3.8 (
PROPOSAL, QMI-02). For each Study with an affected session: read the sessions in scope, apply the generation table (§3.15), compare-and-set each session head against the version the plan used (recompute if the reviewer saved meanwhile), write generated versions and mapped revisions, write Study, capture notices once per recipient. Admission of new studies to the form and reconciliation-readiness changes pause until phase 2 ends; reviewers keep saving. - After. The impact manifest is built from authoritative records at the operation's stamp. The publisher gets a completion or stall notice. Reviewers see an in-form alert when they next open the session. Drafts rebase at their next autosave.
4.9 Publish a form version that changes only the standard target¶
| Aspect | Detail |
|---|---|
| Preview | Studies whose sufficiency changes (below or above the new target), reconciliation readiness changes, accepted results that would change authority, Studies with overrides and their treatment (RD-R16), active places beyond the new target where capacity enforcement uses it (SP) |
| Treatments the admin confirms | For a raised target: keep existing accepted results current, labelled "below current target" (RS-R10), or suspend them pending reconciliation with the new number of reviewers (RS defines the result record). For a lowered target with AutoAccept: create SingleAnnotator results now, or at the next qualifying completion, for Studies that now have exactly one qualifying candidate and no accepted result (RS §4.6, RS-R11). For each override group: an explicit treatment (RD-R16) |
| Writes | Phase 1 as §4.8 (no question versions). Phase 2 per Study: result versions under the confirmed treatment, override versions where the admin chose to change them, Study write. No session version is generated |
| Derived afterwards | Effective targets and readiness at query time; automatic stage completion re-evaluates; stage filters that use reconciled answers re-evaluate the affected Studies (SP) |
4.10 Apply a Study target override¶
| Aspect | Detail |
|---|---|
| Reads | The current published form version and its standard target; the current override version; qualifying contributions for the Study × form from currentEvidence (verified current); active places and drafts; the open reconciliation task and the current accepted result |
| Shown before commit | Old and new effective target; readiness change; active reviewers affected (counts, names only with Monitor, D3-20); whether lowering the target leaves temporary reservations beyond it, with Cancel or Apply anyway (Apply anyway releases those reservations only and keeps drafts; Q-24) |
| Writes | One StudyTargetOverride version; Study write (currentEvidence.effectiveTarget); a StudyTargetOverrideChanged history event; reservation releases if Apply anyway was chosen |
| Transaction boundary | One study-scoped interactive transaction |
| Derived afterwards | Readiness and capacity; automatic stage completion; notices to the reconciler if readiness changed and to reviewers whose reservation was released. No form version is created |
4.11 Bulk additional-review request¶
| Aspect | Detail |
|---|---|
| Preview | The selected Studies (a list or a saved selection resolved at preview); per Study the standard target, any override, current qualifying count, the new effective target, and each named assignee's eligibility; assignees who already have a qualifying contribution on a Study are flagged because they cannot count twice; active work |
| Writes at commit | The request record and, for large selections, an operation record. Per Study, one short transaction: an override version with basis AdditionalReviewRequest(requestId, raiseBy), a scoped assignment per named member or group, and the Study write. Each item is idempotent per (requestId, studyId) |
| Notified after | One notice per assignee per request listing their Studies; the requester gets progress and completion |
| Derived afterwards | Sufficiency uses the raised effective target; qualifying reviewers count once across routes; the extra assessments see no other candidate's answers; the reconciler is told when readiness changes. Nothing sets an accepted result automatically (RA5) |
4.12 Publish a screening-profile version¶
| Aspect | Detail |
|---|---|
| Preview | The proposed version against every profile version still in use by existing decisions, collective outcomes and adjudications; mismatches and their consequences per Study; active screeners and adjudicators; dependent pools (SP) and accepted results (RS); whether eligibility changes and therefore needs a protocol amendment entry (RI, D4-05) |
| Treatments the admin resolves | Keep decisions pinned to their version; request new decisions; or carry compatible decisions forward as attributable generated profile-session versions. Policy is recorded at profile scope, never per stage |
| Writes | Phase 1 as §4.8 for the profile. Phase 2 per Study: generated profile-session versions where the treatment carries forward or requests renewal, the collective outcome recomputed under the chosen policy, the Study write, notices |
| Derived afterwards | Required new screening stays visibly pending; original decisions, outcome history and frozen reports are untouched; changed outcomes trigger targeted pool re-evaluation with structured history (SP); accepted or adjudicated results whose inputs changed follow the explicit reconsideration rule |
4.13 Revise a publication policy (FV4) and guided correction¶
- FV4 revision. Reads the operation and its current policy generation. Writes a new generation by compare-and-set. Phase 2 re-sweeps under the new generation and may generate further versions, for example restoring a completed status by re-pinning a session to the form version under which its Complete was validated. Earlier generated versions stay in history.
- Guided correction of a wrong compatibility declaration or mapping. Reads the publications that used the declaration and every generated version and mapped revision they produced. The preview shows what rolling back changes. The commit creates a corrected question version (same content, corrected declaration), publishes a new form version through §4.8, and generates versions that restore the pre-mapping values or apply the corrected treatment, each attributed to the correction. The wrong declaration stays in history with a "corrected by" link. Nothing is edited in place.
4.14 Shared-question accepted answers across two forms (D2-09, decided)¶
Decided-amended by Chris on 5 October 2026 (programme status page, 03:37 BST; recorded as
answers/D2-09: "agree", with the note "But should be encourage to provide a reason (though not
compulsory). They can also raise query if need be."; decision register §1.16).
The recommendation is adopted with two amendments. This supersedes the earlier text of this section,
which carried both options behind a parameterised fixture until Chris answered.
When two forms share a question and the first form's reconciler has already accepted an answer for a Study:
- What the second reconciler sees. The second form's reconciliation task reads the existing accepted answer with its source snapshot and reconciler. It is shown as a labelled hint with an explicit "Use accepted answer" action (click-to-fill), never prefilled (OS-A04; RS-R32, RS-R33); the reconciler's name follows RS-R32's history-access rule. The original question's word "prefilled" is superseded by OS-A04.
- Revision. The second reconciler may revise the accepted answer in their own final submission.
The Complete publishes a new snapshot (RS §3.3); where the answer changed, the new reconciled
revision carries provenance
{supersedesEntry, task, reconciler}and, when given, the reason. Where the reconciler keeps the existing answer, the snapshot keeps the existing entry unchanged (GS1;PROPOSAL). Earlier snapshots stay in history, and RE4 still holds: there is one shared accepted answer, never competing gold. - Reason (amendment 1). When the reconciler's answer differs from the existing accepted answer,
an optional reason field is shown and prompted for. Save progress and Complete never require it. A
given reason is stored with the revision's provenance and shown in accepted-answer history. The
prompt's wording and placement are a UX brief detail (
PROPOSAL). - Query (amendment 2). The reconciler may also raise a query on the accepted answer when needed, through the queries release R4b (QY1; AC-R4b-01, AC-R4b-10): the query targets the accepted-answer version they saw. Queries remain the route for everyone else.
- Placement. Forms that overlap on reconciled questions need R2d (A-19), so pilots before R2d still use forms that do not overlap. The query action needs R4b.
Tests: FX-VM-45 (RD-AE25). Tracker rows T-OI-01 (Decided) and T-RD-06.
5. Rules¶
| ID | Rule | Source |
|---|---|---|
| RD-R01 | The Study is the project's reviewable item. Forms, sessions and targets attach to Study × form and are shared across stages. | OWNER consolidation §1 |
| RD-R02 | A reference is an immutable import record and a report is a source document. Original imports, identities, sources and import times are kept; two references are never collapsed into a fabricated original. Storage follows §3.3. | OWNER consolidation §1; storage PROPOSAL |
| RD-R03 | A conference abstract and a journal article may remain separate Studies. Linking distinct reports to one investigation is deferred. | OWNER consolidation §1; D4-08 (RI) |
| RD-R04 | One session per reviewer per Study × form, reached from every stage, tab and device. Route and stage provenance stay on submitted versions; stages never own the evidence. | OWNER consolidation §1; SF1 |
| RD-R05 | Autosave sends diffs with base-version checks, keeps a recoverable draft and a reconstructable history, and never submits, creates a version or changes qualification. | OWNER consolidation §1; SL1 |
| RD-R06 | Save creates an immutable checkpoint that may be incomplete and becomes current. A Save after Complete removes the completed qualification. | OWNER consolidation §1; SL2, SL3 |
| RD-R07 | Complete validates every required applicable answer on the server, independent of what is rendered, and creates a completed checkpoint. | OWNER consolidation §1, §6 |
| RD-R08 | Status text keeps draft auto-saved, version checkpoint saved and completed distinct; the words may iterate. | OWNER U1 (D3-03); UX |
| RD-R09 | Readiness uses current applicable evidence at query time, or a projection guaranteed current for its input versions. A stale projection never authorises work. | OWNER Q-27 |
| RD-R10 | Before an explicit change that affects dependent work, the actor sees which work is affected and how, within their access and blinding; the dependency set is rechecked at commit; affected authors are informed afterwards. Dependent work and accepted results are never rewritten automatically; reconsideration is explicit and creates new immutable versions. | OWNER Q-27 |
| RD-R11 | The form owns the inactivity timeout and per-reviewer in-progress limit across routes and tabs. One idle tab never releases the place while another connection is active. Expiry keeps the draft. | OWNER D2-07, Q-28 |
| RD-R12 | The standard reviewer target is part of the immutable form version. Changing it creates a new form version and goes through the publication impact process, even without question changes. | OWNER target-versions-form |
| RD-R13 | Every other form setting is classified as inside the version or operational, using the rule and table in §3.5. | PROPOSAL (D2-05 brief) |
| RD-R14 | A Study target override is an immutable, audited, versioned Study × form decision applying across routes. There is no step-level override. Changing one override creates no form version. | OWNER consolidation §1 |
| RD-R15 | Results and readiness snapshots record the form version and any override version they used. | OWNER target-versions-form |
| RD-R16 | When a new standard target is published, every existing override gets an explicit admin treatment in the preview (keep its effective value, rebase it, or remove it). The suggested default keeps each Study's effective target unchanged and flags overrides that become redundant or fall below the new standard. No effective target changes silently. | OWNER requires an explicit definition; the treatment set is a PROPOSAL |
| RD-R17 | An additional-review request may name people or groups and many Studies. It raises each Study's effective target explicitly through an override version, and qualifying reviewers count once across routes. | OWNER consolidation §1; D3-13 clause |
| RD-R18 | The reviewer target is a minimum and stays separate from any enforced capacity cap. | OWNER consolidation §1; D3-17 (SP) |
| RD-R19 | General statistics show the standard target and explain study-specific exceptions separately. | OWNER consolidation §1; reading in §12 |
| RD-R20 | Compatibility belongs to the immutable question version. SyRF suggests a default; the authorised publisher declares compatibility and whether mapping is appropriate, with actor and time. The declaration never changes; corrections use guided rollback and republication. | OWNER D2-02 amended, Q-34 |
| RD-R21 | Option mapping is explicit per option, allowed only where meaning is unchanged, and writes new immutable revisions with mapping provenance while keeping the originals. It never bypasses type or option validation or a mandatory re-review. | OWNER Q-34 |
| RD-R22 | Publication previews the impact on existing work under every prior version and every route and on active reviewers, records the admin's treatment, and rechecks the inputs at commit. | OWNER consolidation §1; Q-20; FV2 |
| RD-R23 | Publication may create attributable generated session versions under the table in §3.15. A generated version is attributed to the operation and the publisher, never claims a Complete that fails validation, and never overwrites a newer reviewer version. | OWNER D2-01 amended; table PROPOSAL |
| RD-R24 | Drafts survive publication. A draft whose base was superseded, by a generated version or by the reviewer's own Save in another tab, is rebased: non-overlapping changes apply, overlapping ones are shown as a conflict with both values, and nothing is discarded silently. A late Save on a superseded base is refused as stale where a version was generated. | OWNER Q-20, D2-10 ("prevent stale saves … overwriting"); mechanism PROPOSAL |
| RD-R25 | Many drafts may exist; one publication operation per form or profile is active at a time; the next publication rechecks its impact against the state the previous one produced. | OWNER D2-11 |
| RD-R26 | Design pages show authorised presence (viewing and editing), reflect accepted changes live, keep local unsaved edits, refuse silent overwrites by base checks, keep conflicting edits recoverable, and stamp each accepted change with actor, time and base revision. Presence is never an audit record. Drafts never alter a published requirement. | OWNER collaborative question drafts |
| RD-R27 | Screening profiles have immutable versions. Publication detects mismatches with the exact versions of existing decisions, outcomes and adjudications, previews them, and applies the admin's treatment after a final recheck. Originals and frozen reports are kept; required new screening stays pending. | OWNER Q-26 |
| RD-R28 | A reviewer's own edit that makes another answer need attention produces an in-form warning only. A change by someone else produces a deduplicated in-app notice per recipient and cause. Notices for generated versions follow the recorded impact policy. | OWNER Q-20 |
| RD-R29 | A target change may lead to a new accepted-result version under the agreed authority rules. It never rewrites an old result, invents a missing review or invalidates a recorded answer. | OWNER target-versions-form; Q-29 (RS) |
| RD-R30 | A data-type or selection-multiplicity change is an incompatible version of the same question identity. 6 October 2026: a change of reference target kind, or between single and multiple targets, is incompatible in the same way (CPR-R16). | PROPOSAL D2-03 (BRIEF) |
| RD-R31 | A stage binds the form identity and records the version it bound; the live route presents the session's resolved version; the effective target comes from the form version and any override, never from the stage. | PROPOSAL D2-04 (BRIEF) |
| RD-R32 | System questions are stored as versioned data and reach a project only when its admin publishes a form version that pins the new system version. | PROPOSAL D2-06 (BRIEF) |
| RD-R33 | No form is excluded from the new engine because of its size. The largest project is an acceptance case; commit, draft and pin limits are engineered and measured to fit it. | OWNER D2-16 replaced; consolidation §6 |
| RD-R34 | Retired 5 October 2026: D2-09 is decided (§4.14). It read "Until D2-09 is answered, pilots avoid forms that overlap on reconciled questions"; overlapping reconciled questions still wait for R2d (A-19). The decided behaviour is RD-R37. | OWNER D2-09 (decided) |
| RD-R35 | Publication pauses only the affected form, lets in-flight saves finish, keeps drafts, and has tested pause and operation limits; the earlier 90-second and 30-minute figures are proposed, not approved. | BRIEF D2-10 |
| RD-R36 | Nothing on this page authorises implementation, migration, activation or notification delivery. | OWNER hold, 5 October 2026 |
| RD-R37 | When two forms share a question, the second form's reconciler sees the existing accepted answer as a labelled hint with click-to-fill (never prefilled) and may revise it in their own final submission, writing a new snapshot with provenance. An optional reason is prompted for when the answer differs and is never required; the reconciler may also raise a query on the accepted answer (R4b). | OWNER D2-09 (Decided-amended, 5 October 2026); OS-A04; reason storage and prompt placement PROPOSAL |
| RD-R38 | Filtered options are version content keyed by parent option IDs, and they are new authoring. The server validates them against the pinned parent version, and a schema-v0 project gets an explained refusal. No parity with the legacy editor is claimed, because neither editor saves them today. | PROPOSAL (M-15, M-23; replaces AC-R1a-06's parity premise) |
| RD-R39 | Where a project keeps the answered-question lock (legacy API mode), the server enforces it: an edit or delete that the lock forbids is refused with a typed reason whatever the client sends, and the editor never offers Edit or Delete on an answered question while counts load, fail or are switched off. Canonical forms version questions instead of locking them. | PROPOSAL (M-12; the lock is UI-only today) |
| RD-R40 | The server already refuses changing a referenced boolean parent's type and removing or renaming a referenced option, keyed by value (#2697; M-26). R1a adds only a client warning that explains this refusal and flags conditions that were already dangling. R2a re-keys the refusal to option IDs of pinned parent versions and extends it to composition: ancestor closure, cycles (NQ005) and option filters (CPA001, CPA002). | PROPOSAL (M-26; H-TREE-01) |
| RD-R41 | Composition and placement validation use one rule-code namespace (FL, NQ, CPA, AQ) and the shared fixture set FX-COMPOSE, run by the legacy validator and the canonical composition validator. Refusals are typed (400 with ProblemDetails), never a generic 500. In baseline conversion the same rules produce findings, never refusals. | PROPOSAL (M-02, M-03, M-25; C-D09) |
| RD-R42 | Answer labels are question-version presentation content. Changing one is compatible by default; the publisher may declare it incompatible (VM §3.5, Q-34). Conversion carries the label into v1. | PROPOSAL (M-20) |
| RD-R43 | The global system-question seed's seq 1 equals main's code-built system questions for each production SystemQuestionVersion, proved by a parity test against a frozen copy. |
PROPOSAL (D2-06 engineering contract; M-24; H-DOM-07) |
| RD-R44 | The typed answer payload is named distinctly from main's RoB-AI AnnotationAnswer. It serialises through an explicit discriminator with a custom System.Text.Json converter (no [JsonPolymorphic] before that plan's R4), keeps decimals exact, compares lists structurally, and is digested over explicit, versioned projections. |
PROPOSAL (X-20, X-23) |
| RD-R45 | Design presence is ephemeral and TTL-bounded, reaches users on every API pod, is shown only to users with design access, and is never an audit record. The recommended carrier is a presence record read by the realtime v2 change-feed reader; the carrier is owner question QMI-01. Presence and live updates ship with R2c on realtime hub v2; if v2 is not live, R2c ships base checks only, with presence behind its flag and off. | OWNER collaborative question drafts (presence is never an audit record); carrier and placement PROPOSAL (QMI-01; X-03, X-06) |
| RD-R46 | Publication operations work under either message bus: a host-neutral driver and watchdog with generation guards that never rely on cancelling a scheduled message, and a Wolverine switch-over drain that pauses programme operations. Phase 1 is delegated and atomic; phase 2 is an approved system obligation that runs to completion. | PROPOSAL (ADR-021; X-17, X-18; P9 class QMI-02, X-41) |
| RD-R47 | The designer's client state follows the state-management plan. The R1a hardening keeps today's store and adds pure functions; that plan's annotation-question migration follows it, for legacy mode only; R2a's canonical stores are born to the plan's rules (root definitions store, route-scoped draft store, resource reads, ordered writes keyed by clientChangeId, signal forms and one debounce stream per item). |
PROPOSAL (X-08, X-09; who migrates is a brief confirmation) |
| RD-R48 | main's new editor, refreshed, is the one designer for Classic and Versioned projects, with two modes and the saving and assignment behaviour of each project mode. Legacy API mode writes through the legacy endpoints, which R0's writer inventory lists and refuses on canonical scopes, and never introduces versioned publication, draft or assignment semantics into an unconverted project. Canonical mode writes only DesignDraftChange appends with base revisions; no canonical write goes through the editor's direct, project-wide writes. |
OWNER DQ-01, option (a) (Chris, 6 October 2026) for one editor with mode-appropriate behaviour; the mode mechanics PROPOSAL (C17; M-09, M-27); retirement timing of the legacy designer PROPOSAL (T-RD-17; QMI-04 answered in part) |
| RD-R49 | New questions are required by default. Requiredness stays form-owned, and the default for a newly pinned question is required. Optional sits under advanced settings with the warning "reviewers can skip this without saying why", is discouraged, exists mainly for backward compatibility, and its use is counted from published form versions. | OWNER required by default (decided-amended, 6 October 2026); counting PROPOSAL |
| RD-R50 | Each question version declares the reasons no value is provided that it allows: the defaults (Not reported, Not applicable, Unable to assess), custom reasons and sets copied from catalogue templates such as SYRCLE. Each has a stable noValueReasonId and its reason-specific metadata requirements. Recording a reason answers the question (answer status "answered with a reason no value is provided"). Risk-of-bias "Unclear" values are values, never reasons. The "Not applicable" reason is distinct from the derived NotApplicable state. "Other, please specify" is a value, never a reason. |
OWNER required by default (decided-amended, 6 October 2026); terms OWNER DQ-46 (decided with revised terminology, 6 October 2026); noValueReasonId PROPOSAL |
| RD-R51 | Complete requires a value or a reason no value is provided for every applicable question that the declared form version pins as required, evaluated on the server per ancestor instance; Save never requires an answer. A required repeatable question needs its minimum instance count or the group-level reason "None reported". | OWNER required by default (decided-amended, 6 October 2026); repeatable mechanics PROPOSAL |
| RD-R52 | Each question version declares metadata fields of closed types (comment, unit, evidence quote with source location, reason). Each field is hidden, allowed or required per recorded answer state: a value, a specific option, each reason no value is provided, and unanswered where the form pins the question optional. Save refuses hidden and undeclared fields; Complete requires every field that the chosen state requires. Metadata without a value or a reason is allowed only where the version permits metadata in the unanswered state (V-D3). The "Other, please specify" text is part of the value, not a metadata field (DQ-46). | OWNER configurable answer metadata (Chris's direction, 6 October 2026); the Other re-model OWNER DQ-46; field shapes and validation timing PROPOSAL |
| RD-R53 | A revision payload is exactly one of: a value, which for an "Other, please specify" option carries its option ID and specifiedText; a reason no value is provided (noValueReasonId); or the explicit Unanswered record. Each carries metadata validated for that state. An absent answer means never answered. Clearing writes an Unanswered revision. Empty or whitespace-only text is normalised to Unanswered on the server (for an "Other, please specify" value, to the option without text), and empty strings are never stored. Nothing is pre-written at Complete. |
The value and reason kinds and the Other re-model follow DQ-46 (OWNER); the payload shape, noValueReasonId and specifiedText are PROPOSAL; the Unanswered record is PROPOSAL (open owner item DQ-50, §12) |
| RD-R54 | Adding a reason no value is provided or a metadata field, or loosening a field for an answer state, is compatible. Removing or retiring a reason is incompatible unless mapped one-to-one to another reason of unchanged meaning (Q-34's rules). Removing, retyping, requiring or hiding a metadata field for an answer state is incompatible. For an "Other, please specify" option, adding an optional text request or loosening a required text is compatible; requiring the text or removing the request is incompatible. An option is never mapped to a reason in MVP. | PROPOSAL (versioning model §3.5) |
| RD-R55 | In a Versioned project the design editor saves each accepted field change automatically into the unpublished design draft as a DesignDraftChange, shows a clear save status, keeps a conflicting local edit beside the current value (RD-R26) and offers discard per question. Saving a design draft never publishes to reviewers; only a publication does. A Classic project has no design draft and keeps today's save semantics (RD-R48). |
OWNER DQ-03, option (a) (Chris, 6 October 2026); discard mechanism and debounce PROPOSAL |
6. Authorisation, blinding and provenance¶
- Capabilities (names are placeholders until A-03; Q-03 approved the list). Review writes sessions
and drafts. Design edits design drafts. Publish publishes form and profile versions and makes
compatibility and mapping declarations. Applying a Study target override needs Publish on the form
or a separate adjust-targets grant (
PROPOSAL; settled in the C10 catalogue). An additional-review request needsRequest an additional review(RA5). Seeing active reviewers' names in a preview needs Monitor (D3-20). Seeing design presence needs design access. The design topic's policy is checked at subscribe and is revocation-driven: losing design access removes the subscription and the viewer's presence (PROPOSAL, X-42). Publication phase 1 carries a delegated-work binding that rechecks the publisher on execution and retry (X-42). - Server authority. Every read and command checks scope, permission and admission on the server; hiding a control is never the control.
- Blinding. Warnings and notices about dependent reconciliation never reveal a reconciler's identity or another candidate's answers to a blinded reviewer. Notices about generated versions name the publishing admin, which reveals no candidate. Reconciliation identity blinding and hint availability are form-owned (profile-owned for screening), as RS specifies.
- Provenance on every record. Session versions record actor, effective author, operation, route, declared form version and exposure. Generated versions add the operation, policy generation and publisher. Mapped revisions add the source revision and mapping. Question versions record the publisher's declaration with actor and time. Overrides record basis, actor, reason and the standard target they were made against. Design changes record actor, time and base revision.
7. Active-work impacts¶
| Action | Warned before commit | Rechecked at commit | Notified after | Apply anyway |
|---|---|---|---|---|
| Form publication (§4.8) | Sessions by category, prior version and route; active connections and drafts; reconciliations in progress; accepted results and dependent steps affected | Preview digest in a pinned snapshot after the drain | Each affected reviewer once (in-form alert and in-app notice); reconcilers with drifted tasks; the publisher on completion or stall | Not applicable; drafts are always kept |
| Target-only publication (§4.9) | Sufficiency, readiness and authority changes; overrides; reservations beyond a lowered target where enforcement applies | As above | Reconcilers whose readiness changed; reviewers whose reservation was released | Releases incompatible temporary reservations only; keeps drafts; never bypasses permissions or legal configuration |
| Study target override (§4.10) | Effective target change; readiness; active reviewers | Study version CAS | Reconciler; affected reviewers | As above |
| Additional-review request (§4.11) | Assignees' existing contributions; capacity | Per-Study item CAS | Assignees; requester | Not applicable |
| Profile publication (§4.12) | Mismatched decisions and outcomes; active screeners and adjudicators; dependent pools | Preview digest | Affected screeners and adjudicators; admins | Not applicable |
| Incomplete Save after Complete (§4.5) | Dependent reconciliation, accepted results and steps, shaped by blinding | Dependency set recomputed | Affected authors once | Not applicable |
| Operational form setting change (timeout, in-progress limit, capacity cap) | Active reviewers whose places or limits change | Settings CAS | Affected reviewers | For a lower cap or in-progress limit, releases conflicting temporary reservations only (SP §7); a shorter timeout counts from the change and needs none |
8. Failure and recovery¶
| Failure | Handling | What the user sees |
|---|---|---|
| Network loss during autosave | The client retries with the same change ID; a duplicate is success. Whether unacknowledged edits are held on the device, and how, is UX ambiguity A1 (recommended: a bounded in-session holding area cleared at logout, completion and access loss) | "Offline. Your latest edits are held until you reconnect." then "Draft auto-saved" (UX §3.2; illustrative) |
| Conflicting autosave from another tab | Conflict copy kept; both values shown | Conflict panel with both values |
| Stale base on Save or Complete | Typed StaleBase; draft kept |
The changed answers, with a way to continue |
| Indeterminate commit | OutcomeUnknown; retry with the same command ID resolves through the ledger |
"Checking whether your save landed" |
| Preview changed before phase 1 | PreviewDigestChanged |
The publisher reviews the impact again |
| Second publication attempt | PublicationInProgress |
Which publication is running and its progress |
| Phase 2 crash | Lease expiry, takeover, resume; deterministic generated-version IDs make replays return the existing version | Progress resumes |
| Phase 2 beyond its limit | The operation stalls, the publisher is notified, admission for the form stays closed on stale projections | "Publication stalled" with progress |
| Reviewer saved during phase 2 | The item recomputes against the new head or skips if the reviewer already declared the new version | Nothing |
| Late Save after a generated version | Refused as stale; the draft is rebased; overlaps shown | An alert explaining the publication and the rebased draft |
| Bulk request partly applied | Per-Study items are idempotent; the operation resumes; no Study is half-applied | Progress, then completion |
| Design draft conflict | Conflicting edit kept beside the current value | "Keep mine" or "Discard mine" |
Realtime connection lost, or ResyncRequired, on a design page |
The client re-subscribes and reloads the draft head; the lost connection's presence expires by TTL (PROPOSAL, QMI-01) |
Avatars grey out with "Live updates paused", then return |
| Message-bus switch-over window (ADR-021 S2.10, S4) | New publications are refused until the window ends; a running phase 2 finishes or stalls and resumes by lease takeover (PROPOSAL) |
"Publishing is paused for maintenance" (illustrative) |
| Placement or composition refusal | A typed refusal naming the rule code, the question and the parent, never a generic 500 (RD-R41) | The rule's message beside the question |
| Data loss needing restore | D2-13 isolated point-in-time recovery (BC); this is separate from merge reversal | A recorded history discontinuity |
9. User flows and examples¶
The examples use one project, "Stroke neuroprotection review". Priya Shah is the project admin and publisher. Elena Rossi is a designer. Alice Martin, Ben Okoro and Carmen Diaz are reviewers. Dev Patel reconciles. The Risk of bias form (RoB) has a standard target of 2 and is bound to the Full text and Extraction stages. Studies are S-101 (Okafor 2018), S-102 (Lindqvist 2020) and S-103 (Tanaka 2019).
9.1 Alice works across two stages, two tabs and a phone¶
- Loading. Alice opens S-101 RoB from the Full text stage on her laptop. The form shows a loading state, then "No answers yet". No session exists until she types.
- Draft. She answers Q1 to Q4. Autosave sends four small changes. The status reads "Draft auto-saved". Her place is held.
- Second tab. She opens S-101 RoB from the Extraction stage in another tab. It is the same session with the same draft and the same place. She edits Q6 there; the change merges.
- Conflict. She edits Q2 in both tabs within seconds. The second change arrives on a stale base. That tab shows a conflict panel with both values; she keeps the later one.
- Checkpoint. She presses Save progress. Version 1 is a checkpoint, incomplete. The status reads "Version checkpoint saved". Her draft is consumed.
- Phone. On the train she continues on her phone (UX: full annotation on phones). She answers the rest and presses Complete. Server validation finds Q11 required and unanswered although it was below the visible area; the error names Q11. She answers it and Completes. Version 2 is completed and counts once for RoB on S-101, in both stages.
- Failure. Her phone loses signal mid-edit. The status reads "Offline. Your latest edits are held until you reconnect." (UX §3.2; how edits are held is UX ambiguity A1); the change is sent when she reconnects.
9.2 Alice saves an incomplete correction while Dev is reconciling¶
Dev has started reconciling S-101 RoB with Alice's and Ben's completed versions. Alice reopens S-101 and changes Q5. Autosave alone leaves her completed version current. She presses Save progress. Before commit she sees: "Saving this as incomplete removes your completed review. A reconciliation in progress for this study uses it and will need re-checking." She confirms. Version 3 is incomplete and current; S-101 RoB now has one qualifying contribution. Dev gets one notice: "Inputs changed for S-101 Risk of bias: a candidate review is no longer complete." His draft reconciliation is kept and shows "inputs changed · re-check". Nothing in his work or in any accepted answer was rewritten.
9.3 Priya publishes RoB version 3 with a mapped option and a new question¶
RoB v3 replaces Q7's option "Unclear" with "Some concerns" (a new option ID; Priya declares the meaning unchanged, so Q7 is compatible with a mapping Unclear → Some concerns) and adds a required Q12.
- Preview. 40 completed sessions, 12 saved incomplete, 5 draft only, across both stages. Q7: SyRF suggests incompatible (an option was replaced); Priya declares compatible with the mapping and records why. Q12: she chooses "require an answer before counting" for completed sessions.
- Commit. Phase 1 takes a short drain and commits. Phase 2 runs per Study.
- Alice (completed under v2). A generated version 4 pins v3, carries her Q7 "Unclear" as a new mapped revision "Some concerns" with provenance, and leaves Q12 unanswered. It is incomplete, so S-101 RoB loses her qualifying contribution. Her history shows "Version 4 · generated by publication of Risk of bias v3 · Priya Shah". She gets one notice and an in-form alert.
- Ben (saved incomplete). He gets a generated version re-pinned to v3 with his Q7 mapped.
- Carmen (draft only, active). No version is generated. Her next autosave rebases the draft on v3; her Q7 draft value shows "mapped on publication" beside the original. She keeps working.
- Race. Ben pressed Save on v2 while phase 2 ran. His Save committed first; the phase 2 item recomputed against his new head and generated on top of it.
9.4 Priya raises the RoB standard target from 2 to 3¶
RoB v4 changes only standardTarget. The preview lists 140 Studies whose sufficiency drops below
target, 60 with accepted results, and one override: S-103 is set to 2 (made against standard 2).
Priya keeps accepted results current, labelled "below current target (accepted under target 2)".
For S-103 the suggested default keeps the effective target at 2 and flags that it is now below the
standard; she
chooses "remove", so S-103 follows the standard of 3. No session version is generated. Readiness for
S-102 now waits for a third reviewer. The Full text stage, completed manually, stays completed; the
Extraction stage, which completes automatically, shows remaining work again.
9.5 Dev requests one more review for 40 Studies¶
Dev selects 40 Studies with a reconciliation disagreement and asks for one additional review each, assigned to the group "Senior extractors". The preview shows that Carmen, a group member, already reviewed 6 of them and cannot count twice there. Commit writes 40 override versions (basis: Dev's request, raise by 1) and 40 scoped assignments. Each group member gets one notice listing their Studies. When a third qualifying review lands, the task's readiness changes and Dev is told. The project dashboard still shows "Target: 2 reviewers per study" with "40 studies have a study-specific target" listed separately.
9.6 Elena and Priya draft at the same time¶
Elena opens RoB's draft "Wording fixes". Priya's avatar shows "viewing", then "editing Q3". Elena edits Q9's help text; Priya's view updates without touching Priya's unsaved Q3 edit. Both edit Q4's wording. Priya's change lands first; Elena's arrives on a stale base and is refused. Elena's text stays beside the new value and she chooses "keep mine" on the new base. Meanwhile Priya publishes a separate draft, "Guidance update", as RoB v5. Elena's draft is now based on v4; when she publishes, SyRF rebases it item by item and recomputes the impact against v5.
9.7 Priya publishes a new title and abstract profile version¶
The new version enables Unsure (RS) and narrows the species criterion. The preview finds decisions under versions 1 and 2, 300 collective outcomes and 4 adjudications. Priya keeps decisions on Studies already excluded pinned, requests new decisions where the narrowed criterion applies, and carries compatible decisions forward. Required new screening stays pending. An amendment record is required because eligibility changed (RI). Frozen PRISMA reports are unchanged.
9.8 Priya corrects a wrong mapping¶
A week later Priya realises "Unclear" and "Some concerns" differ in meaning. She starts a guided correction from the v3 publication. The preview lists 47 mapped revisions. The commit creates a new Q7 version declared incompatible, publishes the next RoB version with "require re-answer" for Q7, and generates versions marking Q7 as needing an answer. The original mapping stays in history marked "corrected by correction K-2 on 12 October".
9.9 Ben's place expires¶
Ben has S-102 open in two tabs. He leaves one idle and keeps typing in the other; his place stays. He then leaves both for longer than the form's timeout. The place is released and his draft is kept. When he returns, RoB is at capacity under an enabled cap; SyRF tells him so and keeps the draft.
9.10 Shared accepted answers (decided)¶
Forms RoB and "Reporting quality" both include Q2. Dev publishes accepted answers for S-101 through RoB. Once R2d lets the two forms overlap, the Reporting quality reconciler sees Dev's Q2 answer as a labelled accepted answer with "Use accepted answer"; the control stays empty until she clicks. She answers differently, and a field asks why she is changing the accepted answer; she writes a short reason, though she could leave it blank. Her Complete creates a new snapshot that records who superseded what, and why. She could also have raised a query on Dev's answer if she wanted it reviewed (D2-09, decided on 5 October 2026).
9.11 Alice cannot assess a question (6 October 2026; terms decided by DQ-46, screen wording illustrative)¶
RoB v6 pins Q13, "Was allocation concealed?", as required (the default). Q13 allows the reasons no value is provided Not reported and Unable to assess, and requires a comment for Unable to assess. Q14 is an older question that stays optional under advanced settings. Q15, "Control group type", offers the options "Vehicle", "Sham" and "Other, please specify".
- Draft and checkpoint. Alice opens No value to enter (illustrative wording) on Q13 and chooses Unable to assess. The form shows a comment field marked as needed. She presses Save progress without it; Save succeeds ("Version checkpoint saved").
- Complete refused. At Complete, SyRF names Q13: "Add a comment for Unable to assess" (illustrative). She writes "Methods section missing from the PDF" and completes.
- A clear. Ben first answers Q14, then clears it. His history shows "answered, then cleared"; Q14 is optional, so he can complete with it unanswered.
- Comparison. Ben answered Q13 "Not reported". In reconciliation, Dev sees Alice's Unable to assess and Ben's Not reported as two different reasons no value is provided, which disagree. For Q14, Ben's comparison reads "Not compared (unanswered)" (carried from the recommendation; RS-R14).
- A specified value. For Q15 Alice chooses "Other, please specify" and types "Untreated littermates". Her answer status is "answered with a value": the value holds the Other option's ID and her text, and the export shows both in the value columns, never as a reason or as metadata (RI-R64).
10. Rollout and adoption¶
| Scope | Release or lane | Notes |
|---|---|---|
Versioned questions and forms with standardTarget and ReconciliationPolicy inside the version from the first canonical form; sessions; diff-based drafts with the change log; Save and Complete; whole-form validation; one place within one stage |
R2a | No settings-only target path ever exists for canonical forms. Design drafts with base checks and attributed changes ship here for a single editor at a time |
| Reasons no value is provided, "Other, please specify" values, answer metadata, the required default, the answer payload and Complete's answer rule (6 October 2026; §3.16; terms per DQ-46) | F1a (the payload contract, E37); R2a | PROPOSAL placement: these belong with the first canonical form, so no canonical form ever exists without them; the compatibility rows (RD-R54) act at R2c publication; converted forms keep the legacy Optional flag (BC-R49) |
| One session and place across stages; form-owned timeout and in-progress limit; connection tracking | R2b | Capacity mechanics are SP's (D3-17, D3-18) |
| Publication with impact including generated versions, compatibility declaration at commit, Q-34 mapping, target-only publications, Study target overrides and the override treatment at publication; collaborative drafts with presence and live updates; one publication per form | R2c | Freeze F2 must include the generation table and the draft rebase rule. Presence and live updates need realtime hub v2 in the target environment (X-06); if it is not live, R2c ships base checks only and presence stays off behind its flag |
| Editor hardening in legacy API mode: newly built filtered-options authoring with server validation (RD-R38), the server-enforced answered-question lock (RD-R39), the child-condition warning (RD-R40), typed placement refusals (RD-R41), pointer drag | R1a (T-RD-12) |
Legacy projects keep today's semantics otherwise (PROPOSAL) |
One refreshed editor for every project (DQ-01, decided 6 October 2026); when the legacy designer, stage question selection and newQuestionManagement retire |
An R1a follow-on, at the latest R7 (T-RD-17) |
One editor with mode-appropriate behaviour is OWNER (DQ-01, option (a)). The retirement timing stays the PROPOSAL of T-RD-17 (after R1a acceptance and one staging soak): DQ-01 answers QMI-04 in part and does not address the timing |
| Autosave of accepted field changes into the unpublished design draft, with save status, conflict handling and per-question discard (DQ-03, decided 6 October 2026) | R2a, with design drafts | Presence and live updates still ship with R2c (RD-R45) |
| Overlapping forms, Fix, FV4 generations, guided correction | R2d | D2-09 is decided: the second form's revision of shared accepted answers, with the optional reason, ships with overlapping forms; its query action needs R4b |
| Profile publication with mismatch detection | R3b | Content of profile versions is RS's |
| Additional-review requests raising targets; result versions under target changes | R4a | RS owns result authority |
References, source-document links, StudyVersion for new imports |
P1 | DM extends StudyVersion for merges in P2 |
StudyVersion for existing Studies |
First need, or baseline conversion | Labelled CurrentSnapshotOnly (BC) |
- Baseline and MVP. Everything above is baseline for canonical projects. There is no opt-in beta in this specification.
- Deferred. Grouping distinct reports into one investigation (D4-08, RI). Offline review and PWA caching (UX).
- Flags. Canonical behaviour follows per-project enrolment (R0). No new environment flag is
proposed for generated versions because they are part of the publication contract; a project's
publication scope can be withdrawn through enrolment as the kill switch (
PROPOSAL). Design presence gets its own flag, which declares a dependency on the realtime v2 hub and client flags (PROPOSAL, X-40). - Pilots. The largest project (Francesca's) is an acceptance case at the max tier from R2a. Staging pilots use the seeds D3-14 adds; production pilots wait for their own approval.
- Dependencies. F1a (engine contracts, storage ADR), F2 (publication), FEAT-024 usage evidence or Q-31(b) counting, the notification capture contract (delivery is not authorised), SP for capacity and pools, RS for result authority.
11. Acceptance evidence¶
| ID | Evidence | Verification | Amends |
|---|---|---|---|
| RD-AE01 | 200 autosaves on a 2,023-question form send only changed answers; the draft rebuilds byte for byte from its base and change log; no session version and no Study write occur | Integration | AC-R2a-01, AC-R2a-28 |
| RD-AE02 | Two devices edit different answers concurrently and both changes apply; the same answer edited from a stale base yields a conflict with both values recoverable | Integration, e2e | AC-R2a-06 |
| RD-AE03 | A Save after Complete removes qualification; autosave does not; a later Complete restores exactly one contribution | Conformance | AC-R2a-02, AC-R2a-18 |
| RD-AE04 | Complete refuses a missing required applicable answer that was never rendered, naming it | Conformance, e2e | AC-R2a-03 |
| RD-AE05 | One place across two stages and two tabs; one idle tab with another active keeps it; all connections idle past the form timeout release it and keep the draft | Integration | AC-R2a-37, AC-R2b-03, AC-R2b-10 |
| RD-AE06 | The pre-commit warning lists every affected task, accepted result and step without revealing blinded identities; the set is rechecked at commit; each affected author gets one notice; no dependent record changes | Integration, e2e | New |
| RD-AE07 | An injected stale readiness projection never admits a reconciliation start | Integration | New |
| RD-AE08 | A target-only change creates a new form version, shows sufficiency and authority changes, generates no session version, and readiness reflects the new target at query time | Integration, e2e | AC-R2a-33; FX-VM-42 (target part) |
| RD-AE09 | Lowering 2 → 1 under AutoAccept creates SingleAnnotator results only where exactly one qualifying candidate exists; Studies with several agreeing candidates are never auto-accepted; raising the target deletes no result |
Conformance | New |
| RD-AE10 | Each override change is a new immutable version; results record form and override versions; an override change creates no form version | Integration | New |
| RD-AE11 | Publishing a new standard target lists every override with its treatment; no effective target changes without a recorded choice | Integration, e2e | New |
| RD-AE12 | A 500-Study additional-review request writes one override and one assignment per Study, idempotently on replay; an assignee who already qualifies is not counted twice | Integration, benchmark | New |
| RD-AE13 | Project statistics show the standard target and list study-specific exceptions separately | e2e | New |
| RD-AE14 | The publisher's declaration is stored with actor and time and cannot be edited; correction goes through guided rollback and republication | Conformance, integration | AC-R2c-21 |
| RD-AE15 | Mapped revisions carry provenance; originals are unchanged; a declared incompatible change cannot be mapped | Conformance | AC-R2c-23 |
| RD-AE16 | Generated versions follow §3.15 for every treatment combination, are attributed, never record an invalid Complete, replay idempotently after a forced phase 2 crash, and never overwrite a newer reviewer version under barrier-forced races | Conformance, integration | AC-R2c-02, AC-R2c-05, AC-R2c-10 |
| RD-AE17 | No draft edit is lost across a publication; non-overlapping edits rebase; overlapping edits show both values | Integration, e2e | New |
| RD-AE18 | A late Save after a generated version is refused as stale and rebased; under doNothing a late Save is still accepted pinned to its declared version |
Integration | AC-R2c-20 |
| RD-AE19 | One notice per recipient per publication; a reviewer's own edits give in-form warnings only | Integration, e2e | AC-R2c-07 |
| RD-AE20 | With two drafts, the second publication is refused while the first runs, then requires a rebase and a recomputed impact | Integration | AC-R2c-14 |
| RD-AE21 | Presence is visible only to users with design access; accepted changes appear in other views within a measured latency (target proposed, not approved); local unsaved edits survive; every change has actor, time and base revision | e2e, integration | New |
| RD-AE22 | Profile publication finds every mismatched decision, outcome and adjudication version; required new decisions stay pending; frozen reports are unchanged | Integration, conformance | New |
| RD-AE23 | Save, Complete, preview, phase 2 generation and phone annotation pass at the max tier (2,023 questions, the largest project) within measured budgets | Benchmark, e2e | Replaces AC-R2a-22's ceiling |
| RD-AE24 | Citations are never edited or moved; a Study's references are read through its StudyVersion links; an abstract and an article can stay separate Studies |
Integration | New |
| RD-AE25 | FX-VM-45 tests D2-09's decided option: the second form's reconciler sees the existing accepted answer as a hint (never prefilled), a revision in their final submission writes a new snapshot with provenance, the optional reason is prompted for when the answer differs and is never required, and a query can be raised on the accepted answer (R4b) | Conformance, integration | FX-VM-45 |
| RD-AE26 | Publication protection holds under load and its pause and operation limits are measured and recorded | Benchmark | AC-R2c-06, AC-R2c-15 |
| RD-AE27 | Testers can tell a draft auto-saved from a version checkpoint and from a completed session | User test | UX criteria |
| RD-AE28 | From every bound stage the live route presents the session's resolved version, and the effective target never comes from a stage | Integration | AC-R2b-15 |
| RD-AE29 | D2-03 and D2-06 fixtures pass | Conformance | AC-R2c-26, AC-R2a-23 |
| RD-AE30 | FX-COMPOSE (the 16 corpus rules, the 16 valid and 96 invalid placement fixtures, and NQ005, CPA001 and CPA002 cases re-keyed to option IDs) passes on the legacy validator and on the canonical composition validator with one code namespace; a placement refusal returns a typed 400, never a 500 | Conformance | AC-R2a-24; AC-R1a-CONF |
| RD-AE31 | A schema-v1 project saves filtered options keyed by parent option IDs and the server refuses an invalid filter; a schema-v0 project gets an explained refusal; fixtures show AF1 and AF2 offering the same options | Integration, conformance | Replaces AC-R1a-06's parity wording |
| RD-AE32 | In legacy API mode the server refuses an edit or delete of an answered question whatever the client sends, and the editor shows no Edit or Delete on an answered question while counts load, fail or are switched off | Integration, e2e | New |
| RD-AE33 | On fixtures with a referenced option and a condition that was already dangling, R1a's warning names the parent, child and option, and the server's existing refusal is unchanged; in R2a the same fixtures refuse composition keyed by option ID | Integration, e2e | FX-VM-10; AC-R2a-24 |
| RD-AE34 | For each production SystemQuestionVersion, the seed's seq 1 equals main's code-built definitions read from a frozen copy |
Conformance | AC-R2a-23 |
| RD-AE35 | Answer payloads round-trip through System.Text.Json goldens with exact decimals and structural list equality, and their digests are identical across serializer settings | Conformance | New |
| RD-AE36 | Two designers connected to different API pods see each other's presence and accepted changes within the measured budget; after ResyncRequired the page reloads the draft head; a presence record expires by TTL, and no presence data appears in history, exports or audit (whichever carrier QMI-01 chooses) |
e2e, integration | AC-R2c-34 |
| RD-AE37 | A forced host restart and a simulated message-bus switch during phase 2 resume by lease takeover with no duplicate generated version, and no step relies on cancelling a scheduled message | Integration with failure injection | RD-AE16 |
| RD-AE38 | Changing an answer label is classified compatible, and conversion carries the label into v1 | Conformance | New |
| RD-AE39 | A question pinned in a new design draft defaults to required; optional is offered only under advanced settings, with the warning; the count of optional pins per form version is reported from published versions | Integration, e2e | New |
| RD-AE40 | Complete is refused, naming each question, for every applicable required question with neither a value nor a reason no value is provided, including one under a second ancestor instance and one never rendered; a reason satisfies it; Save succeeds with nothing answered; a suppressed question needs nothing (FX-VM-59) | Conformance, e2e | New; extends RD-AE04 |
| RD-AE41 | A required repeatable question with no instance and no "None reported" blocks Complete; "None reported" satisfies it; "None reported" with an active instance is refused at Save (FX-VM-59) | Conformance | New |
| RD-AE42 | For each recorded answer state, a hidden or undeclared metadata field is refused at Save; a required field may be missing at Save and blocks Complete with its name; Unable to assess requires its comment when configured; a metadata-only payload is accepted only where the unanswered state allows metadata. DQ-46: an "Other, please specify" option whose text is required blocks Complete without the text; the text is stored in the value with the option ID, never as metadata, and no "Other: specify" metadata field type exists (FX-VM-60) | Conformance (E37 fixtures) | New |
| RD-AE43 | Empty and whitespace-only text is stored as Unanswered and no empty string is stored; a clear writes an Unanswered revision and history shows "answered, then cleared"; a Complete writes no revision for untouched questions; the "Not applicable" reason and the derived NotApplicable state stay distinct in payloads, exports and per-answer states. DQ-46: payloads, versions and exports keep the answer status, the noValueReasonId of a reason and the option ID with the specified text of an "Other, please specify" value distinct (FX-VM-61) |
Conformance | New |
| RD-AE44 | Adding a reason no value is provided or a metadata field is suggested compatible; removing a reason without a mapping, or removing, retyping, requiring or hiding a field, is suggested incompatible; a mapping to another reason is accepted only under Q-34's rules; an option-to-reason mapping is refused; requiring an "Other, please specify" text or removing the text request is suggested incompatible (FX-VM-62) | Conformance | New |
| RD-AE45 | A set of reasons no value is provided copied from a catalogue template such as SYRCLE records copiedFrom, keeps each reason's stable ID, keeps risk-of-bias "Unclear" as a value option apart from the reasons, and is unchanged when the catalogue item gets a new version |
Integration | New |
| RD-AE46 | In a Versioned project each accepted field change appears in the design draft's change log without a Save action, and the save status updates; a same-item change from another designer keeps the local edit beside the current value; "Discard changes" on one question restores that question's base values by appending changes and leaves other questions untouched; no draft save changes a published form version or anything a reviewer sees; a Classic project shows no draft and saves as today (DQ-01, DQ-03; RD-R55) | Integration, e2e | New |
12. Brief items, specialist inputs and unapproved proposals¶
Entries this specification owns (brief §2).
| Entry | Kind | Required treatment |
|---|---|---|
| D2-10 | One of the 22 session-register brief entries | Specify and test the publication active-work protection with generated versions: drain, per-form pause, per-Study items, draft rebase, stale-save refusal. Measure the pause and operation limits; the 90-second and 30-minute figures are proposed, not approved |
| D2-03 | Engineering contract, no owner question | Keep the PROPOSAL (RD-R30) and freeze it at F1a |
| D2-04 | Engineering contract, no owner question | Keep the PROPOSAL (RD-R31); state that targets never come from stages |
| D2-06 | Engineering contract, no owner question | Keep the PROPOSAL (RD-R32) |
| D2-09 | Decided-amended (Chris, 5 October 2026; T-OI-01) |
No owner question remains. The brief specifies §4.14 and RD-R37: the revision's provenance and reason storage, the reason prompt (wording and placement with UX), and the query entry point with RS and R4b |
Brief details of decided items.
| Item | Proposal |
|---|---|
| D2-05 classification | The §3.5 table; confirm at F1a |
| Override treatment at publication | RD-R16 treatment set and default |
| Generation table | §3.15, including whether autoUpdate generates a version or stays derived (recommendation: generate, so a session's current version pins the form version it satisfies; measure the cost under D2-10) |
| Draft change-log retention | Keep with the session history; any compaction keeps explicit versions and is measured first |
| D2-08 presentation | Concurrent editing with base checks by default; the brief may choose a read-only-with-take-over presentation for small screens |
| D2-16 limits | E28 limits in pins and bytes set at or above the max tier with evidence |
| Presence latency | A measured target, proposed in the brief |
| Additional-review assignment | How a scoped assignment interacts with allocation and capacity (SP) |
Ambiguities, each stated once.
- "Fully reconstructable history" for autosave. Option A: keep every accepted draft change. Option B: keep only the current draft. Recommendation: A, because the owner's wording and the register's "increasing draft versions" both point to it; it replaces PH-33.
- "General statistics use the standard target." Option A: headline figures state the standard target, per-Study completion uses the effective target, and exceptions are listed separately. Option B: progress is computed against the standard target alone. Recommendation: A, because B would show a Study with a raised target as done before it is.
- Override and new standard target. The owner asked for an explicit definition. Recommendation: RD-R16.
Proposals not approved. Every numeric threshold on this page (debounce, drain, operation limit,
presence latency, presence TTL and heartbeat, batch sizes). Automatic acceptance of several agreeing
candidates (T-POL-03).
Owner questions from the question-management integration (5 October 2026, evening). They are
asked in the question-management plan and grouped under tracker row
T-OI-02. None is decided, except that DQ-01 (6 October 2026) answers QMI-04 in part; each
PROPOSAL above that depends on one says so.
| ID | Question in brief | Recommendation | Where it applies here |
|---|---|---|---|
| QMI-01 | How design-page presence and live draft updates reach users on other API pods (3 to 10 pods, no backplane) | An ephemeral, TTL-bounded presence record read by the realtime v2 change-feed reader, never an audit record. Alternatives: per-pod bus fan-out; a Valkey backplane | §3.7, §4.7, RD-R45, RD-AE36 |
| QMI-02 | The P9 class of the new operation kinds | Publication phase 1 delegated and atomic; phase 2 an approved system obligation that runs to completion; baseline conversion atomic with routing rollback before the first canonical write; merge and unmerge staging and stage pool sweeps classed the same way | §3.8, §4.8, RD-R46 |
| QMI-03 | Statistics scope for canonical projects | R2c pilots use Q-31(b) authoritative counting at the protected boundary; the canonical families (E72) and canonical QuestionAnswers are carved out of the statistics brief's "no new scope" before GA, or activated at its 8-week review | §4.8 step 1 usage evidence; §10 dependencies |
| QMI-04 | Whether the new editor becomes the default entry for every project | Answered in part (DQ-01, option (a), Chris, 6 October 2026): the same refreshed editor serves every project, with the saving and assignment behaviour of each project mode. Not addressed, so still the recommendation: the legacy designer and newQuestionManagement retire after R1a acceptance and one staging soak (T-RD-17); alternative, keep the legacy designer until R7 |
§4.7 editor modes, RD-R48, §10 |
| QMI-05 | A proposal to the architecture-review plan: the surface-area plan's D4 adds AnnotationQuestion, Stage and Target, each collapsing to v0 after its R5.0 census; #3988 does not touch SystemQuestionVersion or E24 |
Record as a proposal to that plan, not decided here | §3.4 system questions (the seed reads Project.SystemQuestionVersion, not Audit.SchemaVersion) |
Owner items from 6 October 2026. One is decided (DQ-46) and one stays open (DQ-50). The decision register and tracker rows belong to the integration writer.
| Item | Status | Recommendation | Where it applies here |
|---|---|---|---|
| Naming (DQ-46) | Decided (DQ-46, 6 October 2026): approved with revised terminology (Chris, Codex discussion; decision register §1.18). Chris had first asked: "'Response option' is even more ambiguous as it could easily be confused with a chosen option given as an answer value!? Need to think again about naming. Should reduce ambiguity and be intuitive!" | Decided terms: Answer status for the overall state (Unanswered; answered with a value; answered with a reason no value is provided); reason no value is provided for the configured reasons ("no-value reason" in dense tables; noValueReasonId, PROPOSAL); Other, please specify is a value-bearing answer; No value to enter is illustrative action wording only. Carried from the recommendation; not separately discussed: Unanswered means nothing recorded, Option means only a predefined choice, and "Not compared (unanswered)" labels a missing answer in agreement. Retired from user-facing language: "no-value answer", "blank", "response mode", "response option", "missing-data code", "answer exception" (§3.16) |
§3.16; RD-R50 to RD-R54; RS-R14; versioning model §3.4 |
| Recording unanswered and cleared answers (DQ-50) | Open; PROPOSAL |
Clearing writes an explicit Unanswered revision, which may carry metadata allowed for that state; a question never touched stays absent; nothing is pre-written at Complete, because applicability is derived per ancestor instance and changes later; empty or whitespace-only text is normalised to Unanswered on the server and never stored. Chris asked why pre-writing is avoided; the reasons (no added information, stale records, cost, readers having to ignore them) are in §3.16 | §3.16; RD-R53 |
Brief details from 6 October 2026 (no owner question):
| Item | Proposal |
|---|---|
| Defaults on a new question | Which of the three default reasons no value is provided a new question starts with |
| Optional-use reporting | Where the count of optional pins appears (the designer, the project overview, the catalogue) |
| Repeatable groups | The minimum defaults to 1; the "None reported" head key; the prompt when an instance is added after "None reported" (§3.16, item 4) |
| Option and reason mapping | Not offered in MVP; whether a redesign may turn an option such as a legacy "Not reported" into a reason no value is provided, and how agreement counts it (T-SI-02) |
| Versioned clear | Whether the whole-session clear writes Unanswered revisions or keeps withdrawal revisions |
| Evidence quote location | The source location shape, fixed with E37 and the PDF viewer's anchors |
| How reasons no value is provided count in agreement | Specialist input (T-SI-02), required by Chris's direction |
| "Other, please specify" text (DQ-46) | Whether the text is required by default when the option is chosen (proposed: yes); its maximum length; how two candidates' specified texts compare in agreement and reconciliation (free text, T-SI-02) |
| Reviewer action wording | "No value to enter" is illustrative; the copy deck (T-UX-02) proposes the final label unless Chris confirms it separately |
| Design-draft autosave (DQ-03) | The debounce before a field change is sent; the save-status wording (DH-C105: never "Draft auto-saved"); the shape of a per-question discard |
Brief-level confirmations that touch this page: X-06 (close rollout R-AMB-04 as (a), with the realtime v2 join), X-08 (the state-management plan's D4 names who migrates the editor's state) and X-44 (the target-override grant, §6). Engineering decision: X-16, one durable-intent store (consistency model §9.2).
Harmonisation notes (5 October 2026).
- §3.5: target-one handling now mentions the conversion-only
NoAcceptancevalue (RS-R04a,PROPOSAL) in the form-version content and the classification table, matching RS and BC. - §3.5 classification table: assignment expiry names the profile as owner for adjudication tasks and is off by default, matching RS §3.12. The table is otherwise unchanged and is the reference the other specifications now repeat: blinding, hint availability, completeness and outdated-answer mode inside the form version; timeout, in-progress limit, capacity cap, assignment expiry and bulk acceptance as audited operational settings.
- §4.9 and §9.4: result labels and treatments follow RS (label "below current target";
SingleAnnotatorresults created now or at the next qualifying completion). - §8 and §9.1: offline wording follows UX §3.2, and on-device holding of unacknowledged edits points to UX ambiguity A1 instead of asserting a local copy.
- §4.6: a timeout release no longer writes a history event, matching SP §4.9 and SP §3.14 (claims and refused queries are not retained as history).
- §3.3: RD's
sourceDocumentLinks[](files) and RI'ssourceDocumentKeyonreferenceLinks[](report identity) are now tied together; RI owns D4-08 and the key. - §2: statuses aligned with the owning specifications (Q-29 target part and D3-03 are Decided-amended, as RS and UX record; the D3-13 entry itself is a brief item owned by SP).
- §7 operational-settings row: Apply anyway now matches SP §7 and ACD §7 (available for a lower cap or in-progress limit; a shorter timeout counts from the change and needs none).
13. Amendments to existing package documents¶
- integrated-plan.md → §4 release table row R2c: replace "publication records a policy and writes no evidence" with "publication records a policy and may write attributable generated session versions". §5.4 R2a: move the form target inside the requirement version; replace "an explicit ceiling in pins and bytes (D2-16)" with "limits engineered for the largest project, an acceptance case"; add the draft change log. §5.4 R2c: add generated versions, target-only publications, overrides and the override treatment, collaborative drafts and presence. §5.4 R2d: add guided correction. §5.6 R4a: additional-review requests raise targets.
- domain-model.md → §4.1
ReviewerStudyEvidence: replace "Publication writes no evidence except Q-34 option mapping" with the generated-version rule;SessionDraft: replace the lease and D2-07 middle ground with the diff change log and the decided form-owned timeout. §4.3AdditionalReviewRequest: replace "never sets gold or changes the target" with "raises the effective target through override versions; never sets an accepted result". §4.4 placement table: target →FormVersion.standardTarget; idle timeout and in-progress limit → form (SP for mechanics). §4.5AnnotationForm: requirement part gainsstandardTargetandReconciliationPolicy; operational settings per §3.5; delete the D2-16 size-ceiling invariant;FormVersionIssue: replace "Writes no evidence (D2-01)". §5 Study row: addstate,currentVersionId,StudyVersion. Add rows forStudyVersion,StudyTargetOverride,DesignDraft,DesignDraftChange,SessionDraftChange. §6.3: add commandsApplyStudyTargetOverride,RequestAdditionalReviews(batch),EditDesignDraft,CorrectPublication;ApplyIssuePolicywrites generated versions. §8: replace "Changes kept, not yet saved" with "Draft auto-saved". §13 F1a row: replace "D2-01 to D2-16 answered" with the statuses in §2. - versioning-model.md → the rows of the §3.15 table above; §15.1 statuses for D2-01, D2-02, D2-05, D2-07, D2-08, D2-09, D2-10, D2-11, D2-16; §14 fixtures: rewrite FX-VM-42 (a target change creates a form version), keep FX-VM-45 parameterised, add fixtures for the generation table and draft rebase. Update (5 October 2026, evening): D2-09 is decided, so FX-VM-45 now tests the decided option, the optional reason and the query route (RD-AE25).
- consistency-model.md → the rows of the §3.15 table above; §4.2 add rows for the override, the additional-review batch item and the design draft change; §4.5 replace the D2-07 recommendation with the decided form-owned timeout; §14 matrix rows for drafts and Needs updating.
- contracts.md → C4 publication command: "Effects are derived, never written
(D2-01)" becomes the generated-version rule; compatibility immutable from commit and declared by the
publisher; the operational-settings column loses the minimum target. C5: add
PublicationGenerated; delete "There is no publication-written transition"; drafts contract per §3.10 and §3.11; D2-07 and D2-08 decided. C9: the additional-review row raises the effective target; shared question gold staysOPEN(D2-09). Update (5 October 2026, evening): shared question gold follows D2-09's decided option (§4.14, RD-R37). - acceptance-criteria.md → rewrite AC-R2a-06, AC-R2a-22, AC-R2a-33, AC-R2a-37, AC-R2c-02, AC-R2c-20, AC-R2c-21, AC-R2c-23 per §11; extend AC-R2a-01, AC-R2a-28, AC-R2c-05, AC-R2c-07, AC-R2c-10, AC-R2c-13 (FX-PUB-10K includes generated versions); add RD-AE06 to RD-AE13, RD-AE17, RD-AE21, RD-AE22, RD-AE24 as new rows.
- open-questions-and-assumptions.md → D2 table: statuses per §2; D2-09 remains the one open owner decision (update, 5 October 2026: D2-09 is decided; no owner decision remains open); E28 limits per RD-R33.
- decision-register.md → statuses per §2; superseded rows per §14.
- Owner ledger → overlay notes: RA5's "does not change the normal form target" is superseded by consolidation §1; SF6 now applies literally to generated versions.
- programme-integration.md → notification kinds for generated versions and target changes (capture only; delivery not authorised).
Question-management integration (5 October 2026, evening). This page's body now carries §3.4 (answer labels, filtered options, system seed parity), §3.5 (composition validation), §3.7 (presence, pending QMI-01), §3.8 (operation driver and P9 class), §3.9 (typed payload), §4.7 (editor modes, design topic, client state), §4.8 (P9 classes), §6, §8, §10, RD-R38 to RD-R48, RD-AE30 to RD-AE38 and the owner questions in §12. The package documents below should follow; the question-management plan owns the change list and its "Changes proposed to other plans" section holds every change to plans outside this package.
- versioning-model.md → §3.1: the D2-03 sentence saying the designer
"refuses data-type and multiplicity edits on a published question, which is today's behaviour" is
wrong.
mainoverwrites type, control, multiplicity and the answer array on update; only a referenced parent is protected (M-26). §3.4: the extensibility architecture (M-05) is an Approved document onmain, not recovered, and the F1a C4 and E37 ADR PR amends its decisions 1 and 7. §4.2: name the rule corpus and FX-COMPOSE (RD-R41). - integrated-plan.md → R1a: "absorbs the legacy editor's
filtered-options authoring" becomes new authoring with server validation and a schema-v0 refusal
(RD-R38); the default-entry
PROPOSALbecomes owner question QMI-04 withT-RD-17. - acceptance-criteria.md → AC-R1a-06 is retired for AC-R1a-06r, carrying RD-AE31; AC-R1a-07
deletes the
hybrid-examplespec instead of restoring it; add RD-AE30 and RD-AE32 to RD-AE38. - harvest-map.md → H-TREE-01 names M-26 as the server half that already exists; H-DOM-02 records the payload rename (RD-R44); H-WEB-14 points at QMI-01's carrier instead of "a group on the existing hub".
- contracts.md C4, C5, C17 and C19, the consistency model §4.5, §7.2, §9.2 and §13.1, and the domain model §4.1, §4.5 and §8 are updated in the same change.
Owner answers, 6 October 2026. This page now carries the §1 paragraph, the §2 rows, §3.9 (the payload), §3.16, §4.3 and §4.4, RD-R49 to RD-R54, §9.11, RD-AE39 to RD-AE45, the §12 items and the §14 rows. Updated in the same change: the versioning model §2, §3.2, §3.4 to §3.6, §4.1, §7.3, §7.4, §10.2, §10.3, §11, §14 (FX-VM-59 to FX-VM-62), §15.1, §15.2 (E37) and §16.4; contracts C1, C4, C5, C9 and C11; RS RS-R14, RS-R15 and RS-AE08; BC BC-R49 and BC-AE37. The consistency model needs no change, because no commit boundary, fence or typed outcome changes. Other documents should follow (terms in this list updated by DQ-46 the same day; the list first used the working term):
- acceptance-criteria.md → add rows for RD-AE39 to RD-AE45 (R2a for RD-AE39 to RD-AE43 and RD-AE45; R2c for RD-AE44, which needs publication) and FX-VM-59 to FX-VM-62; AC-R2a-03's wording "required applicable answer" reads "a value or a reason no value is provided for every applicable required question".
- open-questions-and-assumptions.md → the E37 row follows versioning model §15.2; the two owner items of §12.
- decision-register.md → the section "Owner answers, 6 October 2026" records required by default (decided-amended), configurable answer metadata (direction), and the naming and recording items as open; UA1 and AG3 notes gain the "Not compared (unanswered)" label.
- harvest-map.md → V-D3 is settled by RD-R52; H-VAL-07 and H-VAL-12 read "reason no value is provided" for "response mode".
- domain-model.md → the
AnswerValuepayload kinds (value, reason no value is provided, explicit Unanswered) and the per-version reason and metadata field records. - Design handoff and the UX specification → the designer's required default, advanced settings and warning; the picker of reasons no value is provided with catalogue sets; the metadata grid per answer state; the reviewer's reason control and "needs a comment" messages; "Not compared (unanswered)" in reconciliation.
Design-handoff answers, 6 October 2026 (Chris, 6 October 2026, Codex discussion; record archived
at owner-session-2026-10-05/syrf-design-decisions-2026-10-06.md.txt;
decision register §1.18). Chris
approved DQ-01 (option (a)), DQ-02 (option ©), DQ-03 (option (a)), DQ-04 (option (b)) and DQ-46
(with revised terminology), and class B DQ-09 (option (a)). Planning decisions only: feature
implementation remains on hold, recording them does not send the design pack, and the pack is ready
for Chris to send (T-DH-01) only after this change is integrated, checked and merged.
- This page. DQ-46: the §1 paragraph, the §2 rows, §3.9's payload, §3.16 (decided terms, the
answer status table, reasons no value is provided with
noValueReasonId, "Other, please specify" as a value withspecifiedText, the metadata types without "Other: specify" text, compatibility), §4.4's refusals, RD-R50 to RD-R54, §9.11 (with a specified-value step), §10, RD-AE40 and RD-AE42 to RD-AE45, the §12 naming row (decided) and brief details, and §14. DQ-01: §1, §2, §4.7's editor modes, RD-R48, §10 and §12's QMI-04 row (answered in part; theT-RD-17retirement timing stays aPROPOSAL). DQ-03: §1, §2, §3.7, §4.7's Edit and Discard rows, the new RD-R55 and RD-AE46, §10 and §12. DQ-50 stays open. DQ-02 and DQ-04 are UX matters: this page states no editor layout, breakpoint or phone acceptance gate, so it needed no change (RD-AE23's phone annotation concerns annotation, whose device acceptance D3-05 already approved). - Updated in the same change. The versioning model (header, §1.2, §2, §3.2, §3.3, §3.4 renamed "Reasons no value is provided, metadata and suppression", §3.5, §3.6, §4.1, §7.3, §7.4, §10.2, §10.3, §11, §14, §15.1, §15.2 E37, §16.5, the amendments record); contracts C1, C4, C5, C9, C11, C13 and C17; the domain model; the consistency model (a note: no commit boundary changes); RS RS-R13 to RS-R15 and RS-AE08; BC BC-R49; RI §3.9, RI-R64 and RI-AE46; TI and CPR for DQ-09.
- Other documents should follow. acceptance-criteria.md: add
RD-AE46 (R2a) and carry the DQ-46 wording into the rows for RD-AE40 to RD-AE45 and FX-VM-59 to
FX-VM-62. harvest-map.md: H-VAL-07 and H-VAL-12 read "reason no value is
provided". implementation-tracker.md:
T-RD-17keeps its timingPROPOSAL, andT-OI-02records QMI-04 as answered in part.
14. Superseded wording¶
| Old wording | New wording | Where it appears today |
|---|---|---|
| Publication writes no evidence; no session versions are created by publication (D2-01 round-2 proposal) | Publication may create attributable generated session versions | versioning-model §1.1, §2 rule 4, §7.3, §7.5, §8.1, §8.4, §8.5; consistency-model §7.4, §19.3; contracts C4, C5; domain-model §4.1, §4.5; integrated-plan R2c; AC-R2c-02; open questions D2-01 |
| The form target is an operational setting; changing it is an audited setting change, not a publication (D2-05 round-2) | The standard target is part of the immutable form version; a change is a publication with impact | versioning-model §2 rule 6, §4.4; contracts C4; domain-model §4.5; AC-R2a-33; FX-VM-42 |
| An additional review never changes the normal form target (RA5 boundary) | An additional-review request raises the effective Study × form target explicitly and counts reviewers once | owner ledger RA5; contracts C9; domain-model §4.3 |
| A compatibility declaration may change until a revision pins the version | The publisher's declaration is immutable from commit; corrections use guided rollback and republication | versioning-model §3.5; contracts C4 |
| No autosave trail beyond the current draft (PH-33) | Autosave keeps a reconstructable draft change log | versioning-model §7.6; contracts C5 |
| The second tab is read-only with "Take over editing" (D2-08 recommendation) | One shared session across tabs and devices with base-version checks; the presentation is a brief detail | versioning-model §7.6; consistency-model §4.4; contracts C5; AC-R2a-06 |
| A draft holds the place under today's idle and disconnect timers (D2-07 middle ground) | Form-owned inactivity timeout and per-reviewer in-progress limit; one place across connections; expiry keeps the draft | versioning-model §7.6; consistency-model §4.5; contracts C5; AC-R2a-37 |
| Most restrictive bound stage sets the idle timeout; the stage in use sets the in-progress limit | Form-owned timeout and limits (SP) | domain-model §4.4; AC-R2b-10 |
| Form size ceiling; the 2,023-question project stays legacy (D2-16) | No size-based exclusion; the largest project is an acceptance case | domain-model §4.5; open questions D2-16, E28; AC-R2a-22 |
Q-34 option mapping OPEN |
Decided: the publisher declares compatibility and mapping | versioning-model §1.2, §8.9; AC-R2c-23 |
Q-26 OPEN: a profile version publishes only before any decision exists |
Decided: profile publication with mismatch detection and treatment | versioning-model §5.1, §15.1 |
| "Changes kept, not yet saved" | "Draft auto-saved" and "Version checkpoint saved" (illustrative; meaning fixed) | domain-model §8 |
D2-09 OPEN: shared-question gold "prefilled as accepted" for the second task, with both options carried until Chris answers (FX-VM-45 parameterised) |
Decided-amended (5 October 2026): the existing accepted answer is a labelled hint with click-to-fill, never prefilled (OS-A04); the second reconciler may revise it in their final submission as a new snapshot with provenance; an optional reason is prompted for; a query may also be raised (§4.14, RD-R37) | contracts C9; domain-model §4.3; versioning-model §9.5, §14; AC-R4a-43, C9-T15 |
StudyEnteredPool for first release of work |
WorkFirstReleased (SP; renamed to avoid clashing with stage-pool entry) |
domain-model §4.2, §6.2 |
"Response mode"; a payload of "value XOR responseModeId plus metadata" |
"Reason no value is provided" (decided, DQ-46; first replaced by the working term "no-value answer"); a payload of a value, a reason no value is provided or an explicit Unanswered record, each with metadata validated for its state (§3.16, RD-R50, RD-R53; 6 October 2026) | versioning-model §3.2, §3.4 to §3.6, §7.4, §10.2, §15.2 E37; contracts C4, C11; open questions E37; harvest map H-VAL-07, H-VAL-12, V-D3 |
"No-value answer" (working term, 6 October 2026) and noValueAnswerId |
"Reason no value is provided" ("no-value reason" in dense tables) and noValueReasonId (PROPOSAL); Answer status for the overall state (DQ-46, decided 6 October 2026) |
This page, the versioning model, contracts C1, C4, C5, C9, C11, C13, the domain model, RS, BC, TI, CPR, the design handoff, the UX specification, open questions E37, the decision register |
| "Other: specify" text as a metadata field type | Part of the value of the "Other, please specify" option: the option ID with specifiedText, value-bearing, never a reason (DQ-46) |
versioning-model §3.4, §15.2 E37; contracts C4; domain model; FX-VM-60; the design handoff's metadata grid |
| "Blank" for an unanswered question; "Not assessed" for its comparison | "Unanswered"; "Not compared (unanswered)" (carried from the recommendation; not separately discussed by DQ-46; meaning unchanged) | RS §1, RS-R14, RS-AE08; contracts C9; decision register UA1, AG3; open questions Q-04 |
| Which editor is the default entry is owner question QMI-04 (open) | One refreshed editor for every project with mode-appropriate behaviour (DQ-01, decided); only the retirement timing (T-RD-17) stays a PROPOSAL |
contracts C17; UX §3.13, UX-R46; implementation tracker T-OI-02, T-RD-17 |
Requiredness taken from each question's Optional flag, with no form-level default |
Required by default for a newly pinned question; optional only under advanced settings; converted forms keep the legacy flag (RD-R49, BC-R49) | the legacy designer; versioning-model §4.1 |
15. Existing work reused¶
The dormant QM v2 stack feeds this specification most: PR-A's domain types (#2572), PR-B's publication services (#2573), PR-C's API and save path (#2574) and PR-D's designer (#2575). The validation and response-mode PRs (#2986, #2987, #2629, #2812), the template-import PRs (#3934,
2781) and #2387's child-question checks feed it too. Almost none of it ports as is. The¶
harvest map is authoritative for every verdict, target and adaptation; this section only summarises it. Nothing is ported while the hold lasts.
| Entries | Verdict | Target section |
|---|---|---|
| H-DOM-02, H-DOM-06, H-DOM-23 | Adapt | §3.4, §3.9; C1, C2 (F1a, T-RD-01) |
| H-DOM-07 | Adapt | §3.4; RD-R32 (T-RD-01) |
| H-DOM-05, H-DOM-16, H-VAL-08 | Reference only | §3.4, §3.9 (T-RD-01) |
| H-VAL-03, H-VAL-04, H-VAL-07, H-VAL-12 | Adapt | §4.4 ValidationFailed; C4, E23, E37 (T-RD-01) |
| H-DOM-10, H-DOM-11, H-VAL-10, H-VAL-13 | Reference only | §3.4, §3.10 (F1a ADR provenance) |
| H-DOM-08, H-DOM-13, H-API-05 | Adapt | §3.5, §4.2 to §4.4 (R2a, T-RD-02) |
| H-API-01, H-WEB-03, H-WEB-04 | Reference only | §3.4 to §3.8, §4.7 (T-RD-02) |
| H-DOM-01, H-SVC-02, H-SVC-04, H-SVC-05, H-API-02 | Adapt | §3.8, §3.15, §4.8 (F2, T-RD-04) |
| H-DOM-04, H-DOM-17, H-SVC-09, H-SVC-12 | Reference only | §3.15, §4.8 (T-RD-04) |
| H-SVC-01, H-WEB-08, H-WEB-11 | Adapt | §4.8 steps 1, 3 and 5 (R2c, T-RD-05) |
| H-SVC-03, H-SVC-10, H-API-04, H-WEB-06, H-WEB-07, H-WEB-10, H-WEB-12, H-WEB-18 | Reference only | §4.8 (T-RD-05) |
| H-IMP-01, H-IMP-04, H-IMP-06 | Reuse | R1a import through the import-target port (T-RD-11) |
| H-IMP-02, H-IMP-03, H-IMP-05, H-IMP-07, H-IMP-08, H-TREE-01, H-TREE-07 | Adapt | R1a (T-RD-11, T-RD-12); the canonical import adapter and the server-side composition refusal in R2a (§10) |
| H-IMP-09, H-IMP-12, H-TREE-02, H-WEB-17, H-WEB-19 | Reference only | R1a; the M0 harvest record (T-RD-10) |
| H-DOM-03, H-DOM-09, H-DOM-15, H-DOM-18, H-DOM-21, H-SVC-06, H-SVC-07, H-SVC-08, H-SVC-11, H-SVC-13, H-VAL-05, H-VAL-09, H-API-03, H-API-10, H-API-13, H-WEB-01, H-WEB-02, H-WEB-05 | Avoid | They contradict §3.7, §3.9, §3.15 and RD-R04, RD-R20, RD-R21, RD-R23, RD-R26, RD-R31 |
Merged on main (question-management integration, 5 October 2026). The harvest map covers open
pull requests. The question-management work already merged on main is larger and actively
maintained, and this page now builds on it. The question-management plan
holds the full inventory (M-01 to M-35) with evidence; the rows below are the items this page uses.
Nothing is changed while the hold lasts.
Items on main |
Verdict | Where it lands here |
|---|---|---|
| M-09 (the Design/Assign/Preview editor), M-19 (its NgRx question state) | Keep and evolve; the NgRx state bridges legacy mode until R7 | §4.7 editor modes and client state; RD-R47, RD-R48 |
| M-02, M-03, M-25 (rule corpus, placement fixtures, placement validator) | Adapt into C4 composition validation | §3.5; RD-R41; RD-AE30 |
| M-26 (the child-condition guard, #2697) | Keep and evolve; re-keyed in R2a | RD-R40; RD-AE33 |
| M-12 (live question counts and the UI-only lock) | Keep the counts as usage evidence; bridge the lock for legacy projects, enforced on the server | §4.8 step 1; RD-R39; RD-AE32 |
| M-15, M-23 (legacy designer, embedded model) | Bridge until conversion or R7 | RD-R38 (filtered options are new authoring); RD-R48 |
| M-20 (answer labels) | Keep and evolve as version content | §3.4; RD-R42; RD-AE38 |
| M-24 (system questions built from code) | Adapt into the global seed | §3.4; RD-R43; RD-AE34 |
| M-21 (study presence) | Adapt its client patterns only; the design-presence carrier is QMI-01 | §3.7; RD-R45 |
| M-27, M-28 (question endpoints, delete cascade) | Bridge as legacy API mode; refused on canonical scopes | RD-R48; the BC writer inventory (BC-R44) |
| M-11, M-16, M-17 (Preview tab, AF2, AF2 conditions and filters) | Keep and evolve: AF2 renders canonical forms through VersionedAnnotationFormDataSource (C17, T-UX-10); AF2's semantics become the client half of E23 |
§3.5 renderability; C4 applicability |
M-31 (Audit.Version compare-and-set, IAggregateWriteGuard) |
Keep and evolve | §3.1; C16 |
What main already does that earlier package text understated. The server already refuses edits
that break child conditions (M-26), so R1a adds a warning and R2a re-keys the rule. The answered-question
lock is display-only, so RD-R39 moves it to the server for legacy projects. Neither editor saves
filtered options, so RD-R38 treats them as new authoring.
What this specification requires that the earlier work lacks.
- Option identity. Options, mappings, conditions and validation key on option IDs; the earlier work keys on option values throughout.
- An immutable declaration. Compatibility is the publisher's declaration on the question version, fixed at commit (RD-R20); the earlier work kept a mutable draft decision or a boolean.
- The target in the form version.
standardTargetandReconciliationPolicysit in every form version (RD-R12); the earlier work kept the target on the stage and had no form entity. - Collaborative drafts. Many drafts per form, append-only changes with base revisions, and presence that is never an audit record (§3.7, RD-R26); the earlier drafts are single mutable records with last-write-wins saves.
- Separate heads and revisions. Sessions are Study × form with deterministic IDs, and versions are stored apart from heads (§3.9); the earlier aggregates embed unbounded version arrays and pin stage versions.
- Generated versions written safely. Per category and prior version, affected sessions only,
head compare-and-set, deterministic IDs per
(sessionId, operationId, generation), publisher attribution with the reviewer as effective author, and never an invalid Complete (§3.15, RD-R23); the earlier planner has none of these. - Re-answer and mapping that keep history.
requireReanswerkeeps pins and shows Needs updating; mapping writes new revisions with provenance and keeps the originals (RD-R21); the earlier code clears answers and rewrites values. - One publication per form while reviewers keep saving (RD-R25, RD-R35); the earlier code locked review and export per stage.
- System questions as global versioned data, pinned by form versions, with
main's exact text atseq 1(RD-R32); the earlier factory writes per-project copies with edited text. repeatablefixed at creation, and no stage owning a target or session (versioning model §3.1 and D2-03; RD-R31).