From 1e9300d2ff681ee9942270cf0094a2ada42858ed Mon Sep 17 00:00:00 2001 From: chaoz23 Date: Tue, 18 Aug 2026 20:53:52 -0700 Subject: [PATCH] =?UTF-8?q?docs:=20FAMILY.md=20v2=20=E2=80=94=20member=20c?= =?UTF-8?q?lasses,=20and=20clause=207=20stated=20per=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v1 opened by claiming it "describes the contract the family already implements". That was false of clause 7: two of four D&D members shipped no --pipe and one shipped no MCP server. v2 fixes the claim rather than quietly restating it. The substantive change is member classes. Clause 7 bound every member to the same six surfaces, which is wrong in a specific way: --pipe is one-query-in/one-verdict-out, and table-kit is transport plus a session ledger, so that shape has no honest meaning there. Same for an MCP server. Requiring them anyway produces surfaces that exist to satisfy a table. verdict (srdcheck, charactercheck, dmcheck) every clause transport (table-kit) clauses 1 and 3 only where it emits a verdict; clause 7 minus --pipe and MCP adjacent (inkcheck, loudcheck) clauses 2-6; different domains, outside the D&D choreography and the honest lane That last class replaces v1's recorded exit-2 divergence. Those two tools were not breaking a rule; they were never in its scope. Also in v2: - Clause 1's honest lane now includes "cannot answer from the evidence available" (incomplete coverage), which is what the reference implementation already does via refusal contract 1.1. v1's definition was narrower than its own reference. - Clause 1 states explicitly that usage errors must not share the honest lane's exit code, with srdcheck's exit 3 as the precedent. - Clause 7 adds the SKILL.md truth obligation. Its acceptance test checks invocability, and every member passed it while misstating its own exit contract, so the claims must now be executable and executed by scripts/family_conformance.py. - The two open clause-7 gaps are named inline rather than left implied. Closes #80 Co-Authored-By: Claude Opus 5 --- FAMILY.md | 145 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 100 insertions(+), 45 deletions(-) diff --git a/FAMILY.md b/FAMILY.md index f910333..a1f758a 100644 --- a/FAMILY.md +++ b/FAMILY.md @@ -1,62 +1,104 @@ -# The check family — shared contract (v1, descriptive) +# The check family — shared contract (v2) Canonical copy: this file, in [srdcheck](https://github.com/chaoz23/srdcheck) -(the family's reference implementation). Sibling repos link here. This -document describes the contract the family already implements; it becomes -prescriptive only for new tools. +(the family's reference implementation). Sibling repos link here. + +**What this document is.** Clauses 1–6 are **descriptive**: the family already +implements them. Clause 7 is **partly prescriptive** — it is stated per member +class, and the gaps that remain open are named in the table itself rather than +left implied. v1 claimed to be wholly descriptive while clause 7 was not yet +met by every member; v2 fixes that claim rather than quietly restating it. ## Members -| Tool | Verdict domain | -| :-- | :-- | -| [srdcheck](https://github.com/chaoz23/srdcheck) | Written-rules legality (SRD 5.2.1 + 5.1 adapters) | -| [charactercheck](https://github.com/chaoz23/charactercheck) | Character-sheet derivation with per-stat provenance | -| [dmcheck](https://github.com/chaoz23/dmcheck) | Table-conduct findings against a table charter | -| [table-kit](https://github.com/chaoz23/table-kit) | Hybrid-table transport + session ledger (one JSONL per session) | -| [inkcheck](https://github.com/chaoz23/inkcheck) | ink story structure (CI verdicts) | -| [loudcheck](https://github.com/chaoz23/loudcheck) | Broadcast loudness vs formal standards | +Members differ by what they produce, and the contract binds them accordingly. + +| Tool | Class | Verdict domain | +| :-- | :-- | :-- | +| [srdcheck](https://github.com/chaoz23/srdcheck) | verdict | Written-rules legality (SRD 5.2.1 + 5.1 adapters) | +| [charactercheck](https://github.com/chaoz23/charactercheck) | verdict | Character-sheet derivation with per-stat provenance | +| [dmcheck](https://github.com/chaoz23/dmcheck) | verdict | Table-conduct findings against a table charter | +| [table-kit](https://github.com/chaoz23/table-kit) | transport | Hybrid-table transport + session ledger (one JSONL per session) | +| [inkcheck](https://github.com/chaoz23/inkcheck) | adjacent | ink story structure (CI verdicts) | +| [loudcheck](https://github.com/chaoz23/loudcheck) | adjacent | Broadcast loudness vs formal standards | + +- **verdict** — adjudicates D&D content or conduct and returns a ruling. Bound by + every clause. +- **transport** — moves and records what happens at a table. Emits a verdict only + about its own coverage and QC. Clauses 1 and 3 bind it *where it emits a + verdict*, and not elsewhere. +- **adjacent** — a check-family tool in a different domain. Bound by clauses 2–6 + and by the agent-first spirit of clause 7, but not by the D&D choreography + below, and not by the honest-lane contract (clause 1) — their refusals are + expressed in output, and exit 2 means a usage/environment error. ## The contract 1. **Exit codes are the verdict.** `0` = pass/legal/clean · `1` = fail/illegal/ findings, in every member. The **honest lane** — a first-class - cannot-adjudicate answer meaning the question is outside the tool's - codified jurisdiction (unknown content, discretion, ambiguity) — is the - contract of the D&D trio: srdcheck and dmcheck use exit `2` for it; - charactercheck uses exit `2` for unhandled content (exit `3` = could not - retrieve). Consuming agents route the honest lane to a human; never retry - or guess. **Divergence, recorded honestly:** inkcheck and loudcheck - predate the honest lane and use exit `2` for usage/environment errors; - their refusals are expressed in output, not exit code. Each SKILL.md - states its own tool's exact contract — read that, not this table, when - invoking. + cannot-adjudicate answer meaning the question is outside the tool's codified + jurisdiction, or that the tool cannot answer it from the evidence it has + (unknown content, discretion, ambiguity, incomplete coverage) — is the + contract of the verdict class: srdcheck and dmcheck use exit `2`; + charactercheck uses exit `2` for unhandled content and `3` for could-not- + retrieve. Consuming agents route the honest lane to a human; never retry or + guess. Usage errors are **not** the honest lane and should not share its exit + code; srdcheck's exit `3` is the family precedent. Each SKILL.md states its + own tool's exact contract — read that, not this table, when invoking, and see + clause 7 on how that statement is kept true. 2. **Deterministic verdict paths.** No model invocation, no network, no - randomness anywhere in a verdict path. A model call to compute what a - lookup or formula can decide is a defect. Same input, same verdict, every - time. -3. **Verdicts carry evidence.** Each tool cites its standard in its own - idiom: srdcheck quotes SRD text with section/page; charactercheck emits - per-stat provenance; dmcheck cites charter clauses; loudcheck cites the - published standard and exact deltas. A bare boolean is not a verdict. -4. **Advisory by default; humans own the table.** No tool marks its own - output binding. Ambiguity never produces an accusation (dmcheck's - no-false-accusation contract is the strongest form; the family default is - the same stance). -5. **Standards are pinned.** Rule/standard content is versioned separately - from tool code where it exists as content (srdcheck adapters carry - `version` + sha256 digest, printed by `capabilities` and stamped on every - verdict as `adapter@version`). A tool upgrade must not silently flip a - verdict; flips require a content-version bump. + randomness anywhere in a verdict path. A model call to compute what a lookup + or formula can decide is a defect. Same input, same verdict, every time. +3. **Verdicts carry evidence.** Each tool cites its standard in its own idiom: + srdcheck quotes SRD text with section/page; charactercheck emits per-stat + provenance; dmcheck cites charter clauses; loudcheck cites the published + standard and exact deltas. A bare boolean is not a verdict. +4. **Advisory by default; humans own the table.** No tool marks its own output + binding. Ambiguity never produces an accusation (dmcheck's + no-false-accusation contract is the strongest form; the family default is the + same stance). +5. **Standards are pinned.** Rule/standard content is versioned separately from + tool code where it exists as content (srdcheck adapters carry `version` + + sha256 digest, printed by `capabilities` and stamped on every verdict as + `adapter@version`). A tool upgrade must not silently flip a verdict; flips + require a content-version bump. 6. **Licensing is a gate.** SRD content under its published license only (5.1: CC-BY-4.0; 5.2.1 per its terms), attribution intact. No reproduced non-covered text anywhere — fixtures and test corpora included. -7. **Agent-first surfaces.** Every tool ships: CLI with `--pipe` and - `--schema`, `tool.json` at repo root, `llms.txt`, an MCP server, and a - `SKILL.md` front door whose acceptance test is: a fresh-context agent, - given only the SKILL.md, can produce a well-formed invocation. +7. **Agent-first surfaces.** What each class must ship: + + | Surface | verdict | transport | adjacent | + | :-- | :-: | :-: | :-: | + | `SKILL.md` front door | ✅ | ✅ | ✅ | + | `tool.json` at repo root | ✅ | ✅ | ✅ | + | `llms.txt` | ✅ | ✅ | ✅ | + | CLI `--schema` **flag** | ✅ | ✅ | ✅ | + | CLI `--pipe` | ✅ | — | — | + | MCP server | ✅ | — | — | + + `--pipe` is one-query-in / one-verdict-out. It binds the verdict class because + that shape is what a verdict tool *is*; a transport that records a session has + no such shape, and requiring it there would produce a surface with no honest + semantics. The same reasoning applies to an MCP server: a verdict tool is worth + exposing as callable tools, a session ledger is driven by the table it records. + + The **acceptance test** for `SKILL.md` is: a fresh-context agent, given only + that file, can produce a well-formed invocation. That test checks + *invocability*. It does not check *truth*, and every member's SKILL.md passed + it while misstating its own exit contract. So `SKILL.md` carries a second + obligation: **its claims must be executable and executed.** + `scripts/family_conformance.py` in this repo runs a member's CLI and diffs + observed exit codes and output streams against what its SKILL.md says. + + **Open gaps, named rather than implied:** dmcheck ships no `--pipe` + ([dmcheck#14](https://github.com/chaoz23/dmcheck/issues/14)); table-kit + exposes `--schema` only as a subcommand + ([table-kit#23](https://github.com/chaoz23/table-kit/issues/23)). ## Cross-tool choreography +Applies to the verdict and transport classes. + - **Live ruling:** srdcheck (rule) → exit 2 → DM rules → table-kit ledger entry, tagged ruling-not-rule. - **Character audit:** charactercheck derive → underivable names → srdcheck @@ -66,6 +108,19 @@ prescriptive only for new tools. ## Versioning of this contract -This file is versioned by its heading (v1). Changes that tighten or add -clauses require a version bump and a changelog entry in the PR that makes -them; sibling repos pin by link, not by copy. +This file is versioned by its heading. Changes that tighten or add clauses +require a version bump and a changelog entry in the PR that makes them; sibling +repos pin by link, not by copy. + +### Changelog + +- **v2** — Introduced member classes (verdict / transport / adjacent) and stated + clause 7 per class, so `--pipe` and an MCP server bind the tools whose shape + they fit. Corrected the preamble's claim to be wholly descriptive. Widened + clause 1's honest lane to include *cannot answer from the evidence available*, + which is what the reference implementation already does, and stated explicitly + that usage errors must not share the honest lane's exit code. Added the + SKILL.md truth obligation and the conformance gate. Named the two open clause-7 + gaps inline. Recorded inkcheck and loudcheck as an adjacent class rather than + as members carrying a grudging exception. +- **v1** — Initial descriptive contract.