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
11 changes: 11 additions & 0 deletions collab-supplementary-materials-guard/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "collab-supplementary-materials-guard",
"version": "1.0.0",
"description": "Deterministic supplementary-material export guard for collaborative scientific editor manuscripts.",
"type": "module",
"scripts": {
"demo": "node scripts/demo.js",
"test": "node --test test/*.test.js"
},
"license": "MIT"
}
37 changes: 37 additions & 0 deletions collab-supplementary-materials-guard/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Collaborative Supplementary Materials Guard

This module is a focused slice for SCIBASE.AI issue #12, Real-time collaborative research editor & interface.

It validates whether supplementary materials can safely ship with a collaborative manuscript export. The guard is intentionally separate from broad editor foundations, notebook execution queues, data-availability statements, statistics wording checks, alt-text accessibility, terminology governance, and table formula integrity.

## What It Checks

- Every exported supplement is cited from the manuscript.
- Exported supplement hashes match the current source artifact hashes.
- Notebook-derived supplements have fresh execution evidence.
- Restricted-data supplements have approved redaction review.
- Private reviewer or collaborator notes are not included in public exports.
- Blocking supplement comments are resolved or waived.
- Publication licenses are approved.
- Corresponding author and data steward approvals are present.
- Supplement sections are locked or snapshotted before export.

## Decisions

- `hold`: one or more blocker findings must be fixed before export.
- `revise`: no blockers, but warning-level publication readiness gaps remain.
- `export-ready`: the supplement packet is cited, fresh, approved, redacted, and locked.

## Run

```bash
npm test
npm run demo
```

## Reviewer Artifacts

- `reports/supplementary-materials-manifest.json`
- `reports/supplementary-materials-report.md`
- `reports/summary.svg`
- `reports/supplementary-materials-demo.mp4`
23 changes: 23 additions & 0 deletions collab-supplementary-materials-guard/reports/summary.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{
"generatedAt": "2026-06-05T15:10:00.000Z",
"manuscriptId": "ms-collab-neuro-042",
"decision": "hold",
"supplements": [
{
"id": "supp-figure-1",
"type": "figure-panel",
"sourceHash": "sha256:figure-current",
"exportHash": "sha256:figure-current",
"referenced": true,
"lockedAtExport": true,
"license": "CC-BY-4.0"
},
{
"id": "supp-table-2",
"type": "csv-table",
"sourceHash": "sha256:table-current",
"exportHash": "sha256:table-stale",
"referenced": true,
"lockedAtExport": false,
"license": null
},
{
"id": "supp-protocol-3",
"type": "protocol-pdf",
"sourceHash": "sha256:protocol-current",
"exportHash": "sha256:protocol-current",
"referenced": false,
"lockedAtExport": true,
"license": "institutional-approved"
}
],
"findings": [
{
"severity": "blocker",
"code": "stale-export-hash",
"supplementId": "supp-table-2",
"message": "Supplement supp-table-2 export hash does not match the current source hash.",
"remediation": "Regenerate the exported supplement from the current source artifact before publication export."
},
{
"severity": "blocker",
"code": "stale-notebook-output",
"supplementId": "supp-table-2",
"message": "Supplement supp-table-2 was generated from a notebook with stale or missing execution evidence.",
"remediation": "Re-run the notebook, attach the execution digest, and rebuild the supplement export."
},
{
"severity": "blocker",
"code": "missing-redaction-review",
"supplementId": "supp-table-2",
"message": "Supplement supp-table-2 contains restricted data without an approved redaction review.",
"remediation": "Hold export until restricted fields are redacted and the data steward approves the redaction review."
},
{
"severity": "blocker",
"code": "private-reviewer-note-leak",
"supplementId": "supp-table-2",
"message": "Supplement supp-table-2 includes private reviewer or collaborator notes in the public export.",
"remediation": "Strip private notes from the export bundle and regenerate the artifact manifest."
},
{
"severity": "blocker",
"code": "unresolved-blocking-comment",
"supplementId": "supp-table-2",
"message": "Supplement supp-table-2 has 1 unresolved blocking comment(s).",
"remediation": "Resolve or explicitly waive blocking supplement comments before export."
},
{
"severity": "warning",
"code": "license-needs-review",
"supplementId": "supp-table-2",
"message": "Supplement supp-table-2 has missing or unsupported license metadata.",
"remediation": "Attach an approved publication license or route the supplement for institutional licensing review."
},
{
"severity": "warning",
"code": "missing-export-approval",
"supplementId": "supp-table-2",
"message": "Supplement supp-table-2 is missing export approval from: data-steward.",
"remediation": "Collect the missing collaborator approvals before marking the manuscript export-ready."
},
{
"severity": "warning",
"code": "unlocked-supplement-section",
"supplementId": "supp-table-2",
"message": "Supplement supp-table-2 remains editable while the export packet is being prepared.",
"remediation": "Lock the supplement section or create a named version snapshot before export."
},
{
"severity": "blocker",
"code": "unreferenced-supplement",
"supplementId": "supp-protocol-3",
"message": "Supplement supp-protocol-3 is present in the export packet but not cited by the manuscript.",
"remediation": "Add a stable manuscript citation for the supplement or remove it from the export bundle."
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Supplementary Materials Export Report

Generated: 2026-06-05T15:10:00.000Z

Manuscript: `ms-collab-neuro-042`

Decision: `hold`

## Summary

- Supplements checked: 3
- Blockers: 6
- Warnings: 3

## Release Blockers

- `supp-table-2`: exported hash is stale against the current source artifact.
- `supp-table-2`: notebook-derived output is stale or missing execution evidence.
- `supp-table-2`: restricted data lacks approved redaction review.
- `supp-table-2`: private reviewer notes are included in the public export.
- `supp-table-2`: one blocking supplement comment is still unresolved.
- `supp-protocol-3`: supplement is included in the export packet but not cited by the manuscript.

## Required Remediation

1. Re-run notebook-backed supplementary materials and regenerate exports.
2. Complete data-steward redaction review for restricted tables.
3. Strip private reviewer notes from public artifacts.
4. Resolve blocking comments or record explicit waiver evidence.
5. Add stable manuscript citations for every exported supplement.
6. Attach approved license metadata and lock supplement sections before export.

## Scope Mapping

This supports SCIBASE.AI issue #12 by adding a publication-export readiness guard inside the real-time collaborative editor workflow for scientific manuscript supplements.
13 changes: 13 additions & 0 deletions collab-supplementary-materials-guard/scripts/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {
buildSupplementManifest,
evaluateSupplementaryExport,
samplePackets,
} from '../src/index.js';

const blockedEvaluation = evaluateSupplementaryExport(samplePackets.blocked);
const readyEvaluation = evaluateSupplementaryExport(samplePackets.ready);

console.log(JSON.stringify({
blocked: buildSupplementManifest(samplePackets.blocked, blockedEvaluation),
ready: buildSupplementManifest(samplePackets.ready, readyEvaluation),
}, null, 2));
Loading