Skip to content

PRISMA Constraint Annotations for Phases 3-16

Purpose

This document annotates each implementation phase (3-16) with binding PRISMA constraints. Each phase's executor MUST read the relevant section before implementation. Release-level validation checklists MUST pass before deployment.

These constraints exist because data model decisions in any phase can silently break PRISMA 2020 flow diagram generation. A field added with a conflicting name, a lifecycle status that doubles as a screening outcome, or an Citation deletion during dedup -- any of these would make PRISMA reporting impossible or incorrect. By making constraints explicit, we prevent these mistakes at the point of implementation.

Normative language: "MUST" indicates an absolute requirement. "MUST NOT" indicates an absolute prohibition. "SHOULD" indicates a strong recommendation.

Cross-references: - prisma-flow-diagram-mapping.md -- PRISMA box-to-field mapping (17 boxes, 34 fields) - three-level-data-model.md -- Publication/Citation/Study entity specifications - deduplication-service-specification.md -- Dedup service interface, confidence model, enrichment rules - study-lifecycle-and-source-taxonomy.md -- 9-state lifecycle model, 6-value source taxonomy, PRISMA count derivation


How to Use This Document

  1. Before implementing a phase, read the corresponding section below. Each section lists MUST (required), MUST NOT (prohibited), and SHOULD (recommended) constraints.
  2. Cross-references point to the specific specification document and section that defines the requirement. Follow the link and read the referenced section before implementation.
  3. Release checklists (Section 4) are validation gates. Every item must be checked before the release deploys.
  4. If a phase's implementation conflicts with any MUST constraint, the implementation must be revised -- the constraint takes precedence.
  5. Constraint severity:
  6. MUST / MUST NOT: Violation would break PRISMA reporting or create irrecoverable data model conflicts
  7. SHOULD: Violation would not break correctness but would create technical debt or inconsistency

Per-Phase Constraint Annotations

Phase 3: Collection Infrastructure

PRISMA Impact: Low

Phase 3 creates pmAnnotationQuestion and pmQuestionSet collections with scope fields and optimistic concurrency. These collections are internal to annotation management and do not directly produce PRISMA data, but their naming and scope patterns should be forward-compatible.

Constraints:

  • MUST: Scope fields on pmAnnotationQuestion and pmQuestionSet support project-level filtering, ensuring future PRISMA report generation can aggregate annotation data by project
  • SHOULD: Use consistent naming patterns that align with other PRISMA-related entities (the pm prefix convention, camelCase field names)
  • SHOULD: Optimistic concurrency pattern on Study (version field) should be designed to coexist with future lifecycleStatus, screeningOutcomes[], and citations[] fields

Cross-references: - three-level-data-model.md Section 1 (scope field convention)


Phase 4: Question Lifecycle

PRISMA Impact: None

Phase 4 implements draft question creation, stage activation, and AQ versioning. The question lifecycle is entirely internal to annotation management. No PRISMA constraints apply.

Constraints:

  • None. Draft/Activated question lifecycle is internal to annotation management and does not affect PRISMA counting.

Phase 5: Annotation Form v2

PRISMA Impact: None

Phase 5 rebuilds the annotation form with signal forms, virtual scroll, and per-question auto-save. The form renders questions but does not affect PRISMA counting.

Constraints:

  • None. The annotation form renders questions and collects answers but does not produce PRISMA-relevant data.

Phase 6: Question Management UI

PRISMA Impact: None

Phase 6 adds version history, version badges, and admin decision framework for question management. These are internal to QM.

Constraints:

  • None. Version history and admin decisions for questions are internal to question management.

Phase 7: Release 1 Data Migration

PRISMA Impact: Medium (forward compatibility)

Phase 7 is the first migration that touches the Study and SystematicSearch entities. While Phase 7 does not populate PRISMA fields, it MUST ensure the schema is forward-compatible with fields that will be added in Phases 12-16.

Constraints:

  • MUST: Add nullable sourceType field (SearchSourceType?) to SystematicSearch entity -- this field will be populated in Phase 16 but the schema must accommodate it now
  • MUST: Add nullable sourceName field (string?) to SystematicSearch entity -- free-text source name for PRISMA reporting
  • MUST: Ensure Study document schema is forward-compatible with future additions: lifecycleStatus, screeningOutcomes[], duplicateGroupId, publicationId, citations[], fullTextStatus
  • MUST NOT: Add any field named status, state, or lifecycle to Study that would conflict with the specified StudyLifecycleStatus enum (Active, Duplicate, PendingDuplicateReview, FullTextSought, FullTextNotRetrieved, Included, Merged, RemovedByAutomation, RemovedOther)
  • MUST NOT: Add any field to SystematicSearch named type or category that would conflict with SearchSourceType (Database, Register, Website, Organisation, CitationSearching, Other)
  • SHOULD: Verify no existing field names on Study conflict with planned PRISMA fields by running the validation query in Section 5

Cross-references: - study-lifecycle-and-source-taxonomy.md Sections 3, 5 (enum definitions) - three-level-data-model.md Section 3.3 (Study entity modifications)


Phase 8: Project Groups & Permissions

PRISMA Impact: Low

Phase 8 implements custom project groups and group-based stage permissions. The permission model indirectly supports PRISMA by enabling screener and reconciler role assignment for screening workflows that produce PRISMA data.

Constraints:

  • MUST: Ensure StageActivity.Reconcile permission works for both annotation reconciliation AND screening reconciliation (screening reconciliation produces PRISMA exclusion reason data used in box 9)
  • SHOULD: Group-based permissions support future screener role assignment for PRISMA-tracked screening stages
  • SHOULD: Permission group naming avoids terms that could be confused with PRISMA lifecycle terminology (e.g., do not name a group "Included" or "Excluded")

Cross-references: - study-lifecycle-and-source-taxonomy.md Section 2 (screening outcomes require reconciliation for PRISMA authority)


Phase 9: Reconciliation Model & Authority

PRISMA Impact: Low

Phase 9 creates the ReconciliationSession entity and authority determination rules. The reconciliation model itself does not produce PRISMA data, but its patterns MUST be compatible with the screening reconciliation model that does.

Constraints:

  • MUST: ReconciliationSession model is compatible with the FinalScreeningOutcome pattern -- both use authority determination + versioned snapshots, so naming and structural patterns should align
  • MUST NOT: Authority determination rules overwrite or conflict with screening outcome data on Study -- annotation reconciliation writes to ReconciliationSession, NOT to Study.screeningOutcomes
  • MUST NOT: Add a study-level "reconciliation status" field that could be confused with lifecycleStatus -- reconciliation status is per-session, not per-study
  • SHOULD: Use naming patterns consistent with the ScreeningAuthority enum values (CandidateAgreement, Reconciled) so that annotation and screening reconciliation share a coherent vocabulary

Cross-references: - study-lifecycle-and-source-taxonomy.md Section 2 (screening authority model, ScreeningAuthority enum)


Phase 10: Reconciliation Workflow & UI

PRISMA Impact: Low

Phase 10 implements the reconciliation workflow UI (pool assignment, blinded comparison, bulk approve, metrics, dashboard). The reconciliation workflow produces annotation authority but not PRISMA data.

Constraints:

  • MUST NOT: Reconciliation outcomes modify Study.screeningOutcomes -- those are set by screening reconciliation (Phase 15), not annotation reconciliation
  • SHOULD: Reconciliation dashboard could surface PRISMA-relevant counts (studies reconciled vs. pending) as a future enhancement, so data structures should not preclude this

Cross-references: - study-lifecycle-and-source-taxonomy.md Section 2 (distinction between annotation reconciliation and screening reconciliation)


Phase 11: Release 2 Data Migration

PRISMA Impact: Medium (must not conflict)

Phase 11 migrates study classification, reconciliation pools, and group data. While these do not produce PRISMA data directly, they MUST NOT introduce field names that conflict with the lifecycle and screening models that Phase 12-16 will implement.

Constraints:

  • MUST NOT: Add any study classification field that uses names from the StudyLifecycleStatus enum (Active, Duplicate, PendingDuplicateReview, FullTextSought, FullTextNotRetrieved, Included, Merged, RemovedByAutomation, RemovedOther)
  • MUST NOT: Add any field that stores screening outcomes in a format incompatible with the specified ScreeningOutcome model ({ profileId, stageId, result, primaryExclusionReason, resolvedAt, authority })
  • MUST: Any study classification added in this phase (e.g., reconciliation pool entry, auto-promote status) uses field names that are distinct from PRISMA lifecycle fields
  • SHOULD: Study classification fields added in this phase should be designed to coexist with the future lifecycleStatus field without requiring migration renames

Cross-references: - study-lifecycle-and-source-taxonomy.md Sections 3, 7 (lifecycle status enum, field naming)


Phase 12: Deduplication Service

PRISMA Impact: HIGH (direct PRISMA data)

Phase 12 is the first phase that directly produces PRISMA data. It creates the Publication entity, Citation pipeline, and deduplication service. Every constraint in this section is critical for PRISMA box 3 accuracy.

Constraints:

  • MUST: Create pmPublication collection per three-level-data-model.md Section 2 specification (DOI unique sparse index, PMID unique sparse index)
  • MUST: Create Citation entity with ALL fields specified in three-level-data-model.md Section 3.2, including: rawTitle, rawAuthors, rawDoi, rawPages, rawVolume, rawIssue, rawIsbn, rawAbstract, sourceType, sourceName, systematicSearchId, publicationId, importedAt
  • MUST: Implement dedup service interface per deduplication-service-specification.md Section 3 (DeduplicationResult, DuplicateGroup, MatchSummary types)
  • MUST: Set lifecycleStatus = Duplicate on auto-confirmed duplicates (high-confidence ASySD pairs)
  • MUST: Set lifecycleStatus = PendingDuplicateReview on probable duplicates (below auto-confirm threshold)
  • MUST: Preserve ALL Citations immutably -- never delete, never modify after creation (PRISMA requirement: per-source counting must remain derivable)
  • MUST: Track duplicate count as COUNT(Citations) - COUNT(distinct active Studies) for PRISMA box 3 (duplicates field)
  • MUST: Implement canonical enrichment per deduplication-service-specification.md Section 5 field-by-field priority rules (10 fields with MetadataProvenance tracking)
  • MUST: Implement DedupAuditLog for all dedup decisions (auto and admin) per deduplication-service-specification.md Section 7
  • MUST: Exclude Duplicate and Merged studies from all stage study pools (query-level enforcement, not deletion)
  • MUST NOT: Delete Citations during dedup -- this breaks PRISMA per-source counting (box 2a, 2b)
  • MUST NOT: Auto-merge studies that have review data (screening decisions or annotation sessions) -- admin MUST always decide for reviewed studies (system invariant)

Cross-references: - deduplication-service-specification.md -- Complete service specification (all sections) - three-level-data-model.md Sections 2, 3 (entity definitions) - prisma-flow-diagram-mapping.md Section 3.1, box 3 (duplicate count derivation)


Phase 13: Screening Profiles & Stage Settings

PRISMA Impact: HIGH (direct PRISMA data)

Phase 13 adds the screeningOutcomes[] array to the Study entity and creates screening profiles. This is the data structure that feeds PRISMA boxes 4-5 (title/abstract screening) and boxes 8-9 (full-text screening).

Constraints:

  • MUST: Add screeningOutcomes[] array to Study entity per study-lifecycle-and-source-taxonomy.md Section 2 specification
  • MUST: Each screening outcome records: profileId, stageId, result (Included/Excluded), primaryExclusionReason, resolvedAt, authority (CandidateAgreement/Reconciled)
  • MUST: Screening profile result is per-profile (NOT a single Study-level screening status) -- each profile in the pipeline produces its own independent outcome
  • MUST NOT: Add a single Study-level screeningStatus field -- this violates the multi-profile architecture that enables multi-stage PRISMA screening (boxes 4-5 vs. 8-9)

Cross-references: - study-lifecycle-and-source-taxonomy.md Sections 2, 7 (ScreeningOutcome model, edge cases)


Phase 14: Stage Filtering

PRISMA Impact: Medium

Phase 14 implements stage study pools with configurable filter rules. Pool membership tracking is essential for accurate "records screened" counts in PRISMA boxes 4 and 8.

Constraints:

  • MUST: Stage study pools track pool entry for accurate "records screened" counting (PRISMA box 4: dbr_screened = number of records that entered the title/abstract screening pool)
  • MUST: Pool membership is derivable from filter rules for count verification -- pool counts MUST match the result of re-running filter rules against the study collection
  • SHOULD: Pool entry events are timestamped to enable temporal PRISMA reporting (when were records screened, not just how many)

Cross-references: - prisma-flow-diagram-mapping.md Section 3.2, boxes 4, 8 (screening count derivation)


Phase 15: Screening Annotations & Reconciliation

PRISMA Impact: HIGH (direct PRISMA data)

Phase 15 implements structured exclusion reasons and screening reconciliation. This is the phase that produces the data for PRISMA box 9 (reports excluded with reasons) and determines the authority of screening outcomes.

Constraints:

  • MUST: Implement structured exclusion reasons with primaryReason field -- this directly feeds PRISMA box 9 (dbr_excluded, broken down by exclusion reason category)
  • MUST: FinalScreeningOutcome uses the ScreeningAuthority enum (CandidateAgreement, Reconciled) to record how the screening decision was determined
  • MUST: Exclusion reasons are categorized and countable for PRISMA "Reports excluded with reasons" breakdown -- free-text-only reasons are not PRISMA-compatible
  • MUST: Screening reconciliation produces the authoritative screeningOutcome on Study (the array entry's authority field is set to Reconciled when reconciliation determines the outcome)
  • MUST NOT: Store exclusion reasons in a free-text-only format -- PRISMA requires categorized, countable exclusion reasons for the box 9 breakdown

Cross-references: - study-lifecycle-and-source-taxonomy.md Sections 2, 4 (ScreeningOutcome model, derivation rules for boxes 5, 9)


Phase 16: Release 3 Migration, Data Export & PRISMA

PRISMA Impact: CRITICAL (PRISMA implementation)

Phase 16 is the culmination of all PRISMA work. It backfills lifecycle statuses, migrates screening data, and implements the PRISMA flow diagram generation. Every prior constraint converges here.

Constraints:

  • MUST: Backfill lifecycleStatus = Active on ALL existing studies (MIG-11) -- studies created before Phase 12 do not have lifecycle status; they default to Active
  • MUST: Migrate existing screening decisions to screeningOutcomes[] format (MIG-12) -- legacy screening data stored in the old format must be converted to the per-profile ScreeningOutcome model
  • MUST: Populate sourceType on SystematicSearches where determinable from LibraryFileType (MIG-13), using the inference table from study-lifecycle-and-source-taxonomy.md Section 5.4 (at minimum: PubmedXml -> Database)
  • MUST: Migrate stage settings from legacy booleans to unified schema (MIG-14)
  • MUST: Implement PRISMA flow diagram generation using ALL derivation rules from prisma-flow-diagram-mapping.md Sections 3.1-3.3
  • MUST: Validate all 34 PRISMA fields are correctly derivable using the validation queries in this document (Section 5)
  • MUST: Export PRISMA data as structured JSON/CSV (EXP-05)
  • MUST: Export dedup report with canonical mappings and confidence scores (EXP-06)
  • MUST NOT: Assume all SystematicSearches will have sourceType populated -- some will remain null for legacy data where the source type cannot be inferred; null sourceType must be handled gracefully in PRISMA generation (counted separately or grouped with "Other")

Cross-references: - ALL specification documents in this directory -- Phase 16 must satisfy constraints from all four specifications


Release Validation Checklists

Release 1 Checklist

All items must pass before R1 deployment.

  • SystematicSearch entity has nullable sourceType field (SearchSourceType?)
  • SystematicSearch entity has nullable sourceName field (string?)
  • Study document schema has NO fields that conflict with planned PRISMA additions: lifecycleStatus, screeningOutcomes[], duplicateGroupId, publicationId, citations[], fullTextStatus
  • No fields on Study named status, state, or lifecycle (reserved for StudyLifecycleStatus)
  • No fields on SystematicSearch named type or category (reserved for SearchSourceType)
  • Verify: db.pmStudy.findOne({}, {lifecycleStatus: 1, screeningOutcomes: 1, duplicateGroupId: 1}) returns null for all three fields (not yet populated)

Release 2 Checklist

All items must pass before R2 deployment.

  • Study classification fields (if any added by Phase 11) do NOT use names from the StudyLifecycleStatus enum (Active, Duplicate, PendingDuplicateReview, FullTextSought, FullTextNotRetrieved, Included, Merged, RemovedByAutomation, RemovedOther)
  • ReconciliationSession data model does NOT overwrite Study.screeningOutcomes
  • Authority patterns (CandidateAgreement, Reconciled) are consistent between annotation reconciliation and screening reconciliation
  • No field on Study stores a single screening outcome that would conflict with per-profile screeningOutcomes[]
  • StageActivity.Reconcile permission supports both annotation and screening reconciliation

Release 3 Checklist

All items must pass before R3 deployment. This is the most extensive checklist because Release 3 delivers the PRISMA implementation.

Lifecycle & Status: - [ ] lifecycleStatus field on Study uses StudyLifecycleStatus enum values exactly as specified (Active=0, Duplicate=1, PendingDuplicateReview=2, FullTextSought=3, FullTextNotRetrieved=4, Included=5, Merged=6, RemovedByAutomation=7, RemovedOther=8) - [ ] ALL existing studies have lifecycleStatus backfilled (default: Active) - [ ] Duplicate and Merged studies are excluded from ALL stage study pools

Screening Outcomes: - [ ] screeningOutcomes[] on Study matches ScreeningOutcome schema: { profileId, stageId, result, primaryExclusionReason, resolvedAt, authority } - [ ] Existing screening decisions migrated to screeningOutcomes[] format - [ ] FinalScreeningOutcome has structured exclusion reasons (NOT free-text only) - [ ] Exclusion reasons groupable by primaryReason for PRISMA box 9 counts

Publication & Citation: - [ ] pmPublication collection exists with DOI (unique sparse) and PMID (unique sparse) indexes - [ ] Citation entity has ALL specified fields: rawTitle, rawAuthors, rawDoi, rawPages, rawVolume, rawIssue, rawIsbn, rawAbstract, sourceType, sourceName, systematicSearchId, publicationId, importedAt - [ ] ALL Citations are immutable (verify no update operations on Citation fields) - [ ] Duplicate count derivable: COUNT(citations) - COUNT(DISTINCT studies WHERE lifecycleStatus NOT IN (Duplicate, Merged))

Source Types: - [ ] sourceType populated on SystematicSearches for new imports - [ ] sourceType backfilled where determinable from LibraryFileType (at minimum: PubmedXml -> Database)

PRISMA Reporting: - [ ] PRISMA flow diagram generates correctly from: lifecycle counts + screening outcome aggregations + import record counts - [ ] All 34 PRISMA fields derivable via queries documented in prisma-flow-diagram-mapping.md Section 3 - [ ] Source column assignment works: Database/Register sources -> Column 1, all others -> Column 2

Audit & Compliance: - [ ] DedupAuditLog captures all dedup decisions (auto and admin) - [ ] Duplicate/Merged studies excluded from all stage study pools - [ ] Dedup report exportable with canonical mappings and confidence scores


Validation Procedures

How to Validate Release 1 Checklist

1. Verify sourceType field exists on SystematicSearch:

// Field should exist and be null (not yet populated)
db.pmSystematicSearch.findOne({}, { sourceType: 1, sourceName: 1 })
// Expected: { _id: ..., sourceType: null, sourceName: null }

2. Verify no conflicting fields on Study:

// Check for field name conflicts with planned PRISMA additions
var study = db.pmStudy.findOne();
var conflictingFields = ['lifecycleStatus', 'screeningOutcomes', 'duplicateGroupId',
  'publicationId', 'citations', 'fullTextStatus'];
conflictingFields.forEach(function(f) {
  if (study.hasOwnProperty(f)) {
    print('CONFLICT: Study already has field ' + f);
  } else {
    print('OK: ' + f + ' not present (expected)');
  }
});

3. Verify no reserved field names on Study:

// These names are reserved for StudyLifecycleStatus
var reserved = ['status', 'state', 'lifecycle'];
var study = db.pmStudy.findOne();
reserved.forEach(function(f) {
  if (study.hasOwnProperty(f)) {
    print('CONFLICT: Study has reserved field name ' + f);
  } else {
    print('OK: ' + f + ' not present (expected)');
  }
});

How to Validate Release 2 Checklist

1. Verify no lifecycle name conflicts:

// Check that no study classification field uses lifecycle enum names
var lifecycleNames = ['Active', 'Duplicate', 'PendingDuplicateReview', 'FullTextSought',
  'FullTextNotRetrieved', 'Included', 'Merged', 'RemovedByAutomation', 'RemovedOther'];
// Grep codebase for these as field names (not enum references)
# Code search: verify no Study field uses lifecycle status names
grep -rn "lifecycleStatus\|screeningStatus\|studyStatus" \
  src/libs/project-management/SyRF.ProjectManagement.Core/Model/Study.cs

2. Verify ReconciliationSession independence:

# Verify ReconciliationSession does NOT write to screeningOutcomes
grep -rn "screeningOutcomes" \
  src/libs/project-management/SyRF.ProjectManagement.Core/Model/ReconciliationSession.cs \
  src/services/project-management/
# Expected: no matches in reconciliation code

How to Validate Release 3 Checklist

1. Verify lifecycle status backfill:

// All studies should have lifecycleStatus
var total = db.pmStudy.countDocuments({});
var withStatus = db.pmStudy.countDocuments({ lifecycleStatus: { $exists: true } });
var withoutStatus = db.pmStudy.countDocuments({ lifecycleStatus: { $exists: false } });
print('Total: ' + total + ', With status: ' + withStatus + ', Without: ' + withoutStatus);
// Expected: withoutStatus = 0

2. Verify pmPublication collection and indexes:

// Check collection exists and has correct indexes
db.pmPublication.getIndexes().forEach(function(idx) {
  print(JSON.stringify(idx.key) + ' unique:' + idx.unique + ' sparse:' + idx.sparse);
});
// Expected: doi_1 (unique, sparse), pmid_1 (unique, sparse)

3. Verify Citation immutability:

# No update operations should target Citation sub-fields
grep -rn "citations\.\$\[" \
  src/libs/project-management/SyRF.ProjectManagement.Mongo.Data/Repositories/
# Expected: no matches (Citations are never updated after creation)

4. Verify PRISMA box derivation:

// Box 3: Duplicate count
var importCount = db.pmStudy.aggregate([
  { $unwind: "$citations" },
  { $count: "total" }
]).next().total;

var activeStudyCount = db.pmStudy.countDocuments({
  lifecycleStatus: { $nin: [1, 6] }  // Not Duplicate, not Merged
});

var duplicateCount = importCount - activeStudyCount;
print('Import records: ' + importCount + ', Active studies: ' + activeStudyCount +
      ', Duplicates (box 3): ' + duplicateCount);

5. Verify screening outcome structure:

// Verify screeningOutcomes array structure
db.pmStudy.findOne(
  { "screeningOutcomes.0": { $exists: true } },
  { "screeningOutcomes": 1 }
);
// Each entry should have: profileId, stageId, result, primaryExclusionReason, resolvedAt, authority

6. Verify exclusion reason categorization:

// Exclusion reasons must be groupable by primaryReason
db.pmStudy.aggregate([
  { $unwind: "$screeningOutcomes" },
  { $match: { "screeningOutcomes.result": "Excluded" } },
  { $group: { _id: "$screeningOutcomes.primaryExclusionReason", count: { $sum: 1 } } },
  { $sort: { count: -1 } }
]);
// Expected: categorized reasons, not free-text

7. Verify source type backfill:

// Check sourceType population
var total = db.pmSystematicSearch.countDocuments({});
var withType = db.pmSystematicSearch.countDocuments({ sourceType: { $ne: null } });
var withoutType = db.pmSystematicSearch.countDocuments({ sourceType: null });
print('Total: ' + total + ', With sourceType: ' + withType + ', Without: ' + withoutType);
// Some null is acceptable (legacy data where type cannot be inferred)

8. Verify stage pool exclusion:

# Verify pool queries exclude Duplicate and Merged studies
grep -rn "lifecycleStatus" \
  src/libs/project-management/SyRF.ProjectManagement.Mongo.Data/Repositories/
# Expected: pool queries filter by lifecycleStatus != Duplicate, != Merged

Summary: PRISMA Impact by Phase

Phase Release PRISMA Impact MUST Constraints MUST NOT Constraints
3 R1 Low 1 0
4 R1 None 0 0
5 R1 None 0 0
6 R1 None 0 0
7 R1 Medium 2 2
8 R2 Low 1 0
9 R2 Low 1 2
10 R2 Low 0 1
11 R2 Medium 1 2
12 R3 HIGH 12 2
13 R3 HIGH 3 1
14 R3 Medium 2 0
15 R3 HIGH 4 1
16 R3 CRITICAL 8 1

Total constraints: 35 MUST, 12 MUST NOT, 10 SHOULD


Document created: 2026-02-17 Part of: PRISMA 2020 Specification & Data Model Constraints