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
38 changes: 38 additions & 0 deletions supplementary-media-accessibility-guard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Supplementary Media Accessibility Guard

This module is a focused Scientific/Engineering Data & Code Hosting slice for SCIBASE issue #14. It validates hosted supplementary media before public previews, API access, archive exports, or reviewer packets are released.

The guard checks:

- alt text for images, figure panels, and thumbnails
- captions for figures, microscopy clips, and protocol videos
- transcript and timecoded segment coverage for videos
- thumbnail provenance against the source artifact checksum
- checksum and metadata parity between source media and previews
- embargo and restricted-access state before public release
- DataCite and schema.org accessibility metadata readiness
- deterministic reviewer actions to release, revise, or hold previews

It is intentionally separate from broad FAIR manifests, artifact package integrity, preview cache/version drift, raw-instrument previews, notebook previews, retention/tombstones, model-card lineage, license metadata, sensitive redaction, schema evolution, data dictionaries, persistent identifiers, SBOM/advisory checks, upload checkpoints, replica consistency, column sensitivity, malware/archive quarantine, and sandbox egress. This slice focuses on accessibility and provenance readiness for supplementary scientific media.

## Reviewer Path

```bash
npm run check
npm test
npm run demo
npm run verify-video
```

Generated reviewer artifacts:

- `reports/clean-media-packet.json`
- `reports/risky-media-packet.json`
- `reports/media-accessibility-report.md`
- `reports/summary.svg`
- `reports/demo-script.txt`
- `reports/demo.mp4`

## Safety

All fixtures are synthetic. The module does not call live media stores, private projects, uploaded datasets, customer portals, payment systems, credential stores, external APIs, or financial accounts.
50 changes: 50 additions & 0 deletions supplementary-media-accessibility-guard/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const fs = require("node:fs");
const path = require("node:path");
const { evaluateMediaPacket, renderMarkdownReport, renderSvgSummary } = require("./index");
const { cleanPacket, riskyPacket } = require("./sample-data");

const reportsDir = path.join(__dirname, "reports");
fs.mkdirSync(reportsDir, { recursive: true });

const cleanEvaluation = evaluateMediaPacket(cleanPacket);
const riskyEvaluation = evaluateMediaPacket(riskyPacket);

fs.writeFileSync(
path.join(reportsDir, "clean-media-packet.json"),
`${JSON.stringify({ input: cleanPacket, evaluation: cleanEvaluation }, null, 2)}\n`
);
fs.writeFileSync(
path.join(reportsDir, "risky-media-packet.json"),
`${JSON.stringify({ input: riskyPacket, evaluation: riskyEvaluation }, null, 2)}\n`
);
fs.writeFileSync(
path.join(reportsDir, "media-accessibility-report.md"),
renderMarkdownReport(riskyPacket, riskyEvaluation)
);
fs.writeFileSync(
path.join(reportsDir, "summary.svg"),
renderSvgSummary(riskyEvaluation)
);
fs.writeFileSync(
path.join(reportsDir, "demo-script.txt"),
[
"Supplementary media accessibility preview guard demo",
"",
`Clean packet decision: ${cleanEvaluation.summary.decision}`,
`Clean audit digest: ${cleanEvaluation.summary.auditDigest}`,
"",
`Risky packet decision: ${riskyEvaluation.summary.decision}`,
`Risky finding count: ${riskyEvaluation.summary.findingCount}`,
`Risky audit digest: ${riskyEvaluation.summary.auditDigest}`,
"",
"The risky packet demonstrates an embargoed restricted video exposed for public preview, incomplete transcript coverage, unlabeled segments, thumbnail/preview checksum drift, missing alt text, missing captions, and incomplete accessibility metadata.",
""
].join("\n")
);

console.log(JSON.stringify({
cleanDecision: cleanEvaluation.summary.decision,
riskyDecision: riskyEvaluation.summary.decision,
riskyFindings: riskyEvaluation.summary.findingCount,
report: "reports/media-accessibility-report.md"
}, null, 2));
Loading