Skip to main content

Runnable AGENT.md compile loop for scriptorium: drives `scrip` via subprocess + Claude. Not part of the deterministic scrip core.

Project description

scrip-harness — the runnable compile loop

The deterministic scrip keeper does staleness, provenance, and queries. It never calls a model. scrip-harness is the optional judgment layer that makes the AGENT.md COMPILE step runnable: it asks Claude to synthesize a wiki page from a source, then hands every verifiable step back to scrip.

The dependency points one way only: the harness depends on scrip (and the Anthropic SDK); scrip depends on neither. Removing this directory leaves a fully valid, fully deterministic vault and CLI behind.

How a compile runs

scrip-harness compile <slug> (for vault/raw/<slug>.md):

  1. Draft — Claude (claude-opus-4-8, adaptive thinking, structured output) returns a DraftPage: a title, markdown prose with footnote markers [^a1], [^a2], …, and one verbatim quote per marker.
  2. Mint — each quote goes through scrip anchor, which fails the compile if the quote isn't present in the source or isn't unique. A hallucinated or paraphrased quote cannot get past this step.
  3. Scaffold + fillscrip new writes the frontmatter; the harness fills the body with the prose + the minted footnote definitions.
  4. Stamp + verifyscrip stamp records provenance hashes; scrip verify proves every citation resolves. If verify fails, the compile errors out rather than leaving a stamped-but-broken page.

So the model owns what to say; scrip owns what is true on disk.

How an extract runs

scrip-harness extract <slug> (for vault/raw/<slug>.md):

  1. Draft — Claude returns a DraftExtraction: structured claims, each with a verbatim quote, a subject/predicate/object triple, and a polarity.
  2. Mint + append — the claims go to scrip fact add --stdin, which verifies every quote (minting anchors), assigns ids and timestamps, skips exact duplicates, and appends all-or-nothing under the write lock.
  3. Retry — if quotes come back BROKEN/AMBIGUOUS, the failures go back to Claude for one replacement per failure (lengthened until unique, or an empty quote to drop the claim); bounded retries, then the extract fails cleanly.
  4. Stamp + verifyscrip stamp vault/facts/_meta.yaml, then scrip verify; contradiction candidates from scrip query contradictions are surfaced for the operator to RECONCILE per AGENT.md.

How a promote runs

scrip-harness promote <slug> (for a compiled vault/wiki/<kind>s/<slug>.md):

  1. Scorescrip similar ranks existing pages by overlap (shared sources + title tokens + derived tags) with the candidate, excluding itself.
  2. Band the top score: --merge-threshold (0.5) → merge into it, deterministically (no model); < --keep-threshold (0.25) → keep the page as its own; in between → Claude decides merge-vs-keep over the small candidate set (the only model call in PROMOTE).
  3. Merge — append the candidate into the target (its [^a1].. footnotes renumbered to avoid collision), union the derived-from, record the absorbed id in supersedes, delete the absorbed page, then scrip stamp + scrip verify. --dry-run prints the decision and mutates nothing.

How a reconcile runs

scrip-harness reconcile (over every open contradiction):

  1. Findscrip query contradictions lists the candidate pairs (same subject+predicate, opposing polarity, different sources, not yet adjudicated).
  2. Read — for each pair, scrip span --claim <id> fetches both verbatim cited spans, and Claude decides supersede (with a winner), qualify, or keep-both, with a rationale.
  3. Record — the decisions are written append-only with scrip fact add --table reconciliations (existing claim rows are never rewritten), logged to wiki/log.md, then scrip stamp + scrip verify. Adjudicated pairs stop being surfaced by scrip query contradictions. --dry-run prints the decisions without recording.

Install & run

Both packages are on PyPI. scrip-harness bundles scriptoria as a dependency and drives it through its own interpreter, so it is self-sufficient — install scriptoria as a tool too only if you want the scrip command on PATH for direct use:

uv tool install scrip-harness            # this package → `scrip-harness` (pulls scriptoria)
uv tool install 'scriptoria[ingest]'     # optional: `scrip` on PATH + HTML/PDF ingest
export ANTHROPIC_API_KEY=...              # the harness calls Claude; scrip never does

scrip-harness compile article            # synthesize + verify a page from raw/article
scrip-harness extract article            # pull claims into facts/
scrip ingest <url> --slug article        # bring a source in (needs the install above)

(From a checkout, uv tool install ./scrip and uv tool install ./harness install the local versions instead.)

Develop / test

cd harness && uv run pytest        # hermetic: the model is stubbed; scrip runs for real

The tests inject a stub draft function (no network, no API key) and drive the real scrip subcommands over a temp vault, asserting the result is stamped and verified.

Scope & limits (v1)

  • Covers COMPILE (one source → one wiki page), EXTRACT (one source → claims in facts/, with the bounded quote-retry loop), PROMOTE (score → merge/keep, model only in the middle band), and RECONCILE (adjudicate every contradiction → record the decision). Entities/edges go through scrip fact add --table entities|edges by hand.
  • Single source per page/extract; merge is append (not re-synthesis). reconcile records the decision (supersede/qualify/keep-both); for a qualify, authoring the nuancing polarity: qualifies claim + the page caveat is still operator follow-up. Multi-source synthesis, and adopting the quote-retry loop in COMPILE too, are future work.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scrip_harness-0.5.0.tar.gz (64.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scrip_harness-0.5.0-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file scrip_harness-0.5.0.tar.gz.

File metadata

  • Download URL: scrip_harness-0.5.0.tar.gz
  • Upload date:
  • Size: 64.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for scrip_harness-0.5.0.tar.gz
Algorithm Hash digest
SHA256 37a3cf02dc1b9528dd915a99929f26b8e60622e50b6a18ea603424ba0c4bffc1
MD5 843345e35cd9a8a587974a9cbfc4c2ba
BLAKE2b-256 f039d60938b5eb5d8b54c2b274902903a96b419d8b62a5ff650f1c44c25fecb8

See more details on using hashes here.

File details

Details for the file scrip_harness-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: scrip_harness-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 20.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for scrip_harness-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8ab50ff2ffc0d8dd2bfc2df4067a172f8dfd9d4ed7e644761d78a362014404b5
MD5 e2f2da8e9f166e13d837e61e36cdb99e
BLAKE2b-256 2dd9bb631563b388929a7c830d50eaef159146b384ab15438e68d386f0e76560

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page