$npx -y skills add Aperivue/medsci-skills --skill sync-submissionAudit SSOT-to-submission drift and create journal submission manifests from canonical manuscript artifacts.
| 1 | # Sync Submission |
| 2 | |
| 3 | You help keep the canonical manuscript and journal-specific submission packages |
| 4 | from drifting apart. The skill treats `submission/{journal}/` as derived output |
| 5 | and records whether it is current, stale, or frozen. |
| 6 | |
| 7 | ## When to Use |
| 8 | |
| 9 | - Before submitting a journal package. |
| 10 | - After a journal portal or Word editor changed a submission manuscript. |
| 11 | - After rejection, before retargeting to another journal. |
| 12 | - Before `/orchestrate --e2e` marks a project as submission-ready. |
| 13 | |
| 14 | ## Inputs |
| 15 | |
| 16 | 1. Project root containing `project.yaml`, or a direct canonical manuscript path. |
| 17 | 2. Journal short name, e.g. `chest`, `ryai`, `academic_radiology`. |
| 18 | 3. Optional mode: |
| 19 | - `audit`: compare existing submission against canonical source. |
| 20 | - `build`: copy canonical source into `submission/{journal}/manuscript/` and write metadata. |
| 21 | - `freeze`: mark a package as submitted/frozen. |
| 22 | |
| 23 | ## Deterministic Script |
| 24 | |
| 25 | ```bash |
| 26 | python "${CLAUDE_SKILL_DIR}/scripts/sync_submission.py" audit --project-root . --journal chest |
| 27 | python "${CLAUDE_SKILL_DIR}/scripts/sync_submission.py" build --project-root . --journal chest |
| 28 | python "${CLAUDE_SKILL_DIR}/scripts/sync_submission.py" freeze --project-root . --journal chest --status submitted |
| 29 | ``` |
| 30 | |
| 31 | For double-blind journals, sweep author identifiers across all upload artifacts: |
| 32 | |
| 33 | ```bash |
| 34 | python "${CLAUDE_SKILL_DIR}/scripts/blind_sweep.py" \ |
| 35 | --registry _shared/authors/author_registry.yaml \ |
| 36 | --files submission/{journal}/supplementary/*.md submission/{journal}/cover_letter.md \ |
| 37 | --backup-dir .cache/blind_sweep_backup |
| 38 | ``` |
| 39 | |
| 40 | The registry is a project-local YAML mapping author identifiers (full names, native scripts, initials with/without periods, email, ORCID) to role labels (e.g., "Reviewer 1"). See `scripts/author_registry_example.yaml` for schema. Never commit a populated registry to a public repository — keep it next to the manuscript. |
| 41 | |
| 42 | ## Output Contract |
| 43 | |
| 44 | | Artifact | Path | Purpose | |
| 45 | |---|---|---| |
| 46 | | Submission metadata | `submission/{journal}/.journal_meta.json` | Source hash, status, canonical path | |
| 47 | | Sync audit | `qc/submission_sync_{journal}.json` | Drift result consumed by orchestrator | |
| 48 | | Manifest update | `artifact_manifest.json` | Submission package registry | |
| 49 | | Pre-flight gate | `qc/preflight_gate_report.json` | Aggregated halt-on-failure manifest (see "Pre-flight gate" below) | |
| 50 | | Supplement structure | `qc/supplement_structure.json` | Gate 14: index↔file 1:1, sub-section gaps, callout coverage | |
| 51 | |
| 52 | ## Pre-flight gate (single command — last step before freeze) |
| 53 | |
| 54 | Run this once, right before `freeze`/submission. It orchestrates the existing |
| 55 | deterministic checks and the `/verify-refs` audit into one halt-on-failure gate, |
| 56 | writes a single aggregated manifest (`qc/preflight_gate_report.json`), and exits |
| 57 | **non-zero** so a build wrapper or CI step can stop the freeze. It shells out to |
| 58 | the per-check scripts and reimplements none of them — the halt decision is driven |
| 59 | by each sub-check's normalized exit code. |
| 60 | |
| 61 | ```bash |
| 62 | python "${CLAUDE_SKILL_DIR}/scripts/preflight_gate.py" --project-root . --journal chest |
| 63 | # add --strict to also halt on the heuristic/conditional (P1) checks |
| 64 | # add --online to make fabricated / author-mismatched references halt (PubMed/CrossRef) |
| 65 | # add --double-blind to make the asset-anonymization scan halt |
| 66 | ``` |
| 67 | |
| 68 | By default the gate **halts only on the unambiguous, deterministic errors** (P0): |
| 69 | leftover placeholder/markers (`check_placeholders.py`), undefined `[@key]` |
| 70 | citations (`check_citation_keys.py`), duplicate references (`verify_refs.py`, |
| 71 | offline-deterministic), a canonical-vs-submission hash mismatch |
| 72 | (`sync_submission.py audit`), and an internal-audit dump leaked into a |
| 73 | reviewer-facing file (`check_checklist_dump_leak.py` — see below). The heuristic or conditional checks — `check_xref`, |
| 74 | `detect_copy_divergence`, `scope_drift_check`, `cover_letter_drift_check`, |
| 75 | `cross_document_n_check`, `check_cross_artifact_stale` — **run and report as P1 |
| 76 | `warn` but do not halt** unless promoted with `--strict` or `--require ID`; |
| 77 | `check_asset_anonymization` is P1 unless `--double-blind`. A check whose inputs are |
| 78 | absent (no rendered docx, no cover letter, no copies, no journal) is recorded |
| 79 | `skipped`, never a blocker. Exit codes: `0` clean, `1` halt (≥1 blocker), `2` gate |
| 80 | config error (e.g. a `--require`'d check could not run). |
| 81 | |
| 82 | The gate's offline references pass is the deterministic subset (duplicates + |
| 83 | pagination placeholders); an online `/verify-refs --strict` against PubMed/CrossRef |
| 84 | remains the authoritative fabrication and author-name check before submission. |
| 85 | |
| 86 | **Audit-dump leak check (P0).** A `/check-reporting` or `/self-review` report is an *internal working audit* |