Files
dotfiles/claude/governance/fool/seed/FOOL-SEED-RULE.md
T
David F GliddenandClaude Opus 5 d6377af572 [FIX] §2a records one ruling and one steward decision, not two rulings
The heading read "Two corrections to the v2 §6b block — RULED, no veto" while
the ruling beneath it addressed only the retrieval URL. Its settling test —
"could this correction have moved the outcome?" — returns no for the URL and
YES for the provenance commit, since the provenance SHA is half the seed
string. The heading therefore claimed a scope the ruling could not reach.

Jurist confirmed 2026-08-23: "I ruled on one thing. The URL." The provenance
commit was never a correction under veto — the steward selected a still-open
value on the jurist's recommendation, before filing. It is now recorded as a
steward decision of 2026-08-22, with its reasoning, because a value that moves
the outcome must be attributable to the party entitled to choose it.

Verified independently against git, not relayed:
  4d2ae87 = 2026-07-28 11:32:39 +0200; trial 01 = 2026-08-01 (four days later)
  last commit to CLAUDE.md before trial 01 (next is c30dfe0, 2026-08-02)
  "Differently biased checkers": 0 at 4d2ae87, 1 at 3b0730d5
  blob SHA re-derived = 2d6e250a...120d, matches the filed value

EDIT IS INERT WITH RESPECT TO THE DRAW, proven rather than asserted. The filed
discipline is that no edit touches this rule before it fires; derive_fool.py
does not read this document — it hardcodes its constants and recomputes the
provenance SHA from git — so prose cannot steer the draw. Same synthetic
vector before and after gives the identical seed
3d8cc243f9b6ffc5fc7d254306ca4ca135a71d76d483df924736a18345fb8b7a;
selftest passes; diff removes no constant line.

  rule sha256 before: e1fa6fb3e4f928e468dc102f011d554c20eb14d9b49c17ce1f6f839106179bff
  rule sha256 after:  fb11818dd2e3c2bdcf21e2740fc3110a7aa9a9ead57098a93f27b9051d438551

The synthetic vector above is not a pulse and its output is not bones.
Refs PENDING-150 AMENDMENT 2/3, REVIEWED-125 AMENDMENT 1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JQKeKY9T9d95KpvHwwok8T
2026-08-23 16:24:29 +02:00

282 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: FOOL-SEED-RULE
description: "The filed rule required by PENDING-149 §4 steps 1-4: ratified axes, seed derivation rule (both components), retirement and regeneration criteria. Filed and pushed BEFORE the beacon timestamp 2026-08-25T12:00:00Z. Governs derive_fool.py; where the code and this rule disagree, THIS RULE GOVERNS."
metadata:
node_type: governance-artifact
type: reference
---
# FOOL SEED DERIVATION RULE — filed 2026-08-22
**Filed and pushed before the beacon timestamp, as §4 requires.** Nothing has been
derived. No target pulse has been fetched. This document governs
`derive_fool.py`; where the code and this rule disagree, **the rule governs and the
code is the defect**.
---
## 1 · Perception axes — RATIFIED
**Ratified by the steward in writing, 2026-08-22.** The steward ratified the five
verbally ("Perfect", after §5a was settled) and then directed that the ratification be
recorded explicitly rather than resting on v2's §5 heading — *"a heading asserting
ratification and a deliverable requiring it are two different records."* This section
is that record.
| axis | question |
|---|---|
| **SUCCESSION** | would this be legible to someone arriving cold, with no thread? |
| **ABSENCE** | what is not here, not asked, not yet existing? |
| **AIM** | is this the right question, at the right level? |
| **SCALE** | is the unit right? (item vs block vs programme) |
| **STAKE** | who bears the cost if this is wrong? |
A sixth **PROCEDURE** axis was proposed by the executor and **declined** by the jurist
(v2 §5a) on structural grounds the executor accepts: procedure failures are checkable,
§2 makes gradeable output a design failure, and a PROCEDURE-peaked fool would produce
nothing but gradeable observations. Redirected to a separate `[HARDENING]` extension of
`governance-drift-check.py`.
**Order is fixed as listed** — the derivation permutes over this order, so it is part of
the rule, not presentation.
## 2 · The filed rule
```
FOOL SEED DERIVATION RULE
Filed: 2026-08-22 Governs: PENDING-149 §6
ENTROPY COMPONENT
Source: NIST Randomness Beacon v2.0, https://beacon.nist.gov/beacon/2.0/
Retrieval: GET https://beacon.nist.gov/beacon/2.0/pulse/time/1787659200000
(= 2026-08-25T12:00:00Z in epoch milliseconds)
Field: pulse.outputValue, hex, LOWERCASED before use
Transport: curl. See §5 — python urllib cannot reach the host in this environment.
PROVENANCE COMPONENT
File: CLAUDE.md (repo root) in ~/dotfiles, at commit
4d2ae87a4e5350c4d3bb3aa50f9544b521d9c53d
Value: SHA-256 of the file contents at that commit, hex, lowercase
= 2d6e250a347d25698fb147f80e2dababbb930c4b3b3f9bb822478f360153120d
Note: contributes provenance, NOT unpredictability. Past commit,
named by full hash. Verify with:
git -C ~/dotfiles cat-file -p \
4d2ae87a4e5350c4d3bb3aa50f9544b521d9c53d:CLAUDE.md | shasum -a 256
SEED
seed_string = <provenance-sha256> || <beacon-outputValue-lowercased>
seed = SHA-256(seed_string), hex, lowercase
DERIVATION
seed -> FNV-1a (32-bit) -> Mulberry32 -> stat draws over the five axes of §1.
One peak, one dump, three scattered. No salt from any reference
implementation.
EXECUTION
Run ONCE. The executor does not retry on its own authority.
A re-run against the SAME recorded outputValue is legitimate (broken
implementation). A re-run against a LATER pulse is a new draw, governed
by §4 REGENERATION.
Record outputValue the moment it is fetched, before running anything.
UNAVAILABILITY
If no pulse is returned at or after the stated timestamp, retry the same
request for up to 24 hours. If still unavailable: STOP and report. Do not
substitute a different timestamp, beacon, or source.
TESTING
Dry runs use a fixed historical pulse only. Never the target pulse, never
a near-future pulse.
```
### 2a · ⚠ One correction RULED (the URL) · one STEWARD DECISION (the provenance commit)
⚠ **JURIST RULING, 2026-08-22 — scope: the retrieval URL, correction (b) below, and
nothing else. No veto; the correction stands.** Recorded with its reasons, since it will
be read later.
> The UNAVAILABILITY clause forbids substituting a different **timestamp, beacon, or
> source**. None of the three changed. Same beacon (NIST v2.0), same pulse
> (2026-08-25T12:00:00Z, epoch-ms 1787659200000), same field. What changed is the
> address at which the identical object is retrieved — the difference between a wrong
> phone number and a different person.
>
> The test that settles it: **could this correction have moved the outcome?** No. The
> pulse's value does not exist yet and does not depend on the URL used to fetch it. A
> substitution rule exists to prevent redraws; a correction that cannot affect the draw
> is not one. Read otherwise, the clause would forbid fixing a typo in a field name, and
> would have guaranteed a stop on the 25th for a reason unrelated to entropy — the
> opposite of what it protects.
⚠ **The ruling above does not reach (a), and was never offered as reaching it.**
Confirmed by the jurist, 2026-08-23: *"I ruled on one thing. The URL."* Its settling test
— *could this correction have moved the outcome?* — returns **no** for the URL and **yes**
for the provenance commit, since the provenance SHA is half the seed string. A value that
moves the outcome is attributable to the party entitled to choose it. **This heading
previously read *"Two corrections … RULED, no veto"* and over-claimed the ruling's scope.**
**One correction and one decision, both marked rather than silent:**
The draft said to commit its block verbatim. **Two values in it do not resolve**, and a
rule that cannot be resolved on the day is not a rule (v2's own standard).
**(a) The provenance commit — a STEWARD DECISION of 2026-08-22, taken on the jurist's
recommendation. Not a correction, and not under veto.**
`3b0730d59336113aa3a500a889a3e154be6a1de7` → `4d2ae87a4e5350c4d3bb3aa50f9544b521d9c53d`
**The sequence, as the jurist records it (2026-08-23):** the steward proposed
`3b0730d5`; the jurist wrote a rationale for it; the executor found the rationale **false
of that commit** and offered three dispositions; the jurist recommended (ii), switching to
`4d2ae87`; **the steward chose it, while the value was still open and before anything was
filed.** There was nothing to veto — this is the steward selecting a value entitled to him,
not the executor amending a filed rule.
**Why the original rationale failed.** *"The constitution as it stood before the fool was
conceived"* is false of `3b0730d5`: it is dated **2026-08-06**, five days after trial 01,
its subject line names the **PENDING-89 docket** (the question §11 forbids the fool from
being cited on), and **Constraint 6 is already present in it**.
**Verified against git 2026-08-23 — all four re-run independently, not relayed:**
| check | result |
|---|---|
| `4d2ae87` date | **2026-07-28 11:32:39 +0200** — four days before trial 01 |
| trial 01 date (trials table) | **2026-08-01** |
| last commit to `CLAUDE.md` before trial 01 | ✅ yes — the next is `c30dfe0`, 2026-08-02 |
| `Differently biased checkers` at `4d2ae87` | **0 occurrences** (at `3b0730d5`: **1**) |
| provenance blob SHA re-derived | `2d6e250a…120d` — **matches the filed value** |
Exactly one `CLAUDE.md` exists at that commit.
**(b) The retrieval URL — corrected on evidence, and this is the executor's change.**
The block's `GET /pulse?timeGE=2026-08-25T12:00:00Z` **returns HTTP 302 with an empty
body**, redirecting to `https://csrc.nist.gov/projects/interoperable-randomness-beacons`
— an HTML page, not JSON. Measured 2026-08-22 against a *historical* timestamp.
`/beacon/2.0/pulse/time/<epoch-ms>` returns 200 and the expected JSON.
⚠ **Had this been filed verbatim, the 25th would have produced no pulse, the
UNAVAILABILITY clause would have run its 24-hour retry against a URL that cannot ever
return one, and the rule would have STOPPED — correctly, and for the wrong reason.**
Found only because §6b's TESTING clause directs a historical dry run.
**This is the same beacon, the same source and the same pulse — only the address form
changes.** The executor judges that correcting an unresolvable address for the named
source is not "substituting a different beacon or source". **If the jurist reads it
otherwise, this is the line to strike, and it must be struck before 2026-08-25.**
## 3 · Draw ranges — EXECUTOR-SPECIFIED, declared
v2 says *"one peak (near max), one dump (near floor), three scattered"* without numbers.
The executor supplies them. **Filed before the beacon value is known**, which is what
makes them non-steering: they set magnitudes, while the permutation — driven entirely by
the entropy component — decides which axis receives which.
| role | range (inclusive) |
|---|---|
| peak | 85–100 |
| dump | 0–15 |
| scattered ×3 | 25–75 |
**No floor is applied to the dump** — it can reach 0. v2 §3 forbids the rarity mechanic
precisely because it would soften the dump.
## 4 · Pre-registered criteria (§4 steps 3 and 4)
⚠ **Naming note:** §4 step 3 calls for an *"abandonment criterion"*; §10 defines
**RETIREMENT**. They are the same criterion under two names; §10 is the referent.
**REGENERATION** — permitted ONLY on a demonstrable implementation error, verified
against this filed rule. **Not because the output is disliked.** A re-run against the
same recorded `outputValue` is legitimate; a re-run against a later pulse is a new draw.
**RETIREMENT (abandonment)** — only on mechanical failure: does not fire; fires
constantly; or produces gradeable in-genre findings despite §9.
**NOT grounds for retirement:** being uncomfortable, being frequently wrong, being
annoying, being ignored. *Those are the specification. Lear ignores his Fool for four
acts and the Fool is not thereby broken.*
## 4a · ⚠ The uppercase finding is the more serious of the two — jurist's assessment, adopted
> `outputValue` served uppercase against a rule specifying lowercase is a **silent seed
> divergence** — the pipeline would have run clean, produced bones, and nobody could have
> said afterwards which normalization had been applied. That is worse than the URL
> failure, which at least announced itself.
**Both were caught by the TESTING clause's historical dry run. The clause justified
itself twice on its first use**, and that is recorded here rather than left to inference.
## 5 · Implementation and its verification
`derive_fool.py`, same directory. Deterministic, no cache, no reroll path, no salt. It
recomputes the provenance SHA from git on every run and **refuses to proceed** if it
disagrees with this rule.
`--selftest` runs 12 checks with **no network and no live pulse** — synthetic vectors
only — including two positive controls proving the PRNG moves both peak and dump across
all five axes over 200 draws. All 12 pass as of 2026-08-22.
**End-to-end dry run, 2024-01-01T12:00:00Z pulse** (a fixed historical pulse, per
TESTING): pipeline verified from fetch through bones. **That output is not the fool and
is recorded nowhere as bones.**
⚠ **Transport constraint, measured:** `curl` reaches the beacon; **python `urllib`
times out** in this environment. The fetch on the 25th must use curl.
⚠ **`outputValue` is served UPPERCASE** (128 hex chars). The rule's *"lowercased before
use"* is therefore **load-bearing, not cosmetic** — omitting it yields a different seed.
### 5a · Normalization — the jurist's pre-25th condition, DISCHARGED
**Confirmed: lowercasing is applied at exactly ONE point** — `derive_fool.py:79`,
`beacon_output_value.strip().lower()`, inside `derive()`. It is the only `.lower()`,
`.upper()` or `casefold` in the file. Every downstream use, including the recorded
`beacon_outputValue` field, reads from that single normalized value.
**Unit-tested against a known uppercase input**, four checks, including one that proves
the test can fail:
| check | |
|---|---|
| UPPERCASE input normalizes: bones identical to lowercase | PASS |
| UPPERCASE input matches an **independently computed** seed (not read back from `derive()`) | PASS |
| the recorded beacon field is stored lowercased | PASS |
| **NEGATIVE CONTROL:** un-normalized input *would* give a different seed | PASS |
⚠ **Checking this found that the 2026-08-22 dry run had bypassed the step it was meant to
verify.** The run lowercased the value *outside* the code (`ov.lower()` into a temp file)
and passed it in already normalized, so the single normalization point was never
exercised on an uppercase input in the only end-to-end run. **The test's subject was the
pipeline; it silently excluded the step under scrutiny** — the same wrong-subject shape
the record has been tracking all week.
**Re-run with the RAW uppercase value through the real path**, 2024-01-01 pulse:
seed `d8e5e74def52c7cd…`, identical to the pre-lowercased run. Normalization verified in
the path that will actually be used.
⚠ **PROCEDURE FOR THE 25th, binding:** the fetched `outputValue` is passed to
`derive_fool.py` **exactly as served**. It is never lowercased, trimmed or otherwise
normalized by any wrapper, shell step or hand edit before it reaches `derive()`. One
normalization point, and it is in the code.
## 5b · Owed after the 25th, non-blocking
**`[FIX]` — 'abandonment' → 'retirement' throughout the fool's doctrine.** The jurist
owns the mismatch (§4 step 3 says *abandonment*, §10 defines *RETIREMENT*) and rules that
the fool's own doctrine should read **retirement**, one word with one meaning —
*abandonment* is the word §6 of the trial design owns, with a specific sense about the
jester form. Naming rather than silently harmonizing was correct; the harmonization is a
`[FIX]` **after** the beacon, so no edit touches this rule before it fires.
**The mumble-hook answer** (v2 §8) — clock-governed, event-checked, residual burst
sensitivity declared rather than claimed away. The daemon alternative to be **costed, not
dismissed**. A build decision, not a governance one. Also after the 25th.
## 6 · What has NOT happened
- The target pulse has **not** been fetched. No near-future pulse has been fetched.
- No bones have been derived. No soul has been generated.
- `~/CLAUDE.md` has **not** been touched (PENDING-150, unbundled).
- Nothing has been implemented of §8, §8a or §9 — the status line is confirmed free but
not built.