Document source, ingestion, extraction, metadata, and citation recovery.
Find a file
tegwick b3eaa4b406
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Persist PDF bytes in IndexedDB for session reload.
Mirror PdfByteStore put/delete/clear into a session-scoped IndexedDB store
and expose hydrate() so the umbrella can restore bytes after page reload.
2026-07-30 20:05:24 +02:00
.claude/rules feat(pdf): extract standalone PDF ingest package (ESRC-WP-0001) 2026-07-08 20:55:28 +02:00
.forgejo/workflows Add Forgejo CI smoke workflow (enablement template) 2026-07-08 12:32:09 +02:00
docs Clarify structureMap is populated by anchor viewers, not ingest 2026-07-09 09:18:46 +02:00
registry feat(pdf): extract standalone PDF ingest package (ESRC-WP-0001) 2026-07-08 20:55:28 +02:00
src Persist PDF bytes in IndexedDB for session reload. 2026-07-30 20:05:24 +02:00
tests Implement ESRC-WP-0002/0003/0004: HTML/MD ingest, metadata, recovery 2026-07-09 01:48:28 +02:00
workplans Implement ESRC-WP-0002/0003/0004: HTML/MD ingest, metadata, recovery 2026-07-09 01:48:28 +02:00
.custodian-brief.md chore(consistency): sync task status from DB [auto] 2026-07-09 01:49:06 +02:00
.gitignore feat(pdf): extract standalone PDF ingest package (ESRC-WP-0001) 2026-07-08 20:55:28 +02:00
.repo-classification.yaml Add .repo-classification.yaml (CUST-WP-0050 T11 agent first-pass) 2026-06-22 17:47:36 +02:00
AGENTS.md Regenerate agent instructions from state-hub templates (CUST-WP-0055 T01) 2026-07-08 14:50:21 +02:00
CLAUDE.md Normalize agent instructions and workplan frontmatter (STATE-WP-0067) 2026-06-22 23:16:24 +02:00
eslint.config.js feat(pdf): extract standalone PDF ingest package (ESRC-WP-0001) 2026-07-08 20:55:28 +02:00
INTENT.md Add MVP Coordination section: code lives in citation-evidence umbrella during MVP 2026-05-24 16:51:06 +02:00
LICENSE Adopt Target Revenue Source License V1C1 (org-wide preliminary rollout) 2026-07-30 00:09:01 +02:00
package.json feat(pdf): extract standalone PDF ingest package (ESRC-WP-0001) 2026-07-08 20:55:28 +02:00
pnpm-lock.yaml feat(pdf): extract standalone PDF ingest package (ESRC-WP-0001) 2026-07-08 20:55:28 +02:00
README.md Implement ESRC-WP-0002/0003/0004: HTML/MD ingest, metadata, recovery 2026-07-09 01:48:28 +02:00
SCOPE.md Implement ESRC-WP-0002/0003/0004: HTML/MD ingest, metadata, recovery 2026-07-09 01:48:28 +02:00
tsconfig.json feat(pdf): extract standalone PDF ingest package (ESRC-WP-0001) 2026-07-08 20:55:28 +02:00
vitest.config.ts feat(pdf): extract standalone PDF ingest package (ESRC-WP-0001) 2026-07-08 20:55:28 +02:00

evidence-source

Headless document ingest for the citation-evidence ecosystem. Turns raw PDF, HTML, and Markdown bytes into engine-owned evidence contracts — a Document (media type, SHA-256 fingerprint, optional title/uri/metadata) and a DocumentRepresentation (canonical text, page/offset maps where applicable). Ingest is pure over bytes: no persistence, no viewer state, no React.

Status

Implemented: PDF ingest (ESRC-WP-0001), HTML/Markdown ingest (ESRC-WP-0002), PDF metadata enrichment (ESRC-WP-0003), and citation recovery primitives (ESRC-WP-0004). See workplans/ for history.

Install

Requires a sibling checkout of citation-engine (domain contracts) and, for tests, citation-evidence (fixture corpus — see docs/ADR-0002-fixture-ownership.md).

pnpm install   # resolves @citation-evidence/engine via link:../citation-engine

Usage

import {
  ingestPdf,
  ingestHtml,
  ingestMarkdown,
} from "@citation-evidence/evidence-source";

const pdf = await ingestPdf(pdfBytes, { filename: "contract.pdf" });
const html = await ingestHtml(htmlBytes, { filename: "brief.html" });
const md = await ingestMarkdown("# Title\n\nBody text.", { filename: "notes.md" });
// document.fingerprint -> SHA-256 hex
// representation.canonicalText / pageMap / offsetMap (format-dependent)

Browser upload helpers (in-memory blob: byte store + ingestPdfFromFile) live behind a separate, clearly-isolated entry point so headless consumers do not pull in browser machinery:

import { createPdfByteStore, ingestPdfFromFile }
  from "@citation-evidence/evidence-source/browser";

Extraction requires the host to configure the PDF.js worker (GlobalWorkerOptions.workerSrc) before calling extractPdf/ingestPdf; the module itself does no worker setup so it loads cleanly in Node and browsers.

Dev commands

pnpm test        # vitest (fixture suites skip if the corpus is absent)
pnpm typecheck   # tsc --noEmit
pnpm lint        # eslint

Point EVIDENCE_SOURCE_FIXTURE_DIR at the PDF corpus when the sibling citation-evidence checkout is not at ../citation-evidence.

Architecture

  • src/pdf/ — PDF ingest, extraction, fingerprinting, metadata enrichment.
  • src/html/, src/markdown/ — reflowable-format ingest (ADR-0003).
  • src/recovery/ — re-ingest/reconcile, local quote search, discovery hooks (ADR-0004).
  • src/browser/ — browser upload surface: byte-store, upload. Separated by an ESLint boundary so the core never imports it.
  • Domain contracts come from @citation-evidence/engine/shared; none are copied locally.
  • Boundary and fixture decisions: docs/ADR-0001 through docs/ADR-0004.

viewer-url resolution stays in the consuming app (citation-evidence), which imports this package's ingest core through a thin façade.