# Epigraphy Knowledge Network

> Turn located, human-adjudicated epigraphic text and located literature evidence into an auditable knowledge graph of candidate mentions, human-adjudicated assertions and evidence-backed edges, with deterministic timeline, relationship-path and entity queries. Use when Codex must build, verify, query or export a rubbing-derived knowledge graph without letting OCR, AI proposals, name matches, modern place names, calendar conversions or graph paths become historical facts.

- Skill: `lx050/epigraphy-knowledge-network` (Agent Skill, multi-file: 18 files)
- Install (CLI): `npx skillmds@latest add lx050/epigraphy-knowledge-network`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lx050/epigraphy-knowledge-network/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Research & Search
- Author: Lx050 (https://skillmd.com/u/lx050)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/lx050/epigraphy-knowledge-network

---


# Epigraphy Knowledge Network

Build the evidence chain

```text
CandidateMention → HumanAdjudicatedAssertion → EvidenceBackedGraphEdge
```

Software may create candidates. Only a trusted human adjudication creates an
assertion. Only accepted assertions materialize edges, deterministically. No
layer may be skipped.

Version 1.0.0 runs one lane end to end: `synthetic-test-fixture`. Both real
lanes are parsed, reported and blocked, because no trusted rights, authority or
human-identity verifier exists yet. A synthetic pass proves the contract and the
CLI run; it proves nothing about any rubbing, entity identity or graph quality.

Read [input-contract.md](references/input-contract.md) before building an
intake and [output-contract.md](references/output-contract.md) before consuming
a state, query or export. The JSON Schemas give shape; the controller performs
the authoritative semantic and current-file checks.

## Preconditions

1. Finish OCR review and text structuring first; pass an immutable
   `epigraphy-text-structure` state plus its verification report, never a draft,
   a handoff or a bare OCR result.
2. Register every source, rights record and evidence card, with page/folio or
   byte span, excerpt hash and independence group.
3. Freeze `docs/research/registries/predicate-registry-v01.json`; it is a
   required input and it is self-hashed.
4. Keep one ResearchCase v1 with question, falsification and stop conditions.
5. Wrap material runs with `research-run-ledger`.

## Verify an intake

```bash
python3 scripts/knowledge_network.py intake-verify \
  --intake-bundle /new/run/intake-bundle.json \
  --output-report /new/run/intake.verify.json
```

The report separates qualification, schema integrity, locator, evidence, rights,
human identity and ResearchCase gates. `human_identity` is always `block`.

## Create an immutable graph case

```bash
python3 scripts/knowledge_network.py init \
  --verified-intake /new/run/intake.verify.json \
  --graph-case-id SYN-GRAPH-CASE-001 \
  --output-dir /new/run/graph-case
```

`init` refuses an existing directory and creates `graph-state-v001.json`,
`events/0001-init.json`, `inputs/`, `locators/`, `queries/`, `exports/` and
`verification/`.

## Append the three layers

```bash
python3 scripts/knowledge_network.py candidate-append \
  --graph .../graph-state-v001.json --candidate .../mention.json \
  --output-graph .../graph-state-v002.json --output-event .../events/0002-candidate.json

python3 scripts/knowledge_network.py assertion-propose \
  --graph .../graph-state-v002.json --proposal .../proposal.json \
  --output-graph .../graph-state-v003.json --output-event .../events/0003-proposal.json

python3 scripts/knowledge_network.py decision-append \
  --graph .../graph-state-v003.json --decision .../decision.json \
  --identity-assertion /frozen/identity-assertion.json \
  --output-graph .../graph-state-v004.json --output-event .../events/0004-decision.json
```

A candidate may not declare `accepted`, a human actor, an `OBS`/`SRC` entity
candidate or an edge. A proposal may not contain an edge or an adjudication. A
decision may not choose its own reviewer, identity assurance, evidence or
locators — the controller injects them.

`conflict-register` and `uncertainty-register` append typed `ConflictSet` and
`Uncertainty` objects over existing assertions. They exist because §10 of the
contract requires structured conflicts and uncertainties; the contract's §14
command list is a minimum, not a maximum.

## Materialize, verify, query

```bash
python3 scripts/knowledge_network.py materialize \
  --graph .../graph-state-v00N.json \
  --output-graph .../graph-state-v00N+1.json --output-event .../events/000N+1-materialized.json

python3 scripts/knowledge_network.py verify \
  --graph .../graph-state-v00N+1.json --check-current-files \
  --output-report .../verification/graph.verify.json

python3 scripts/knowledge_network.py query \
  --graph .../graph-state-v00N+1.json --query .../queries/timeline.json \
  --view draft --generated-at 2026-07-24T00:00:00Z \
  --output .../queries/timeline-result.json
```

`materialize` takes no edge input at all. `verify` walks the whole chain,
re-derives the projection and reports every gate separately. `query` binds the
graph state hash and the canonical query hash; `--view publishable` re-runs the
publish gate and exits 3 when it blocks; `--as-of-state` replays an ancestor
state so a withdrawn edge stays recoverable.

## Export

```bash
python3 scripts/knowledge_network.py export-draft \
  --graph .../graph-state-v00N.json --output-dir .../exports/draft

python3 scripts/knowledge_network.py export-publishable \
  --graph .../graph-state-v00N.json \
  --research-case /frozen/research-case.json \
  --integrity-audit /frozen/integrity-audit.json \
  --output-dir .../exports/publish
```

`export-draft` exits 0 and is explicitly not a verified knowledge graph.
`export-publishable` writes its exclusions, conflicts and negative-result
sidecars first and then exits 3 while any gate blocks, including
`no-publishable-content` when no edge is eligible.

## Integrity rules

- Reject symlinks, hardlink aliases, path traversal, oversized JSON, unknown
  fields, duplicate ids, hash drift, existing outputs and non-monotonic versions.
- Recompute every surface, excerpt, carrier, card, registry and asset hash.
- One carrier is one independence group, however often it is transcluded.
- Never merge entities by name, alias, dynasty, office, place or model
  similarity; a high-impact identity claim needs an evidentiary basis dimension,
  two independent evidence groups and an explicit exclusion of each competing
  candidate.
- Never fill in a missing month or day, and never draw an interval as a point.
- Never resolve a conflict by last write, majority vote or same-source
  transclusion; open conflicts block unconditional publication and are always
  listed.
- Never let a graph path imply causation; path output is structural only.
- Never remove the synthetic policy, notice or `SYN-` prefixes.
- Machine output is never ground truth, and an AI actor never satisfies a human
  gate.

## Validate the installation

From the project root:

```bash
PYTHONDONTWRITEBYTECODE=1 \
python3 skills/epigraphy-knowledge-network/tests/test_knowledge_network.py

PYTHONNOUSERSITE=1 PYTHONDONTWRITEBYTECODE=1 \
python3 -m unittest \
  skills/epigraphy-knowledge-network/tests/test_knowledge_network.py
```

The tests are standard-library `unittest` and require no third-party package.
The implementation binding contains 15 files: the controller, `SKILL.md`,
`agents/openai.yaml`, both reference contracts, `schema-catalog.json` and all
nine JSON Schemas. Declare all 15 as material inputs when wrapping a run with
`research-run-ledger`.

## Offline schema resolution

Treat `https://huayun.local/schemas/epigraphy-knowledge-network/` as an
identifier namespace, never a network source. Load every URI-to-file mapping
from [schema-catalog.json](references/schema-catalog.json) into the Draft
2020-12 resolver before validating, and do not permit resolver network fallback.

