Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [``tests/``](tests/) - Updated ``tests/GDI-SOP0000_sop-template-for-linting.md`` to fit testing standards of the linting script.
- [``GDI-SOP_charter.md``](docs/GDI-SOP_charter.md) - Updated Glossary section with new acronyms and terms from other three SOPs.
- [``GDI-SOP_style-guide.md``](docs/GDI-SOP_style-guide.md) - Added section regarding positioning of tables in MD files.
- [``GDI-SOP0007_sop-template-creation.md``](sops/european-level/GDI-SOP0007_sop-template-creation.md) - Annual review (https://github.com/GenomicDataInfrastructure/standard-operating-procedures/pull/70).

### Fixed
- [``GDI-SOP0002_ncps-veto-edic-decision.md``](sops/node-specific/GDI-SOP0002_ncps-veto-edic-decision.md):
Expand Down
14 changes: 7 additions & 7 deletions docs/GDI-SOP_charter.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ The following table defines the abbreviations and terms relevant to GDI SOPs.


## 3. Roles and Responsibilities
| Role | Full name | GDI/node role | Organisation |
|------------|-----------------|-----------------|--------------|
| **Author** | Mallory Freeberg | Task 4.3 member | EMBL-EBI |
| **Author** | Marcos Casado Barbero | Task 4.3 member | EMBL-EBI |
| **Reviewer** | Elisavet Torstensson | Task 4.3 member | UU / NBIS |
| **Approver** | Erik Hedman | Task 4.3 member | UU / NBIS |
| **Approver** | Markus Englund | Task 4.3 member | UU / NBIS |
| Role | Full name | GDI/node role | Organisation | Notes |
|------------|-----------------|-----------------|--------------|-------|
| **Author** | Mallory Freeberg | Task 4.3 member | EMBL-EBI | |
| **Author** | Marcos Casado Barbero | Task 4.3 member | EMBL-EBI | |
| **Reviewer** | Elisavet Torstensson | Task 4.3 member | UU / NBIS | |
| **Approver** | Erik Hedman | Task 4.3 member | UU / NBIS | |
| **Approver** | Markus Englund | Task 4.3 member | UU / NBIS | |

## 4. Introduction
The [**European Genomic Data Infrastructure (GDI)**](https://gdi.onemilliongenomes.eu) project is a pioneering initiative that aims to **enable access to genomic, phenotypic, and clinical data across Europe**. This access is crucial for advancing research, policymaking, and healthcare on a continental scale. Central to this mission is the 1+ Million Genomes (1+MG) network, which encompasses a diverse array of national human data-sharing projects, each at different stages of development.
Expand Down
20 changes: 10 additions & 10 deletions docs/GDI-SOP_information-service-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ The following table defines the abbreviations and terms relevant to GDI SOPs.

## 3. Roles and Responsibilities

| Role | Full name | GDI/node role | Organisation |
| ------------ | --------------------- | --------------- | ----------------------- |
| **Author** | Mallory Freeberg | Task 4.3 member | EMBL-EBI |
| **Author** | Silvia Bahena | Task 4.3 member | EMBL-EBI |
| **Reviewer** | Jeroen Belien | GDI-Member | Health-RI/Amsterdam UMC |
| **Reviewer** | Mattias Strömberg | Task 4.3 member | UU |
| **Reviewer** | Elisavet Torstensson | Task 4.3 member | UU |
| **Reviewer** | Gabriele Rinck | Task 4.3 member | EMBL-EBI |
| **Approver** | Marcos Casado Barbero | Task 4.3 member | EMBL-EBI |
| **Approver** | Markus Englund | Task 4.3 member | UU / NBIS |
| Role | Full name | GDI/node role | Organisation | Notes |
| ------------ | --------------------- | --------------- | ----------------------- |-------|
| **Author** | Mallory Freeberg | Task 4.3 member | EMBL-EBI | |
| **Author** | Silvia Bahena | Task 4.3 member | EMBL-EBI | |
| **Reviewer** | Jeroen Belien | GDI-Member | Health-RI/Amsterdam UMC | |
| **Reviewer** | Mattias Strömberg | Task 4.3 member | UU | |
| **Reviewer** | Elisavet Torstensson | Task 4.3 member | UU | |
| **Reviewer** | Gabriele Rinck | Task 4.3 member | EMBL-EBI | |
| **Approver** | Marcos Casado Barbero | Task 4.3 member | EMBL-EBI | |
| **Approver** | Markus Englund | Task 4.3 member | UU / NBIS | |


## 4. Purpose
Expand Down
17 changes: 9 additions & 8 deletions docs/GDI-SOP_organisational-roles-and-responsibilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ Find GDI SOPs common Glossary at the [charter document](./GDI-SOP_charter.md#2-g
| SOP resources | All SOP-related documentation and processes, including but not limited to supporting documents, SOP templates and SOP instances. |

## 3. Roles and Responsibilities
| Role | Full name | GDI/node role | Organisation |
|------------|-----------------|-----------------|--------------|
| **Author** | Mallory Freeberg | Task 4.3 member | EMBL-EBI |
| **Author** | Marcos Casado Barbero | Task 4.3 member | EMBL-EBI |
| **Reviewer** | Gabriele Rinck | Task 4.3 member | EMBL-EBI |
| **Reviewer** | Markus Englund | Task 4.3 member | UU / NBIS |
| **Approver** | Gabriele Rinck | Task 4.3 member | EMBL-EBI |
| **Approver** | Markus Englund | Task 4.3 member | UU / NBIS |
| Role | Full name | GDI/node role | Organisation | Notes |
|------------|-----------------|-----------------|--------------|-------|
| **Author** | Mallory Freeberg | Task 4.3 member | EMBL-EBI | |
| **Author** | Marcos Casado Barbero | Task 4.3 member | EMBL-EBI | |
| **Reviewer** | Gabriele Rinck | Task 4.3 member | EMBL-EBI | |
| **Reviewer** | Markus Englund | Task 4.3 member | UU / NBIS | |
| **Approver** | Gabriele Rinck | Task 4.3 member | EMBL-EBI | |
| **Approver** | Markus Englund | Task 4.3 member | UU / NBIS | |

## 4. Purpose
This document outlines the roles, responsibilities, and tasks for individuals involved in the writing, implementation, management, and use of GDI SOP resources. It contributes to the framework, defined in the [Charter](./GDI-SOP_charter.md), for SOP development, review, approval, authorisation, maintenance and training within the GDI network.
Expand All @@ -51,6 +51,7 @@ The roles and responsibilities described in this document apply to:
| **Author** | European and Node level | - **Fill in content of SOP Templates** based on expertise and input from stakeholders across GDI nodes. <br> - Ensure **compliance with data policies** (e.g., GDPR). <br> - Ensure consistency with related GDI SOPs and resolve potential conflicts between documents where necessary. <br> - Take the role of "SOP Trainer" for their authored SOP Templates if required. | - Expertise in the relevant area. <br> - Strong communication and collaboration skills. <br> - Knowledge of GDPR and data handling requirements. |
| **Reviewer** | European and Node level | - **Review SOP Templates** for accuracy, compliance and consistency. <br> - Suggest improvements and ensure alignment with GDI objectives. <br> - Facilitate inter-node communication. | - Broad understanding of GDI's objectives. <br> - Detail-oriented with a critical eye for potential issues. <br> - Experience in collaborative reviews and multi-disciplinary teams. |
| **Approver** | European and Node level | - **Confirm SOP Templates readiness** post-review. <br> - **Ensure compliance** with **GDI standards and GDPR**. <br> - Document and store released SOP Templates and instances in designated platforms (i.e., GitHub). <br> - Oversee SOP lifecycle and ensure periodic reviews. | - Leadership and decision-making capabilities. <br> - Deep understanding of GDI strategic goals. <br> - Proficiency in managing project documentation platforms. <br> - Experience in document lifecycle management. |
| **Delegate** | European and Node level | - Act on behalf of a named Approver within the delegated scope and deadline. <br> - Assess the SOP's technical and operational readiness, including relevant GDI standards and data-protection requirements. <br> - Record a formal approval or justified rejection in the relevant GitHub issue or Pull Request and escalate out-of-scope concerns to the responsible Approver. | - Authority to make the delegated decision and subject-matter expertise relevant to the SOP. <br> - Ability to assess technical correctness, operational feasibility, and security or data-protection implications. <br> - Proficiency with GitHub issues and Pull Requests, Markdown SOPs, and the repository's validation workflow. |
| **Authoriser** | European level | - **Grant (or veto) official permission for SOPs to be released**. | - High-level management skills. <br> - Part of the GDI executive leadership. <br> - Understanding of GDI scope and operations. <br> - Time-management skills: where necessary, exercise veto rights within a set time period. |
| **Main repository Maintainer (OC/SDPC)** | European level | - **Oversee SOP creation and review process** for the GDI GitHub repository. <br> - **Coordinate with Authors, Reviewers, Approvers and Authorizers** to ensure SOP templates meet GDI standards. <br> - Manage version control, ensure updates are made consistently. <br> - **Conduct periodic audits** of the SOP repository to maintain quality and compliance. | - Strong project management and oversight skills. <br> - Proficiency in GitHub repository management, including version control and collaborative document handling. <br> - Comprehensive understanding of GDI operations and objectives. <br> - Ability to work effectively with multidisciplinary teams and manage stakeholder expectations. |
| **Trainer** | European and Node level | - **Conduct training** on SOP Templates for relevant stakeholders. <br> - Ensure understanding of procedures and compliance requirements. <br> - Provide updates on SOP revisions. | - In-depth knowledge of SOPs and the GDI context. <br> - Strong communication and training skills. <br> - Experience in adult education and training methodologies. |
Expand Down
18 changes: 11 additions & 7 deletions docs/GDI-SOP_sop-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,16 @@ _< Roles and responsibilities table to be completed with who is responsible to a

See qualifications and responsabilities of the roles at the [**Organisational Roles and Responsibilities**](https://github.com/GenomicDataInfrastructure/standard-operating-procedures/blob/main/docs/GDI-SOP_organisational-roles-and-responsibilities.md) document.

| Role | Full name | GDI/node role | Organisation |
|------------|-----------------|-----------------|--------------|
| Author | | | |
| Reviewer | | | |
| Approver | | | |
| Authorizer | | | |
| Role | Full name | GDI/node role | Organisation | Notes |
|------------|-----------------|-----------------|--------------|-------|
| Author | | | | |
| Reviewer | | | | |
| Approver | | | | |
| Approver | | | | |
| Approver | | | | |
| Authorizer | | | | |

_< Use an optional `Delegate` row when an Approver delegates approval. Record the relationship in both rows using `Delegated approval to <delegate full name>.` in the Approver's Notes and `Approval delegated by <approver full name>.` in the Delegate's Notes. The Delegate's Notes must name an Approver listed in the same SOP's table. >_

_< Example GDI/node roles: Legal Officer, Service Lead, Data Protection Officer, Admin Lead... >_

Expand Down Expand Up @@ -149,4 +153,4 @@ _< Include references to useful information to understand this document. >_
| [1](#) | European GDI - SOP Charter (including Glossary) |
| [2](#) | European GDI - Procedures for Information Service Management (ISM) for SOPs |
| [3](#) | European GDI - Organisational Roles and Responsibilities (ORR) |
| [4](#) | ... |
| [4](#) | ... |
51 changes: 46 additions & 5 deletions scripts/sop_linter.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,15 +278,18 @@ def lr_check_document_history(self, soup: BeautifulSoup, file_path: str):

def lr_check_roles_and_responsibilities(self, soup: BeautifulSoup, file_path: str):
"""
Checks if the Roles and Responsibilities table exists and has at least one non-empty Full Name for roles Author, Reviewer, and Approver.
Checks if the Roles and Responsibilities table exists, has the required
five-column shape, and contains the required named roles. SOPs must
list at least three distinct approvers. Optional Delegate rows must
name a different listed Approver in their Notes cell.

:param soup: BeautifulSoup object of the parsed SOP content.
:param file_path: Path to the SOP file.
"""
if self.verbosity > 1:
print("-- Linting rule: checking Roles and Responsibilities table...")

aim_headers = ["Role", "Full name", "GDI/node role", "Organisation"]
aim_headers = ["Role", "Full name", "GDI/node role", "Organisation", "Notes"]
table_find_result = self.find_tables(soup, file_path, aim_headers)

if not table_find_result:
Expand All @@ -296,25 +299,63 @@ def lr_check_roles_and_responsibilities(self, soup: BeautifulSoup, file_path: st
roles_table = table_find_result[0]
required_roles = ["Author", "Reviewer", "Approver"]
found_roles = {role: False for role in required_roles}
approver_names = {}
delegates = []

rows = roles_table.find_all('tr')[1:] # Skip the header row
for row in rows:
columns = [col.text.strip() for col in row.find_all('td')]
if len(columns) != 4:
self.report_issue(f"Roles and Responsibilities table row is incorrectly formatted (expected 4 columns): '{' | '.join(columns)}'.", file_path, error=True)
if len(columns) != 5:
self.report_issue(f"Roles and Responsibilities table row is incorrectly formatted (expected 5 columns): '{' | '.join(columns)}'.", file_path, error=True)
continue

role, full_name = columns[0], columns[1]
role, full_name, notes = columns[0], columns[1], columns[4]

# If we haven't already found one, and this one is required and has a full name value
if role in required_roles and full_name:
if not found_roles[role]:
found_roles[role] = True

if role == "Approver" and full_name:
normalised_name = re.sub(r"\s+", " ", full_name).strip().casefold()
approver_names[normalised_name] = full_name

if role == "Delegate":
if not full_name:
self.report_issue("Delegate rows must contain a non-empty Full Name.", file_path, error=True)
if not notes:
self.report_issue(f"Delegate row for '{full_name}' must contain a non-empty Notes value naming the delegating Approver.", file_path, error=True)
delegates.append((full_name, notes))

for role, found in found_roles.items():
if not found:
self.report_issue(f"Role '{role}' is missing a non-empty Full Name row in the Roles and Responsibilities table.", file_path, error=True)

if len(approver_names) < 3:
self.report_issue(
f"Roles and Responsibilities table must contain at least 3 distinct named Approvers; found {len(approver_names)}.",
file_path,
error=True
)

normalised_approvers = list(approver_names.keys())
for delegate_name, notes in delegates:
normalised_delegate = re.sub(r"\s+", " ", delegate_name).strip().casefold()
matching_approvers = [
approver_name for approver_name in normalised_approvers
if approver_name != normalised_delegate
and re.search(
rf"(?<!\w){re.escape(approver_name)}(?!\w)",
re.sub(r"\s+", " ", notes).strip().casefold()
)
]
if not matching_approvers:
self.report_issue(
f"Delegate row for '{delegate_name}' must name a different Approver from the same table in its Notes value.",
file_path,
error=True
)

if self.verbosity > 1:
print(f"{json.dumps(self.results[file_path], indent=2)}\n")

Expand Down
6 changes: 3 additions & 3 deletions sops/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
Below you can find the full list of SOPs in this repository.
| Name | Identifier | Template version | Topic | Type | GDI Node | Instance version | Nº steps | Last modified |
|:--------------------------------------------------------------------------------------------------------------------|:-------------|:-------------------|:---------------------------|:-------------------|:-----------|:-------------------|-----------:|:----------------|
| [GDI-SOP0002_ncps-veto-edic-decision.md](./node-specific/GDI-SOP0002_ncps-veto-edic-decision.md) | GDI-SOP0002 | v1 | Helpdesk & operations | Node-specific SOP | | | 7 | 2024.10.29 |
| [GDI-SOP0003_1+mg-dac-recommendation-approval.md](./european-level/GDI-SOP0003_1+mg-dac-recommendation-approval.md) | GDI-SOP0003 | v1 | Data & metadata management | European-Level SOP | | | 10 | 2024.11.11 |
| [GDI-SOP0007_sop-template-creation.md](./european-level/GDI-SOP0007_sop-template-creation.md) | GDI-SOP0007 | v1 | Helpdesk & operations | European-Level SOP | | | 7 | 2024.10.29 |
| [GDI-SOP0002_ncps-veto-edic-decision.md](./node-specific/GDI-SOP0002_ncps-veto-edic-decision.md) | GDI-SOP0002 | v1 | Helpdesk & operations | Node-specific SOP | | | 7 | 2026.07.31 |
| [GDI-SOP0003_1+mg-dac-recommendation-approval.md](./european-level/GDI-SOP0003_1+mg-dac-recommendation-approval.md) | GDI-SOP0003 | v1 | Data & metadata management | European-Level SOP | | | 10 | 2026.07.31 |
| [GDI-SOP0007_sop-template-creation.md](./european-level/GDI-SOP0007_sop-template-creation.md) | GDI-SOP0007 | v1 | Helpdesk & operations | European-Level SOP | | | 6 | 2026.07.31 |
Loading
Loading