Skip to content
Merged
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
5 changes: 3 additions & 2 deletions .agents/skills/protocol-migration/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ You may normalize formatting only when the meaning is unchanged and unambiguous:
- Standardize chemical formulas with HTML subscripts, for example H2O to H<sub>2</sub>O. Similarly for other chemical formulas (e.g. MgCl2 to MgCl<sub>2</sub>).
- Do not use Unicode subscript characters such as `₂`.
- Standardize `RNAseq` or `RNA-Seq` to `RNA-seq`. Same for `ChIP-seq`, `ATAC-seq`, etc.
- Use numbered lists for procedural actions in sequence. For other non-procedural content, bullets are better. Note-like text such as Note, NB, Optional, Recommended, and Warning should use blockquote style such as `> **Note**`.
- Normalize bullet formatting and markdown table formatting.
- Normalize heading structure to match the repository template.
- For reaction mixes and anything tabular, place them inside a table as in template.
- Normalize markdown headings, bullets, and tables.
- "Note" or "NOTE" or "Optional" or "Recommended" or "Warning" are normalized to start with `>` (example `> **Note**`) and are placed immediately after the step they refer to, or at the end of the protocol if they clearly refer to the whole protocol.
- "Note" or "NOTE" or "NB" or "Optional" or "Recommended" or "Warning" are normalized to start with `>` (example `> **Note**`) and are placed immediately after the step they refer to, or at the end of the protocol if they clearly refer to the whole protocol.
- Remove empty columns from tables.
- Synchronize `Contents` with actual headings in the protocol.

Expand Down Expand Up @@ -82,7 +83,7 @@ You may normalize formatting only when the meaning is unchanged and unambiguous:
- add `# Migration notes` including:
- imported protocol metadata from `source-metadata.yml` if present
- imported protocol metadata from `source-metadata.yml` using only the non-blank lines
- template metadata from `template-metadata.yml`
- template_version from `template-metadata.yml`
- ambiguous mappings
- normalized formatting changes
- content copied verbatim but not confidently placed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ You may normalize formatting only when the meaning is unchanged and unambiguous:
- Standardize chemical formulas with HTML subscripts, for example H2O to H<sub>2</sub>O. Similarly for other chemical formulas (e.g. MgCl2 to MgCl<sub>2</sub>).
- Do not use Unicode subscript characters such as `₂`.
- Standardize `RNAseq` or `RNA-Seq` to `RNA-seq`. Same for `ChIP-seq`, `ATAC-seq`, etc.
- Use numbered lists for procedural actions in sequence. For other non-procedural content, bullets are better. Note-like text such as Note, NB, Optional, Recommended, and Warning should use blockquote style such as `> **Note**`.
- Normalize bullet formatting and markdown table formatting.
- Normalize heading structure to match the repository template.
- For reaction mixes and anything tabular, place them inside a table as in template.
- Normalize markdown headings, bullets, and tables.
- "Note" or "NOTE" or "Optional" or "Recommended" or "Warning" are normalized to start with `>` (example `> **Note**`) and are placed immediately after the step they refer to, or at the end of the protocol if they clearly refer to the whole protocol.
- "Note" or "NOTE" or "NB" or "Optional" or "Recommended" or "Warning" are normalized to start with `>` (example `> **Note**`) and are placed immediately after the step they refer to, or at the end of the protocol if they clearly refer to the whole protocol.
- Remove empty columns from tables.
- Synchronize `Contents` with actual headings in the protocol.

Expand Down Expand Up @@ -82,7 +83,7 @@ You may normalize formatting only when the meaning is unchanged and unambiguous:
- add `# Migration notes` including:
- imported protocol metadata from `source-metadata.yml` if present
- imported protocol metadata from `source-metadata.yml` using only the non-blank lines
- template metadata from `template-metadata.yml`
- template_version from `template-metadata.yml`
- ambiguous mappings
- normalized formatting changes
- content copied verbatim but not confidently placed
Expand Down
5 changes: 3 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ You may normalize formatting only when the meaning is unchanged and unambiguous:
- Standardize chemical formulas with HTML subscripts, for example H2O to H<sub>2</sub>O. Similarly for other chemical formulas (e.g. MgCl2 to MgCl<sub>2</sub>).
- Do not use Unicode subscript characters such as `₂`.
- Standardize `RNAseq` or `RNA-Seq` to `RNA-seq`. Same for `ChIP-seq`, `ATAC-seq`, etc.
- Use numbered lists for procedural actions in sequence. For other non-procedural content, bullets are better. Note-like text such as Note, NB, Optional, Recommended, and Warning should use blockquote style such as `> **Note**`.
- Normalize bullet formatting and markdown table formatting.
- Normalize heading structure to match the repository template.
- For reaction mixes and anything tabular, place them inside a table as in template.
- Normalize markdown headings, bullets, and tables.
- "Note" or "NOTE" or "Optional" or "Recommended" or "Warning" are normalized to start with `>` (example `> **Note**`) and are placed immediately after the step they refer to, or at the end of the protocol if they clearly refer to the whole protocol.
- "Note" or "NOTE" or "NB" or "Optional" or "Recommended" or "Warning" are normalized to start with `>` (example `> **Note**`) and are placed immediately after the step they refer to, or at the end of the protocol if they clearly refer to the whole protocol.
- Remove empty columns from tables.
- Synchronize `Contents` with actual headings in the protocol.

Expand Down Expand Up @@ -73,7 +74,7 @@ When drafting a migrated protocol:
- content placed in `## Unplaced content`
- Imported protocol metadata from `source-metadata.yml` (only the non-blank lines).
- Imported protocol metadata from `source-metadata.yml` if present.
- template metadata from `template-metadata.yml`.
- template_version from `template-metadata.yml`.
- ambiguous mappings.
- normalized formatting changes.
- content copied verbatim but not confidently placed.
Expand Down
32 changes: 18 additions & 14 deletions .github/workflows/validate-protocol.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ on:
- main
paths:
- README.md
- legacy/source.txt
- scripts/validate_protocol.py
- tests/test_validate_protocol.py
- .github/workflows/validate_protocol.yml
- scripts/validate_protocol_content.py
- scripts/validate_protocol_style.py
- tests/test_validate_protocol_content.py
- tests/test_validate_protocol_style.py
- .github/workflows/validate-protocol.yml
push:
branches:
- main
paths:
- README.md
- legacy/source.txt
- scripts/validate_protocol.py
- tests/test_validate_protocol.py
- .github/workflows/validate_protocol.yml
- scripts/validate_protocol_content.py
- scripts/validate_protocol_style.py
- tests/test_validate_protocol_content.py
- tests/test_validate_protocol_style.py
- .github/workflows/validate-protocol.yml
workflow_dispatch:

jobs:
Expand All @@ -35,7 +39,7 @@ jobs:
with:
python-version: "3.11"

- name: Check whether validation should run
- name: Check whether README validation should run
id: validation_gate
run: |
set -euo pipefail
Expand All @@ -56,15 +60,15 @@ jobs:
echo "should_validate=true" >> "$GITHUB_OUTPUT"

- name: Run validator tests
if: steps.validation_gate.outputs.should_validate == 'true'
run: |
python -m unittest discover -s tests -p 'test_*.py'

- name: Run protocol validation
- name: Run content validation
if: steps.validation_gate.outputs.should_validate == 'true'
run: |
if [ -f legacy/source.txt ]; then
python scripts/validate_protocol.py README.md legacy/source.txt
else
python scripts/validate_protocol.py README.md
fi
python scripts/validate_protocol_content.py README.md

- name: Run style validation
if: steps.validation_gate.outputs.should_validate == 'true'
run: |
python scripts/validate_protocol_style.py README.md
57 changes: 30 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
4. [Step 4](#4-step-4)
5. [Step 5](#5-step-5)
6. [Step 6](#6-step-6)
7. [Buffers](#buffers)
7. [Materials](#7-materials)
8. [Migration notes](#migration-notes)

---
Expand All @@ -32,25 +32,25 @@

## 1.1 Sub-step of Step 1 TODO if Step 1 is complex

- TODO
- TODO
- TODO
1. TODO
2. TODO
3. TODO

## 1.2 Sub-step of Step 1 TODO if Step 1 is complex

- TODO
- TODO
- TODO
1. TODO
2. TODO
3. TODO

> **Note:** TODO

---

# 2. Step 2

- TODO
- TODO
- TODO
1. TODO
2. TODO
3. TODO

## Reagents / mix

Expand All @@ -66,9 +66,9 @@

# 3. Step 3

- TODO
- TODO
- TODO
1. TODO
2. TODO
3. TODO

## Program / incubation

Expand All @@ -82,19 +82,19 @@

# 4. Step 4

- TODO
- TODO
- TODO
1. TODO
2. TODO
3. TODO

> **Optional:** TODO

---

# 5. Step 5

- TODO
- TODO
- TODO
1. TODO
2. TODO
3. TODO

## Reaction setup

Expand All @@ -108,19 +108,22 @@

# 6. Step 6

- TODO
- TODO
- TODO
1. TODO
2. TODO
3. TODO

## Output / QC

- TODO
- TODO
- TODO
1. TODO
2. TODO
3. TODO

---

# 7. Buffers
# 7. Materials

## 7.1 Buffers
## 7.2 Reagents

---

Expand All @@ -131,4 +134,4 @@

## Unplaced content

## CHECK items
## CHECK items
5 changes: 3 additions & 2 deletions docs/PROMPT.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ Normalize formatting only when the meaning is unchanged and unambiguous:
- standardize chemical formulas with HTML subscripts, for example H2O to H<sub>2</sub>O and MgCl2 to MgCl<sub>2</sub>
- do not use Unicode subscript characters such as `₂`
- standardize `RNAseq` or `RNA-Seq` to `RNA-seq`, and similarly for `ChIP-seq`, `ATAC-seq`, and related names
- Use numbered lists for procedural actions in sequence. For other non-procedural content, bullets are better. Note-like text such as Note, NB, Optional, Recommended, and Warning should use blockquote style such as `> **Note**`.
- normalize bullets, headings, and markdown tables to match the repository template
- use tables for reaction mixes and other tabular content
- normalize note-like text to blockquote style, for example `> **Note**`
- normalize note-like text such as Note, NB, Optional, Recommended, and Warning to blockquote style, for example `> **Note**`
- place note-like text immediately after the step it refers to, or at the end of the protocol if it clearly refers to the whole protocol
- remove empty columns from tables
- synchronize `Contents` with the actual headings in the protocol
Expand Down Expand Up @@ -78,7 +79,7 @@ Normalize formatting only when the meaning is unchanged and unambiguous:
- Include the following in `# Migration notes`:
- imported protocol metadata from `source-metadata.yml` if present
- imported protocol metadata from `source-metadata.yml` using only the non-blank lines
- template metadata from `template-metadata.yml`
- template_version from `template-metadata.yml`
- ambiguous mappings
- normalized formatting changes
- content copied verbatim but not confidently placed
Expand Down
5 changes: 3 additions & 2 deletions docs/USING_THIS_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ The main file you must edit for protocol content is `README.md`. Do not rename t
7. Follow the guidelines in [3. General guidelines for the protocol file (`README.md`)](#3-general-guidelines-for-the-protocol-file-readmemd)
8. Commit your changes, then push.
9. Once you are happy with the result, open a pull request from `import-protocol` into `main`.
10. A validation GitHub Actions workflow will run on that pull request when `README.md` has changed. It checks the required title, status line, status legend, key headings, unresolved placeholders, and placeholder step names. If checks fail, fix them before merging into `main`.
10. A validation GitHub Actions workflow will run on that pull request when `README.md` has changed. It runs a content check for the required title, status line, status legend, key headings, unresolved placeholders, and placeholder step names, plus a style check for unit formatting. If checks fail, fix them before merging into `main`.
11. Ask for a reviewer.

> **Note:** Always check accuracy and make sure required sections, such as protocol status and the status legend, are present.
Expand Down Expand Up @@ -121,7 +121,7 @@ This route can save time. It helps keep the template structure consistent, norma
14. Follow the guidelines in [3. General guidelines for the protocol file (`README.md`)](#3-general-guidelines-for-the-protocol-file-readmemd)
15. Commit your changes, then push.
16. Once you are happy with the result, open a pull request from `import-protocol` into `main`.
17. A validation GitHub Actions workflow will run on that pull request when `README.md` has changed. It checks the required title, status line, status legend, key headings, unresolved placeholders, and placeholder step names. If `legacy/source.txt` is present, it also checks that key quantities from the source appear in `README.md`. If checks fail, fix them before merging into `main`.
17. A validation GitHub Actions workflow will run on that pull request when `README.md` has changed. It runs a content check for the required title, status line, status legend, key headings, unresolved placeholders, and placeholder step names, plus a style check for unit formatting. If checks fail, fix them before merging into `main`.
18. Ask for a reviewer.

---
Expand All @@ -141,6 +141,7 @@ Mandatory items for validation:
- a status legend row containing `[OK]`, `[?]`, and `[X]`
- a short description (`# About`)
- contents (`## Contents`)
- a materials section (`# ... Materials`)

Recommended content:

Expand Down
2 changes: 1 addition & 1 deletion docs/template-metadata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ template_authors:
- name: Ira A. Iosub
template_doi:
template_version: 1.0.0dev
template_release_date: 2026-04-10
template_release_date:
Binary file modified protocol-template.pdf
Binary file not shown.
46 changes: 8 additions & 38 deletions scripts/validate_protocol.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,15 @@
"""Validate a protocol README against template requirements and optional source text."""
"""Backward-compatible entrypoint for protocol README validation."""

from pathlib import Path
import re
import sys
from typing import Dict, List, Optional, Tuple

HEADING_RE = re.compile(r"^(#{1,6})\s+(.+?)\s*$", re.MULTILINE)
STATUS_LINE_RE = re.compile(
r"^### Status:\s+.*`\[(?:OK|\?|X)\]`.*$",
re.MULTILINE,
)
STATUS_LEGEND_RE = re.compile(
r"^\| \*\*\*Status legend\*\*\*:.*`\[OK\]`.*`\[\?\]`.*`\[X\]`.*\|$",
re.MULTILINE,
)
PLACEHOLDER_STEP_HEADING_RE = re.compile(
r"^#{1,6}\s+\d+(?:\.\d+)*(?:\.)?\s+(?:Step|Sub-step)\b.*$",
re.MULTILINE,
)
PLACEHOLDER_CONTENTS_RE = re.compile(
r"^\d+\.\s+\[Step\s+\d+\]\(#.*$",
re.MULTILINE,
)

REQUIRED_HEADINGS = [
(1, "About"),
(2, "Contents"),
]

BAD_PLACEHOLDERS = {
"TODO": re.compile(r"\bTODO\b"),
"TBD": re.compile(r"\bTBD\b"),
"XXX": re.compile(r"\bXXX\b"),
"CHECK:": re.compile(r"CHECK:"),
}

DISALLOWED_TEMPLATE_TEXT = [
"> Template repository: Click `Use this template` to create a new protocol repo. Template docs are in [docs/USING_THIS_TEMPLATE.md](https://github.com/ulelab/protocol-template/blob/main/docs/USING_THIS_TEMPLATE.md)",
]
try:
from scripts.validate_protocol_content import validate_readme as validate_content
from scripts.validate_protocol_style import validate_readme_style
except ModuleNotFoundError:
from validate_protocol_content import validate_readme as validate_content
from validate_protocol_style import validate_readme_style


def extract_headings(text: str) -> List[Tuple[int, str]]:
Expand Down Expand Up @@ -213,9 +185,7 @@ def main() -> None:
sys.exit(1)

readme = Path(sys.argv[1]).read_text(encoding="utf-8")
source = Path(sys.argv[2]).read_text(encoding="utf-8") if len(sys.argv) == 3 else None

failures = validate_readme(readme, source)
failures = validate_readme(readme)

if failures:
print("VALIDATION FAILED")
Expand Down
Loading
Loading