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
4 changes: 4 additions & 0 deletions repository-external-reference-pin-guard/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
reports/demo-frame.png
__pycache__/
*.tmp
32 changes: 32 additions & 0 deletions repository-external-reference-pin-guard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Repository External Reference Pin Guard

Self-contained Project Repository & Version Control slice for issue #10.

This module checks whether a scientific repository can safely publish a DOI, citation badge, API view, or export bundle when it depends on external references such as Git submodules, linked datasets, API snapshots, model weights, or external code/data pointers.

## What It Checks

- Git submodules and external code are pinned to immutable commit SHAs, rejecting null all-zero placeholders.
- Linked datasets and model weights have full-length SHA checksum, parseable DOI, or immutable version evidence; placeholders such as `pending` and floating aliases such as `latest` do not count.
- Supplied checksum and DOI metadata must be valid even when another durable identifier is present, so malformed evidence cannot slip into export or citation packets.
- The external-reference manifest itself must be an array, so object-shaped or missing reviewer data cannot be treated as a clean empty audit.
- Malformed external-reference entries create release-blocking repair actions instead of crashing assessment or disappearing from reviewer packets.
- API sources use parseable, non-future dated snapshots with full-length SHA checksum evidence instead of floating "latest" endpoints.
- Export bundles do not require authenticated external references.
- License and attribution metadata are present before DOI publication.
- Reference verification evidence is present, fresh enough for release, and not future-dated.

## Commands

```powershell
npm test
npm run demo
npm run video
npm run check
```

The demo writes deterministic JSON, Markdown, SVG, and MP4 reviewer artifacts under `reports/`.

## Safety

All records are synthetic. The module does not call external repositories, APIs, DOI registries, identity providers, storage systems, payment systems, or private research databases.
34 changes: 34 additions & 0 deletions repository-external-reference-pin-guard/acceptance-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Acceptance Notes

## Local Validation

Run from `repository-external-reference-pin-guard/`:

```powershell
npm test
npm run demo
npm run video
npm run check
```

Expected evidence:

- `reports/blocked-packet.json` blocks repository release when external references are floating, authenticated only, stale, missing durable identifiers, or carrying malformed checksum/DOI evidence.
- All-zero Git commit placeholders are treated as unpinned references rather than immutable release evidence.
- Floating version aliases such as `latest` are blocked unless the reference also has checksum or DOI evidence.
- Invalid checksum placeholders such as `pending` do not count as durable identifier or API snapshot evidence and now produce explicit evidence-repair actions.
- Invalid DOI placeholders such as `pending` do not count as durable identifier evidence and now produce explicit evidence-repair actions.
- Truncated checksum values such as `sha256:abcdef` do not count as API snapshot evidence or export metadata even when another identifier is valid.
- Malformed object-shaped reference manifests produce `MALFORMED_REFERENCE_MANIFEST` blockers and `repair_reference_manifest:*` actions instead of being treated as empty clean audits.
- Malformed external-reference entries produce `MALFORMED_REFERENCE_ENTRY` blockers and `repair_reference_entry:*` actions instead of crashing or disappearing from reviewer packets.
- Future-dated API snapshots do not count as pinned snapshot evidence for DOI/export release.
- Otherwise pinned references without verification timestamps are blocked until verification evidence is refreshed.
- `reports/warning-packet.json` stages pinned references that still need license and attribution metadata.
- `reports/clean-packet.json` releases a repository with immutable external pins, fresh verification evidence, and exportable metadata.
- `reports/external-reference-report.md` summarizes lanes and finding codes.
- `reports/summary.svg` provides a visual reviewer packet.
- `reports/demo.mp4` is a short H.264 walkthrough generated from synthetic frames.

## Safety Boundaries

All records are synthetic. No external repositories, live APIs, DOI registries, object stores, credentials, private research data, identity providers, or payment systems are contacted.
60 changes: 60 additions & 0 deletions repository-external-reference-pin-guard/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const fs = require('fs');
const path = require('path');

const { assessExternalReferences } = require('./index');
const {
riskyRepository,
cleanRepository,
warningRepository,
malformedRepository,
malformedManifestRepository
} = require('./sample-data');

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

const packets = [
['blocked-packet.json', assessExternalReferences(riskyRepository)],
['malformed-manifest-packet.json', assessExternalReferences(malformedManifestRepository)],
['malformed-packet.json', assessExternalReferences(malformedRepository)],
['clean-packet.json', assessExternalReferences(cleanRepository)],
['warning-packet.json', assessExternalReferences(warningRepository)]
];

for (const [fileName, packet] of packets) {
fs.writeFileSync(path.join(reportsDir, fileName), `${JSON.stringify(packet, null, 2)}\n`);
console.log(`${fileName}: ${packet.status}; findings=${packet.findings.length}; digest=${packet.auditDigest.slice(0, 12)}`);
}

const markdown = [
'# Repository External Reference Pin Guard Report',
'',
'| Packet | Status | DOI publication | Export bundle | API access | Findings |',
'| --- | --- | --- | --- | --- | --- |',
...packets.map(([fileName, packet]) => `| ${fileName} | ${packet.status} | ${packet.releaseLanes.doiPublication} | ${packet.releaseLanes.exportBundle} | ${packet.releaseLanes.apiAccess} | ${packet.findings.map((finding) => finding.code).join(', ') || 'none'} |`),
'',
'Synthetic data only. No external repositories, APIs, DOI registries, or private data sources are contacted.'
].join('\n');
fs.writeFileSync(path.join(reportsDir, 'external-reference-report.md'), `${markdown}\n`);

const rows = packets.map(([fileName, packet], index) => {
const y = 94 + index * 68;
const color = packet.status === 'hold_repository_release' ? '#b91c1c' : packet.status === 'stage_reference_metadata_revision' ? '#a16207' : '#047857';
return `
<g transform="translate(48 ${y})">
<rect width="1104" height="52" rx="6" fill="#f8fafc" stroke="#cbd5e1"/>
<circle cx="28" cy="26" r="11" fill="${color}"/>
<text x="58" y="22" font-size="18" font-family="Arial" fill="#111827">${packet.repositoryId}</text>
<text x="58" y="41" font-size="13" font-family="Arial" fill="#475569">${fileName} | findings ${packet.findings.length} | digest ${packet.auditDigest.slice(0, 16)}</text>
</g>`;
}).join('');

const svgHeight = 408;
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="${svgHeight}" viewBox="0 0 1200 ${svgHeight}">
<rect width="1200" height="${svgHeight}" fill="#ffffff"/>
<text x="48" y="48" font-size="28" font-family="Arial" font-weight="700" fill="#111827">Repository External Reference Pin Guard</text>
<text x="48" y="74" font-size="15" font-family="Arial" fill="#475569">Issue #10 release/export gate for submodules, linked datasets, API sources, and model references</text>
${rows}
</svg>
`;
fs.writeFileSync(path.join(reportsDir, 'summary.svg'), svg);
Loading