Metadata-Version: 2.5
Name: docket-ledger
Version: 0.1.2
Summary: The repo's courtroom: contracts, evidence, verdicts. File-native, deliberately boring.
Project-URL: Repository, https://github.com/pyros-projects/docket
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.12
Requires-Dist: pydantic>=2.7
Requires-Dist: ruamel-yaml>=0.18
Description-Content-Type: text/markdown

<div align="center">

<h1>docket</h1>
<p>The test suite was how CI governed code; the contract is how humans govern agents.</p>

</div>

<div align="center">

[![Python][python-shield]][python-url]
[![Tests][tests-shield]][tests-url]
[![Kernel verdict][verdict-shield]][verdict-url]

</div>

<div align="center">
  <a href="#quick-start">Quick Start</a> &middot;
  <a href="#the-contract-file">Contract format</a> &middot;
  <a href="#commands">Commands</a> &middot;
  <a href="docs/concepts/00-docket-why-and-what.md">Design</a>
</div>

---

## ELI5

**What's the problem?** You tell your agent "never break the public
API", "keep it under 2000 lines", "page within 60 seconds". The rule
holds — for that one task. Next session, new agent, fresh context: the
rule only survives if somebody repeats it. Tests guard your code, but
nothing guards the rules themselves — and even a rule that is written
down somewhere is never re-checked after the next change quietly breaks
it. Repeating rules is not enforcing them.

**How does this repo solve it?** You write the rule down **once**, as a
small YAML contract with a mechanical check attached, and import it
into your repo's ledger. From then on `docket check --all` is a gate:
after every change it re-proves exactly the rules the change touched
and leaves the standing proof of untouched rules alone. Green means
"still proven", not "someone remembered to mention it". The parts a
machine can't judge get routed to a named human instead of being
silently dropped.

**"But can't the AI just ignore all of this?"** Yes — exactly the way a
developer can just never run the tests. And that's fine, because those
are two *different* failures, and only one of them is deadly. A safety
system can **lie from the inside**: it says "checked ✓" when nothing
was really checked — that one kills you, because even when everyone
plays along, green means nothing. Docket is built so this cannot
happen: green only ever comes from a check that actually ran, and a
human "looks fine" can never stand in for a missing proof. Or a safety
system can be **walked around from the outside**: the agent simply
never opens the courtroom. No tool can prevent that (whatever wraps
the agent can be ignored too) — but docket makes it impossible to
*hide*: every state you see is recomputed from the evidence at that
moment, so an ignored ledger shows `stale` and `unproven` the instant
a human glances at it. Closing the walk-around takes one line you
already know: make `docket check --all` a required CI check, and
"ignore it" stops being an option at the merge. Rule of thumb:
**docket guarantees green cannot lie; your CI guarantees nobody ships
without looking.**

## The longer version

Obligations that must hold across many changes have no home. A
change-scoped tool creates requirements while planning a change and
archives them when the change completes — the obligation dies with the
work that satisfied it. At one-human scale that is survivable. When
agents outnumber the humans reviewing them, it is not.

So docket is the repo's courtroom: a file-native ledger of obligations
(contracts), the evidence that satisfies them, and the verdicts that
bind them. Contracts are **amortized authority** — a handful of
sovereign human decisions, mechanically enforced many times without
re-asking. The human appears at three moments: the glance (`status`),
the verdict (`verdict`), the amendment (`amend`). They decide; they
never score.

## Features

- **Evidence that knows what it proved.** Every check binds to the
  clause's own declared slice of the repository (a content-hash
  manifest), its normative text, and its acceptance. Change a file in
  clause A's slice and only A goes stale — its neighbours keep holding
  on their original evidence. Restore the exact bytes and the original
  evidence is admissible again.
- **A door, not a linter.** Contracts enter through the Accord
  (admission checks A1–A9): one MUST per clause, born-checkable
  acceptance, provenance anchors, no qualitative hopes without a number
  or a residue. Import is atomic — one refusal and nothing becomes law.
- **A gate that fails closed.** `docket check --all` exits non-zero for
  every active mechanical clause lacking current green proof —
  `unproven` and `pending-harness` included. An accepted verdict cannot
  substitute for a passing check, an empty evidence bundle holds
  nothing, and a command that mutates its own slice while exiting zero
  is not green.
- **Qualitative law that decomposes instead of being refused.** An
  intent ("do not overengineer") enters as prose plus mechanically
  decidable proxies plus a human-verdict residue clause naming its
  authority. No no-residue escape: full mechanical coverage would claim
  the statement was never qualitative.
- **State is derived, never stored.** Git is the database. Every state
  you see (`holding`, `stale`, `unproven`, `broken`, `review`, …) is
  recomputed from law plus history at read time; no status field exists
  to rot.
- **Producer-agnostic by construction.** Contracts arrive from SFD
  prototype interviews, compiled regulations, SLAs, legacy suites — the
  door defines quality, not the producer. If a change would require
  docket to know who produced or consumes a contract, the change is
  wrong.

## When to use

Reach for docket when an obligation must outlive the changes that
satisfy it — compat promises, SLAs, security policies, architecture
ceilings, "don't overengineer". It is not a task tracker, not CI, not a
spec system, and not a change-lifecycle governor; it deliberately owns
no worktrees, no repair loops, and no second definition of done.

## Quick Start

You never drive docket by hand — your coding agent does. You sign law,
glance at status, and rule on residue; the agent stages, imports,
implements, and proves. So the quickest start is watching that split
play out for real:

**→ [The hands-on tutorial](docs/tutorial.md)** builds a tiny task CLI
under docket end to end — prototype, blind round-trip, a leak becoming
law, TDD against `PENDING-HARNESS`, a broken clause refusing to go
green, and the one human verdict. Every transcript in it is from a
real run played against Claude agents. 20–30 minutes to replay with
your own agent.

The short version of who does what:

- **Your agent** runs the loop: stage the contract, `docket import`
  (the door writes the law), `docket tasks --next`, implement,
  `docket check --all`, `docket file`.
- **You** glance and rule: `docket status`, `docket verdict`,
  `docket amend` — signature, judgment, and law changes stay human.

(The repo's own live example is `.contracts/docket.contract.yaml` —
docket governing itself.)

## Install

Two roads, same destination: both end with the agent skill wired into
your repo (`.agents/skills/docket/` as real files, plus the
`.claude/skills/docket` link) and the tool itself one `uvx` away.

**Road 1 — uv (Python side).** The package carries the skill;
`docket init` materializes it:

```bash
uvx --from docket-ledger docket init
```

(The PyPI distribution is `docket-ledger` — PyPI prohibits the bare
name — but the tool you get is plain `docket`.)

Until the PyPI release — or against the private repo — point uvx at the
source; uv clones through the system git, so gh's credential helper
(`gh auth setup-git`) or SSH keys authenticate it:

```bash
uvx --from git+https://github.com/pyros-projects/docket.git docket init
```

Without any credentials, use a local checkout:
`uvx --from /path/to/docket docket init` — the skill asks for that path
when the other routes fail.

**Road 2 — the skills CLI (Node side):**

```bash
npx skills pyros-projects/docket
```

Inside this repo:

```bash
uv sync
uv run docket --version
```

**Supported:** Linux and macOS, with Python ≥ 3.12, git, and bash on
PATH (acceptance commands run through bash — see the trust model
below). On Windows, use WSL.

## The contract file

Law is YAML: one contract, monotonically numbered clauses, each with
exactly one RFC-2119 obligation, a born-checkable acceptance, and
provenance anchors. The full schema-by-example lives in
[concepts/01](docs/concepts/01-contract-schema-and-door-policy.md).

```yaml
contract: ops
rev: 1
source: "compiled from the on-call SLA §4"
signed: []
intents:
  - id: I-001
    statement: >
      Incidents stay survivable: detection fast, recovery rehearsed,
      the rest judged by a human.
clauses:
  - id: OPS-001
    implements: I-001
    obligation: >
      Alerting MUST page within the contracted latency budget.
    acceptance:
      metric: "scripts/alert-latency.sh"
      threshold: "p95 < 60s"
    anchors:
      - sla: "on-call SLA §4.2"
    scope:
      applies_to: [alerting/**]

  - id: OPS-002
    implements: I-001
    obligation: >
      The restore drill MUST exit clean from a cold backup.
    acceptance:
      command: "scripts/restore-drill.sh"
      expect: drill restores the reference backup end to end
      expect_exit: 0
      expect_stdout: '^restore: OK$'
    anchors:
      - incident: "INC-2041 postmortem"

  - id: OPS-003
    implements: I-001
    obligation: >
      pyro MUST verdict the runbook-quality residue the proxies do
      not cover.
    acceptance:
      verdict: human
      authority: pyro
    anchors:
      - sla: "on-call SLA §6"
```

Three things the door will teach you quickly: a `command:` acceptance
needs a structured expectation (`expect_exit`, and/or `expect_stdout` /
`expect_stderr` regexes) — prose-only `expect:` is admitted but can
never go green; a clause's `scope.applies_to` doubles as its evidence
slice (files, not directories — declare `dir/**`); and anchors carry
provenance (`surface`, `decision`, `incident`, `regulation`, `sla`,
`compat`, `test`, `policy`, `legacy`, `regulation-section`).

## Commands

| Command | What it does |
|---|---|
| `docket import <file>` | Admit a contract through the Accord. Atomic: any refusal writes nothing. |
| `docket check [CLAUSE] \| --all` | Run acceptance, record evidence, derive state. The blocking gate: exits non-zero while any active mechanical clause lacks current green proof. |
| `docket status [--json]` | The glance — derived state of every clause; `--json` adds record stems per clause for machine consumers. |
| `docket tasks [--next --json]` | Derived to-do view: clauses minus admissible evidence. |
| `docket file <clause> --bundle <json>` | File an evidence bundle (append-only, bound to the slice state at filing). |
| `docket verdict <clause> --bundle <stem> --accept\|--reject <type> --by <who>` | The authority rules on a filed bundle. Verdicts hold human clauses; they never substitute for mechanical proof. |
| `docket amend <clause> --obligation <text> --by <who>` | Change the law on the record: door re-run over the amended contract, rev bump, amendment history the validity floor reads. |
| `docket audit` | Coverage views — incompleteness made inspectable. |
| `docket init` | Install the agent skill into this repo (`.agents/skills/docket/` + the `.claude/skills` link) — the uvx twin of `npx skills`. |

The bundle `docket file` takes is JSON with five required keys; evidence
entries are objects with at least a string `kind` and `ref` (a `stuck`
claim additionally needs `stuck_on`):

```json
{
  "clause": "OPS-002",
  "claim": "satisfied",
  "filed_by": "claude-loop#7",
  "rev_at_filing": 1,
  "evidence": [
    {"kind": "test", "ref": "tests/test_restore.py::test_cold_backup", "result": "PASS"},
    {"kind": "trace", "ref": "loop transcript #18", "note": "3 iterations, stop=contract-green"}
  ]
}
```

Docket binds the slice's content state at filing time itself — the
filer's own claims never stand in for it.

## How state derives

Evidence is admissible for a clause only if it passes four checks: the
amendment floor (V1), the clause's normative digest (V2), its
acceptance digest (V3), and its subject slice manifest (V4). Failing
only V4 is `stale` — proven against a prior state of the slice, visible
in history, never silently reused. A mechanical clause is `holding` iff
its latest admissible check is green; a human clause holds on a current
accepted verdict for an admissible bundle. Everything else fails the
gate.

→ [Why and what](docs/concepts/00-docket-why-and-what.md) ·
[Schema and door policy](docs/concepts/01-contract-schema-and-door-policy.md) ·
[Surfaces](docs/concepts/02-surfaces.md) ·
[v0 scope and falsifier](docs/concepts/03-v0-scope-and-falsifier.md)

## Does the thesis hold?

The kernel's one question — *does a contract outlive the changes that
satisfy it?* — was answered on a preregistered bench frozen **before**
the mechanism existed: after a change touching one clause's slice, the
untouched clauses derived `holding` on exactly their original evidence
records; 11 of 12 injection rows matched the frozen predictions, and
the one mismatch is recorded rather than edited away. The repo also
governs itself: its own YAGNI contract (`.contracts/docket.contract.yaml`)
gates every change, and was watched refusing a seeded violation before
the first governed change landed.

→ [Bench run record](docs/runs/2026-07-26-contract-kernel-bench/run.md) ·
[Verdict (DC-0006)](memory/decisions/DC-0006-contract-kernel-v1-bench-verdict-go.md)

## Trust model

Admitted contract YAML is **trusted executable code**: `docket check`
runs acceptance commands via bash with the caller's full privileges.
Import is schema admission through the Accord — not authentication and
not a safety review. `signed:` entries are unverified declarations;
docket verifies no signatures and ships no cryptography. Only import
and check contracts from sources you have reviewed locally.

## Repository notes

The courtroom surfaces sketched in the concept docs (`docket review`,
`docket sign`) were cut by DC-0003 and stay cut. The agent-facing skill lives in
[`skills/docket/`](skills/docket/) — installable with
`npx skills pyros-projects/docket`; the two producer methodologies
(surface-first, contract-first) are its references. Agent operational memory lives in
[`memory/`](memory/); decisions worth reading start at
`memory/decisions/DC-0001` and end, currently, at DC-0006.

---

<div align="center">
<sub>Crafted with <a href="https://github.com/motiful/readme-craft">Readme Craft</a></sub>
</div>

[python-shield]: https://img.shields.io/badge/python-3.12%2B-3776AB
[python-url]: pyproject.toml
[tests-shield]: https://img.shields.io/badge/tests-152%20passing-2ea44f
[tests-url]: tests/
[verdict-shield]: https://img.shields.io/badge/kernel%20verdict-GO%20(DC--0006)-6f42c1
[verdict-url]: memory/decisions/DC-0006-contract-kernel-v1-bench-verdict-go.md
