Contributor Guide
1. Introduction
This guide covers everything a contributor needs to author and maintain documentation for the PCR Analysis System. It is the central entry point for documentation work: repository layout, Docusaurus mechanics, version management, traceability, and validation.
Audience: Developers, QA engineers, and LLM agents working on requirements, design, or test documentation.
Scope:
- Repository structure and directory conventions
- Docusaurus frontmatter, sidebar config, linking, images, and diagrams
- Version management and snapshot workflow
- Code-to-documentation traceability (code_tags.json)
- Validation commands and pre-commit checklists
Out of scope: STD/testing workflows are covered by the Dev Testing Guide. SRS and SDS authoring formats are covered by their respective detail guides:
- SRS Authoring Guide -- classification taxonomy, document format, operations
- SDS Authoring Guide -- design document format, principles, operations
2. Getting Started
Prerequisites
- Node.js >= 20
Commands
# Install dependencies
cd docusaurus && npm install
# Start local dev server (hot reload)
npm start
# Production build (validates all links)
npm run build
# Serve production build locally
npm run serve
A successful npm run build with 0 broken link warnings is the primary quality gate. Run it before every commit.
3. Repository Layout
docusaurus/
├── docs/ # Current working version (edit here)
│ ├── srs/ # SRS domain files (29)
│ │ ├── introduction.md
│ │ ├── analytics.md
│ │ ├── kitcfg.md
│ │ └── ...
│ ├── srs/rules/ # SRS rule files (61)
│ │ ├── rules.md # Rule index page
│ │ ├── rule-adj.md
│ │ ├── rule-amb.md
│ │ └── ...
│ ├── sds/ # SDS files (34 total)
│ │ ├── sds-01-introduction.md # Template & conventions (frozen)
│ │ ├── sds-02-system-context.md
│ │ ├── sds-03-architecture-overview.md
│ │ ├── sds-04-data-architecture.md
│ │ ├── sds-05-security-architecture.md
│ │ ├── sds-06-cross-cutting.md
│ │ ├── sds-master-index.md
│ │ ├── domains/ # 14 domain design docs
│ │ ├── rules/ # 8 rule design docs
│ │ ├── reference/ # 4 reference docs (API, config, DB, glossary)
│ │ └── traceability/ # Coverage tracking
│ ├── std/ # STD files (91)
│ │ ├── std-test-plan.md
│ │ ├── std-ui-testability.md # NOTE: at std/ root, not std/domains/
│ │ ├── domains/ # 29 domain test docs
│ │ └── rules/ # 60 rule test docs
│ ├── guides/ # This guide and others
│ └── traceability/ # Known issues, traceability, coverage
├── versioned_docs/ # Frozen version snapshots (do NOT edit)
│ └── version-3.0.0/
├── versioned_sidebars/
│ └── version-3.0.0-sidebars.json
├── static/media/ # Images and assets
├── sidebars.js # Manual sidebar configuration
├── docusaurus.config.js # Site configuration
└── versions.json # Version registry
versioned_docs/-- Frozen release snapshots. Do not edit unless deliberately replacing a version.sdd/-- Deprecated legacy design documents. Retained for reference only; all new design content goes insds/.
4. Version Management
How It Works
Docusaurus uses directory-based versioning:
| Directory | Version | URL Path |
|---|---|---|
docs/ | Working "Next" version | /next/ |
versioned_docs/version-3.0.0/ | Frozen v3.0.0 release | / (root, current default) |
The docusaurus.config.js docs.versions block controls which version is served at which URL. Currently, v3.0.0 is served at the site root and "Next" is served at /next/.
Creating a Version Snapshot
cd docusaurus
npx docusaurus docs:version X.Y.Z
This creates:
versioned_docs/version-X.Y.Z/-- frozen copy ofdocs/versioned_sidebars/version-X.Y.Z-sidebars.json-- frozen sidebar configuration
After Snapshotting
Update docusaurus.config.js to configure the new version's label and URL path:
// In docusaurus.config.js → docs.versions
versions: {
current: {
label: 'Next',
path: 'next',
},
'X.Y.Z': {
label: 'X.Y.Z',
path: '/',
},
// older versions...
},
When to Snapshot
- Before a product release, after documentation is finalized
- After completing a major documentation milestone (e.g., SDS creation, STD reconciliation)
- Use semantic versioning matching the product release:
3.0.0,3.1.0,3.0.1
Replacing an Existing Snapshot
To update a frozen version: delete the old versioned_docs/version-X.Y.Z/ directory and sidebar file, copy fresh docs/ content in, restore the version in versions.json, and rebuild. See the Docusaurus versioning docs for detailed steps.
5. Docusaurus Mechanics
5.1 Frontmatter
Every documentation file requires YAML frontmatter:
---
title: "Human-readable title"
description: "One sentence summary for SEO/meta"
sidebar_position: N
---
| Field | Required | Guidelines |
|---|---|---|
title | Yes | Title Case, max ~40 characters for clean sidebar rendering. Can abbreviate the H1. |
description | Yes | One sentence, 10-20 words. Describe what the document covers. Include key terms for search. |
sidebar_position | Yes | Integer determining order within its category. See Section 5.2 and Section 7 for ranges. |
5.2 Sidebar Configuration
The sidebar is 100% manually configured in docusaurus/sidebars.js. Every new file must be explicitly added or it will not appear in navigation.
Document IDs are the file path relative to docs/ without the .md extension:
| File Path | Document ID |
|---|---|
docs/srs/analytics.md | srs/analytics |
docs/srs/rules/rule-adj.md | srs/rules/rule-adj |
docs/sds/domains/sds-domain-kitcfg.md | sds/domains/sds-domain-kitcfg |
docs/guides/contributor-guide.md | guides/contributor-guide |
docs/traceability/known-issues.md | traceability/known-issues |
Sidebar structure (abbreviated):
const sidebars = {
srsSidebar: [
'srs/introduction',
{ type: 'category', label: 'Run Management', items: ['srs/upload-runs', ...] },
{ type: 'category', label: 'Analysis & Rules', items: ['srs/analytics', ...] },
{ type: 'category', label: 'User Interface', items: ['srs/ui', ...] },
{ type: 'category', label: 'Configuration', items: ['srs/kitcfg', ...] },
{ type: 'category', label: 'User & Audit', items: ['srs/user-management', ...] },
{ type: 'category', label: 'Reference', items: ['srs/nfr'] },
{ type: 'category', label: 'Rule Definitions', collapsed: true, items: [...] },
],
sdsSidebar: [
'sds/sds-01-introduction',
{ type: 'category', label: 'System Architecture', collapsed: false, items: [...] },
{ type: 'category', label: 'Domain Design', collapsed: true, items: [...] },
{ type: 'category', label: 'Rules Design', collapsed: true, items: [...] },
{ type: 'category', label: 'Reference', items: [...] },
{ type: 'category', label: 'Traceability', items: [...] },
],
stdSidebar: [
'std/std-introduction',
'std/std-test-plan',
{ type: 'category', label: 'Test Infrastructure', items: [...] },
{ type: 'category', label: 'Domain Tests', collapsed: true, items: [...] },
{ type: 'category', label: 'Rule Tests', collapsed: true, items: [...] },
{ type: 'category', label: 'Reference', items: [...] },
],
guidesSidebar: [
{ type: 'category', label: 'Guides', collapsed: false, items: [...] },
],
};
Adding a new file to the sidebar:
- Create the file with correct frontmatter
- Determine the document ID (path without
docs/prefix and.mdsuffix) - Add the ID to the appropriate category array in
sidebars.js - Run
npm run buildto verify
Position ranges by document type:
| Document Type | Position Range | Category |
|---|---|---|
| SRS | 1 | Introduction |
| SRS | 10-19 | Run Management |
| SRS | 20-29 | Analysis & Rules |
| SRS | 30-39 | User Interface |
| SRS | 40-49 | Configuration |
| SRS | 50-59 | User & Audit |
| SRS | 90-99 | Reference |
| SRS Rules | 1-62 | Alphabetical by rule name |
| SDS | 1-9 | System Architecture (Tier 1) |
| SDS | 10-29 | Domain Design (Tier 2) |
| SDS | 30-49 | Rules Design (Tier 2) |
| SDS | 50-59 | Reference (Tier 3) |
| SDS | 60-69 | Traceability (Tier 4) |
| SDS | 90 | Master Index |
When sidebars.js uses explicit item arrays, the array order takes precedence over sidebar_position in frontmatter. Both should agree, but the array is authoritative.
5.3 Links and Anchors
Relative Path Rules
All internal links use relative paths based on the source file's location:
| Source File Location | Target | Link Format |
|---|---|---|
docs/guides/ | SRS file | ../srs/kitcfg.md |
docs/guides/ | SDS domain doc | ../sds/domains/sds-domain-kitcfg.md |
docs/srs/ | SDS file | ../sds/sds-03-architecture-overview.md |
docs/srs/ | STD file | ../std/std-test-plan.md |
docs/sds/domains/ | SRS file | ../../srs/analytics.md |
docs/sds/domains/ | Sibling SDS domain | ./sds-domain-audit.md |
docs/sds/domains/ | SDS root file | ../sds-03-architecture-overview.md |
docs/sds/domains/ | SDS reference | ../reference/sds-ref-config.md |
docs/sds/domains/ | SDS rules | ../rules/sds-rules-engine.md |
Use absolute paths only for static assets (images served from /media/).
Anchor Format
Headers generate automatic anchors, but explicit anchors are recommended for REQ headers to ensure stability:
## REQ-KITCFG-001: Configuration Validation \{#req-kitcfg-001}
Anchors are lowercase with hyphens: #req-kitcfg-001 (not #REQ-KITCFG-001).
File Naming Gotchas
SRS filenames do not always match domain codes:
| Domain Code | Actual Filename | Common Mistake |
|---|---|---|
| AUDIT | audit-log.md | audit.md |
| USERMGMT | user-management.md | usermgmt.md |
| RUNFILE | runfile-list.md and runfile-report.md | runfile.md |
Helper Scripts
# Add explicit anchors to REQ headers (idempotent, safe to run repeatedly)
python docusaurus/scripts/add-req-anchors.py --dry-run # Preview
python docusaurus/scripts/add-req-anchors.py # Apply
# Convert bare Jira references to linked format
./docusaurus/scripts/link-jira-refs.sh -n # Dry-run preview
./docusaurus/scripts/link-jira-refs.sh # Apply
fix-docusaurus-links.py is NOT idempotent. Running it multiple times corrupts paths. Always run git restore docusaurus/docs/ before using it:
git restore docusaurus/docs/
python docusaurus/scripts/fix-docusaurus-links.py --docs-root docusaurus/docs --dry-run
python docusaurus/scripts/fix-docusaurus-links.py --docs-root docusaurus/docs --apply
5.4 Images and Media
- Place new images in
docusaurus/static/media/with descriptive filenames - Images are served at
/media/filename.png(absolute path) - Use absolute paths for static assets in markdown:

The Docusaurus preprocessor in docusaurus.config.js automatically rewrites legacy image paths (../../pilot/restructured/adocs/media/ and similar) to /img/. SDD images are routed to /img/sdd/ to avoid filename collisions.
5.5 Mermaid Diagrams
Mermaid is enabled globally via the @docusaurus/theme-mermaid plugin.
Primary diagram types:
| Type | Use For |
|---|---|
flowchart TD / flowchart LR | Decision logic, algorithms, workflows |
erDiagram | Entity relationships, data models |
sequenceDiagram | Interaction flows between components |
graph TB / graph LR | Component architecture, dependencies |
stateDiagram-v2 | State machines |
Conventions:
- SRS files: one diagram near the top of the file, section titled "Behavior Overview (Illustrative)" or "Rule Flowchart (Illustrative)"
- SDS files: multiple diagrams per file (dependencies, components, ERD, algorithms)
- Always mark illustrative diagrams explicitly -- never use "non-normative"
Syntax gotchas:
| Issue | Wrong | Correct |
|---|---|---|
| Pipe chars in labels | `{ | CT |
| Forward slashes in labels | Node[/api/runs] | Node["/api/runs"] |
| Node ID = subgraph ID | Causes cycle errors | Use distinct IDs |
Special chars (@, ()) | Unquoted in labels | Quote the label |
| Cross-subgraph connections | Inside subgraph block | Define outside subgraph blocks |
Validation:
bash docusaurus/scripts/validate-mermaid.sh docusaurus/docs
This script uses the exact mermaid version bundled with Docusaurus (docusaurus/node_modules/mermaid) to ensure zero version drift.
6. Traceability and Code Linking
6.1 Code Mapping Registry
Code-to-documentation traceability is maintained in a single JSON registry rather than inline code comments.
Registry location: tests/catalogue/code_tags.json
Structure:
{
"by_file": {
"app/Http/Controllers/RunImportController.php": {
"srs": ["REQ-RUNIMPORT-012", "REQ-AUDIT-004"],
"sdd": ["sds-domain-fileimport.md#run-import-process"]
}
},
"by_srs": {
"REQ-RUNIMPORT-012": ["app/Http/Controllers/RunImportController.php", "app/Services/RunImportService.php"]
},
"by_sdd": {
"sds-domain-fileimport.md#run-import-process": ["app/Http/Controllers/RunImportController.php"]
}
}
Keys:
| Key | Usage |
|---|---|
by_file | File path to its SRS and SDS references |
by_srs | REQ ID to all implementing code files |
by_sdd | SDS anchor to all implementing code files |
Mappings are many-to-many: one code file can reference multiple REQs, and one REQ can be mapped to multiple code files.
6.2 What to Map
Add entries for these (navigation anchor points):
| Category | Examples | Why |
|---|---|---|
| Entry points | HTTP controllers, API routes, CLI commands | User-facing boundaries |
| Queue workers | Jobs, event listeners | Async processing entry points |
| Core domain services | RulesEngine, RunImportService | Business logic centers |
| Persistence boundaries | Migrations with logic, repositories | Data layer decisions |
| Integration boundaries | S3, SES, Pusher, Cognito handlers | External system touchpoints |
Do NOT add entries for these:
| Category | Examples | Why |
|---|---|---|
| Utilities | String helpers, formatters | No direct requirement mapping |
| Simple CRUD | Basic model accessors | Too granular |
| Presentational | Blade templates, simple Vue components | UI layer, not behavior |
| Config files | .env, config/*.php | Not code boundaries |
6.3 Unified Traceability System
The project uses an auto-generated unified traceability system that replaces the old hand-maintained matrices.
Source of truth: tests/catalogue/unified-traceability.json -- a single JSON file that maps every REQ to its SDS design sections, STD test vectors, Behat feature files, and code mappings.
Generated views (3 Markdown files, do not edit manually):
| File | Content |
|---|---|
docusaurus/docs/traceability/unified-traceability-matrix.md | Full REQ-to-test mapping (site homepage) |
docusaurus/docs/traceability/unified-coverage-report.md | Coverage metrics and gap analysis |
docusaurus/docs/traceability/unified-release-checklist.md | Test inventory for release validation |
Regeneration command:
python3 docusaurus/scripts/generate-unified-traceability.py --render-md
Run this after any STD, SDS, or code_tags.json changes.
6.4 Bidirectional Maintenance
Traceability flows in both directions and both sides must stay in sync:
| Direction | Mechanism | Location |
|---|---|---|
| Code to Docs | Entries in code_tags.json | tests/catalogue/code_tags.json |
| Docs to Code | Implementation sections in SRS files | ## Implementation (Illustrative) |
When code moves or requirements change, update both sides:
- Update the entry in
tests/catalogue/code_tags.json(add, move, or remove file paths and REQ IDs) - Update the Implementation section in the corresponding SRS file
- Update the Implementation Mapping section (section 8) in the corresponding SDS domain doc
- Regenerate unified traceability:
python3 docusaurus/scripts/generate-unified-traceability.py --render-md
6.5 Cross-References Between Docs
The documentation suite is cross-linked at multiple levels:
| From | To | Purpose |
|---|---|---|
| SRS files | SDS sections in Traceability blocks | Link requirements to design |
| SDS Requirements Covered tables | SRS REQ IDs | Map design back to requirements |
| SDS domain docs | sds-master-index.md | Navigation hub |
| SDS domain docs | sds-ref-config.md, sds-ref-database.md, etc. | Shared reference material |
| STD test docs | SRS REQ IDs | Test coverage traceability |
When adding new content, keep these linkages current:
- Update
sds-master-index.mdfor new SDS sections or documents - Update SDS reference docs (
sds-ref-api.md,sds-ref-config.md,sds-ref-database.md,sds-ref-glossary.md) for new APIs, config options, schema changes, or terms - Update the SRS Traceability Matrix for new requirements
For detailed authoring procedures, see SRS operations and SDS operations.
7. Sidebar Taxonomy & Positions
File Naming Conventions
| Document Type | Pattern | Example |
|---|---|---|
| SRS domain | {domain}.md | kitcfg.md, analytics.md |
| SRS rule | rule-{name}.md | rule-adj.md, rule-amb.md |
| SDS | sds-{topic}.md | sds-03-architecture-overview.md |
| SDS domain | sds-domain-{name}.md | sds-domain-kitcfg.md |
| SDS rule | sds-rules-{name}.md | sds-rules-engine.md |
| STD | std-{topic}.md | std-test-plan.md |
| SDD (legacy) | sdd-{topic}.md | sdd-architecture.md |
Position Ranges by Document Type
The position ranges below supplement the table in Section 5.2. STD ranges are included here for completeness.
| Doc Type | Range | Category |
|---|---|---|
| STD | 1 | Introduction |
| STD | 10-19 | Test Infrastructure |
| STD | 20-29 | Test Plans |
| STD | 90-99 | Reference (traceability, coverage) |
| SRS Rules | 1-62 | Alphabetical by rule name |
| Guides | 1+ | Ordered by audience (ops, dev, contributor) |
SRS and SDS ranges are already listed in Section 5.2.
8. Link Conventions
This section consolidates linking rules. See also Section 5.3 for relative path tables and anchor format.
Jira Reference Format
Bare Jira keys (BT-123, CST-456, PCRAI-789) should be converted to linked format:
[BT-123](https://arctichare.atlassian.net/browse/BT-123)
Auto-convert with ./docusaurus/scripts/link-jira-refs.sh (or -n for dry-run). Supported prefixes: BT-*, CST-*, PCRAI-*.
Static Asset Paths
Files in docusaurus/static/media/ are served at /media/. Always use absolute paths for images:

SDD images use /img/sdd/ to avoid filename collisions (handled by the preprocessor in docusaurus.config.js).
Code Mapping Format
Code-to-documentation traceability is maintained in tests/catalogue/code_tags.json. See Section 6.1 for the JSON structure and update workflow.
9. Validation and Quality
9.1 Validation Commands
cd docusaurus
# 1. Build -- authoritative link check (0 broken links = pass)
npm run build 2>&1 | tail -5
# 2. Mermaid diagram validation (0 errors = pass)
bash scripts/validate-mermaid.sh docs
# 3. REQ anchor check (idempotent, safe to run)
python scripts/add-req-anchors.py --dry-run
# 4. Code mapping orphan check
jq -r '.by_srs | keys[]' ../tests/catalogue/code_tags.json | sort -u > /tmp/code-refs.txt
grep -roh "REQ-[A-Z]*-[0-9]*" docs/srs/*.md docs/srs/rules/ | sort -u > /tmp/srs-ids.txt
comm -23 /tmp/code-refs.txt /tmp/srs-ids.txt
# Should return empty
9.2 Common Build Issues
| Build Warning | Cause | Fix |
|---|---|---|
couldn't be resolved on a file path | Wrong relative path | Count ../ levels from source file location |
#anchor couldn't be resolved | Header anchor missing or mismatched | Run add-req-anchors.py or add explicit {#anchor} |
../sdd/sdd-*.md couldn't be resolved | Legacy SDD reference | Update to ../sds/sds-*.md path |
| YAML error | Malformed frontmatter | Check for missing --- delimiters, unquoted special characters |
| Document not in sidebar | Missing from sidebars.js | Add document ID to correct category |
10. Checklists
The following checklists cover common documentation workflows. For the full consolidated checklist reference (including validation commands), see the Authoring Checklists Reference.
10.1 Pre-Commit Checklist
-
npm run buildproduces 0 broken link warnings -
bash docusaurus/scripts/validate-mermaid.sh docusaurus/docsproduces 0 errors -
python docusaurus/scripts/add-req-anchors.py --dry-runshows no missing anchors - No files modified in
versioned_docs/(unless intentionally replacing a snapshot) - No files modified in
sdd/(deprecated) -
sidebar_positiondoes not conflict with existing files in the same category - All new files tracked in
sidebars.js -
code_tags.jsonupdated if code changed (add/move/remove file mappings) - Cross-document references are bidirectional (docs link to code AND code links to docs)
11. Quick Reference
Domain Code Table
For the full domain-to-file mapping, see the SDS Master Index.
Validation Commands Summary
| Task | Command |
|---|---|
| Full build (authoritative) | cd docusaurus && npm run build |
| Mermaid validation | bash docusaurus/scripts/validate-mermaid.sh docusaurus/docs |
| Add REQ anchors | python docusaurus/scripts/add-req-anchors.py |
| Preview REQ anchors | python docusaurus/scripts/add-req-anchors.py --dry-run |
| Convert Jira refs | ./docusaurus/scripts/link-jira-refs.sh |
| Preview Jira refs | ./docusaurus/scripts/link-jira-refs.sh -n |
| Preview link fixes | python docusaurus/scripts/fix-docusaurus-links.py --docs-root docusaurus/docs --dry-run |
| Run all Behat tests (V3+legacy+browser) | python3 tests/scripts/behat-optimizer.py run --workers 10 --pre-migrate --rerun-failures --suite all --browser-workers 6 |
| Run V3 API tests only | python3 tests/scripts/behat-optimizer.py run --workers 10 --dir tests/exports/cucumber/v3 |
Parallel test execution: The behat-optimizer.py script consolidates feature files by identical config hash and runs them in parallel across the DB pool. Default mode runs migrate:fresh per file for correctness (~118 min, 99% pass rate). The --skip-migrate-fresh flag is faster (~28 min) but may cause FK constraint failures (~73% pass rate). See the Dev Testing Guide for full CLI reference and details.
Version tagging for tests: This is a multi-tenant medical device SaaS where clients run different versions. When a test's expected behavior differs between versions, create version-tagged scenario copies:
| Tag | When to use |
|---|---|
| (no tag) | Test passes on all versions (default — most tests) |
@V3_0_0 | Assertions specific to v3.0.0 behavior |
@V3_0_1 | Assertions specific to v3.0.1 behavior |
Only add version tags when behavior actually differs between versions. Both tagged copies share the same BT key, TV tags, and fixtures — only assertions change. The --target-version flag on behat-optimizer.py selects which version set to run (default = latest, excludes @V3_0_0). See the Dev Testing Guide for the full scheme and examples.