4. The smallest law
Draft 2, the author session, 3 November 2026 — re-cut on the construction from the first draft of 3 November. Provenance tags as plan.md §2; the record is renavondata/jack at 6ebea1a. The kernel quoted is the one at that commit, 450 lines by tools/count_kernel.py; appendix B carries it whole.
The figure: Dr Bonham
In 1610 the College of Physicians fined Thomas Bonham for practising without its licence and kept half the fine. Coke, for the court, held the College's judgement void: no one may be judge in his own cause, and a body that profits from a conviction is not a court but a party. The judgement has been argued over for four centuries, and the argument has never touched the maxim — only how far it reaches. Here it reaches the whole way. The record of chapter 3 says who wrote each line; this chapter says who may, what counts, and who decides — and the one who decides is never the one who proposed.
4.1 What we have, and what it cannot do
We have a record anyone with a key can append to, which faithfully says who did. It does not say which keys exist or what each may write; it does not say what makes an entry valid beyond its shape; and it does not say who judges a proposal to extend it. Hart (1961) named these as exactly the three defects of a regime of rules of conduct alone — uncertainty, a static character, inefficiency — and the three secondary rules as their remedies, together enough to make "indisputably a legal system" (ch. V §3): a rule of recognition, rules of change, rules of adjudication. On the book's reading, which is defect-for-defect rather than Hart's claim, a regime lacking any one of them keeps its defect: it cannot tell law from not-law, cannot change lawfully, or cannot settle a breach. This chapter builds the three and nothing else. Everything a reader might expect of a law — rules about what proposers may do — is absent, deliberately, and the last section says what that absence costs and when it ends.
4.2 Recognition — what counts as a valid entry
Recognition is the function check_entry in kernel/check.py, forty-six lines, called once per line by check, which folds the log from an empty state and returns the first refusal or the count [kernel/check.py:check, lines 103–111]. The state it folds is ten things [kernel/check.py:State]: the head hash; the keys, each a principal, a public-key blob and a set of powers; the owners, a map from blob to key id for the life of the log; the promulgated charter; the amendments with their heights; the trusted base in force; the transmuted set; the forecasts, seq to proposer; the resolved seqs; and the previous entry's timestamp. Nothing else is state, and the charter in force at any position is computable from it [State.charter_at].
The predicate runs in a fixed order, and the first failure decides [SPEC §8]. The order is not incidental: it determines which of two defects a line is refused for, and the two checkers must agree on that, so the order is part of the law.
| step | check | reason | where |
|---|---|---|---|
| 1 | the line parses as a canonical JSON object | malformed_json, not_canonical | log.py:parse_line |
| 2 | exactly the seven members, each of the right shape; ts a real UTC instant in ASCII digits | schema | log.py:check_shape, instant |
| 2a | ts not earlier than the previous entry's (genesis exempt) | ts_decreased | check.py line 59 |
| 3 | seq equals the line's index | bad_seq | line 61 |
| 4 | parent equals the head | parent_mismatch | line 63 |
| 5 | genesis at line 0 and nowhere else | genesis_misplaced | line 65 |
| 6 | proposer not empty | no_proposer | line 67 |
| 7 | the body has its type's required members; an amend's id unused and its height above its seq; a forecast's resolves_by not before its ts; a resolution's forecast recorded and unresolved | schema | log.py:check_body; check.py lines 71–76 |
| 8 | the signature: an exact SSHSIG container; a declared key; that key's principal is the proposer; the type is in the key's powers; Ed25519 verifies | bad_signature, unknown_key, proposer_mismatch, no_power, bad_signature | check.py:signer |
| 8a | a resolution is not by its forecast's principal | self_judged | line 82 |
| 9 | the entry's effect on the state: a key declared, re-declared or revoked (a weak or already-owned public key, or the last key power lost, refused); an amend promulgated and scheduled; a push installed; a transmute recorded; a forecast or resolution recorded; the timestamp carried | bad_key | check.py:declare; lines 84–99 |
| 10 | the head becomes the line's hash | — | line 100 |
Fourteen reason codes, a closed set [kernel/log.py:REASONS; SPEC §9]; the verdict is one JSON object, {"ok":true,"entries":N} or {"ok":false,"seq":n,"reason":…,"detail":…}, and detail is free text that the two checkers are never compared on [SPEC §9, §9a.4].
Three things in this order carry law in them. First, the signature is checked after the body's schema, so that a resolution of an unresolved forecast by a stranger is schema and not unknown_key; and self_judged is checked after the signature, so that the party is a verified fact before it is judged against — "so that two keys of one party cannot launder a judgement", and a self-resolution with a bad signature is refused for the signature [SPEC §7, forecasts; CHARTER A3.3]. Second, the keys used to verify entry i are the keys before entry i's own effect: signer reads state.keys and only afterwards does declare run, so a key declared at i does not sign i, and a revocation at j never reaches an entry before j [check.py lines 77–85; LAW.md §2.2]. That is prospectivity — Fuller's third principle and the charter's second maxim — as a line order rather than a rule, and it is why no pin for final_law_for_all was needed at C0: there is no site a mutant could edit to make later law reach back [REPORT.md §4.10]. Third, genesis certifies itself: for line 0 the keys are those its own body declares, registered in array order before its signature is checked [SPEC §7; check.py lines 78–80]. The record has one root of trust and it is the line the sovereign signed [seq 0].
What recognition does not do is as much the law as what it does. It reads no clock — ts is a field, and only its order is checked [SPEC §4]. It reads no file but the log, makes no network call and runs no model [CHARTER §9, refusal list; the second checker's notes say the same of itself, kernel2/NOTES.md]. It reads no member of a body beyond the required ones: forecast.type, forecast.args, push.record are optional members the tools read and the kernel ignores, and "a body schema never gains a required member", because a member required today would refuse the entries of yesterday [SPEC §5]. And it judges no merit: a proposal and a merge have no effect on the state beyond the head and the timestamp [SPEC §8 step 9]. The whole of what the kernel knows about the world is that forecasts exist and get resolved once.
4.3 Change — who may write
Hart's rule of change is the one that makes a system of rules something other than a custom. In jack it has two parts, because there are two things that change: who may act, and what the law says.
Who may act is a key with powers. A key declaration names a key id, a principal, a public key and a list of entry types the key may sign [SPEC §5, key declaration; kernel/log.py:KEY_DECL]. Genesis declares the first keys; a key entry, signed by a key holding the key power, declares another, re-declares one — the latest declaration of a key id wins, so a re-declaration can change the principal or the powers — or revokes one by declaring it with empty powers [SPEC §7; check.py:declare]. Three constraints are in the kernel and nowhere else. One public key is one identity for the life of the log: a blob once declared under a key id may never be declared under another, even after revocation [check.py line 50]. A weak public key is refused [check.py line 48]. And the power to declare keys cannot be lost: a key entry that would leave no declared key holding key is refused, "the power to declare keys, once lost, can be regained by no entry" [SPEC §7; CHARTER A2.5; check.py line 86] — the fourth maxim applied to the one act whose irreversibility would be total.
The record shows the mechanism used as intended. Genesis declared one key, guy-master, with four powers [seq 0]; it was re-declared with seven as C1 opened [seq 1] and with nine when the ledger's types arrived [seq 33]. The parties entered by declaration — builder, reviewer, counsel [seqs 6–8], each widened as the layer needed [seqs 31–34, 48–49] — and the herald, the process that merges, received merge and nothing else [seq 51; herald-2, seq 201]. When the herald's key moved from counsel's session to the sovereign's machine, the old key and a session-held builder key were revoked by declaring them with no powers [seqs 216, 217], and every entry those keys had signed remains valid, because recognition judged each by the law before it. Seventeen key entries in all [log@6ebea1a]. The keys are Dennis and Van Horn's capabilities and Miller's authority-as-reference (chapter 4 §4.4): a party that does not hold merge cannot merge, and there is no instruction anywhere that says it may not.
What the law says changes by amendment — three acts and a wait, set out here and used in chapter 9 [CHARTER A2.7; SPEC §10.12–13]. A decision of kind transmute names the amendment; the amend entry follows, carrying the SHA-256 of CHARTER.md with the amendment's text appended and an activate_at above its own seq; the amendment is in force from that height and never before; and between the amend and its height no push is lawful — "the law changes, then the code". The kernel records the promulgated charter and the schedule [check.py lines 94–95] and refuses an amend whose id is reused or whose height is not above its seq [line 71]; the judge enforces the rest, because it needs git: charter_mismatch if trunk's CHARTER.md does not hash to the promulgated charter, amend_untransmuted if an amend was not preceded by its transmute, push_during_amendment if a push falls in the wait [SPEC §10.2, §10.12–13]. The transmute-then-amend shape is Suber's (1990): an entrenched rule is first made mutable, as a separate move, and the two moves are two signed entries on the log. The price of an amendment is recorded in its own text [CHARTER A3.4, A4.5, A5.3] — the fifth amendment says it is the fifth in seventeen days and what the procedure ratio stood at that morning — and a forecast about whether it will ever bite is entered beside it [CHARTER A4.5: seq 60; A5.3: seq 121].
What the code is changes by push. The trusted base — the five paths of SPEC §10.1 — is digested over path and content, and a push entry signed by the master key names the digest of the trunk it authorises [SPEC §5, push; CHARTER A2.6]. The judge refuses a trunk whose digest is not the one in force, self-check included, so a change to the checker that no entry records turns main red [SPEC §10.11, trusted_base_unrecorded]. The record binds the code in the plain sense that every digest a push names is the digest of a commit on main: the author resolved all seven, and genesis's, to the first first-parent commit carrying each [judge/judge.py:digest over git rev-list --first-parent main @6ebea1a]:
| seq | ts | what the push installed | commit |
|---|---|---|---|
| 0 | 2026-10-14T05:41:39Z | genesis's checker: the founding kernel | b627904 (PR #1 merged) |
| 2 | 2026-10-18T14:42:38Z | the first recorded trusted base, C1's types | c2effd2 |
| 5 | 2026-10-19T04:36:23Z | C1's scope and cap, 4,500 | b3f2c4e |
| 9 | 2026-10-19T06:00:46Z | the scope block held to the text | 06cfbc9 |
| 12 | 2026-10-20T02:06:48Z | regular files only in the trusted base | f345ab0 |
| 29 | 2026-10-25T16:16:20Z | C1a's installing push: the ledger's types, ts_decreased, self_judged | 377aad9 |
| 197 | 2026-10-31T13:04:49Z | cap 6,200 → 6,900 for the clerk | 770d233 |
| 367 | 2026-11-01T15:04:14Z | C2a's opening: cap 7,800 | cd9d8eb |
One gap in that table is the law's own precedent. Between genesis and seq 2 the trusted base changed — the second checker, the judge's fixes, the CI — and no entry recorded it, because at C0 there was no entry type that could; counsel's exit report disclosed the two digests [REPORT.md §8.3.6, as transcript], and amendment A2.6 made "the sovereign's acts are entries" mechanical from the next push on. The gap is visible in the table as the four days between seq 0 and seq 2. That is what a record that binds looks like when it is honest: the exception is on it.
4.4 Adjudication — who decides
The checker decides validity and nothing else can [CHARTER §3, Adjudication]. But the log alone cannot carry some facts the law needs — what the trusted base of a commit is, whether CHARTER.md hashes to the promulgated charter, whether a proposal's log is a byte extension of trunk's, which paths a commit touched — and these are the judge's [SPEC §10; judge/judge.py:judge]. The judge runs in CI on pull_request_target, so the workflow and the judge are trunk's whatever the proposal contains [.github/workflows/judge.yml; LAW.md §2.1]; it extracts trunk's kernel from the trunk commit into a temporary directory and runs that, never a checkout [judge/judge.py:run_kernel]; it runs the second checker likewise and refuses checker_drift on any disagreement [SPEC §10.5]; it holds no secret and a read-only token [CHARTER §9.6]. The proposal's code is never executed. Its entries are data.
The judge's grounds are fourteen, in order, each a refusal of the whole proposal [SPEC §10]. The first six are the record's: trusted_path (a digest differs, or CHARTER.md differs by a byte, or a non-regular file sits under a trusted path), charter_mismatch, prefix_broken, genesis_by_proposal, the kernel's own verdict with checker_drift, and judge_from_proposal (a merge naming a checker trunk does not have). Four are about the party and its scope, and they are the mechanism behind amendment A2.9, "review ends by construction": unattributed_proposal (no signed proposal entry names a commit of the proposal, or a commit after it touches more than log.jsonl), party_scope, out_of_scope and code_cap. The party is "the principal of the key that signed the last such proposal entry, under the law in force at it (§7); the kernel has verified the signature, so the party is a fact, not a claim" [SPEC §10.7]. judge/scope.json, itself under a trusted path, assigns each party its prefixes: a builder may not touch the pins and vectors that judge it; a reviewer may propose only under pins/ and spec/vectors/; counsel touches documents only [SPEC §10.8; CHARTER A2.9]. "Code enters from a builder, written to a text Guy has read; findings enter from a reviewer, as pins." The last four grounds apply to every judged log including trunk's own: trusted_base_unrecorded, push_during_amendment, amend_untransmuted, decision_by_other — the sovereign's acts are his, so a decision must be signed by a key declared in genesis [SPEC §10.11–14].
Every ground is decidable from git and the log alone, stated over powers and paths and never over a party's name, and refusing costs the proposer nothing but resubmission [CHARTER A2.3]. That clause is the standard against which any new ground is tested, and it is why the judge cannot become a reviewer: a ground that read the quality of code would fail the first test, and one that named a model would fail the second.
The code cap deserves a paragraph, because it is the one place where the judge counts and a reader might mistake the count for a judgement. code_cap refuses a proposal whose counted Python under the counted prefixes exceeds judge/scope.json's cap [SPEC §10.10]. The cap is a resource constant: it is raised by a push at a window's opening, the push is the sovereign's, and the record says what it stood at and why — 3,000 at C0; 4,500 at C1's opening, 5,500 the same day, 6,200 at C1a's installing push, 6,900 at seq 197, 7,800 at seq 367, each raise a finding against the pre-statement that preceded it [SPEC §10, the paragraph before the scope block; seqs 5, 29, 197, 367]. The book will say in chapter 8 what those findings cost. Here the point is narrower: the cap enters no score and gates no merit; it is the court's budget line, and the judge enforces it the way it enforces everything else, by refusing.
4.5 Coke, Fuller and the maxims as mechanisms
The charter's §2 states four maxims and says where each came from; appendix A argues why each is forced. This section records what each became.
No one judges their own cause (Coke, Dr Bonham's Case). Three mechanisms. The checker that decides an entry is fixed before the entry exists: trunk's kernel, by digest, run from trunk [§4.4]. A resolution's proposer differs from its forecast's: self_judged, judged by principal and not by key, in the kernel since C1a [check.py line 82; CHARTER A3.3; seq 29]. And the last judge of value is the world, through a judge no party can edit — the sealed judge of C3, which waits [CHARTER §8]. The maxim was extended to the sovereign by A2.8: the head hash of the log is published on every push, and a monitor he does not operate verifies that each head extends the last and that both checkers accept the log [CHARTER A2.8].
The law looks forward and never commands the impossible (Fuller; lex non cogit ad impossibilia). Forward: the fold [§4.2]; the amendment's wait [§4.3]; a key at i governs entries after i. The impossible, refused: a weak key [sig.py:weak_key] and the last key power [A2.5]. The witness rule — every rule admitted with a violating and a satisfying witness, the first proving it can fail and the second that compliance is possible — is written [CHARTER §3, Change] and waits for the first primary rule, which waits for the first case [CHARTER A2.1]. That is the common law's order, as Blackstone (1765–69) described it, with the decided case as the evidence of the rule: "Primary rules accrete as precedent (Blackstone), each from a witnessed case" [CHARTER §3]. The book says so each time; the essay of 1 November said more than the record supports, and plan.md E1 records it.
Whatever is held must be produced (habeas corpus). The clerk, which chapter 5 builds: obligations derived from state and the clock, each with a deadline, escalating when it passes. Nothing in this chapter's law holds an obligation; the record only says what was promised.
Decide by expected value; forbid only the irreversible (after Arrow–Fisher). The master key's verbs and the last-key rule [§4.3]; refusal costs resubmission [A2.3]; the irreversible is chapter 9's subject; windows that fail are followed, not patched [CHARTER §6]; wealth never reset [A4.1]. The corollary — every source of influence is scored, and no party acts except through entries that carry its identity — is no_proposer, unknown_key, proposer_mismatch, one blob one identity, and the judge's fingerprinting of a proposal's signers from the blobs and never from its claims [LAW.md §2.4; judge/judge.py:fingerprint]. Counsel's own key is on the log [seqs 8, 22, 31, 48], and its forecasts are scored with everyone's (chapter 12).
Fuller's eight, as the charter's table has them, with the code as it now stands:
| Fuller | check | where |
|---|---|---|
| generality | rules quantify over entry types, never name a party | judge/scope.json is keyed by party role; every ground is over powers and paths [A2.3] |
| promulgation | the charter's hash and the checker's digest are entries | genesis charter and checker; every amend and push [SPEC §5; charter_mismatch] |
| non-retroactivity | prefix interpretation, by construction | check.py:check, the fold; activate_at [SPEC §7] |
| clarity | every rule decidable, with its witnesses | SPEC §8 and §10 are decidable; witnesses wait for rules [A2.1] |
| non-contradiction | the satisfying witnesses pass the whole law together | waits for rules |
| possibility of compliance | each satisfying witness passes the law in force plus its rule | waits for rules; bad_key refuses the impossible now |
| constancy | change only by change entries; the rate is reported | five amendments in seventeen days, each pricing itself [A3.4, A4.5, A5.3] |
| congruence | the checker that runs is the one whose digest is recorded; two implementations agree | trusted_base_unrecorded; checker_drift; tools/enforcement.json rows code and hand |
The last row is the one to dwell on. Congruence between declared rule and official action is the principle a prompt-based harness cannot have, because the model that reads the rule is the party it binds. jack's enforcement map says, row by row, whether a principle is enforced by code or by hand, and C1b's criterion 7 required the rows it moved to read code [status.py --subject C1b … @6b800e14, "map" lines]. Two rows still read hand: that no party acts except through entries, enforced by sessions rather than code; and the election of proposers, which had no witness before C2 [tools/enforcement.json]. The map is how the book will say, at each layer, how much of the law was law.
4.6 What the law does not yet contain, and what this chapter leaves open
The honest inventory. No primary rule exists; no rule language, no witness, no lapse, no notice period [CHARTER §3, Change; A2.1]. Recognition's clause (c), "every rule in force at its parent accepts it", holds vacuously [SPEC §7, last paragraph]. The thesis that three secondary rules suffice is therefore on trial, and the trial has a verdict date: if no case has arisen by C2's exit, C2's report says so [A2.1]. Two rows of the enforcement map read hand [§4.5]. The code cap has moved four times against pre-statements [§4.4]. The clerk's writ to the sovereign — the top of the escalation ladder — has not yet been needed, which is the point, and also means it is untested except by its pins. And the charter's lapse rule, by which law that has outlived its necessity falls away unless defended, cannot operate until there is law of that kind to lapse.
None of this is hidden; all of it is in the court's own texts. The book's claim for this chapter is not that the law is complete. It is that what exists is exactly the three rules, held by a 450-line kernel and the judge that runs it (one precondition of change, the transmute before an amend, is enforced by the judge rather than the kernel: SPEC §10.13), and that everything it lacks is written down as lacking, with the condition under which it arrives.
What the chapter leaves open is what the record now holds that the law does not act on. A forecast carries a deadline, and nothing in the three rules notices when it passes; a merge can land without a witness; a window's criteria can be met for days with no one to say so. The record knows what was promised and cannot make anyone keep it. That is chapter 5.
4.7 What would show this chapter wrong
A reason code the kernel raises that is not in the table of §4.2, or a refusal path in check_entry the table does not cover: either means the chapter has not read the kernel it claims to have read. The count is fourteen and the author walked the file; appendix A lets the reader walk it too.
A primary rule found to be in the kernel after all — a check on conduct rather than on validity. The candidate is self_judged, and the chapter's answer (§4.5) is that it is a rule about what counts as a valid resolution, placed in recognition by amendment and said to be so. A referee who reads it as a conduct rule has an argument, and the book should meet it rather than wave it away.
An amendment that did not follow the path — an amend without its transmute, or a push in the wait — on the log. The judge's grounds make this a red main [SPEC §10.12–13], and the author checked the five pairs [seqs 3–4, 28–30, 66–67, 136–137].
A push whose digest matches no commit on main. The table of §4.3 resolves all eight; a reader can repeat it with judge/judge.py:digest over the first-parent history.
And the one that cuts deepest: a first case arising that recognition does not refuse, answered by a rule written into the kernel rather than entering as a precedent with witnesses. That would not show the chapter wrong about the law as it stands; it would show the programme abandoning the thesis the chapter is built on, and chapter 8 would have to say so.