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
42 changes: 42 additions & 0 deletions citation-provenance-readiness/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Citation Provenance Readiness

This module is a focused slice for SCIBASE issue `#13`, AI-Assisted Research Tools.

It does not call external AI services or citation APIs. Instead, it gives reviewers a deterministic readiness gate for manuscript claims before a paper leaves the workspace:

- extracts evidence-backed summary modes for a manuscript packet
- checks whether research claims have citation keys, bibliography records, and local evidence artifacts
- flags citation, statistics, and compliance gaps
- ranks candidate citations with transparent overlap, DOI, recency, and open-access signals
- emits APA and Nature-style insertion plans for reviewer action
- produces a stable digest for audit packets

## Local Verification

```bash
cd citation-provenance-readiness
npm run check
npm test
npm run demo
npm run render-demo
```

The demo is based on synthetic sample data in `examples/project.json`.

## Demo Output

```text
Project: Protocol-Guided Perturbation Screening
Status: hold
Readiness score: 22
Claims reviewed: 3
Missing bibliography keys: missing2026
Top citation insertion: nguyen2025
Top reviewer action: Add at least one source-backed citation or mark the claim as internal preliminary evidence.
```

## Why This Slice Is Distinct

Existing issue `#13` submissions mostly cover broad AI summarizer, peer-review, and citation demos. This module targets the provenance boundary: whether a concrete manuscript packet has traceable sources, evidence artifacts, statistical context, citation insertions, and compliance statements before an AI-assisted research tool recommends release.

The implementation is dependency-free, credential-free, and uses synthetic data only.
Binary file added citation-provenance-readiness/docs/demo.mp4
Binary file not shown.
21 changes: 21 additions & 0 deletions citation-provenance-readiness/docs/demo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
123 changes: 123 additions & 0 deletions citation-provenance-readiness/examples/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{
"id": "scibase-protocol-screening-demo",
"title": "Protocol-Guided Perturbation Screening",
"manuscript": {
"sections": [
{
"id": "abstract",
"title": "Abstract",
"text": "We describe a CRISPR perturbation screen for MAPK stress response signatures and a reproducible notebook workflow for follow-up analysis."
},
{
"id": "methods",
"title": "Methods",
"text": "The analysis pipeline uses notebooks, a small synthetic dataset, and a protocol checklist to compare perturbation response clusters."
},
{
"id": "results",
"title": "Results",
"text": "CRISPR perturbation reduced MAPK activation in the treated cohort. The workflow is fully reproducible across all reviewer machines. A secondary endpoint reached p < 0.049 in a small exploratory subset."
},
{
"id": "limitations",
"title": "Limitations",
"text": "The dataset is synthetic for this demo and should be replaced with controlled-access evidence before external review."
}
]
},
"claims": [
{
"id": "c1",
"sectionId": "results",
"text": "CRISPR perturbation reduced MAPK activation in the treated cohort.",
"citationKeys": ["doe2024"],
"evidenceIds": ["e1"],
"tags": ["CRISPR", "MAPK", "single-cell"]
},
{
"id": "c2",
"sectionId": "results",
"text": "The workflow is fully reproducible across all reviewer machines.",
"citationKeys": [],
"evidenceIds": ["e2"],
"tags": ["reproducibility", "notebook", "workflow"]
},
{
"id": "c3",
"sectionId": "results",
"text": "A secondary endpoint reached p < 0.049 in a small exploratory subset.",
"citationKeys": ["missing2026"],
"evidenceIds": [],
"tags": ["statistics", "exploratory", "endpoint"]
}
],
"bibliography": [
{
"key": "doe2024",
"title": "Single-cell perturbation screens for pathway response mapping",
"authors": ["Doe, J.", "Ibrahim, S."],
"year": 2024,
"venue": "Open Molecular Systems",
"doi": "10.5555/omols.2024.1001",
"url": "https://example.org/omols-2024-1001"
}
],
"candidateCitations": [
{
"key": "nguyen2025",
"title": "Reproducible notebook capsules for computational biology review",
"authors": ["Nguyen, A.", "Patel, R."],
"year": 2025,
"venue": "Journal of Open Reproducibility",
"doi": "10.5555/jor.2025.021",
"url": "https://example.org/jor-2025-021",
"tags": ["reproducibility", "notebook", "workflow", "review"],
"openAccess": true
},
{
"key": "chen2023",
"title": "Confidence interval reporting for exploratory omics endpoints",
"authors": ["Chen, L.", "Morrison, T."],
"year": 2023,
"venue": "Statistical Methods in Biology",
"doi": "10.5555/smb.2023.44",
"url": "https://example.org/smb-2023-44",
"tags": ["statistics", "exploratory", "confidence interval", "endpoint"],
"openAccess": true
},
{
"key": "alvarez2022",
"title": "MAPK pathway annotations in single-cell stress models",
"authors": ["Alvarez, M."],
"year": 2022,
"venue": "Cell Systems Notes",
"doi": "",
"url": "https://example.org/cell-systems-notes-mapk",
"tags": ["MAPK", "single-cell", "stress response"],
"openAccess": false
}
],
"evidenceArtifacts": [
{
"id": "e1",
"label": "Synthetic perturbation response table",
"type": "dataset",
"checksum": "sha256:2b5cf2c7b8a6d0e5e01b6a5dce0afac0",
"access": "reviewer-visible",
"supports": ["c1"]
},
{
"id": "e2",
"label": "Notebook replay manifest",
"type": "notebook-manifest",
"checksum": "sha256:7c8e4b1b326b2a4d7efbf2a79d1bb0a5",
"access": "reviewer-visible",
"supports": ["c2"]
}
],
"compliance": {
"dataAvailability": false,
"ethicsStatement": true,
"codeAvailability": false
}
}
16 changes: 16 additions & 0 deletions citation-provenance-readiness/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "citation-provenance-readiness",
"version": "1.0.0",
"description": "Dependency-free citation provenance readiness module for SCIBASE AI-assisted research tools.",
"type": "module",
"scripts": {
"check": "node --check src/citation-provenance-readiness.mjs && node --check tests/citation-provenance-readiness.test.mjs && node --check scripts/render-demo.mjs",
"test": "node --test tests/citation-provenance-readiness.test.mjs",
"demo": "node src/citation-provenance-readiness.mjs examples/project.json",
"render-demo": "node scripts/render-demo.mjs"
},
"engines": {
"node": ">=20"
},
"license": "MIT"
}
34 changes: 34 additions & 0 deletions citation-provenance-readiness/requirement-map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Requirement Map

Issue `#13` asks for AI-assisted research tools at MVP level. This module covers a narrow, reviewer-ready slice of that workflow.

## AI Paper Summarizer

- Abstract-style summary: `buildSummaryModes().abstract`
- Executive summary: `buildSummaryModes().executive`
- Layperson explanation: `buildSummaryModes().layperson`
- Key findings and next actions: CLI output and `diagnostics[].action`

## AI Peer Review Aid

- Missing citation and bibliography checks: `buildClaimDiagnostics`
- Statistical context checks for p-value claims without confidence intervals: `buildClaimDiagnostics`
- Data/code/ethics availability checks: `buildProjectDiagnostics`
- Reviewer-ready actions: `diagnostics[].action`
- Stable audit digest: `digest`

## AI Citation Tool

- Citation candidate ranking: `rankCandidateCitations`
- Transparent reasons for each recommendation: `recommendedCitations[].reasons`
- APA and Nature formatting: `formatCitation`
- One-click style insertion text: `citationInsertions[].insertionText`
- Similar-source style tags: candidate and claim tag overlap scoring

## Safety And Reviewability

- No external API calls
- No live credentials, private data, payment data, or user identity data
- Synthetic demo data only
- Deterministic test coverage in `tests/citation-provenance-readiness.test.mjs`
- Demo artifact generated by `npm run render-demo`
46 changes: 46 additions & 0 deletions citation-provenance-readiness/scripts/render-demo.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import project from "../examples/project.json" with { type: "json" };
import { buildCitationProvenanceReadiness } from "../src/citation-provenance-readiness.mjs";

const root = dirname(dirname(fileURLToPath(import.meta.url)));
const docsDir = join(root, "docs");
mkdirSync(docsDir, { recursive: true });

const report = buildCitationProvenanceReadiness(project);
const topInsertion = report.citationInsertions[0];
const topDiagnostic = report.diagnostics[0];
const svg = `<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="1280" height="720" viewBox="0 0 1280 720">
<rect width="1280" height="720" fill="#0f172a"/>
<rect x="56" y="52" width="1168" height="616" rx="22" fill="#f8fafc"/>
<text x="96" y="118" fill="#0f172a" font-family="Arial, sans-serif" font-size="40" font-weight="700">Citation provenance readiness</text>
<text x="96" y="164" fill="#475569" font-family="Arial, sans-serif" font-size="24">${escapeXml(report.title)}</text>
<rect x="96" y="210" width="270" height="116" rx="18" fill="#fee2e2"/>
<text x="124" y="258" fill="#991b1b" font-family="Arial, sans-serif" font-size="26" font-weight="700">Status</text>
<text x="124" y="298" fill="#7f1d1d" font-family="Arial, sans-serif" font-size="32">${escapeXml(report.readinessStatus)}</text>
<rect x="394" y="210" width="270" height="116" rx="18" fill="#e0f2fe"/>
<text x="422" y="258" fill="#075985" font-family="Arial, sans-serif" font-size="26" font-weight="700">Score</text>
<text x="422" y="298" fill="#0c4a6e" font-family="Arial, sans-serif" font-size="32">${report.readinessScore}/100</text>
<rect x="692" y="210" width="452" height="116" rx="18" fill="#ecfccb"/>
<text x="720" y="258" fill="#3f6212" font-family="Arial, sans-serif" font-size="26" font-weight="700">Recommended citation</text>
<text x="720" y="298" fill="#365314" font-family="Arial, sans-serif" font-size="32">@${escapeXml(topInsertion.recommendedCitations[0].key)}</text>
<text x="96" y="396" fill="#0f172a" font-family="Arial, sans-serif" font-size="28" font-weight="700">Top reviewer action</text>
<text x="96" y="438" fill="#334155" font-family="Arial, sans-serif" font-size="24">${escapeXml(topDiagnostic.action)}</text>
<text x="96" y="504" fill="#0f172a" font-family="Arial, sans-serif" font-size="28" font-weight="700">Missing bibliography</text>
<text x="96" y="546" fill="#334155" font-family="Arial, sans-serif" font-size="24">${escapeXml(report.missingBibliography.join(", ") || "none")}</text>
<text x="96" y="612" fill="#64748b" font-family="Arial, sans-serif" font-size="20">Digest ${report.digest.slice(0, 24)}</text>
</svg>
`;

writeFileSync(join(docsDir, "demo.svg"), svg);
console.log(`Wrote ${join(docsDir, "demo.svg")}`);

function escapeXml(value) {
return String(value)
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;");
}
Loading