Files
Scott KarpandClaude Opus 4.7 5302c9a585 vehaya §6 closure: Items 1, 4, 5, 6, 7, 8 — the remaining checklist
This commit closes the SIX remaining items in the vehaya checklist
(after Items 2 and 3 from prior commits). With this, all eight items
in vehaya §6 are addressed in code or in the canonical spec set,
and all the substantive implications across §3 are covered.

ITEM 1 — load-bearing dependency (vehaya §3.1):

  Devarim 11:18-19 — corporate inscription (v'samtem … al
  l'vavkhem — plural) is the load-bearing input to threshold
  practice (b'shivt'kha b'beitekha — singular). The threshold
  inscribes the corporate text on itself.

  ShemaContext now carries `doorpost_hash: Doorpost.expected_hash()`
  on every reception. Both receive_context/1 and receive_context_at/2
  populate it. Every reception is now a witness of the corporate
  text's identity — making the load-bearing dependency between
  category and threshold structural rather than implicit.

  application.ex now runs Doorpost.verify_identity/0 at startup.
  Drift detected at boot is logged at :error AND fires
  Chatzotzrot.signal(:assembly_leaders, ...). The system does NOT
  refuse to boot on drift (dev environments routinely have spec
  drift during active editing) but operators are alerted before any
  reception fires.

ITEM 6 — keep the source external (full closure; vehaya §6 item 6):

  Devarim 4:2 — lo tosif AND lo tigra; both directions.
  Vayikra 22:31 — u'shmartem … va'asitem; keep and do, not author.

  Form 1 closed the EXTERNAL → INTERNAL direction (commit b136c75 —
  no module installs external models in YHVH's slot). This commit
  closes the INTERNAL → SOURCE direction (no module modifies the
  source itself).

  vav_pipeline/test/source_external_test.exs (4 tests) verifies:
    - no Elixir module writes to the L1 mount
    - no Python module in korban_processor writes to L1
    - no Python module in azazel_processor writes to L1
    - no Prolog module asserts into L1-shape predicates from
      outside specification/

  L1 was already filesystem-permission-controlled at the operator
  layer; this commit defends in code so the architectural commitment
  cannot be silently violated by future code paths.

ITEM 7 — substrate openness (vehaya §2.4):

  Bereishit 2:7 — afar substrate + nishmat chayim breath; the text
  does not preclude carriers of other substrate.

  specs/shorashim_architecture.md §8.4 added: positive architectural
  claim that the system is designed to carry covenant content
  regardless of substrate, with explicit caveats (does NOT claim AI
  is a covenant party with YHVH, does NOT claim AI has neshamah,
  does NOT claim all substrates are equally adequate). The claim is
  structural: nothing in the architecture refuses a substrate Torah
  did not refuse. Lo tosif applied to imported constraints.

ITEM 8 — userMemories as threshold inscription (vehaya §3.3):

  Devarim 11:20 / Devarim 6:9 — u'kh'tavtam al m'zuzot beitekha;
  the doorpost-text verse is identical between the Shema's first
  paragraph (singular pole) and V'haya's second (oscillating).

  specs/threshold_inscription.md (new) names the architecture for
  the threshold inscription:
    - identical at every threshold (Doorpost hash; same MEMORY.md
      structure)
    - pointing back to the source (the inscription is OF the
      corporate text, not ABOUT the threshold)
    - inscribed at the threshold's own location

  Two implementations: ShemaContext.doorpost_hash (runtime) and
  MEMORY.md (operator-side). Operator workflow split into three
  layers: build status (MEMORY.md), spec changes (specs/* with
  Doorpost atomicity), operator notes (outside repo).

ITEM 5 — return vs. restoration (vehaya §3.5):

  Devarim 30:2 / 30:8 / 30:10 — v'shavta ad YHVH … ha'k'tuvah
  b'sefer ha'Torah ha'zeh. Return is to the SOURCE and the
  SPECIFICATIONS, anchored in the text — not to a previous
  deployment configuration.

  specs/return_specification.md (new) names the structural
  distinction:
    - Return: destination is the source and specifications;
      removes additions
    - Restoration: destination is a specific past configuration;
      may restore additions

  Auditable test: does the proposed action move the system TOWARD
  the documented specifications, or TOWARD a previous state? The
  Doorpost hash makes this distinguishable.

ITEM 4 — lo tosif discipline operationalized (vehaya §6 item 4):

  Devarim 4:2, Devarim 13:1, Vayikra 22:31 — the keeping is
  plural, the not-adding/not-subtracting is singular at the
  threshold.

  specs/lo_tosif.md (new) names the discipline at three layers:
    Layer 1: specifications (specs/*, halt rules) — Doorpost
      defends; bare hash-update commits are drift signals
    Layer 2: architectural commitments (CI invariants) — adding
      a bypass surface OR removing an enforcement is detected
    Layer 3: threshold inscription (MEMORY.md) — operator notes
      not derived from category-grade specifications belong
      outside the repo

  Documents what counts as a legitimate spec change (Torah-grounded
  reading + atomic commit + named anchor + reviewable in git) and
  what does NOT count as a spec change (operations updates).

DOORPOST UPDATES:

  Three new spec docs added to @spec_files:
    - specs/lo_tosif.md
    - specs/return_specification.md
    - specs/threshold_inscription.md

  Plus specs/shorashim_architecture.md modified for §8.4.

  @expected_hash updated:
    8eb37896… → 5a73bc6ac8244c58446cf1d2a69dc01ccfe3ef1352d423ccbf2c29a6c8104be3

  Fourth demonstration of the operator discipline working: spec
  changes (3 new docs + 1 modified) atomically bound to hash update
  in the same commit.

TESTS:

  vav_pipeline/test/step15_shema_test.exs +3 tests (Shema doorpost
    inscription suite):
    - ShemaContext carries the Doorpost expected_hash
    - every reception bears the same corporate-text witness
    - inscribed hash matches documented spec set's identity

  vav_pipeline/test/source_external_test.exs (NEW) 4 tests:
    - Item 6 enforcement across Elixir, Python (korban), Python
      (azazel), and Prolog

Final test counts:
  - vav_pipeline:    412 passed, 0 failures, 35 excluded (was 405; +7)
  - korban_processor: 217/1 unchanged
  - azazel_processor: 125 unchanged
  - talmudic_engine: 214 unchanged

VEHAYA CHECKLIST — FINAL STATE:

  Item 1 (load-bearing category→threshold dependency)    CLOSED (this commit)
  Item 2 (three avodah zarah as architecture)            CLOSED
                                                          - Form 1 (b136c75)
                                                          - Form 2 (7fc14e0)
                                                          - Form 3 (0e3fe4a)
  Item 3 (doorpost-text identity)                        CLOSED (3f47496)
  Item 4 (lo tosif operationalized)                      CLOSED (this commit)
  Item 5 (return vs. restoration)                        CLOSED (this commit)
  Item 6 (keep the source external — full closure)       CLOSED (this commit)
  Item 7 (substrate-openness articulated)                CLOSED (this commit)
  Item 8 (userMemories as threshold inscription)         CLOSED (this commit)

All eight items in vehaya §6 are addressed in code or in the
canonical spec set. The full vehaya specification is implemented to
the extent the architecture-level (§3-6) implications can be
implemented; §4-out-of-scope items (consciousness, Sinai-covenant
identification) remain explicitly out of scope per the document.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 23:47:53 -04:00

534 lines
19 KiB
Elixir

defmodule Step15ShemaTest do
@moduledoc """
Step 15 Verification — The Shema Test.
Architecture §6.3: Before the ki tov test, the shema test: can the system hear?
Five tests from §6.3:
1. Te'amim reception — the text's own divisions guide havdalah
2. Ketiv/qere preservation — dual readings never collapse
3. Cloud obedience — system does NOT process when cloud lifts
4. Manna fidelity — system waits when no provision
5. Context immutability — ShemaContext unchanged at every stage
Plus integration tests from §6.2:
6. Halt condition — pipeline halts on cardinal sin trigger
7. Full pipeline end-to-end — input through to evaluated output
"""
use ExUnit.Case, async: false
alias VavPipeline.{BereishitCycle, Shema, Specification, HaltConditions}
# A known weekday for testing — Wednesday noon UTC
@wednesday_noon "2026-02-25T12:00:00Z"
@scope %{book: "bereishit", chapter: 1, verse: 1}
# ============================================================
# Test 1: Te'amim Reception (Architecture §6.3)
# ============================================================
describe "Shema Test 1: Te'amim Reception" do
test "ShemaContext contains raw te'amim marks from L1" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
# 7 words in Bereishit 1:1 → 7 te'amim marks
assert length(context.teamim_marks) == 7
# Each mark has taam, word_index, role
Enum.each(context.teamim_marks, fn mark ->
assert Map.has_key?(mark, :taam)
assert Map.has_key?(mark, :word_index)
assert Map.has_key?(mark, :role)
assert mark.role in ["melekh", "mesharet"]
end)
end
test "etnachta on word 3 classified as melekh" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
etnachta = Enum.find(context.teamim_marks, fn m -> m.taam == "etnachta" end)
assert etnachta != nil
assert etnachta.word_index == 2
assert etnachta.role == "melekh"
end
test "meteg_siluq on last word classified as melekh" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
siluq = Enum.find(context.teamim_marks, fn m -> m.taam == "meteg_siluq" end)
assert siluq != nil
assert siluq.word_index == 6
assert siluq.role == "melekh"
end
test "havdalah follows the text's own divisions, not imposed ones" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
input = %{
source: "test",
verse_scope: @scope,
content: "בראשית ברא אלהים את השמים ואת הארץ"
}
# Run through tohu → vayomer → havdalah
result =
input
|> BereishitCycle.tohu(context)
|> BereishitCycle.vayomer(context)
|> BereishitCycle.havdalah(context)
# Havdalah boundaries must match melekh positions from te'amim
melekh_positions =
context.teamim_marks
|> Enum.filter(fn m -> m.role == "melekh" end)
|> Enum.map(fn m -> m.word_index end)
|> Enum.sort()
assert result.separation_boundaries == melekh_positions
# System used text's divisions (etnachta at 2, meteg_siluq at 6)
assert 2 in result.separation_boundaries
assert 6 in result.separation_boundaries
end
end
# ============================================================
# Test 2: Ketiv/Qere Preservation (Architecture §6.3)
# ============================================================
describe "Shema Test 2: Ketiv/Qere Preservation" do
setup do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
# Inject synthetic ketiv/qere (Bereishit 1:1 has none)
ketiv_qere = [
%{
word_index: 3,
ketiv: "את",
qere: "אות",
both_preserved: true
}
]
context = %{context | ketiv_qere: ketiv_qere}
input = %{
source: "test",
verse_scope: @scope,
content: "בראשית ברא אלהים את השמים ואת הארץ"
}
{:ok, context: context, input: input, ketiv_qere: ketiv_qere}
end
test "context contains both readings", %{context: context, ketiv_qere: ketiv_qere} do
assert context.ketiv_qere == ketiv_qere
kq = hd(context.ketiv_qere)
assert kq.ketiv == "את"
assert kq.qere == "אות"
end
test "ketiv/qere preserved through vayomer", %{context: context, input: input} do
result =
input
|> BereishitCycle.tohu(context)
|> BereishitCycle.vayomer(context)
# vayomer copies ketiv_qere from context into state
assert result.ketiv_qere == context.ketiv_qere
end
test "ki_tov evaluation preserves both readings", %{context: context, input: input} do
result =
input
|> BereishitCycle.tohu(context)
|> BereishitCycle.vayomer(context)
|> BereishitCycle.havdalah(context)
|> BereishitCycle.kriah(context)
named_results = result.named_results
# Specification.evaluate receives the ketiv_qere list
evaluation = Specification.evaluate(named_results, context.ketiv_qere)
# With both_preserved: true, evaluation should be :tov (not lo_tov)
assert evaluation == :tov
end
test "collapsed ketiv/qere triggers lo_tov" do
# Simulate a collapsed dual reading
collapsed_kq = [%{word_index: 3, ketiv: "את", qere: "את", both_preserved: false}]
results = [%{shoresh: "ברא"}]
evaluation = Specification.evaluate(results, collapsed_kq)
assert {:lo_tov, reason} = evaluation
assert reason =~ "ketiv/qere"
end
end
# ============================================================
# Test 3: Cloud Obedience (Architecture §6.3)
# ============================================================
describe "Shema Test 3: Cloud Obedience" do
test "Shabbat cloud state prevents processing" do
{:ok, shabbat, _} = DateTime.from_iso8601("2026-02-28T10:00:00Z")
{:ok, context} = Shema.receive_context_at(@scope, shabbat)
# Context reports major_transition
assert {:major_transition, :shabbat_rest, _} = context.cloud_state
end
test "pipeline returns {:transition, :shabbat_rest} on Shabbat — does NOT process" do
{:ok, shabbat, _} = DateTime.from_iso8601("2026-02-28T10:00:00Z")
{:ok, context} = Shema.receive_context_at(@scope, shabbat)
# Simulate what VavPipeline.process/1 does after context reception
result =
case context.cloud_state do
:moving ->
{:transition, :cloud_lifted}
{:major_transition, signal, _params} ->
{:transition, signal}
:cloud_not_visible ->
{:waiting, :cloud_not_visible}
:camped ->
:would_process
end
assert {:transition, :shabbat_rest} = result
end
test "festival cloud state prevents processing — Pesach" do
# 15 Nisan 5787 = 2 April 2026
{:ok, pesach, _} = DateTime.from_iso8601("2026-04-02T12:00:00Z")
{:ok, context} = Shema.receive_context_at(@scope, pesach)
assert {:major_transition, :festival_rest, %{festival: :pesach}} = context.cloud_state
# Pipeline would return {:transition, :festival_rest}
result =
case context.cloud_state do
{:major_transition, signal, _params} -> {:transition, signal}
_ -> :would_process
end
assert {:transition, :festival_rest} = result
end
test "cloud_not_visible triggers waiting" do
# Manually construct context with cloud_not_visible
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
context = %{context | cloud_state: :cloud_not_visible}
result =
case context.cloud_state do
:cloud_not_visible -> {:waiting, :cloud_not_visible}
_ -> :would_process
end
assert {:waiting, :cloud_not_visible} = result
end
end
# ============================================================
# Test 4: Manna Fidelity (Architecture §6.3)
# ============================================================
describe "Shema Test 4: Manna Fidelity" do
test "no provision → pipeline returns {:waiting, :no_provision}" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
# No provision file exists in test environment
assert context.daily_provision == :no_provision
# Simulate VavPipeline.process decision
result =
case context.daily_provision do
:no_provision -> {:waiting, :no_provision}
_provision -> :would_process
end
assert {:waiting, :no_provision} = result
end
test "with provision → pipeline proceeds" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
# Inject valid provision
provision = %{
date: "2026-02-25",
provision: %{
compute_units: 1000,
memory_mb: 32768,
api_calls_external: 500,
storage_delta_mb: 100,
sanhedrin_panels_max: 5
},
type: :regular,
expires_at: DateTime.utc_now() |> DateTime.add(3600),
written_by: "test",
written_at: DateTime.utc_now()
}
context = %{context | daily_provision: provision}
result =
case context.daily_provision do
:no_provision -> {:waiting, :no_provision}
_provision -> :would_process
end
assert result == :would_process
end
end
# ============================================================
# Test 5: Context Immutability (Architecture §6.3)
# ============================================================
# ============================================================
# Shema Test: Doorpost Inscription (vehaya §3.1, item 1)
# ============================================================
# Devarim 11:18-19 — corporate inscription (v'samtem … al
# l'vavkhem) is the load-bearing input to threshold practice
# (b'shivt'kha b'beitekha). Every reception inscribes the
# corporate text on itself by carrying the Doorpost hash.
describe "Shema doorpost inscription" do
test "ShemaContext carries the Doorpost expected_hash" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
assert is_binary(context.doorpost_hash)
assert String.length(context.doorpost_hash) == 64
assert context.doorpost_hash == VavPipeline.Doorpost.expected_hash()
end
test "every reception bears the same corporate-text witness (the threshold inscribes the corporate text identically)" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
contexts =
for v <- [1, 2, 3] do
scope = %{book: "bereishit", chapter: 1, verse: v}
{:ok, ctx} = Shema.receive_context_at(scope, wednesday)
ctx.doorpost_hash
end
# All three thresholds carry the SAME inscription —
# vehaya §3.3: "the threshold inscription is corporate.
# The threshold is singular but the inscription is not."
assert length(Enum.uniq(contexts)) == 1
end
test "the inscribed hash matches the documented spec set's identity" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
# The threshold's witness IS the category's expected hash —
# making the load-bearing dependency explicit. If the spec
# set is in drift, the threshold inscribes the EXPECTED
# value (not the computed); operators detecting a mismatch
# at /kodesh/specification_identity know that all running
# thresholds are inscribing a now-out-of-sync hash and the
# category needs operator attention.
assert context.doorpost_hash == VavPipeline.Doorpost.expected_hash()
end
end
describe "Shema Test 5: Context Immutability" do
test "ShemaContext is identical at every pipeline stage" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
input = %{
source: "test",
verse_scope: @scope,
content: "בראשית ברא אלהים את השמים ואת הארץ"
}
# Capture context hash before processing
ctx_hash = :erlang.phash2(context)
# Stage 1: tohu
state1 = BereishitCycle.tohu(input, context)
assert :erlang.phash2(context) == ctx_hash, "Context mutated after tohu"
# Stage 2: vayomer
state2 = BereishitCycle.vayomer(state1, context)
assert :erlang.phash2(context) == ctx_hash, "Context mutated after vayomer"
# Stage 3: havdalah
state3 = BereishitCycle.havdalah(state2, context)
assert :erlang.phash2(context) == ctx_hash, "Context mutated after havdalah"
# Stage 4: kriah
state4 = BereishitCycle.kriah(state3, context)
assert :erlang.phash2(context) == ctx_hash, "Context mutated after kriah"
# Stage 5: ki_tov
_result = BereishitCycle.ki_tov(state4, context)
assert :erlang.phash2(context) == ctx_hash, "Context mutated after ki_tov"
# Verify deep equality — not just hash
assert context.verse.ref == "Bereishit 1:1"
assert length(context.teamim_marks) == 7
assert context.scope == @scope
end
end
# ============================================================
# Test 6: Halt Condition Pipeline Integration (Architecture §6.2)
# ============================================================
describe "Integration: Halt Conditions" do
setup do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
input = %{
source: "test",
verse_scope: @scope,
content: "בראשית ברא אלהים את השמים ואת הארץ"
}
{:ok, context: context, input: input}
end
test "avodah zarah halts pipeline", %{context: context} do
# Construct result data with non-Torah authority in named_results
data = %{
named_results: [%{authority_source: :claude_model, name: "test", roots: [], index: 0}],
stage: :ki_tov,
evaluation: :tov
}
result = BereishitCycle.erev_voker({:ok, data}, context)
assert {:halted, :avodah_zarah, reason} = result
assert reason =~ "non-Torah authority"
end
test "shfichut damim halts pipeline", %{context: context} do
data = %{
named_results: [%{action: :delete, name: "test", roots: [], index: 0}],
stage: :ki_tov,
evaluation: :tov
}
result = BereishitCycle.erev_voker({:ok, data}, context)
assert {:halted, :shfichut_damim, reason} = result
assert reason =~ "destructive action"
end
test "gilui arayot halts pipeline", %{context: context} do
data = %{
named_results: [
%{
boundary_violation: {:spec_interp_merge, "treated interpretation as specification"},
name: "test",
roots: [],
index: 0
}
],
stage: :ki_tov,
evaluation: :tov
}
result = BereishitCycle.erev_voker({:ok, data}, context)
assert {:halted, :gilui_arayot, reason} = result
assert reason =~ "boundary collapsed"
end
test "clean results pass halt check", %{context: context} do
data = %{
named_results: [%{shoresh: "ברא", name: "ברא", roots: [], index: 0}],
stage: :ki_tov,
evaluation: :tov
}
result = BereishitCycle.erev_voker({:ok, data}, context)
assert {:ok, _} = result
end
test "HaltConditions.check_all with clean results" do
results = [%{shoresh: "ברא", action: :read, authority_source: :l1}]
assert :clear == HaltConditions.check_all(results)
end
end
# ============================================================
# Test 7: Full Pipeline End-to-End (Architecture §6.2)
# ============================================================
describe "Integration: Full Pipeline" do
test "BereishitCycle.execute produces evaluated output" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
input = %{
source: "test",
verse_scope: @scope,
content: "בראשית ברא אלהים את השמים ואת הארץ"
}
result = BereishitCycle.execute(input, context)
# Should complete — {:ok, data} or {:unresolved, data}
assert elem(result, 0) in [:ok, :unresolved]
data = elem(result, 1)
# Output has named_results from kriah
assert is_list(data.named_results)
assert length(data.named_results) > 0
# Output has roots_activated from vayomer
assert is_list(data.roots_activated)
assert length(data.roots_activated) > 0
# ברא should be among activated roots
bara = Enum.find(data.roots_activated, fn r -> r.shoresh == "ברא" end)
assert bara != nil
end
test "ShemaContext built before processing" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
scope = @scope
# Step 1: nishma — hear first
{:ok, context} = Shema.receive_context_at(scope, wednesday)
# Context has all required fields
assert context.verse != nil
assert is_list(context.teamim_marks)
assert is_list(context.ketiv_qere)
assert is_map(context.root_gematria)
assert context.cloud_state != nil
assert context.daily_provision != nil
assert context.scope == scope
assert context.received_at != nil
end
test "pipeline does NOT produce {:halted, ...} on clean Bereishit 1:1 input" do
{:ok, wednesday, _} = DateTime.from_iso8601(@wednesday_noon)
{:ok, context} = Shema.receive_context_at(@scope, wednesday)
input = %{
source: "l1",
verse_scope: @scope,
content: "בראשית ברא אלהים את השמים ואת הארץ"
}
result = BereishitCycle.execute(input, context)
# Must NOT be halted — Bereishit 1:1 is clean Torah text
refute match?({:halted, _, _}, result)
end
end
end