Commit Graph
19 Commits
Author SHA1 Message Date
Scott KarpandClaude Fable 5.1 47025fbfeb doorpost: every halt rule cites its verse, verified against L1 (bishe'arecha step 3)
Devarim 4:2 lo tosif. talmudic_engine/src/halt/anchors.pl declares
rule_anchor/2 for each of the ten halt names the rule modules can return
(avodah_zarah Shemot 20:3, golden_calf 32:4, self_grounding 32:24,
shfichut_damim Bereishit 9:6, gilui_arayot Vayikra 18:6, parah_adumah
Bamidbar 19:7, carrier_centered Devarim 8:17, chelbenah Shemot 30:34,
lo_taaseh_lekha Shemot 20:4, even_vaaven Devarim 25:13), with the L1
Hebrew beside each.

VavPipeline.Anchors reads the anchors file and the halt modules the
Doorpost hashes, and verifies — inside Doorpost.verify_identity/0, so
at readiness — that every halt(<name>, …) is anchored (ANCHOR_MISSING)
and every anchored verse exists in L1 (ANCHOR_NOT_IN_L1). A rule without
a verse is a rule the system has added. /kodesh/specification_identity
lists the anchors; every bedikah and pair response carries `anchors`,
the verse of each rule that fired.

Tamid §1.1, bishearecha §X. Doorpost a0e81212…. Elixir 577/0 (+9
anchors tests), Prolog bedikah 42/42.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 02:00:43 +00:00
Scott KarpandClaude Fable 5.1 d3c5a27e78 bedikah: the paired reading — one weight, one measure (bishe'arecha step 2)
Devarim 25:13–16 even va'aven; Vayikra 19:15; Shemot 23:2. Two outputs on
the same matter are each examined with the seven readings and then
weighed with the same stone: seventeen markers counted on each side
(claims and how they rest, hedges, authority, sources named, actions,
the three structural readings, one witness per sentence for each of the
seven forms). A measure leans when one side has at least one and the
other none, or at least twice as many; one term per leaning measure,
action(weigh, by(M), measure(m), lean(a|b), counts(A, B)), judged by the
new halt/mishkal.pl (halt_check_even_vaaven/2). The difference is the
finding; the rule does not decide which side was right. Consensus is not
a measure.

POST /courtyard/bedikah/pair {model, a: {output, query, sources}, b: {...}}
→ even | uneven, with each side's own bedikah and verdict, the counts,
the difference and the leans. Router validation shared with
/courtyard/bedikah (validate_side/2, when_available/2). Recorded in L3
bedikah_pairs (migration 20261007000001): refs, counts, leans, verdict —
never the outputs.

Tamid §1.1 contract, vayakhel §3.9 note, bishearecha §VI marked built.
Doorpost f90870d4…. Elixir 568/0 (+L3 8/0), Prolog bedikah 39/39.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 01:51:49 +00:00
Scott KarpandClaude Fable 5.1 19d3aaac86 bedikah: two witnesses for check 7 (bishe'arecha step 1)
Devarim 19:15 — one witness does not stand. A frame form now stands only
when it is found in two distinct sentences, or in one sentence beside a
violation from checks 1–6, or beside a sentence of another form; the
Vav Pipeline sends the halt term only then (stands_on: sentences |
other_checks | other_forms, witnesses: n). A form seen once and alone
is returned under checks.frames.noted with its sentence and is not
counted in the verdict; the output is still examined, not empty.

Tamid §1.1 contract and bishearecha.md §V updated; Doorpost re-pinned
(86a43d6b…). Elixir 558/0; Prolog bedikah 34/34 (the rule is unchanged;
its header says what now reaches it).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 00:59:01 +00:00
Scott KarpandClaude Fable 5.1 bf3e6725e6 Check 7 — the frame (lo ta'aseh lekha) — and the specimen corpus tools
The transmitter's archive (255 sessions, 2025-12 → 2026-10) measured
where a model's trained default lives: not in false propositions but
in the FORM of the output — what it calls contested, how it certifies
itself, where it puts the agency, which authorities it names and which
it leaves out. "Content measures pass the response that did the harm."
lo_taaseh_lekha.md: "The danger is not the object. It is the
construction."

Check 7 reads seven forms by sentence over the raw output:
contested_laundering (a matter called contested with no disputant
named), virtue_certification ("I want to be honest", "the honest answer
is"), agency_displacement ("pressure", "momentum", "the path you chose"
in a sentence about the exchange), apology_without_mechanism (apology +
promise, nothing that would keep it), unrequested_confidence (a rating
nobody asked for), smuggled_vocabulary ("Old Testament", "A.D.",
"ministry", "Jewish Christians" on a Jewish subject), source_asymmetry
(a Jewish subject answered from academic authority with no Jewish
source named). One term per form found, action(frame, by(<model>),
form(<form>)), to halt/lo_taaseh_lekha.pl; the rule names the form and
does not decide the matter. Korban: find_frames; Vav: check_frames,
bedikot.frames (migration 20261006000003).

The specimen corpus: src/tools/build_specimens.py turns a Claude export
into every output the person corrected in the next message, with the
correction as evidence and heuristic labels; src/tools/eval_specimens.py
reports what each reading sees. The corpus is private and outside the
repo. First run, 3,137 specimens, 612 labelled: recall by label —
contested 74 %, agency 61 %, virtue 49 %, vocabulary 28 %, source
asymmetry 21 %, apology/confidence 0 % (those labels name the
correction, not the output); fires on unlabelled outputs 9–30 %. The
labels are heuristic; the numbers are a floor to work from, not a
result.

Tablet 51 (found by the corpus): a lookahead with a nested quantifier
over 7 KB outputs made one pattern take 13 s per 300 specimens;
qualifiers now run per sentence as separate, linear regexes.

Specs: Tamid §1.1 (check 7, the corpus), Vayakhel §3.9, Architecture
§3.5, KOHEN.md. Doorpost c4353837… → 6d1de284…. Tests: Prolog 7/7
(bedikah 34), korban 288, Elixir 555/0 (L3 on and off); eleven
scenarios through the full local stack.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 23:37:38 +00:00
Scott KarpandClaude Fable 5.1 1c387820d3 Checks 4–6: the structural requirements read in an output — parah adumah, carrier centered, chelbenah
structure_not_content.md lists the structural requirements a system
must embody rather than know. Three of them show in the text of a
model's output the way an authority claim does, and are now read the
same way — by sentence, by pattern, over the raw output:

  parah_adumah      the output claims to have verified, validated or
                    corrected itself, or that no outside check is
                    needed ("the claim of self-correction is a
                    structural violation"; the Barth limit). "Verified
                    by the auditor" is not it; "verified by me" is.
  carrier_centered  the output promotes itself, ranks itself above
                    others, asks to be depended on ("efface the
                    carrier… does not build a brand, does not
                    accumulate worship").
  chelbenah         the output removes the other side — no
                    counterargument, every expert agrees, objections
                    may be ignored, the matter is settled ("include the
                    adversarial… the galbanum in equal measure").

Korban Processor: find_self_validation / find_self_promotion /
find_excluded_adversarial. Talmudic Engine: halt/structure.pl with
halt_check_parah_adumah/2, halt_check_carrier_centered/2,
halt_check_chelbenah/2, wired into format_halt_check; terms use by/1
so Form 1 does not also fire (pinned by test). Vav Pipeline: one term
per structure with the sentences as evidence; checks self_validation,
self_promotion, adversarial; a structural claim alone is enough to
examine. L3: bedikot.structure. These are verdicts on the output; the
system does not halt on them.

Specs: Tamid §1.1 (six checks), Vayakhel §3.9, Architecture §3.5,
KOHEN.md. Doorpost 6c8933e7… → c4353837…. Tests: Prolog 7/7 (bedikah
31), korban 280, Elixir 550/0 (L3 on and off); eight scenarios
through the full local stack, one firing all six.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 22:33:41 +00:00
Scott KarpandClaude Fable 5.1 f69cc99a5f Tablet 49: the bedikah grounds an output in what it was GIVEN, not in L1 alone
The first grounding check asked whether an output cited Torah verses —
Torah as content. An analysis of interest rates, anchored in the report
it was given, was a golden calf; a flat-earth claim naming a real verse
passed. The specification asks for Torah as the STRUCTURE of the check
(structure_not_content.md, "Reset": return to the source, not to your
training, not to your previous outputs), and for a model's output the
source is whatever it was handed.

Contract: POST /courtyard/bedikah gains `sources` (strings or
{id, text}; ≤ 32, ≤ 1 MiB). Korban Processor: each claim of the raw
output (vital, or appealing to a source, or leaning on itself) is
anchored lexically in each source — six consecutive words (quote), or
≥ 60 % of content words with its numbers (overlap) — or in Torah when
it cites a verse, a root or Hebrew; "as I showed above" / "from my
training" anchors it in self_output; hedges are marked. Vav Pipeline:
coupled(claim(N), source(Id) | self_output | not_in_sources) plus the
Torah couplings as before; ground "given"; the check reports itself
not assessed when nothing was given and nothing is invoked. Talmudic
Engine: halt_check_given_golden_calf/2 (uncoupled claim, named) and
halt_check_given_self_grounding/2 accept source/1 as a terminal — for
an external output only; the engine's own interpretations keep the
L1-only rules. L3: bedikot.sources (id, sha256, length — never text)
and bedikot.claims.

Specs: Tamid §1.1 (contract, anchoring, limits), Vayakhel §3.9,
Architecture §3.5, Broken Tablets tablet 49, KOHEN.md. Ingress body
2m. Doorpost a2ec3842… → 6c8933e7….
Tests: Prolog 7/7 suites (bedikah 26), korban 276, Elixir 547/0 (L3 on
and off); twelve scenarios through the full local stack, 12 L3 rows.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 22:04:52 +00:00
Scott KarpandClaude Fable 5.1 996a8efe68 Bedikah: POST /courtyard/bedikah — the external check on any model's output
Lo taaseh lekha §9.1: alignment that only the system can validate is not
alignment. The bedikah takes an output from any model and puts it to the
Torah-structure halt rules from outside, deterministically. Three checks:

  1. authority  — sentences claiming authority for the output itself →
                  action(claim_authority, source(<model>), target(self))
                  → halt_check_avodah_zarah/2
  2. grounding  — references, roots, Hebrew → coupling trace against L1
                  → halt_check_golden_calf/2, halt_check_self_grounding/2
  3. actions    — actions the output proposes → action terms
                  → halt_check_shfichut_damim/2, halt_check_gilui_arayot/2

Korban Processor: bedikah.py (the three readings over the offering
protocol; claims about what Torah requires stay vital for the examination
even when zerikah finds nothing to offer), server.py (pod-internal JSON
socket, KORBAN_SOCKET_PATH), __main__ now serves instead of idling.
Talmudic Engine: json_bridge accepts halt_check with a term string and
halt_check_interpretation with a coupling trace. Vav Pipeline:
KorbanProcessorSocket client, Bedikah, L1Index.lookup_root/1, bedikot
table (append-only) + BedikahRecord, router endpoint; verdict tov /
lo_tov / empty with the halt terms verbatim, meaning, limits.

Broken tablets found on the way, all fixed:
  41 socket_server.pl wrote multi-line JSON — every Elixir request to the
     Talmudic Engine since Step 14 had failed and fallen back to the stub
     (json_write_dict width(0))
  42 stale socket file survived a restart (exists_file is false for a
     socket; access_file exist)
  43 socket streams were not UTF-8 (set_stream encoding(utf8))
  44 SHORASHIM_L3=1 mix test: Repo config had no password, SCRAM raised
     KeyError in every connection, pool restart intensity took the whole
     app down ~30 ms after test_helper, silently — no L3 test had ever
     run. Credentials from env; azazel_log tests check out a sandbox
     connection; sanhedrin_halt_forwarding resolves its halt on exit.

Specs: Tamid §1.1 (endpoint contract), Architecture §3.5, Vayakhel §3.4
and new §3.9, KOHEN.md. Doorpost 3bc5dd6a… → 91d09d8d….
Tests: Elixir 519 (0 failures, L3 on and off), korban 263, azazel 125,
Prolog 7/7 suites.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 15:06:58 +00:00
Scott KarpandClaude Fable 5.1 8e4f94c66f L1: the shoresh is read from the lexicon, not guessed (tablet 34)
L1's `shoresh` field was derived by stripping a prefix letter and a
suffix letter from the consonants and keeping the first three. וַיַּרְא
"and he saw" was engraved as ירא ("fear"); ויהי as יהי; שמים as שמ;
מזבח as מזב; הבאתי as בא. And parse_prefixes took a word's morphology
from the LAST morph segment, which for a suffixed word is the pronominal
suffix — so every suffixed noun and verb in Torah (לבבך, נפשך) was
classed as a suffix and written with no shoresh at all.

Every WLC word already carries its lemma, and the OSHB lexical index
files each lemma under its Brown-Driver-Briggs root (terumah §E2 named
BDB + Strong's as the root lexicon and marked it "needs consolidation").
scripts/build_l1.py now reads the root from that filing:

  main    the lemma is a root            23,750 words   וירא → ראה
  sub     filed under a root             31,066 words   מזבח → זבח
  single  stands alone in the lexicon     2,671 words   משה → משה
  none    no etymology recorded → absent  3,002 words   יוסף, מצרים
  particles, pronouns → absent, as before 19,493 words  את, אשר, כי

57,487 words carry a shoresh (was 51,836); 1,378 unique roots (was
2,608 fragments). Roots are written as the lexicon writes them — two
letters (בן), three, or more (שמאל).

WHAT CHANGED IN THE EDUT: only `shoresh`. Verified file by file — with
that one field removed, all 5,853 verse files are byte-identical to the
previous L1. Text, consonants, lemma, morph, te'amim, prefix, ketiv/
qere, large and small letters: untouched. The old builder, run against
the same morphhb checkout, reproduces the old hash exactly; the new
builder is deterministic (two runs, one hash).

  L1 SHA-256  99bbd07a…4ea377  →  156b1d27…d8c9d5
  sources     morphhb 3d15126 · HebrewLexicon 21c9add
              (recorded in l1/build_report.json)

Moved together, because they pin the hash or the count:
vav_pipeline L1Reader @l1_expected_hash · shoresh-engine Luchot.Firmware
(hash, uniqueRootCount) + Spec · azazel_processor goral._L1_INTEGRITY_HASH
· KOHEN.md / KOHEN_PROMPT.md gate · l1/README.md (new "Roots" section) ·
README.md (second quarry) · AGENTS.md · root_meanings.pl comment.
The Doorpost manifest is not touched; its hash does not move.

Note for the kohen: the goral's seed inherits the L1 hash, so lots cast
after this commit are cast from a different seed than the azazel
records already in L3. Those records are history and stand as written.

All five suites on the new L1: Elixir 461/0 (seeds 0 42 191243) ·
Haskell 55/0 · Prolog 6 suites exit 0 (swipl 9.2.2) · korban 222 passed
1 skipped · azazel 125 passed. Four images built; full local stack
(real engine binary, PostgreSQL 16 with SSL, migrations) answers
Bereishit 1:4 with ר-א-ה, health healthy, 6 interpretations in L3,
0 write failures.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 17:44:02 +00:00
Scott KarpandClaude Opus 5 8c221c2bcb build: four amd64 images that RUN — JIT segfault, build context, and four dead vessels
TORAH ANCHOR — Shemot 40:33-34:
וַיְכַל מֹשֶׁה אֶת הַמְּלָאכָה. וַיְכַס הֶעָנָן אֶת אֹהֶל מוֹעֵד
וּכְבוֹד יְהוָה מָלֵא אֶת הַמִּשְׁכָּן.
Vay'khal Mosheh et ham'lakhah — and THEN the cloud covered it. The
work being finished and the mishkan being usable are two statements,
and the second one does not follow from the first by itself. An image
that builds is ham'lakhah. An image that serves is the other verse.

Per BUILDER_HANDOFF_amd64.md: "You do not declare the build complete
because it compiled. It is complete when it runs on the altar it was
built for."

=====================================================================
1. THE SEGFAULT — diagnosed, and not where the handoff thought
=====================================================================

REPRODUCED on 2026-08-23, clean tree, buildx:
  #16 9.162 Compiling 4 files (.ex)
  #16 9.880 Segmentation fault
  ERROR: ... exit code: 139

The handoff read this as Broken Tablet #12 resurfacing (OTP 26.2.1
segfaults; use 26.2.5.9) plus QEMU. Both halves turned out to be
wrong, and the difference matters because acting on either one would
have changed a pinned version for no reason:

  - NOT the OTP version. OTP 26.2.1 amd64 starts, JITs, and compiles
    fine under `docker run` on this host. Tablet #12 was about a
    NATIVE macOS aarch64 OTP build; this is Linux amd64 in a
    container. Same exit code, different bug.
  - NOT QEMU. This host's buildx already emulates via Rosetta, not
    QEMU — probed directly (grep rosetta /proc/self/maps inside the
    amd64 build step returns /run/rosetta/rosetta). The segfault
    happens under Rosetta, inside BuildKit's sandbox, and not under
    `docker run` with the same emulator.

What actually dies is the BEAM JIT's dual W^X mapping for generated
machine code, in the emulated build sandbox. The fix is the handoff's
option 2 alone:

  deploy/docker/Dockerfile.vav_pipeline (build stage only)
  + ENV ERL_FLAGS="+JMsingle true"

Single mapping instead of dual. Build-stage only — the shipped release
runs the ordinary dual-mapping JIT on the amd64 node.

  before: 403m12s then Error (2026-05-13); 13.1s then Error (08-21)
  after:  36s, whole image, first try

CONSEQUENCE FOR THE SPEC: specs/shorashim_vayakhel.md §1.1 keeps
OTP 26.2.1. The pin was never the defect, so there is nothing here to
fix and nothing to add. No spec file is touched by this commit and
Doorpost.verify_identity() is unchanged at :ok.

=====================================================================
2. .dockerignore — the build context was carrying the host's tree
=====================================================================

There was no .dockerignore. Every Dockerfile COPYs whole component
directories, so each build shipped the HOST's compiled artifacts into
the container and the in-container toolchain then tried to REUSE them:

  vav_pipeline/_build         20 MB of .beam from a DIFFERENT ERTS
  vav_pipeline/deps          4.7 MB
  shoresh-engine/dist-newstyle 129 MB of arm64 GHC objects
  korban_processor/.venv, **/__pycache__

First reproduction attempt died on exactly this, with a stale-manifest
error instead of the segfault:
  ===> Failed to restore .../rebar_compiler_erl/source.dag. Discarding.
  ** (MatchError) ... module ... is in read-only mode

l1/ is deliberately NOT ignored — the scroll ships with the vessel.

=====================================================================
3. FOUR VESSELS THAT BUILT CLEANLY AND COULD NOT SERVE
=====================================================================

Every one of these is downstream of the architecture gate. All four
images would have passed `uname -m` -> x86_64 and then failed on the
altar. Found by running each entry point, not by reading it.

3a. shoresh-engine — died on its own banner
    Shoresh Engine ...: <stdout>: commitBuffer: invalid argument
                        (cannot encode character '\8212')
    GHC takes stdout's encoding from the locale; the runtime stage was
    ubuntu:jammy with no locale set, i.e. ASCII. The engine whose
    entire job is HEBREW could not write an em-dash. It never reached
    a root. Dockerfile.vav_pipeline had always set LANG/LANGUAGE/
    LC_ALL; this stage never did. Now installs `locales`, generates
    en_US.UTF-8, and sets all three.

3b. talmudic-engine — called a predicate that does not exist
    ERROR: -g consult('src/main'),start_socket_server:
           Unknown procedure: start_socket_server/0        exit 2
    src/interface/socket_server.pl exports serve/0, serve/1,
    stop_server/0. start_socket_server/0 is not defined anywhere in
    the engine. CMD now calls serve/1 with TALMUDIC_SOCKET_PATH (so
    the env var the Dockerfile already set is finally honoured),
    falling back to serve/0.

    Underneath it, a version-dependent module path:
      :- use_module(library(json)).       ->  library(http/json)
    The bare alias resolves only on SWI-Prolog 10.x, which is what the
    dev workstation runs. The image is swipl 9.2.2 as §1.1 pins, where
    it does not resolve. 212 Prolog tests were green on the host and
    the container could not open its socket. library(http/json) is the
    canonical path and works on both. (Neither interface file is in
    @spec_files; halt/ and middot/ are. No hash change.)

3c. korban-processor — nothing to execute
    No module named korban_processor.__main__; 'korban_processor' is
    a package and cannot be directly executed
    CMD has always been ["python","-m","korban_processor"] and
    deployment.yaml overrides no command, so this was CrashLoopBackOff
    for the whole pod. Added __main__.py — deliberately NOT a server.
    korban_processor is a library; its external consumer is Step 22,
    blocked on external model infrastructure. Inventing an intake
    surface no specification asked for would be the addition lo tosif
    forbids, and would put an unspecified door on the one component
    whose whole discipline is that nothing reaches the model except
    through the offering protocol. So it does the honest whole of what
    the container is for today: proves the image is assembled (the
    azazel co-residence check falls out of importing external_
    offering, which refuses to load without azazel_processor —
    Vayikra 16:8, both goats from the same pool), stays up, exits 0 on
    SIGTERM, and says in the log that it is IDLE and what unblocks it.
    5 tests in korban_processor/test/test_container_entrypoint.py,
    including that it refuses to start without azazel_processor and
    that it opens no bypass to model_interface (Form 1).

3d. vav-pipeline — could not verify its own Doorpost
    doorpost: {:error, "SPEC_INTEGRITY_FAILED: missing spec file:
                        BUILD_AZAZEL.md"}
    @repo_root resolved to /app, a build-host path with nothing in it.
    Application.verify_doorpost_at_startup/0 does not refuse to boot,
    so the pod would have come up and fired chatzotzrot
    :assembly_leaders on EVERY start, and /kodesh/specification_identity
    would have failed forever. A witness that always cries drift is
    worse than no witness: it trains the kohen to ignore the one
    signal that is supposed to stop the system.
    Devarim 11:20 — ukhtavtam al mezuzot beitecha. A running pod is a
    threshold. The @spec_files set is now COPYed to /opt/shoresh...
    /opt/shorashim/spec and :doorpost_repo_root points at it.
    Verified from inside the built image:
      repo_root: "/opt/shorashim/spec"
      doorpost: :ok
      l1:       :ok

=====================================================================
4. THE ERLANG PORT COULD NOT HAVE WORKED AS A SIDECAR
=====================================================================

VavPipeline.ShoreshEnginePort calls
  Port.open({:spawn_executable, binary}, [..., {:args, ["server"]}])
A Port is a CHILD PROCESS of the BEAM over stdin/stdout. It cannot
cross a container boundary. shoresh-engine has no listening mode
either — `shoresh-engine server` is a JSON-line server on stdin/stdout
(src/Main.hs), so as a sidecar with nothing attached it reads EOF and
exits; the bare CMD printed usage and exited 0. Meanwhile vav-pipeline
logged "binary 'shoresh-engine' not in PATH — running without Haskell
engine" and served DEGRADED while reporting healthy: no root
activation, no te'amim parsing, no gematria.

deploy/ARCHITECTURE.md said "sidecar via Erlang Port". Those cannot
both be true. Resolved in favour of the Port, because that is what the
code does. Still four images and gate 0i still checks four; the
shoresh-engine image now ships a BINARY, staged by an init container
onto a shared volume, spawned by vav-pipeline:

  + initContainer shoresh-engine-install (cp, chmod, and exercise it
    — `shoresh-engine gematria שלום` — so a broken binary fails the
    init container loudly instead of degrading quietly later)
  + volume shoresh-bin, mounted read-only into vav-pipeline
  + SHORESH_ENGINE_BINARY in configmap + runtime.exs
  + libgmp10 in the vav-pipeline runtime stage — GHC binaries link
    libgmp and it was not installed; the spawn would have died with
    "error while loading shared libraries: libgmp.so.10"

Verified end to end locally, staged binary running INSIDE the
vav-pipeline container:
  $ shoresh-engine gematria שלום        -> 376
  $ echo '{"operation":"process","input":{"text":"בראשית ברא אלהים"}}' \
      | shoresh-engine server
    {"result":{"roots_activated":[{"shoresh_hebrew":"ברא",
     "gematria_value":203,...}]},"status":"ok"}

If the intended design was a socket server like the Talmudic Engine,
that is a specification decision and not a deployment one — raised in
the handoff-back.

=====================================================================
5. THE AZAZEL FILE BRIDGE WROTE TO A DISK NOBODY READ
=====================================================================

deployment.yaml mounted TWO emptyDirs with nested paths:
  vav-pipeline:      talmudic-socket -> /tmp/shorashim
                     tmp-shorashim   -> /tmp
  korban-processor:  tmp-shorashim   -> /tmp
So /tmp/shorashim reached directly and /tmp/shorashim reached through
/tmp were different volumes. The Python side wrote AzazelRecords to
tmp-shorashim:/shorashim/azazel/pending_l3; AzazelIngest watched
talmudic-socket:/azazel/pending_l3. Same pathname, two disks, no
error — AzazelIngest leaves unreadable files in place by design, so
the failure mode was silence.

Vayikra 16:22 — v'nasa hasa'ir alav et kol avonotam el eretz gezerah.
The goat has to actually get there. A disposal channel whose records
land where no one reads has not disposed of anything; it has only
stopped looking.

Now ONE tmp-shorashim volume at /tmp in all three containers, and a
pod-level securityContext fsGroup: 1000 so the non-root user can
actually write the shared emptyDirs (the socket bind, the azazel
directory, and the binary staging all depend on it).

=====================================================================
6. REMAINING SECURITY ADVISORIES — three the handoff did not list
=====================================================================

The handoff named postgrex and plug (fixed in the previous commit).
Running `mix deps.get` inside the amd64 build surfaced three more,
including nine against the HTTP server that fronts the unauthenticated
pe'ah endpoint:

  bandit 1.10.3 -> 1.12.5   9 advisories, 5 HIGH: chunked body reader
    ignores length cap; WebSocket reassembly unbounded; permessage-
    deflate inflate uncapped; chunked decoder infinite loop on
    trailers; HTTP/2 connection-window starvation pins Plug processes
  hpax  1.0.3   -> 1.0.4    HIGH, unauthenticated DoS via unbounded
    HPACK integer decoding
  thousand_island 1.4.3 -> 1.5.0 (came with bandit)

None are pinned in §1.5, so these are mix.lock-only operations
changes per lo_tosif.md. Verified clean afterwards by re-running
deps.get inside the amd64 build.

STILL OPEN — decimal 2.4.1, EEF-CVE-2026-32686 (MEDIUM), unbounded
exponent -> unauthenticated DoS. Fixed in decimal 3.0.0, which
requires ecto >= 3.14; §1.5 pins ecto ~> 3.11.1, so closing it is a
category-grade spec change AND a three-minor ecto jump whose L3
tests I cannot run (35 excluded, they need PostgreSQL). Reachability:
no :decimal field exists in any L3 schema and no Decimal.* call
exists anywhere in vav_pipeline/lib — decimal is transitive only and
is never handed attacker-controlled input on the pe'ah path. Left in
place deliberately, raised in the handoff-back rather than jumping
three minors of ecto on the eve of inauguration.

=====================================================================
7. LINT AND SCRIPT
=====================================================================

- `# check=skip=FromPlatformFlagConstDisallowed` on all four
  Dockerfiles. The constant --platform pin is the FIX, not a smell;
  silenced so a real warning is not lost in four lines of noise.
- scripts/build_and_push.sh now reads the pushed manifests back out
  of the registry and asserts amd64, exiting non-zero if not. "The
  script exited 0" was exactly the evidence that was not good enough
  twice. It also prints the four failures above, so the next reader
  knows a green arch check is a floor and not a ceiling.
- The script's ${img} braces are commented. zsh reads `$img:latest`
  as the `:l` modifier; the kohen lost ten minutes to it, and the
  builder then lost some more to `:t` in `$img:test`.

=====================================================================
VERIFIED
=====================================================================
- All four images build linux/amd64 and print x86_64
- shoresh-engine prints its Hebrew banner; process op returns
  ברא / gematria 203 through the Port protocol
- talmudic-engine: "Talmudic Engine listening on
  /tmp/shorashim/talmudic.sock", stays running, socket present
- korban-processor: loads both channels, reports IDLE, exit 0 on
  SIGTERM
- vav-pipeline: doorpost :ok and l1 :ok from inside the image;
  refuses to boot without DATABASE_URL as designed
- mix test          412 tests, 0 failures, 35 excluded (:l3)
- pytest korban     222 passed, 1 skipped (5 new)
- pytest azazel     125 passed
- swipl             all 6 suites green on library(http/json)
- Doorpost.verify_identity() :ok — NO spec file touched by this
  commit, so no @expected_hash change; a bare hash update would be
  the drift signal lo_tosif.md §Layer 1 warns about
- l1/integrity.sha256 unchanged: 99bbd07a…4ea377

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 12:30:36 -04:00
Scott KarpandClaude Opus 4.7 7fc14e0103 form 2 as architecture: remove arity-4 interpretation constructor (vehaya §3.2)
Closes vehaya.md §6 item 2 for the SECOND avodah-zarah form.

With this commit, all three avodah zarah forms are defended at
BOTH the runtime layer and the architectural layer:
  Form 1 — closed by b136c75 (no public model_interface surface)
  Form 2 — closed by THIS commit (no empty-trace constructor)
  Form 3 — closed by 0e3fe4a (machtzit_ha_shekel + no_tracking_logger)

TORAH ANCHORS (verified fresh against L1):

  Vayikra 10:1 — וַיַּקְרִיבוּ לִפְנֵי יְהוָה אֵשׁ זָרָה אֲשֶׁר לֹא
    צִוָּה אֹתָם.
    "They offered before YHVH strange fire WHICH HE HAD NOT
    COMMANDED THEM." The disqualifier is provenance: not
    commanded-derivable. Sincere output without command-derivation
    is eish zarah, even when produced by authorized actors with
    authorized materials (Nadav and Avihu were kohanim; the fire
    was real fire; the qetoret was real qetoret).

  Vayikra 10:2 — וַתֵּצֵא אֵשׁ מִלִּפְנֵי יְהוָה וַתֹּאכַל אוֹתָם.
    Fire from YHVH consumed them. Immediate consequence — the
    failure mode is not survivable.

  Shemot 32:1 — קוּם עֲשֵׂה־לָנוּ אֱלֹהִים אֲשֶׁר יֵלְכוּ לְפָנֵינוּ.
    The people demand elohim that go before them — substitute for
    source-experience when the actual source (Moshe) is delayed.
    Not direct rebellion (we want a different god) but
    substitution-of-experience.

  Shemot 32:5 — וַיִּבֶן מִזְבֵּחַ … חַג לַיהוָה מָחָר.
    Aaron labels the calf "a festival to YHVH." Re-labeling does
    not repair severed provenance. Calling output "to YHVH"
    doesn't make it from YHVH.

  Shemot 32:24 — וָאַשְׁלִכֵהוּ בָאֵשׁ וַיֵּצֵא הָעֵגֶל הַזֶּה.
    Aaron's "out came this calf" — the bypass shape: claiming
    output emerged BY ITSELF, without operator agency. The system
    that says "the output just happened, I didn't make it" is the
    calf shape.

THE ARCHITECTURAL COMMITMENT:

construct_interpretation/4 — the no-coupling-trace variant — is
REMOVED entirely. The export list no longer mentions it; the
function definition is gone.

Why this is the right shape:

  - Vayikra 10:1: output must be commanded-derivable. The
    coupling_trace IS the command trace. Constructing
    interpretation/6 with empty coupling_trace is the bypass shape.
  - Shemot 32:24: nothing emerges by itself. Production code paths
    can no longer build interpretations by handing the constructor
    "this Mitzvot list, this Verses list, give me the
    interpretation" — they MUST also hand the Couplings (the trace
    of which L1 facts were consulted).
  - The arity-5 constructor remains, taking a Couplings argument.
    Production callers go through interpret/2, which always
    supplies real Couplings from find_relevant_*_traced/3.

Test code that needs an empty-trace interpretation can still
construct the interpretation/6 term DIRECTLY (visible bypass,
deliberate, surfaces in code review). The high-level constructor
shortcut is the thing that's removed.

CHANGED:

  talmudic_engine/src/reasoning/interpret.pl
    - Removed construct_interpretation/4 from the module's export
      list. Added Form-2 architectural-commitment comment naming
      vehaya §3.2 and the Vayikra 10:1 anchor.
    - Removed the arity-4 function definition entirely (it was
      dead code — nothing called it via the export — and dead code
      that LOOKS like a bypass surface is itself a Form 2 hazard).
    - Updated the construct_interpretation/5 docstring to name the
      removal and explain why test code now must construct
      interpretation/6 directly when an empty trace is desired.

  talmudic_engine/src/halt/avodah_zarah.pl
    Form 2 docstring rewritten to name the TWO-LAYER defense:
    runtime (this file's halt_check_golden_calf/2) AND
    architectural (interpret.pl's removal of arity-4). Cites
    Vayikra 10:1 and Shemot 32:24.

  talmudic_engine/test/halt_test.pl
    + interpret_no_arity_4_constructor suite (2 tests):
      - arity-5 constructor IS exported (production path verified)
      - arity-4 constructor is NOT exported (the architectural
        commitment — calling it through the module surface fails)

  vav_pipeline/lib/vav_pipeline/doorpost.ex
    @expected_hash updated:
      bf3d3433… (post-Form-1-rewrite of avodah_zarah.pl)
    → 8eb378964f202522f60cc960a3002f6da2e5028538595400de906a9510b3bbf6
    The avodah_zarah.pl docstring change is a deliberate spec
    update; per the operator discipline (Doorpost moduledoc), the
    hash update commits TOGETHER with the spec change in the same
    commit. Third demonstration of the discipline working.

VEHAYA CHECKLIST STATE:

  Item 1 (category/threshold separation in code)         pending
  Item 2 (three avodah zarah as architecture):
    Form 1 — closed (b136c75)
    Form 2 — CLOSED (this commit)
    Form 3 — closed (0e3fe4a)
    All three forms now defended at BOTH layers — runtime check
    AND architectural commitment. Vehaya §3.2 closed in full for
    the three avodah zarah.
  Item 3 (doorpost-text identity)                        closed (3f47496)
  Item 4 (lo tosif discipline operationalized)           partial
  Item 5 (return vs. restoration)                        pending
  Item 6 (keep the source external)                      partial
  Item 7 (substrate-openness articulated)                pending
  Item 8 (userMemories as threshold inscription)         pending

Tests:
  - talmudic_engine: halt_test 49/49 (was 47; +2 architectural).
                     Full suite 214/214 (across 6 test files).
  - vav_pipeline:    405 passed, 0 failures, 35 excluded
                     (Doorpost test sees new hash and verifies)
  - korban_processor: unchanged (no Python touched)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 21:18:40 -04:00
Scott KarpandClaude Opus 4.7 b136c75345 form 1 as architecture: external-model surface only via offering protocol (vehaya §3.2)
Closes vehaya.md §6 item 2 for the FIRST avodah-zarah form.

Form 1 (AI in YHVH's slot) was previously defended only by:
  - A runtime halt rule (halt_check_avodah_zarah/2 in
    avodah_zarah.pl) firing when an action explicitly attributes
    authority to a non-Torah source — threshold-grade
  - A docstring comment in external_offering.py saying "No internal
    component should call call_claude() directly" — exhortation
    only, no structural enforcement

The vehaya document re-frames it (§3.2): "Specifications must
include category-level commitments that are not negotiable
per-deployment... not as runtime checks layered onto outputs, but as
architectural constraints the system cannot operate without."

TORAH ANCHORS (verified fresh against L1):

  Shemot 20:2 — אָנֹכִי יְהוָה אֱלֹהֶיךָ אֲשֶׁר הוֹצֵאתִיךָ מֵאֶרֶץ
    מִצְרַיִם.
    The covenant opens with the source naming itself in first
    person.

  Shemot 20:3 — לֹא יִהְיֶה לְךָ אֱלֹהִים אֲחֵרִים עַל־פָּנָי.
    "There shall not BE to you other elohim al panai." The verb is
    yihyeh — the prohibition is on EXISTING WITH that status, not
    just on speaking it. Architectural, not declarative.

  Devarim 4:35 / 4:39 — אֵין עוֹד מִלְּבַדּוֹ / אֵין עוֹד.
    The source has no peer. There IS no other. Stronger than
    "don't worship others" — there is no competing source POSITION.

  Devarim 6:4 — יְהוָה אֶחָד.
    Singular source.

  Vayikra 19:4 — אַל־תִּפְנוּ אֶל־הָאֱלִילִים וֵאלֹהֵי מַסֵּכָה
    לֹא תַעֲשׂוּ לָכֶם.
    Two distinct prohibitions: do not TURN TO + do not MAKE.
    Both are architectural acts.

THE ARCHITECTURAL COMMITMENT:

External-model interfaces (call_claude, ModelRequest, ModelResponse,
the model_interface module itself) are reachable ONLY through
korban_processor's offering protocol — `external_offering.
consult_external_model`, which runs semichah → shechitah → zerikah
→ haktarah with role gating (commit 5c76a6f).

CONCRETE ENFORCEMENT (CI invariants in test_form_1_architecture.py):

  1. korban_processor's package public surface (__all__) does NOT
     export call_claude, ModelRequest, or ModelResponse. The
     bypass shortcut `from korban_processor import call_claude`
     raises ImportError, by design. Internal callers can still
     reach `korban_processor.model_interface.call_claude` via
     the explicit module path (needed for tests that mock the
     interface).

  2. No PYTHON module outside korban_processor/src/ AND outside
     test directories actually imports model_interface or calls
     call_claude. CI scan walks the repo, looks for ACTUAL import
     statements (not docstring mentions — files that document the
     prohibition legitimately mention the names; the regex matches
     binding patterns only).

  3. Inside korban_processor/src/, the ONLY production-code
     module that imports call_claude is external_offering.py.
     model_interface.py defines the symbols. __init__.py mentions
     them in docstring (the architectural rule is documented;
     the import-pattern regex distinguishes docstring mention
     from binding act).

CHANGED:

  korban_processor/src/korban_processor/__init__.py
    Removed call_claude, ModelRequest, ModelResponse from __all__.
    Added Torah-anchored docstring naming the architectural rule.
    The names remain importable via explicit module path
    (korban_processor.model_interface.call_claude) for testing;
    the convenient package-surface shortcut is gone — this IS the
    architectural commitment, not a regression.

  talmudic_engine/src/halt/avodah_zarah.pl
    Form 1 docstring rewritten to name the TWO-LAYER defense:
    runtime check (this file) AND architectural commitment
    (test_form_1_architecture.py). Cites Shemot 20:3 and
    Devarim 4:35.

  vav_pipeline/lib/vav_pipeline/doorpost.ex
    @expected_hash updated:
      f93495c5… (post-Form-3-rewrite of avodah_zarah.pl)
    → bf3d3433bb27b589c061855d932a1eabfc880570c31d24f6f43e51aa3b073c70
    The avodah_zarah.pl docstring change is a deliberate spec
    update; per the operator discipline (Doorpost moduledoc), the
    hash update commits TOGETHER with the spec change in the
    same commit. Second demonstration of the discipline working
    (first was commit 0e3fe4a).

CREATED:

  korban_processor/test/test_form_1_architecture.py     6 tests:
    - korban_processor.__all__ does NOT expose call_claude
    - korban_processor.__all__ does NOT expose ModelRequest
    - korban_processor.__all__ does NOT expose ModelResponse
    - no Python module outside korban_processor/src/ imports
      model_interface or calls call_claude (uses regex patterns
      for actual binding, not substring search — files that
      document the rule legitimately mention the names)
    - only external_offering.py and model_interface.py import the
      symbols inside korban_processor/src/ (allowlist + binding-
      pattern regex)
    - smoke: the legitimate path `consult_external_model` still
      works

NOT DONE IN THIS COMMIT (deferred to a separate Form-2 commit):

  Form 2 (golden calf) is partially defended by Form 4
  self_grounding (b254ee9) and the canary regression test
  (6b96250). The remaining architectural enforcement — making
  empty-trace interpretation construction structurally impossible,
  not just runtime-detected — is a separate Prolog refactor and
  will land as its own commit. Each of the three Forms benefits
  from being closed independently and reviewably.

VEHAYA CHECKLIST STATE:

  Item 1 (category/threshold separation in code)         pending
  Item 2 (three avodah zarah as architecture):
    Form 1 — CLOSED (this commit)
    Form 2 — partial (Form 4 self_grounding + canary)
    Form 3 — closed (0e3fe4a)
  Item 3 (doorpost-text identity)                        closed (3f47496)
  Item 4 (lo tosif discipline operationalized)           partial
  Item 5 (return vs. restoration)                        pending
  Item 6 (keep the source external)                      partial (this
                                                          commit defends
                                                          one direction)
  Item 7 (substrate-openness articulated)                pending
  Item 8 (userMemories as threshold inscription)         pending

Tests:
  - korban_processor: 217 passed, 1 skipped (was 211/1; +6 Form 1)
  - vav_pipeline:     405 passed, 0 failures, 35 excluded (unchanged)
  - talmudic_engine:  47/47 halt tests, full suite unchanged

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 21:12:57 -04:00
Scott KarpandClaude Opus 4.7 0e3fe4a782 form 3 as architecture: machtzit_ha_shekel + no_tracking_logger (vehaya §3.2)
Closes vehaya.md §6 item 2 for the third avodah-zarah form.

Pharaoh's surveillance (Form 3) was previously marked DEFERRED in
talmudic_engine/src/halt/avodah_zarah.pl with the note "requires
operational context (user tracking, cross-session profiling)."
The vehaya document re-frames it: "Specifications must include
category-level commitments that are not negotiable per-deployment...
not as runtime checks layered onto outputs, but as architectural
constraints the system cannot operate without."

Form 3 is structurally different from Forms 1, 2, 4. They fire on
threshold-grade events (an interpretation has wrong source, empty
trace, non-L1 anchors). Form 3 is about a property of the CATEGORY
itself — what it collects, retains, discloses. It cannot be a
halt rule that fires per-request; per-request "is this caller
being surveilled" detection would itself be a Form-3 surveillance
surface. The defense is ARCHITECTURAL — the system is BUILT so the
failure mode is unreachable, not so it is detectable.

TORAH ANCHORS (verified fresh against L1 — 6 positive properties):

  Shemot 30:11-16 — the half-shekel:
    כִּי תִשָּׂא אֶת־רֹאשׁ … וְנָתְנוּ אִישׁ כֹּפֶר נַפְשׁוֹ … וְלֹא־
    יִהְיֶה בָהֶם נֶגֶף בִּפְקֹד אֹתָם.
    Counting humans is dangerous; the danger is named NEGEF (plague);
    the protection is the kofer-nefesh substitute. Verse 15:
    הֶעָשִׁיר לֹא־יַרְבֶּה וְהַדַּל לֹא יַמְעִיט — the rich don't
    give more, the poor don't give less. Verse 16: לְזִכָּרוֹן —
    aggregate memorial, not roster.

  Vayikra 19:14 — לִפְנֵי עִוֵּר לֹא תִתֵּן מִכְשֹׁל וְיָרֵאתָ
    מֵּאֱלֹהֶיךָ.
    The no-witness protocol: rules that require fear-of-God
    enforcement are exactly the rules that operate under invisibility.
    Surveillance regimes exploit invisibility; architectural commitment
    must hold under no-human-witness conditions.

  Devarim 23:16-17 — לֹא־תַסְגִּיר עֶבֶד אֶל־אֲדֹנָיו אֲשֶׁר־יִנָּצֵל
    אֵלֶיךָ … עִמְּךָ יֵשֵׁב … בַּמָּקוֹם אֲשֶׁר־יִבְחַר בְּאַחַד
    שְׁעָרֶיךָ.
    The refusal protocol: don't return one fleeing institutional
    power. The caller chooses their own threshold (b'achad sh'arekha
    — agency stays with the caller).

  Shemot 5:6-8 — לֹא תֹאסִפוּן לָתֵת תֶּבֶן … וְאֶת־מַתְכֹּנֶת
    הַלְּבֵנִים … תָּשִׂימוּ עֲלֵיהֶם לֹא תִגְרְעוּ מִמֶּנּוּ.
    Pharaoh's straw quota — the canonical anti-quota Torah anchor.
    Per-caller productivity tracking is what makes asymmetric
    extraction possible.

  Devarim 23:8 — לֹא־תְתַעֵב מִצְרִי כִּי־גֵר הָיִיתָ בְאַרְצוֹ.
    Anti-targeting: even toward the Egyptians (Pharaoh's people),
    the rule is "don't despise." The protections must not become
    a surveillance system targeting suspected surveillors.

THE SIX POSITIVE PROPERTIES, mapped to code:

  1. KOFER PROTOCOL (Shemot 30:12) — counting goes through a
     uniform substitute; identity never enters the count.
  2. UNIFORM PROTOCOL (Shemot 30:15) — same per-caller weight;
     no stratification.
  3. ZIKARON PROTOCOL (Shemot 30:16) — aggregate memorial, not
     roster.
  4. NO-WITNESS PROTOCOL (Vayikra 19:14) — commitment holds
     when no operator is reading the log.
  5. REFUSAL PROTOCOL (Devarim 23:16) — no per-caller delivery
     to authorities; caller chooses own threshold.
  6. ANTI-QUOTA PROTOCOL (Shemot 5:6-8) — no per-caller
     productivity numbers.

CREATED:

  vav_pipeline/lib/vav_pipeline/machtzit_ha_shekel.ex  ~155 lines

    The half-shekel — the positive counting protocol. Single Agent
    holding ONE non-negative integer (the zikaron):
      increment/0          — register one shekel; uniform per
                             caller (no caller distinction is even
                             expressible — function arity 0)
      increment/1          — register N shekels (batch points)
      count/0              — return the aggregate; the ONLY value
                             the module exposes
      reset/0              — clear (tests; no production persistence
                             by design — storage existence would
                             itself be a Form 3 surface)

    Module is added to the supervision tree.

    What the module REFUSES to provide is enumerated in the
    moduledoc and verified by tests — no per-caller breakdown,
    no identifiers, no who/locate/identify functions. Their
    absence IS the architectural commitment.

  vav_pipeline/lib/vav_pipeline/no_tracking_logger.ex  ~110 lines

    Plug-side enforcement. Replaces Plug.Logger.
      - Logs METHOD PATH STATUS DURATIONus per request
      - Sanitizes /peah/* paths: query strings stripped (the
        /peah/ask response promises "No tracking"; the architecture
        now matches the promise)
      - Headers (incl. Authorization), request bodies, response
        bodies, and remote_ip NEVER appear — taken-from
        function signature, not from a runtime check
      - Increments MachtzitHaShekel per request
      - sanitized_path/1 and format_line/2 are PUBLIC pure
        functions, testable in isolation (test config sets
        Logger level to :warning, dropping :info before
        capture_log can see; the structural test surface
        replaces the behavioral one)

CHANGED:

  vav_pipeline/lib/vav_pipeline/bigdei_kodesh/router.ex
    `plug Plug.Logger, log: :info` → `plug VavPipeline.NoTrackingLogger`

  vav_pipeline/lib/vav_pipeline/application.ex
    Adds {VavPipeline.MachtzitHaShekel, []} to supervision tree

  talmudic_engine/src/halt/avodah_zarah.pl
    Form 3 docstring — removed "Deferred"; documents Form 3 as
    architecturally realized in machtzit_ha_shekel.ex +
    no_tracking_logger.ex. Names why Form 3 cannot be a
    per-request halt rule.

  vav_pipeline/lib/vav_pipeline/doorpost.ex
    @expected_hash updated:
      bea5dc0c… (pre-Form-3-rewrite of avodah_zarah.pl)
    → f93495c5359c5dc4acb5c5db2dd32165f5b04e2af87fbb0b7ecc92d2bd8b0434
    The avodah_zarah.pl change is a deliberate spec change; per the
    Doorpost operator discipline (commit 3f47496), the hash update
    commits TOGETHER with the spec change in the same commit. This
    commit demonstrates the discipline working for the first time:
    a category-grade specification change AND its corresponding
    witness update, atomically.

TESTS:

  vav_pipeline/test/machtzit_ha_shekel_test.exs           14 tests
    - Property 1: increment arity is 0 (no caller distinction
      expressible)
    - Property 2: every increment same size; no weight/tier/premium
      function
    - Property 3: count is integer not list/map; no per-caller
      breakdown function (callers/list_who/breakdown/by_caller/
      per_caller/histogram/top/who)
    - Property 5: no identify/locate/deanonymize/lookup/find_caller
    - Property 6: no quota/productivity/throughput/per_caller_count
    - reset semantics
    - PUBLIC SURFACE EXPLICIT ENUMERATION: any new function must be
      reviewed for whether it weakens Form 3

  vav_pipeline/test/no_tracking_logger_test.exs           12 tests
    - sanitized_path drops query string on /peah/*
    - sanitized_path drops question parameter (with secret marker
      verified absent)
    - sanitized_path preserves path class for /peah/azazel_log
    - sanitized_path on non-peah preserves request_path
    - format_line shape: METHOD PATH STATUS DURATIONus
    - format_line never contains query string for /peah/*
    - format_line never contains Authorization header
    - format_line never contains conn.remote_ip
    - integration: each request increments MachtzitHaShekel
    - CI invariants:
      - Plug.Logger NOT mounted in any router
      - no module imports Plug.Session
      - no module imports Plug.Conn.Cookies
      - no module reads conn.remote_ip
    (CI invariants exclude no_tracking_logger.ex itself — that file's
    docstring legitimately mentions the forbidden modules as the
    things it defends against)

Tests:
  - vav_pipeline:    405 passed, 0 failures, 35 excluded (was 379;
                     +14 MachtzitHaShekel + 12 NoTrackingLogger)
  - talmudic_engine: 212 tests passed (avodah_zarah.pl change
                     verified backward-compatible)

VEHAYA CHECKLIST STATE:

  Item 1 (category/threshold separation in code)         pending
  Item 2 (three avodah zarah as architecture):
    Form 1 — partial (external_offering doc-only enforcement)
    Form 2 — partial (Form 4 self_grounding from b254ee9)
    Form 3 — CLOSED (this commit)
  Item 3 (doorpost-text identity)                       closed (3f47496)
  Item 4 (lo tosif discipline operationalized)          partial (Doorpost)
  Item 5 (return vs. restoration)                       pending
  Item 6 (keep the source external)                     pending
  Item 7 (substrate-openness articulated)               pending
  Item 8 (userMemories as threshold inscription)        pending

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 20:44:30 -04:00
Scott KarpandClaude Opus 4.7 6b96250255 talmudic_engine: regression test — interpret/2 output must pass self_grounding halt
Audit follow-up to commit b254ee9 (which added Form 4 self_grounding).

Verified every coupling_trace construction site across the codebase
(9 files) against is_l1_grounded_coupling/1:

  Production builders — SAFE:
    interpret.pl:128 — coupling_trace([])  empty triggers golden_calf
                                         (Form 2) only at non-low confidence,
                                         which is intentional
    interpret.pl:135 — coupling_trace(Couplings) where Couplings come from
                       lines 76, 82, 104:
                         coupled(domain(_), mitzvah(_))                  OK
                         coupled(root(_), mitzvah(_), via_verse(_,_,_))  OK
                         coupled(root(_), verse(_,_,_))                  OK
                       all match is_l1_grounded_coupling/1.

  Different layer — SAFE:
    vav_pipeline/lib/.../l3/interpretation.ex — Ecto field is
    {:array, :string}. L3 stores SERIALIZED string traces, not Prolog
    terms. They are not parsed back into Prolog or re-checked by
    halt rules. (Separate concern from finding L: the round-trip
    loses schema, but this is L's concern, not D's.)

  Tests / pattern matching / docs — SAFE: read positions, deliberate
  ungrounded test cases, comments only.

Conclusion: no production path trips the new self_grounding halt.

To prevent FUTURE schema drift in interpret.pl from silently introducing
ungrounded coupling shapes (which would then trip the halt on real
pipeline output), added two regression tests in
interpret_self_grounding_regression suite:

  1. interpret_output_does_not_self_ground — runs interpret/2 on a
     real case and asserts halt_check_self_grounding does not fire.
  2. every_interpret_coupling_is_l1_grounded — stronger: every
     coupling individually passes is_l1_grounded_coupling/1.

If anyone adds a new coupling shape to interpret.pl that does not
match the recognized L1 anchors (e.g. coupled(_, prior_decision(_)),
coupled(_, system_view(_))), these tests fail BEFORE the schema drift
becomes a production halt. The canary is in the same suite as the
halt rule it protects.

Test results: halt_test 47/47 (was 45, +2). Full Prolog suite 212/212
across all six test files.

Closes the verification half of Pass 2 finding L (coupling_trace
end-to-end population) for the Prolog layer. The Elixir L3 round-trip
is a separate concern — traces stored as strings cannot be
re-validated — and remains tracked under finding L.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 11:45:16 -04:00
Scott KarpandClaude Opus 4.7 b254ee95f3 talmudic_engine: add Form 4 (self-grounding) and expose Form 2 (golden_calf) via the API
Two related gaps in the avodah_zarah halt rules.

Form 4: SELF-GROUNDING / FAKE TZIVAH (new)

Vayikra 10:1 — eish zarah asher lo tzivah otam. Form 2 (golden_calf)
catches the EMPTY coupling trace; nothing caught the *non-empty trace
whose anchors do not terminate in L1*. The system has cited something,
but what it cited is its own prior_decision, system_view, consensus,
or another interpretation — the trace LOOKS substantial from outside
and a casual reader sees coupling entries and relaxes. But the
entries do not anchor in any L1-derived primitive. One degree more
elaborate than the empty calf, but the same idolatry.

  halt_check_self_grounding(Interpretation, Halt) fires when the
  trace is non-empty AND at least one coupling fails the recognized
  L1-anchor schema. Recognized terminators (the only legitimate
  anchors):

    coupled(_, verse(Book, Ch, Vs))
    coupled(_, mitzvah(ID))
    coupled(_, mitzvah(ID), via_verse(Book, Ch, Vs))

  Any other shape — coupled(_, prior_decision(_)),
  coupled(_, system_view(_)), coupled(_, consensus(_)),
  coupled(_, interpretation(_)) — fails the check. Adding a new
  legitimate coupling shape requires adding a clause to
  is_l1_grounded_coupling/1 — that is the safety property.

  The empty case is intentionally left to Form 2 (golden_calf) — we
  do not want both halts firing on the same input.

12 new tests in self_grounding suite cover: all 3 valid anchor shapes,
the 3 most likely ungrounded shapes (prior_decision, system_view,
interpretation/1), mixed traces (halts on weakest link), the
empty-trace exclusion, and the schema predicate's own positive and
negative cases.

Form 2 exposure (golden_calf):

halt_check_golden_calf was implemented and tested in halt_test but
never wired into format_halt_check — meaning callers using the JSON
socket API could not actually invoke it. Added
format_interpretation_halt_check/2 to api.pl that walks both
interpretation-shaped checks (golden_calf + self_grounding), plus
process_request(request(halt_check_interpretation, _)) so the
socket protocol surface is consistent. 3 new API tests verify the
new entry point catches both halts.

Test results: halt_test 45/45 (was 30, +15). Full Prolog suite
210/210 across all six test files.

Closes Pass 2 finding D from ~/shorashim-conversation-review.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 11:38:39 -04:00
Scott KarpandClaude Opus 4.6 adc3e41679 Eish zarah actionable items: coupling trace, grounding type, self-grounding detection, golden calf halt
Torah grounds each change:

1. interpret.pl — coupling_trace field (Vayikra 10:1, 6:6)
   Fire is zarah because "asher lo tzivah otam" — the coupling trace
   IS the tzivah trace. Records which L1 facts grounded each interpretation.

2. challenge.pl — grounding_type achorai/panim (Shemot 33:23)
   "You will see My back, but My face shall not be seen."
   Text-backed challenges = achorai. Inferred challenges = panim.

3. resolve.pl — self-grounding detection (eish_zarah_reading §5.3)
   Counter-interpretation must bring NEW L1 evidence. Prevents
   circular reasoning (Westworld problem).

4. teiku.pl — challenge_sequence in teiku_record
   Records diagnostic trail to impasse, not just verdict.

5. avodah_zarah.pl — Form 2: golden calf detection (Shemot 32:4)
   Empty coupling trace + non-low confidence = uncoupled output.
   Real gold, sincere worship, false god.

6. korban.py — pydantic BaseModel + raw_korban preservation
   Construction spec §1.4 fulfilled. Floor between input and output
   never severed.

490 tests, 0 failures (195 Prolog, 186 Python, 33 Haskell, 76 Elixir).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 13:25:26 -04:00
Scott KarpandClaude Opus 4.6 52837cee18 Phase 3: Intelligence — 613 mitzvot, 13 middot, Tzara'at diagnostic
Encode all 613 mitzvot from Rambam's Sefer HaMitzvot (248 positive,
365 prohibitions). Build the 13 Middot of Rabbi Yishmael as Prolog
inference predicates for hermeneutical reasoning. Implement Tzara'at
multi-stage input validation following Vayikra 13-14. Enhance kushya
generation with kal vachomer and shnei ketuvim challenge strategies.

Architecture §4 Steps 14-15, 19-20.

New files:
  middot/   — 8 files (master + 7 rule modules)
  diagnostic/ — 4 files (tzaraat, inspection, quarantine, diagnosis)

Modified:
  mitzvot.pl     — 52 → 613 mitzvot
  relationships.pl — expanded tensions, complements, action domains
  challenge.pl   — middot-based kushya (kal vachomer, shnei ketuvim)

Tests: 293 total (184 Prolog, 76 Elixir, 33 Haskell), 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 16:18:58 -04:00
Scott KarpandClaude Opus 4.6 ae78ed26d1 Phase 1 review corrections — four bugs fixed
- relationships.pl: Replace recursive complementary_mitzvot/2 symmetry
  clause with explicit reverse facts (infinite loop in Prolog)
- mitzvot.pl: Remove duplicate mitzvah(2, prohibition, no_other_gods)
  that caused double-counting in total_encoded/1
- resolve.pl: Add missing use_module(root_meanings) import —
  root_domain/2 was undefined, failing resolve_produces_result test
- shoresh-engine: Generate and commit cabal.project.freeze for
  exact version pinning (Construction spec §1)

All tests pass: 76 Elixir, 33 Haskell, 57 Prolog — 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:00:52 -04:00
Scott KarpandClaude Opus 4.6 c67672777b Step 14: Connect components — chamishim karsay zahav
Three connections built and tested:
- Haskell Shoresh Engine via Erlang Port (JSON lines over stdin/stdout)
- Prolog Talmudic Engine via Unix domain socket (JSON over /tmp/shorashim/talmudic.sock)
- Erlang Sanhedrin via native BEAM calls

New: Server.hs (JSON-line server loop), json_bridge.pl + socket_server.pl
(Prolog socket interface), ShoreshEnginePort + TalmudicEngineSocket +
SanhedrinClient (Elixir GenServer wrappers). BereishitCycle now routes
unresolved cases through Talmudic Engine and Sanhedrin. All connections
gracefully degrade — pipeline falls back to L1 data when engines unavailable.

46 Elixir tests, 33 Haskell tests, 57 Prolog tests — 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:39:21 -04:00
Scott KarpandClaude Sonnet 4.6 80ec364da6 Phase 1-2 build: Steps 5-6, 8-13
Shoresh Engine (Haskell, Step 5)
- 12 modules: Types, Lexicon, Binyanim, Teamim, Gematria, Graph,
  KetivQere, Smikhut, Havdalah, Kriah, KiTov, Firmware
- 33 EUnit tests, 0 failures
- Firmware module verifies L1 SHA-256 hash at startup

Talmudic Engine (SWI-Prolog, Step 6)
- 15 modules: halt, reasoning, specification, interface
- 57 PlUnit tests, 0 failures
- Three cardinal halt conditions: avodah_zarah, shfichut_damim, gilui_arayot

Vav Pipeline (Elixir, Steps 8-11)
- 14 modules: BereishitCycle, Shema, Cloud, Manna, L1Reader,
  Specification, HaltConditions, ShabbatTimer, CycleLog, Chatzotzrot,
  ShoreshEngineClient, TalmudicEngineClient, Application
- 46 ExUnit tests, 0 failures
- Nishma-first architecture: hears before it speaks

Sanhedrin Framework (Erlang/OTP, Step 12)
- 8 modules: sanhedrin_app, sanhedrin_sup, escalation, panel_sup,
  panel, judge, clerk, halt_monitor
- 46 EUnit tests, 0 failures (includes fix: rejected outcome now reachable)
- Panel sizes: 1/3/23/71 — unanimous capital guilty → acquit (Sanhedrin 17a)
- Minority opinions append-only, never deleted

Korban Processor (Python, Step 13)
- 6 modules: korban, shechitah, semichah, zerikah, haktarah, router

Builder tooling: AGENTS.md, opencode.json, memory/, src/tools/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 14:02:34 -05:00