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
20 changes: 20 additions & 0 deletions knowledge-graph-negative-evidence-guard/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "knowledge-graph-negative-evidence-guard",
"version": "1.0.0",
"description": "Negative-evidence publication guard for SCIBASE scientific knowledge graph recommendations.",
"type": "module",
"private": true,
"scripts": {
"check": "node --check src/index.js && node --check test/index.test.js && node --check scripts/demo.js",
"test": "node --test test/index.test.js",
"demo": "node scripts/demo.js"
},
"keywords": [
"scibase",
"knowledge-graph",
"negative-evidence",
"retractions",
"replication"
],
"license": "MIT"
}
38 changes: 38 additions & 0 deletions knowledge-graph-negative-evidence-guard/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Knowledge Graph Negative-Evidence Guard

This module is a focused SCIBASE.AI issue #17 submission for Scientific Knowledge Graph Integration.

It prevents public graph recommendations from quietly routing around negative scientific evidence. The guard inspects synthetic knowledge-graph packets for contradictions, retractions, failed replications, stale unresolved review windows, and private or embargoed negative evidence before entity pages or recommendation edges publish.

## What It Covers

- Retractions or withdrawn evidence blocking dependent graph paths.
- Conflicting positive and negative evidence requiring curator review.
- High-confidence failed replications downgrading recommendations until resolved.
- Public recommendations refusing private or embargoed evidence chains.
- Reviewer packets that explain blockers, required actions, and recommendation decisions.

## What It Does Not Do

- No live research data is read.
- No external ontology, DOI, storage, payment, or private repository APIs are called.
- No credentials, personal data, private manuscripts, or private datasets are included.
- No broad entity-extraction system is reimplemented; this is a safety gate for negative evidence and recommendation publication.

## Reviewer Path

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

Generated reviewer artifacts:

- `reports/negative-evidence-packet.json`
- `reports/negative-evidence-report.md`
- `reports/summary.svg`

## Claim

Use `/claim #17` in the pull request body.
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
{
"title": "SCIBASE Scientific Knowledge Graph Negative-Evidence Guard",
"issue": "SCIBASE.AI#17",
"claim": "/claim #17",
"purpose": "Prevent public knowledge graph recommendations from hiding contradictions, retractions, failed replications, or private negative evidence.",
"evaluation": {
"status": "block_publication",
"generatedAt": "2026-06-04T00:00:00.000Z",
"graphId": "scibase-kg-negative-evidence-demo",
"digest": "b245bc907bb0911addeb552f2bd24ed4c51e6f895cceca6840a3985df1af39ac",
"counts": {
"claims": 4,
"recommendations": 2,
"blockers": 5,
"warnings": 1,
"heldRecommendations": 2
},
"blockers": [
{
"code": "retracted_evidence_in_graph_path",
"claimId": "claim:retracted-dataset-link",
"recommendationIds": [
"rec:recommend-protocol-v2"
],
"message": "A graph path or recommendation still depends on retracted evidence."
},
{
"code": "stale_negative_evidence_review",
"claimId": "claim:embargoed-contradiction",
"ageDays": 64,
"message": "Negative evidence has been unresolved past the stale-review window."
},
{
"code": "private_evidence_used_publicly",
"claimId": "claim:embargoed-contradiction",
"recommendationIds": [
"rec:recommend-gene-x-dataset"
],
"message": "A public recommendation uses private or embargoed negative-evidence context."
},
{
"code": "unresolved_contradictory_claims",
"tripleKey": "paper:crispr-neuro-2024|supports|finding:gene-x-effect",
"conflictScore": 0.644,
"positiveClaimIds": [
"claim:supports-gene-x"
],
"negativeClaimIds": [
"claim:failed-replication-gene-x"
],
"recommendationIds": [
"rec:recommend-gene-x-dataset"
],
"message": "Conflicting positive and negative evidence requires curator review before recommendations publish."
},
{
"code": "failed_replication_without_curator_outcome",
"claimId": "claim:failed-replication-gene-x",
"recommendationIds": [
"rec:recommend-gene-x-dataset"
],
"message": "High-confidence failed replication evidence needs a curator outcome before graph boosts continue."
}
],
"warnings": [
{
"code": "missing_negative_evidence_doi",
"claimId": "claim:embargoed-contradiction",
"message": "Negative evidence should keep a DOI or stable public source identifier before curator review."
}
],
"actions": [
{
"type": "request_curator_decision",
"claimId": "claim:embargoed-contradiction",
"reason": "Negative evidence is stale and still affects graph recommendations."
},
{
"type": "open_conflict_review",
"tripleKey": "paper:crispr-neuro-2024|supports|finding:gene-x-effect",
"claimIds": [
"claim:supports-gene-x",
"claim:failed-replication-gene-x"
],
"reason": "Positive and negative evidence both exceed the publication hold threshold."
}
],
"claimActions": [
{
"claimId": "claim:retracted-dataset-link",
"decision": "block",
"reason": "Retracted or withdrawn evidence cannot support public graph recommendations."
}
],
"recommendationActions": [
{
"recommendationId": "rec:recommend-gene-x-dataset",
"decision": "hold",
"reasons": [
"private_evidence_for_public_recommendation",
"unresolved_conflict",
"failed_replication"
],
"requiredActions": [
"Replace private evidence with a public citation or keep the recommendation internal.",
"Redact any embargoed evidence from the public graph packet.",
"Attach a curator decision that accepts, qualifies, or suppresses the conflict.",
"Show contradiction context on the entity page before publication.",
"Downgrade recommendation confidence until the failed replication is resolved.",
"Expose failed-replication context beside the graph edge."
]
},
{
"recommendationId": "rec:recommend-protocol-v2",
"decision": "hold",
"reasons": [
"retracted_evidence"
],
"requiredActions": [
"Remove the retracted claim from recommendation evidence.",
"Add a public curator note explaining the withdrawal."
]
}
],
"policy": {
"contradictionHoldConfidence": 0.58,
"failedReplicationHoldConfidence": 0.55,
"staleReviewDays": 30,
"requirePublicEvidenceForPublicRecommendations": true,
"retractionsBlockAllRecommendations": true,
"requireCuratorForConflicts": true
}
},
"reviewerChecklist": [
"Every public recommendation has an explicit evidence chain.",
"Retracted evidence blocks dependent graph paths.",
"Contradictory evidence opens a curator review before publication.",
"Failed replication evidence downgrades recommendations until resolved.",
"Private or embargoed evidence is not leaked into public recommendation paths."
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Negative-Evidence Graph Guard Report

Issue: SCIBASE.AI#17
Claim marker: `/claim #17`
Status: `block_publication`
Digest: `b245bc907bb0911addeb552f2bd24ed4c51e6f895cceca6840a3985df1af39ac`

## Reviewer Checklist
- Every public recommendation has an explicit evidence chain.
- Retracted evidence blocks dependent graph paths.
- Contradictory evidence opens a curator review before publication.
- Failed replication evidence downgrades recommendations until resolved.
- Private or embargoed evidence is not leaked into public recommendation paths.

## Counts
- Claims inspected: 4
- Recommendations inspected: 2
- Blockers: 5
- Warnings: 1
- Held recommendations: 2

## Blockers
- retracted_evidence_in_graph_path: A graph path or recommendation still depends on retracted evidence.
- stale_negative_evidence_review: Negative evidence has been unresolved past the stale-review window.
- private_evidence_used_publicly: A public recommendation uses private or embargoed negative-evidence context.
- unresolved_contradictory_claims: Conflicting positive and negative evidence requires curator review before recommendations publish.
- failed_replication_without_curator_outcome: High-confidence failed replication evidence needs a curator outcome before graph boosts continue.

## Warnings
- missing_negative_evidence_doi: Negative evidence should keep a DOI or stable public source identifier before curator review.

## Recommendation Actions
- rec:recommend-gene-x-dataset: hold (private_evidence_for_public_recommendation, unresolved_conflict, failed_replication)
- rec:recommend-protocol-v2: hold (retracted_evidence)

## Required Actions
- request_curator_decision: Negative evidence is stale and still affects graph recommendations.
- open_conflict_review: Positive and negative evidence both exceed the publication hold threshold.
18 changes: 18 additions & 0 deletions knowledge-graph-negative-evidence-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.
30 changes: 30 additions & 0 deletions knowledge-graph-negative-evidence-guard/scripts/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";

import {
buildReviewerPacket,
demoPacket,
renderMarkdownReport,
renderSvgSummary
} from "../src/index.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const moduleRoot = path.resolve(__dirname, "..");
const reportsDir = path.join(moduleRoot, "reports");
const now = "2026-06-04T00:00:00.000Z";
const packet = demoPacket();
const reviewerPacket = buildReviewerPacket(packet, { now });

fs.mkdirSync(reportsDir, { recursive: true });
fs.writeFileSync(path.join(reportsDir, "negative-evidence-packet.json"), `${JSON.stringify(reviewerPacket, null, 2)}\n`);
fs.writeFileSync(path.join(reportsDir, "negative-evidence-report.md"), renderMarkdownReport(packet, { now }));
fs.writeFileSync(path.join(reportsDir, "summary.svg"), renderSvgSummary(packet, { now }));

console.log(JSON.stringify({
status: reviewerPacket.evaluation.status,
digest: reviewerPacket.evaluation.digest,
blockers: reviewerPacket.evaluation.counts.blockers,
warnings: reviewerPacket.evaluation.counts.warnings,
reportsDir
}, null, 2));
Loading