# CharacterCheck

Experimental, read-only compiler for selected D&D Beyond character fields.
It emits mechanical context, provenance, findings, and immutable snapshots.
It is not complete character validation, encounter/world/session authority, or
proof of action legality. It exposes no mutations.

STATUS:
  This is the CharacterCheck 0.7.0 contract. Historical 0.6.x packages predate
  these safeguards. Pin and verify 0.7.0, then inspect trust-bearing fields;
  the version alone does not make a derived value supported.

START OFFLINE:
  python3 -m charactercheck selftest
  python3 -m charactercheck derive examples/sample-character.json --brief

INPUT:
  Exact positive numeric ID, exact HTTPS dndbeyond.com/characters/<id>, a
  direct local JSON file where allowed, or CharacterSnapshotV1. Inputs are
  size/depth/count bounded and structurally validated. Raw local/remote payloads
  are limited to 8 MiB; local snapshot envelopes to 16 MiB. Missing paths never
  become IDs.

TRUST:
  Read meta, then canonical fields for every value. Use trust for family routing
  and lint/unhandled for evidence and questions. QA rows pair each answer with
  one of the 100 catalog questions; the wording never strengthens row trust.
  "trusted" means no detected
  finding within supported coverage, not globally safe. Family ask_player maps
  to field confirm. Do not improvise through unsupported/unknown/invalid.

PRIVACY:
  Defaults omit account identifiers, linked images, notes, appearance, and
  persona. Explicit trusted local CLI/library persona opt-in is bounded
  untrusted data. MCP exposes no persona, local-file access, authentication,
  role enforcement, or mutation.

SNAPSHOT/DIFF:
  charactercheck snapshot <ref> > baseline.json
  charactercheck diff <ref> --baseline baseline.json
  normalized_data_hash is the default privacy-filtered mechanical revision;
  snapshot_character_hash covers the stored filtered character. Three coverage
  booleans disclose only that unclassified top-level/nested fields or unsafe
  semantic values were omitted. A fourth values-free list names only canonical
  families affected by reviewed mechanical omissions. Derived views repeat the
  typed coverage under meta.source_coverage. Reviewed display/provenance fields
  are trust-neutral; reviewed mechanical omissions route listed families to
  unsupported; unknown-scope omission routes every family to unknown; fixed
  root-item semantic gaps route affected families to unsupported.
  Non-item and nested-item gaps remain global unknown until their dependencies
  are classified.
  Distinct comparisons also become indeterminate at `$` when private modifier-
  restriction semantics were omitted. Same mechanical revision plus a named
  persona/non-mechanical delta is mechanically_unchanged; only exact identity is
  unchanged without findings. Comparisons apply nothing.
  Hashes are unkeyed identifiers, not signatures, provenance, or authorization.

LIBRARY:
  Use derive(ref) or stance(ref) for canonical trust-bearing views. Plain
  fetch(ref) and raw engine.build fail with source_coverage if source values
  were omitted; build is not a package export. Never strip coverage or fixed
  _semanticGaps by recomposing a plain character dict.

ECOSYSTEM:
  Adapter IDs/names come from a pinned offline DDB config registry; membership
  does not mean mechanics are implemented, and runtime performs no config
  fetch. CharacterCheck is a DDB-to-agent compiler/conformance facade, not a
  complete rules engine. DDB, Foundry, and other outputs are attributed claims
  or oracles; unexplained disagreement remains non-trusted conflict.

EXIT (command-specific):
  derive/report: 0 no lint/unhandled, 1 lint only, 2 any unhandled record.
  diff: 0 complete and unchanged, 1 any named change or indeterminate omitted-
  source comparison. stance/qa/snapshot/quiz/seatpack/intake: 0 when emitted;
  inspect their fields/findings. selftest: 0 pass, 1 fail. doctor and structured
  runtime/input failures: 3. Unsupported command-specific flags are structured
  bad_flag exit 2; argparse syntax/usage errors are plain-text exit 2. Never
  treat exit 0 or 2 as autonomous readiness.

MCP TOOLS:
  derive, stance, qa, diff, snapshot, seatpack, quiz, report, intake,
  selftest, doctor.

Read README.md, SUPPORT.md, PRIVACY.md, SECURITY.md, and AGENTS.md.
