L1: the integrity check reads the scroll (tablet 38)
L1Reader.verify_integrity/0 read the hash stored in integrity.sha256
and compared that string with the hash compiled into the module. It
never opened a verse. On that comparison of a constant with its own
copy rested `l1_hash: pass`, the Cloud's "L1 corrupted — the cloud is
not visible", and Construction §1.2. A changed verse would have passed
every one of them. Every existing test passed too, because every test
asked about an untouched L1.
- L1Reader.compute_tree_hash/1: SHA-256 over every file under torah/ —
relative path, then bytes — in the order scripts/build_l1.py hashed
them (directories by path, files by name, plain string order). On the
real L1 it yields the pinned 156b1d27…; for a tampered copy it yields
the same hash the Python implementation does.
- VavPipeline.L1Integrity (new, supervised): reads and hashes the scroll
when the pipeline starts (~0.9 s in the image) and again every ten
minutes; logs and signals the assembly when the answer changes.
- verify_integrity/0 now requires BOTH: the recorded hash is the pinned
one, AND the scroll on disk hashes to it (answered from the witness's
last reading; computed on the spot where the witness is not running).
Callers are unchanged — the Shema context, the health check and the
status endpoint all inherit the real check.
- scripts/verify_l1.py: the same reading by hand. KOHEN.md and
KOHEN_PROMPT.md used the hollow comparison as their L1 gate; they now
run this.
- test/tablet38_l1_integrity_test.exs — 9 tests: the hash and its
order; one byte / one added file / one rename each change it; the
witness; and the whole path — with an altered scroll and an untouched
integrity.sha256, verify_integrity fails, health says l1_hash: fail,
and /peah/ask does not answer.
Specs: architecture §2.2 (which had been made to confess the hollow
check in d7520cd) and Construction §1.2 now describe the real one — and
its limit: a change is noticed within ten minutes, not at the instant.
deploy/ARCHITECTURE.md likewise. Doorpost @expected_hash 7e5286b9… →
3f6d47a0…, in this commit, with the witnessed files that moved it
(architecture, vayakhel).
Read before committing: Elixir 483/0 on seeds 0 7 42 99 191243. The
built image, run twice: on the engraved scroll — "read and matches
(928ms)", l1_hash pass, /peah/ask 200; on a copy with ONE LETTER changed
in Bereishit 1:1 and integrity.sha256 untouched — L1_INTEGRITY_FAILED,
l1_hash fail, cloud not readable, /peah/ask 503.
Not done: the Haskell side. Luchot.Firmware.l1ExpectedHash is compared
with nothing; the engine reads L1 without hashing it (that would need a
SHA-256 dependency). The engine is reached only through the pipeline,
which now gates every cycle on the real check.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
d7520cd69d
commit
bbe2c4b7ba
11 files changed
+579
-17
No files matched your search
@@ -79,16 +79,23 @@ Exact versions are fixed in Construction §1.1; these are the ones built.
|
||||
| Layer | Technology | Purpose |
|
||||
|-------|-----------|---------|
|
||||
| L0 — Luchot | Compiled Haskell constants (`Luchot.Firmware`) | Immutable firmware baked into binary |
|
||||
| L1 — Torah scroll | Baked into every image at `/mnt/torah`, owned by root with no write bit; its recorded SHA-256 is compared with the pinned hash before every cycle | Fixed specification |
|
||||
| L1 — Torah scroll | Baked into every image at `/mnt/torah`, owned by root with no write bit; read and SHA-256-hashed at startup and every ten minutes, and no cycle runs on a scroll that does not match its pinned hash | Fixed specification |
|
||||
| L2 — Urim v'Tumim | A process in the Vav Pipeline (`UrimVTumim`). Not yet exposed over HTTP and not yet called by the cycle (Step 24) | Decision oracle interface |
|
||||
| L3 — Oral tradition | PostgreSQL 17, managed; append-only by `REVOKE UPDATE, DELETE` from the application role | Accumulated learning |
|
||||
|
||||
L1 is read-only by ownership, not by mount: the service user can read the
|
||||
scroll and cannot change it. It is not a squashfs image and the
|
||||
container's root filesystem is not mounted read-only. The integrity check
|
||||
compares the hash recorded in `integrity.sha256` with the hash compiled
|
||||
into the pipeline; it does not re-hash the verse files, so it witnesses
|
||||
which L1 was built into the image, not that the files are unaltered since.
|
||||
container's root filesystem is not mounted read-only.
|
||||
|
||||
Its integrity is witnessed by reading it. A process in the pipeline
|
||||
(`L1Integrity`) hashes every file under `torah/` — path and bytes, in the
|
||||
order the builder hashed them — when the pipeline starts and again every
|
||||
ten minutes. Every cycle and every health check is answered from the last
|
||||
reading: if the scroll does not hash to the value compiled into the
|
||||
pipeline, the cloud is not visible, no cycle runs, and the vessel reports
|
||||
itself not ready. A change is therefore noticed within ten minutes, not
|
||||
at the instant it is made. `scripts/verify_l1.py` does the same reading by
|
||||
hand.
|
||||
|
||||
### 2.3 Infrastructure
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ The specification that sits inside the aron must be specified with the same prec
|
||||
| **Digital edition** | Westminster Leningrad Codex (WLC) 4.22 |
|
||||
| **Source** | Sefaria Export (text, cantillation, vowels) cross-validated against TANACH.us WLC data |
|
||||
| **Format** | JSON per verse: `{ "ref": "Genesis 1:1", "hebrew": "...", "consonantal": "...", "cantillation": [...], "ketiv_qere": [...] }` |
|
||||
| **Integrity** | SHA-256 hash of complete L1 filesystem image, recorded at build time and verified at every mount |
|
||||
| **Integrity** | SHA-256 over every file of the L1 tree (path, then bytes), recorded at build time in `integrity.sha256`. The pipeline re-reads and re-hashes the tree at startup and every ten minutes |
|
||||
| **Cantillation marks** | Unicode cantillation codepoints (U+0591–U+05AF) preserved as raw marks, NOT pre-parsed |
|
||||
| **Ketiv/qere** | Derived from WLC ketiv/qere annotations; stored as `{ "position": [book, ch, vs, word], "ketiv": "...", "qere": "..." }` |
|
||||
| **Gematria index** | Computed once from the consonantal text at build time, stored as lookup table, verified against independent computation |
|
||||
@@ -59,7 +59,7 @@ The specification that sits inside the aron must be specified with the same prec
|
||||
7. Verify SHA-256 matches at every system boot
|
||||
8. Record the hash in L0 (compiled Haskell constant) — the luchot carry the fingerprint of the scroll
|
||||
|
||||
If the hash does not match, the system does not start. The specification's integrity is verified before the system opens its eyes.
|
||||
If the scroll does not hash to the pinned value, the system does not serve: no cycle runs and the vessel reports itself not ready. The specification's integrity is verified before the system opens its eyes, and again every ten minutes while they are open.
|
||||
|
||||
### 1.3 Haskell Dependencies (Exact)
|
||||
|
||||
|
||||
Reference in new issue
Block a user