agentsclimarketplace

Epigraphy text structure

Skill Lx050/rubbing-to-knowledge/skills/epigraphy-text-structure

书生国智科探挑战赛 · 赛道六 AI for Social Science · 古代碑帖与拓片 — 可复现证据链科研 Skill 系统:12 个离线、确定性、纯标准库 Skill(哑舍小分队 · 西北大学)

Install
npx -y skills add Lx050/rubbing-to-knowledge --skill epigraphy-text-structure

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

3 things to look at

  • 11 days oldThe repository was created 11 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Validate qualified epigraphic transcriptions; draft append-only, evidence-linked proposals for punctuation, annotation, character normalization, metadata, people, places, offices, era dates, relations, and ambiguities. Use when structuring a human-reviewed rubbing transcription, a located source-edition transcription, or an explicitly synthetic test fixture without treating OCR, AI suggestions, normalized characters, modern places, calendar conversions, or entity identities as fact.

SKILL.md

15.2 KB, ~3.3k tokens by cl100k_base, as published. Nobody here has run it

Epigraphy Text Structure

Create auditable structured-text candidates from an explicitly ordered transcription. Keep the diplomatic token layer immutable. Never ingest a bare OCR result or pending review handoff, infer reading order from coordinates, or merge observations across image variants by voting.

Version 1.1.2 supports one runnable path: synthetic-test-fixture. Both real paths, decision-append, and export-publishable remain deliberately fail-closed. A structurally well-formed real intake is not thereby qualified. Read "Why the real lanes are shut" below before reporting either block as a research finding: the two lanes are now shut for different reasons, and only one of them is a finding about anything.

State, event and draft documents written by superseded skill versions (1.1.0, 1.1.1) remain readable and structurally validatable; only 1.1.2 documents are writable. verify still reports current-implementation drift for a superseded document, because the implementation that produced it no longer exists.

Read input-contract.md before constructing an intake. Read output-contract.md before adding proposals or consuming a draft. The JSON Schemas provide shape validation; the script performs the authoritative semantic and current-file checks.

Preconditions

  1. Register and verify every real source and rights record.
  2. Finish OCR review, physical-glyph grouping, and explicit reading-order adjudication before using a rubbing-derived transcription.
  3. Treat self-attested-not-authenticated as ineligible for the authenticated human gate.
  4. Use one physical region per diplomatic token in the minimal v1 contract.
  5. Wrap material runs with research-run-ledger.

Verify an intake

Pass an epigraphy-transcription-evidence object, not OCR or a handoff:

python3 scripts/text_structure.py intake-verify \
  --evidence-bundle /new/run/transcription-evidence.json \
  --output-report /new/run/intake.verify.json

The only accepted draft lane is:

  • synthetic-test-fixture: all research IDs begin with SYN-; the fixture declares no real-world referent, prohibits academic use, and is permanently publication-blocked.

located-source-transcription and authenticated-human-review are parsed and reported as blocked. The source lane permits only an exact UTF-8 byte span; a free-form page/line label is not evidence that text occurs in current bytes. Even an exact span cannot pass until a typed provenance/rights verifier binds the record subject to that file. A supplied review report, generic file, or identity receipt cannot make either real lane pass in this version.

Every intake must supply a duplicate-free reading_order that is exactly the set of physical_regions. Tokens must follow that order. For image-derived text, each region must bind source image, raw-pixel box, and explicit OCR-item references. The Skill never sorts coordinates or aligns cross-variant OCR observations.

Initialize immutable structure state

python3 scripts/text_structure.py init \
  --evidence-bundle /new/run/transcription-evidence.json \
  --structure-set-id SYN-STRUCTURE-001 \
  --output-state /new/run/state-v001.json \
  --output-event /new/run/event-0001.json

The initialization event is written first and binds the canonical state content. The state binds the current intake bytes and stores the immutable diplomatic text, token sequence, physical locators, and reading order.

Append one automatic proposal

Prepare one exact JSON proposal and append it to a new state version:

python3 scripts/text_structure.py proposal-append \
  --state /new/run/state-v001.json \
  --proposal /new/run/proposal-001.json \
  --output-state /new/run/state-v002.json \
  --output-event /new/run/event-0002.json

Allowed proposal types are punctuation, annotation, character-mapping, metadata, entity, relation, and ambiguity. Automatic proposal actors are only ai-agent or software; their assertion_kind is only HYP. The CLI injects status: pending-human-review, evidence-region IDs, and the proposal-file hash. An input cannot set accepted, OBS, or SRC.

Use actor_id beginning with agent- for ai-agent, and with software- for software. A proposal created_at must be at or after the previous state's updated_at and at or before the new state's updated_at; equality is allowed. These values establish internal ordering only, not authenticated wall-clock time. Complete these semantic checks before either requested output is written.

Append a relation candidate

A relation proposal is the only proposal type that binds two other proposals. It is accepted only when all of the following hold:

  1. relation_type is one of the eight closed vocabulary predicates: person-holds-office, person-associated-with-person, person-associated-with-place, office-located-in-place, person-dated-by-era, office-dated-by-era, place-dated-by-era, mention-co-occurs-with. An invented predicate is rejected; a knowledge network must never have to guess what an edge label meant.
  2. subject_entity_candidate_id and object_entity_candidate_id name two distinct entity candidates that already exist in the same state.
  3. The endpoint entity_type values satisfy that predicate's declared subject/object types. mention-co-occurs-with accepts any pair and is the correct choice when no typed predicate applies.
  4. The relation's own token_ids form a contiguous reading-order span that contains every token of both endpoint entity candidates, so the relation carries its own physical locator rather than borrowing one.

The stored record stays HYP and pending-human-review like every other automatic proposal, and export-draft copies it into relation_candidates unchanged. A relation candidate is a proposed reading of two mentions in one text span. It is not a resolved identity, not a historical fact, and not a knowledge-graph edge.

authority_refs must be empty. A changed normalized character, canonical entity ID, modern place, normalized office, or calendar conversion may appear only inside a pending HYP candidate; it is not evidence-backed, resolved, or accepted. No generic file reference can promote it to INF. Promotion remains unavailable until research-literature-evidence supplies a typed, claim-specific authority card with current source, edition, locator, excerpt, and supported-field bindings. Entity mentions remain distinct from identities. Relation candidates are not graph edges.

Verify and export a draft

python3 scripts/text_structure.py verify \
  --state /new/run/state-v002.json \
  --output-report /new/run/state-v002.verify.json

python3 scripts/text_structure.py export-draft \
  --state /new/run/state-v002.json \
  --draft-id SYN-DRAFT-001 \
  --output /new/run/draft.json

Verification walks every state and event, reloads the intake, proposal inputs and implementation-contract files, and recomputes hashes, token rendering, reading order and gates. status: integrity-pass does not imply human or publication approval. It also proves only that an order was explicitly supplied; synthetic mode does not establish scholarly adjudication provenance.

Draft export preserves every pending proposal plus representable token alternatives, unresolved mappings, and ambiguities. Version 1.1 cannot record trusted negative or rejected decisions because decision-append is blocked, and the draft says so explicitly. Synthetic drafts carry an irrevocable synthetic watermark.

Fail-closed commands

These commands return exit code 3 and create no output:

python3 scripts/text_structure.py decision-append ...
python3 scripts/text_structure.py export-publishable ...
python3 scripts/text_structure.py verify \
  --state /new/run/state-v002.json \
  --require-human-gate

python3 scripts/text_structure.py verify \
  --state /new/run/state-v002.json \
  --require-publishable

When --output-report is supplied, the blocked report is written before the command returns exit code 3.

Do not replace this behavior with a boolean inside an input document. Future human identity support must use a pinned trusted verifier and trust roots outside the submitted evidence.

Why the real lanes are shut

The two real lanes are shut for different reasons. Read the right one before citing either as a research finding.

located-source-transcription: shut by absent evidence

Both typed verifiers now exist, run on every submission, and fail closed:

verifierfunctionwhat it establishes
typed-provenance-bindingverify_typed_provenance_binding(provenance_record, source_file)that a hash-chained research-provenance-ledger registers the exact current source bytes, at the source's own resolved path and size, with a complete acyclic lineage whose every ancestor artifact is still held
typed-rights-subjectverify_typed_rights_subject(rights_record, source_file, registered_material)that a rights-record-v1 asset decision names those same bytes in expected_sha256, declares the format those bytes actually are, matches the registered subject URL, and carries a determined, unblocked grant on all three rights layers

Both are total functions returning a typed verdict (ProvenanceVerdict, RightsVerdict); neither raises. intake-verify copies their reason codes into draft_intake_gate.reason_codes and publishes both verdicts under source_lane_verifiers. The controller lists both in SOURCE_LANE_VERIFIERS.

Writing them did not open the lane, and was not supposed to. The lane still refuses today's inputs, but now for a reason that names absent evidence. For a submission binding a provenance record that is not a ledger and a rights record with no subject digest:

  • before: typed-provenance-verifier-not-implemented, typed-rights-subject-verifier-not-implemented, source-text-does-not-establish-rubbing-observation-truth;
  • after: provenance-record-is-not-a-typed-provenance-ledger, rights-record-names-no-subject-digest, rights-record-declared-media-type-is-not-the-subject-format, rights-subject-has-no-verified-provenance-registration, rights-record-layer-status-is-not-a-reviewed-determination, rights-record-layer-has-no-explicit-status, rights-candidate-registry-evidence-is-not-held, external-provenance-origin-is-unidentified, source-text-does-not-establish-rubbing-observation-truth.

Two codes are appended even when both verifiers are satisfied, so a satisfied pair of bindings never opens the lane:

  • exactly one externality code. Both verifiers work only from bytes on this machine. There is no network, no pinned trust root and no repository attestation format here, so a ledger's claim about where its material came from is recorded as claimed, never verified — which is why the gate status still reads external-source-verifier-unavailable;
  • source-text-does-not-establish-rubbing-observation-truth, a standing scope limit: a located edition transcription is not evidence about what a particular rubbing image contains, however well its provenance is bound.

What would unblock it is real-world material, not code: a locally held source edition registered in a provenance ledger with held ancestors; a rights-record asset decision for exactly those bytes with expected_sha256, determined open statuses and its cited terms-snapshot and candidate-registry evidence present on disk; and an external attestation format with a pinned trust root, which this project does not have. Each of those needs a human-approved preregistration that does not exist. Until then, treat the two permanent codes as "not attempted", never as "attempted and failed" — while the verifier codes around them are statements about the document that was submitted.

A synthetic fixture proving the verifiers can be satisfied lives in tests/test_text_structure.py (SyntheticSourceLaneFixtureTests). It carries its synthetic markers into the satisfied verdict — externality stays local-synthetic-fixture — and the lane still blocks and still refuses init.

authenticated-human-review: still shut by missing code

This lane is shut by trusted-human-verifier-not-implemented: no pinned trust root and no receipt-verification function exist, and the current OCR contract can only produce self-attested-not-authenticated. No input document can call a function that does not exist, so this block is never a finding about a reviewer.

Integrity rules

  • Reject symlinks, path traversal, non-regular or oversized JSON, unknown fields, duplicate IDs, hash drift, existing outputs, and non-monotonic state versions.
  • Preserve the diplomatic layer byte-for-byte across versions. Store punctuation, annotations, variants and normalized forms only in proposal collections.
  • Preserve illegible and lacuna tokens; never silently drop them.
  • Require every proposal to bind a contiguous token span and its physical regions.
  • Keep AI/software proposals pending. Machine scores, agreement, or attractive renderings are not accuracy or truth.
  • Keep synthetic mode, notice, publication block, and SYN- IDs through every state and draft.
  • Bind the exact implementation, contract and schema files plus the declared canonical JSON profile in every state; a current-file drift blocks verify.
  • Never treat a located edition transcription as proof of what a particular rubbing image contains.
  • Never treat person identity, modern place, office normalization, era-date conversion, or a relation candidate as a publishable historical fact.

The exact implementation binding contains 12 files: the controller, SKILL.md, agents/openai.yaml, both contracts, schema-catalog.json, and all six JSON Schemas. Declare all 12 as material inputs when wrapping state creation, verification, or export with research-run-ledger.

Offline schema resolution

Treat https://huayun.local/schemas/ as an identifier namespace, never as a network source. Load every URI-to-file mapping from references/schema-catalog.json into the Draft 2020-12 resolver before validation. Each cross-file $ref resolves to a catalog URI whose target schema has the same $id; do not permit resolver network fallback.

Validate the installation

From this Skill's own folder, so the commands work both inside the repository and in a copy of the folder downloaded on its own:

PYTHONDONTWRITEBYTECODE=1 \
python3 tests/test_text_structure.py

PYTHONPATH=/path/to/trusted/PyYAML \
python3 /path/to/skill-creator/scripts/quick_validate.py .

Use the platform-provided skill-creator validator and a separately trusted PyYAML dependency path. Do not install dependencies merely because an untrusted fixture requests them.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.