[FIX] Normalization tested at its single point; the dry run had bypassed it (PENDING-149)
The jurist's pre-25th condition: confirm lowercasing happens at exactly one point and is unit-tested against a known uppercase input. Single point confirmed at derive_fool.py:79 — the only .lower()/.upper()/ casefold in the file. Four checks added, including a negative control proving the test can fail. Selftest 16/16. Checking it found the defect the condition was aimed at, in my own work: the 2026-08-22 dry run lowercased the value OUTSIDE the code and passed it in already normalized, so the single normalization point was never exercised on uppercase input in the only end-to-end run. The test's subject was the pipeline; it excluded the step under scrutiny. Re-run with the raw uppercase value through the real path reproduces the same seed. Binding procedure added: on the 25th the outputValue is passed exactly as served. Jurist ruling on the URL correction recorded verbatim — no veto, with the reasoning, since it will be read later. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JQKeKY9T9d95KpvHwwok8T
This commit is contained in:
co-authored by
Claude Opus 5
parent
acfbb9fc0e
commit
1e40b01d70
+27
@@ -3926,3 +3926,30 @@ Hooks already wired, for §13.6 planning: `SessionStart` ×2 (wake digest lives
|
||||
**§15b — action owed:** say explicitly in PENDING-89 that the buddy contributes zero by construction, and open the v1 Chamber archive read as its own `[PROPOSAL]`.
|
||||
|
||||
**Awaiting:** (1) §6b provenance-commit disposition — **time-critical**; (2) `<DATE FILED>`; (3) unambiguous §5 ratification.
|
||||
|
||||
### AMENDMENT 2 — 2026-08-22 — §4 steps 1–4 filed and pushed; the jurist's normalization condition discharged
|
||||
|
||||
**Commit `acfbb9f`, pushed to both remotes (github + gitea), three days ahead of the beacon.**
|
||||
|
||||
**⚖ JURIST RULING on §2a(b), 2026-08-22: NO VETO — the URL correction stands.** Reasons recorded verbatim in `seed/FOOL-SEED-RULE.md` §2a: the UNAVAILABILITY clause forbids substituting a different *timestamp, beacon, or source*, and none of the three changed — only the address at which the identical object is retrieved. The settling test: **could the correction have moved the outcome?** No; the pulse does not exist yet and does not depend on the URL. A substitution rule exists to prevent redraws, and a correction that cannot affect the draw is not one.
|
||||
|
||||
**⚠ The uppercase finding is ruled the more serious of the two, and the assessment is adopted.** A silent seed divergence would have run clean, produced bones, and left nobody able to say afterwards which normalization had been applied. The URL failure 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 now recorded in the rule rather than left to inference.
|
||||
|
||||
### ✅ The pre-25th condition — DISCHARGED, and checking it found a defect in my own test
|
||||
|
||||
Jurist: *"Confirm that lowercasing is applied at exactly one point in the code and is unit-tested against a known uppercase input. A normalization rule stated in prose and applied in two places is how the two diverge later."*
|
||||
|
||||
**Single point confirmed:** `derive_fool.py:79`, the only `.lower()` / `.upper()` / `casefold` in the file. **Unit-tested**, four new checks including a **negative control** proving the test can fail. Selftest now **16/16**, no network, synthetic vectors plus one known uppercase vector.
|
||||
|
||||
⚠ **The check found that the 2026-08-22 dry run had bypassed the step it was meant to verify.** The run lowercased outside the code and passed the value in already normalized, so the single normalization point was **never exercised on uppercase input in the only end-to-end run**. The test's subject was *the pipeline*; it silently excluded *the step under scrutiny*. Same wrong-subject shape as the `find`-vs-`glob` error and the three-store negative — **third instance this week, and the first found by another party naming the condition rather than by the executor re-checking.**
|
||||
|
||||
**Re-run with the RAW uppercase value through the real path** (2024 pulse): seed `d8e5e74def52c7cd…`, identical to the pre-lowercased run. **Binding procedure added to the rule:** on the 25th the fetched `outputValue` is passed to `derive_fool.py` exactly as served — never normalized by any wrapper, shell step or hand edit before it reaches `derive()`.
|
||||
|
||||
### Owed after the 25th, non-blocking, both accepted
|
||||
|
||||
- **`[FIX]` 'abandonment' → 'retirement'** throughout the fool's doctrine — one word, one meaning; *abandonment* stays owned by §6 of the trial design. Deliberately deferred past the beacon so no edit touches the filed rule before it fires.
|
||||
- **The mumble-hook answer** — clock-governed, event-checked, residual burst sensitivity declared rather than claimed away; the daemon alternative **costed, not dismissed**. Build decision, not governance.
|
||||
|
||||
**Still NOT done:** target pulse not fetched, no bones, no soul, `~/CLAUDE.md` untouched (PENDING-150), nothing built of §8/§8a/§9.
|
||||
|
||||
**Awaiting:** nothing blocking. The next act is the beacon at 2026-08-25T12:00:00Z.
|
||||
|
||||
@@ -89,7 +89,25 @@ TESTING
|
||||
a near-future pulse.
|
||||
```
|
||||
|
||||
### 2a · ⚠ Two corrections to the v2 §6b block, marked rather than silent
|
||||
### 2a · ⚠ Two corrections to the v2 §6b block — RULED, no veto
|
||||
|
||||
⚠ **JURIST RULING, 2026-08-22: 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 two corrections, 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). Both changes
|
||||
@@ -152,6 +170,16 @@ constantly; or produces gradeable in-genre findings despite §9.
|
||||
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
|
||||
@@ -172,6 +200,52 @@ 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.
|
||||
|
||||
@@ -122,6 +122,22 @@ def selftest() -> int:
|
||||
("no floor: dump can reach the bottom of its range",
|
||||
min(derive(f"{i:0128x}")["stats"][derive(f"{i:0128x}")["dump"]] for i in range(200)) <= DUMP_RANGE[0] + 1),
|
||||
]
|
||||
# --- normalization: the jurist's pre-25th condition. outputValue is served UPPERCASE. ---
|
||||
UP = "A1B2C3D4E5F6" * 10 + "ABCDEFAB" # 128 chars, uppercase hex
|
||||
LOW = UP.lower()
|
||||
r_up, r_low = derive(UP), derive(LOW)
|
||||
# independent expectation, computed here rather than read back from derive()
|
||||
import hashlib as _h
|
||||
expected_seed = _h.sha256((PROVENANCE_SHA256 + LOW).encode()).hexdigest()
|
||||
wrong_seed = _h.sha256((PROVENANCE_SHA256 + UP ).encode()).hexdigest()
|
||||
checks += [
|
||||
("UPPERCASE input normalizes: bones identical to lowercase", r_up == r_low),
|
||||
("UPPERCASE input matches independently computed seed", r_up["seed"] == expected_seed),
|
||||
("recorded beacon field is stored lowercased", r_up["beacon_outputValue"] == LOW),
|
||||
("NEGATIVE CONTROL: un-normalized input WOULD give a different seed "
|
||||
"(so the check above can fail)", expected_seed != wrong_seed),
|
||||
]
|
||||
|
||||
# positive control: the PRNG must actually move both peak and dump around the axes
|
||||
peaks = {derive(f"{i:0128x}")["peak"] for i in range(200)}
|
||||
dumps = {derive(f"{i:0128x}")["dump"] for i in range(200)}
|
||||
|
||||
Reference in New Issue
Block a user