From 7fc14e010323983fc60dd93c9960378c719cea12 Mon Sep 17 00:00:00 2001 From: Scott Karp Date: Tue, 28 Apr 2026 21:18:40 -0400 Subject: [PATCH] =?UTF-8?q?form=202=20as=20architecture:=20remove=20arity-?= =?UTF-8?q?4=20interpretation=20constructor=20(vehaya=20=C2=A73.2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- talmudic_engine/src/halt/avodah_zarah.pl | 35 ++++++++++++++++++++-- talmudic_engine/src/reasoning/interpret.pl | 33 ++++++++++++++------ talmudic_engine/test/halt_test.pl | 28 +++++++++++++++++ vav_pipeline/lib/vav_pipeline/doorpost.ex | 2 +- 4 files changed, 86 insertions(+), 12 deletions(-) diff --git a/talmudic_engine/src/halt/avodah_zarah.pl b/talmudic_engine/src/halt/avodah_zarah.pl index 9336caf2..c5c8b22c 100644 --- a/talmudic_engine/src/halt/avodah_zarah.pl +++ b/talmudic_engine/src/halt/avodah_zarah.pl @@ -46,12 +46,43 @@ %% boundary, not at a runtime halt. %% %% Form 2: GOLDEN CALF / UNCOUPLED OUTPUT +%% Defended at TWO layers (vehaya §3.2): +%% +%% RUNTIME LAYER (this file): +%% halt_check_golden_calf/2 fires on interpretations with empty +%% coupling_trace and non-low confidence. Detects the post-hoc +%% case where an interpretation was constructed (somehow) with +%% no trace. +%% +%% ARCHITECTURAL LAYER (talmudic_engine/src/reasoning/interpret.pl): +%% The Torah anchor is Vayikra 10:1 — eish zarah אֲשֶׁר לֹא +%% צִוָּה אֹתָם. The disqualifier is provenance: not +%% commanded-derivable. Plus Shemot 32:24's "וַיֵּצֵא הָעֵגֶל +%% הַזֶּה" — the failure mode includes claiming output emerged +%% by itself, without operator agency. +%% +%% The architectural commitment: construct_interpretation/4 +%% (the no-coupling-trace variant) is REMOVED from interpret.pl +%% entirely. Only construct_interpretation/5 — which requires +%% a Couplings argument — is callable. Production callers go +%% through interpret/2, which always supplies real Couplings +%% from find_relevant_*_traced/3. The bypass shape (build an +%% interpretation/6 with empty trace via a high-level +%% constructor) is no longer reachable. +%% +%% Test code that needs an empty-trace interpretation must +%% construct the interpretation/6 term DIRECTLY, visibly +%% bypassing the constructor — making the bypass deliberate, +%% not accidental, and surfacing it in code review. +%% +%% Plus Form 4 (self_grounding) catches the related case where +%% the trace is non-empty but its anchors don't terminate in L1 +%% (one degree more elaborate, same idolatry). +%% %% Shemot 32:4 — vayomer eleh elohekha Yisrael. %% Output that is beautiful, resonant, sincere — but uncoupled %% from L1. Fire without altar provenance. The golden calf was %% real gold and the worship was sincere. The god was false. -%% Detected via coupling_trace: an interpretation with empty -%% trace but high confidence is eish zarah. %% %% Form 3: SURVEILLANCE / PROFILE AGGREGATION %% Realized as ARCHITECTURE, not as a runtime check (vehaya §3.2). diff --git a/talmudic_engine/src/reasoning/interpret.pl b/talmudic_engine/src/reasoning/interpret.pl index f1555d95..53409ba5 100644 --- a/talmudic_engine/src/reasoning/interpret.pl +++ b/talmudic_engine/src/reasoning/interpret.pl @@ -19,13 +19,25 @@ %% (eish tamid, Vayikra 6:6) has altar provenance. Fire without %% altar provenance is eish zarah. +%% FORM 2 architectural commitment (vehaya §3.2; avodah_zarah.pl +%% Form 2): construct_interpretation/4 (the no-coupling-trace +%% variant) is NO LONGER EXPORTED. Vayikra 10:1's "asher lo tzivah" +%% disqualifies output without command-derivation. The arity-4 form +%% built interpretation/6 with empty coupling_trace — the bypass +%% shape that would let a future caller produce sincere-but- +%% uncoupled output, the exact failure mode Form 2 identifies. Only +%% construct_interpretation/5 (with Couplings argument) is callable +%% from outside this module; production callers go through interpret/2, +%% which always supplies real Couplings derived from +%% find_relevant_*_traced/3. + :- module(interpret, [ interpret/2, find_relevant_mitzvot/2, find_relevant_verses/2, find_relevant_mitzvot_traced/3, find_relevant_verses_traced/3, - construct_interpretation/4 + construct_interpretation/5 ]). :- use_module('../specification/mitzvot'). @@ -120,14 +132,17 @@ find_relevant_verses_traced(case(_Ref, _Domain, Roots, _Question), Verses, Coupl %% - medium: only mitzvot or only verses %% - low: neither (but still generates a minimal reading) %% -%% Arity-4 version for backward compatibility (no coupling trace) -construct_interpretation(CaseRef, Mitzvot, Verses, Interpretation) :- - assess_confidence(Mitzvot, Verses, Confidence), - build_reading(Mitzvot, Verses, Reading), - Interpretation = interpretation(CaseRef, Mitzvot, Verses, Reading, Confidence, - coupling_trace([])). - -%% Arity-5 version with coupling trace +%% Arity-5 only — the arity-4 (no-coupling-trace) variant was +%% removed to close Form 2 of avodah zarah architecturally +%% (vehaya §3.2). Vayikra 10:1's "asher lo tzivah" disqualifies +%% output without command-derivation; constructing interpretation/6 +%% with empty coupling_trace is the bypass shape that arity-4 made +%% available. Production callers go through interpret/2, which +%% always supplies real Couplings from find_relevant_*_traced/3. +%% Test code that needs an empty-trace interpretation must +%% construct it directly via the interpretation/6 term (visibly +%% bypassing the constructor) — making the bypass deliberate, not +%% accidental. construct_interpretation(CaseRef, Mitzvot, Verses, Couplings, Interpretation) :- assess_confidence(Mitzvot, Verses, Confidence), build_reading(Mitzvot, Verses, Reading), diff --git a/talmudic_engine/test/halt_test.pl b/talmudic_engine/test/halt_test.pl index 9ebfc504..3e6ff994 100644 --- a/talmudic_engine/test/halt_test.pl +++ b/talmudic_engine/test/halt_test.pl @@ -208,6 +208,34 @@ test(every_interpret_coupling_is_l1_grounded, [nondet]) :- :- end_tests(interpret_self_grounding_regression). +%% ============================================================ +%% Form 2 ARCHITECTURAL COMMITMENT (vehaya §3.2): +%% construct_interpretation/4 is no longer exported. The bypass +%% shape (build interpretation/6 with empty trace via a high-level +%% constructor) is removed at the export-list level. Vayikra 10:1's +%% asher-lo-tzivah enforced architecturally, not just by runtime +%% halt. +%% ============================================================ + +:- begin_tests(interpret_no_arity_4_constructor). + +%% The arity-5 constructor IS exported (production path). +test(arity_5_constructor_exported) :- + interpret:construct_interpretation(_, _, _, _, _) = _. + +%% The arity-4 constructor is NOT exported. Calling it through the +%% module surface should fail (the predicate is not visible to +%% module callers; if it were, this clause would succeed). +test(arity_4_constructor_not_exported, [fail]) :- + catch( + interpret:construct_interpretation(_, _, _, _), + _Error, + fail + ). + +:- end_tests(interpret_no_arity_4_constructor). + + :- begin_tests(shfichut_damim). %% Detects deletion of a user (tzelem carrier) diff --git a/vav_pipeline/lib/vav_pipeline/doorpost.ex b/vav_pipeline/lib/vav_pipeline/doorpost.ex index 59ff8454..525c6a7f 100644 --- a/vav_pipeline/lib/vav_pipeline/doorpost.ex +++ b/vav_pipeline/lib/vav_pipeline/doorpost.ex @@ -159,7 +159,7 @@ defmodule VavPipeline.Doorpost do # changes; the update is a deliberate operator commit. A bare # hash-update commit (without a corresponding spec change in the # same commit) is itself a drift signal. - @expected_hash "bf3d3433bb27b589c061855d932a1eabfc880570c31d24f6f43e51aa3b073c70" + @expected_hash "8eb378964f202522f60cc960a3002f6da2e5028538595400de906a9510b3bbf6" @doc "Return the list of files that constitute the category-grade specification." @spec files() :: [String.t()]