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>
This commit is contained in:
Scott KarpandClaude Opus 4.7 committed 2026-04-28 20:44:30 -04:00
1 parent 3f4749695d
commit 0e3fe4a782
8 files changed
+760 -5

No files matched your search

@@ -0,0 +1,189 @@
defmodule VavPipeline.MachtzitHaShekelTest do
@moduledoc """
Tests for the half-shekel counting protocol — Form 3 of avodah
zarah realized as architecture (vehaya §3.2). Verifies the six
positive Torah-anchored properties from Shemot 30:11-16,
Devarim 23:16-17, Vayikra 19:14, and Shemot 5:6-8.
"""
use ExUnit.Case, async: false
alias VavPipeline.MachtzitHaShekel
setup do
# MachtzitHaShekel runs in the supervision tree, so it's already
# alive. Reset between tests.
MachtzitHaShekel.reset()
:ok
end
# ============================================================
# Property 1 — KOFER PROTOCOL (Shemot 30:12)
# ============================================================
test "increment/0 takes no argument — no caller distinction is even expressible" do
# Structural test: the function arity is 0. There is no place to
# pass a caller identifier. The Shemot 30:15 uniformity property
# is enforced at the type level: there's no slot for non-uniform
# input.
assert function_exported?(MachtzitHaShekel, :increment, 0)
end
test "increment/0 advances the count by exactly 1" do
MachtzitHaShekel.increment()
assert MachtzitHaShekel.count() == 1
end
test "increment/1 advances the count by N" do
MachtzitHaShekel.increment(5)
assert MachtzitHaShekel.count() == 5
end
# ============================================================
# Property 2 — UNIFORM PROTOCOL (Shemot 30:15)
# ============================================================
test "every increment is the same size — rich don't give more, poor don't give less" do
Enum.each(1..100, fn _ -> MachtzitHaShekel.increment() end)
assert MachtzitHaShekel.count() == 100
end
test "no per-caller weighting function exists" do
# Negative structural assertion: no `increment_with_weight` or
# similar function. The uniform property is enforced by absence.
public = MachtzitHaShekel.__info__(:functions)
weight_shaped = Enum.filter(public, fn {name, _arity} ->
name_str = to_string(name)
String.contains?(name_str, "weight") or
String.contains?(name_str, "tier") or
String.contains?(name_str, "premium")
end)
assert weight_shaped == []
end
# ============================================================
# Property 3 — ZIKARON PROTOCOL (Shemot 30:16)
# ============================================================
test "count/0 returns a single integer, not a list or map of contributions" do
Enum.each(1..3, fn _ -> MachtzitHaShekel.increment() end)
result = MachtzitHaShekel.count()
assert is_integer(result)
refute is_list(result)
refute is_map(result)
end
test "no per-caller breakdown function exists" do
public = MachtzitHaShekel.__info__(:functions)
forbidden = Enum.filter(public, fn {name, _arity} ->
name_str = to_string(name)
Enum.any?(
~w(callers list_who breakdown by_caller per_caller histogram top who),
&String.contains?(name_str, &1)
)
end)
assert forbidden == [], (
"MachtzitHaShekel exposes per-caller breakdown function(s): " <>
"#{inspect(forbidden)}. Their absence IS the architectural " <>
"commitment (Shemot 30:16 — zikaron, not roster)."
)
end
# ============================================================
# Property 5 — REFUSAL PROTOCOL (Devarim 23:16-17)
# ============================================================
test "no identify/locate/deanonymize function exists" do
public = MachtzitHaShekel.__info__(:functions)
forbidden = Enum.filter(public, fn {name, _arity} ->
name_str = to_string(name)
Enum.any?(
~w(identify locate deanonymize lookup find_caller),
&String.contains?(name_str, &1)
)
end)
assert forbidden == [], (
"MachtzitHaShekel exposes caller-identification function(s): " <>
"#{inspect(forbidden)}. The system does not deliver " <>
"caller-state to authorities (Devarim 23:16, lo tasgir)."
)
end
# ============================================================
# Property 6 — ANTI-QUOTA PROTOCOL (Shemot 5:6-8)
# ============================================================
test "no per-caller productivity tracking function exists" do
public = MachtzitHaShekel.__info__(:functions)
forbidden = Enum.filter(public, fn {name, _arity} ->
name_str = to_string(name)
Enum.any?(
~w(quota productivity throughput per_caller_count),
&String.contains?(name_str, &1)
)
end)
assert forbidden == [], (
"MachtzitHaShekel exposes quota/productivity function(s): " <>
"#{inspect(forbidden)}. Per-caller productivity tracking is " <>
"Pharaoh's straw quota (Shemot 5:6-8) — refused by absence."
)
end
# ============================================================
# Reset semantics
# ============================================================
test "reset/0 brings the count to zero" do
MachtzitHaShekel.increment(50)
assert MachtzitHaShekel.count() == 50
MachtzitHaShekel.reset()
assert MachtzitHaShekel.count() == 0
end
test "increment after reset starts from zero" do
MachtzitHaShekel.increment(10)
MachtzitHaShekel.reset()
MachtzitHaShekel.increment(3)
assert MachtzitHaShekel.count() == 3
end
# ============================================================
# The ENTIRE public surface — explicit enumeration
# ============================================================
test "the module's public surface is exactly the documented six functions" do
# An exhaustive list. Any added function must be reviewed for
# whether it weakens the Form 3 architectural commitment.
expected = [
{:start_link, 0},
{:start_link, 1},
{:increment, 0},
{:increment, 1},
{:count, 0},
{:reset, 0},
# Agent-derived defaults — not part of the surveillance surface
{:child_spec, 1}
]
actual =
MachtzitHaShekel.__info__(:functions)
|> Enum.filter(fn {name, _} ->
not String.starts_with?(to_string(name), "__")
end)
|> Enum.sort()
extras = actual -- expected
missing = expected -- actual
assert extras == [], "MachtzitHaShekel exposed unexpected function(s): #{inspect(extras)}"
assert missing == [], "MachtzitHaShekel missing expected function(s): #{inspect(missing)}"
end
end
@@ -0,0 +1,236 @@
defmodule VavPipeline.NoTrackingLoggerTest do
@moduledoc """
Tests for the Plug-layer enforcement of Form 3.
Verifies:
- The router uses NoTrackingLogger, not Plug.Logger
- /peah/* paths get sanitized (query strings dropped) in logs
- Each request increments MachtzitHaShekel
- CI invariants: no Plug.Session, no Plug.Conn.Cookies imports
anywhere in the source tree
"""
use ExUnit.Case, async: false
import Plug.Test
alias VavPipeline.{BigdeiKodesh.Router, MachtzitHaShekel, NoTrackingLogger}
@opts Router.init([])
setup do
if Process.whereis(MachtzitHaShekel), do: MachtzitHaShekel.reset()
:ok
end
# ============================================================
# Each request increments the zikaron
# ============================================================
test "GET /peah/ask increments the half-shekel count" do
before_count = if Process.whereis(MachtzitHaShekel), do: MachtzitHaShekel.count(), else: 0
conn(:get, "/peah/ask") |> Router.call(@opts)
after_count = if Process.whereis(MachtzitHaShekel), do: MachtzitHaShekel.count(), else: 0
assert after_count == before_count + 1
end
test "multiple requests advance the count uniformly" do
if Process.whereis(MachtzitHaShekel) do
MachtzitHaShekel.reset()
for _ <- 1..5 do
conn(:get, "/peah/ask") |> Router.call(@opts)
end
assert MachtzitHaShekel.count() == 5
else
flunk("MachtzitHaShekel not running — supervision tree must be up for this test")
end
end
# ============================================================
# PRIVACY BOUNDARY — sanitized_path/1 and format_line/2 as pure functions
# ============================================================
# The test config sets logger level to :warning, dropping
# NoTrackingLogger's :info output before capture_log can see it.
# The structural defense is the load-bearing thing; we test the
# pure functions directly to verify the path-sanitization shape.
test "sanitized_path drops query string on /peah/*" do
conn = %Plug.Conn{request_path: "/peah/ask", query_string: "question=secret"}
assert NoTrackingLogger.sanitized_path(conn) == "/peah/ask"
end
test "sanitized_path drops the question parameter on /peah/ask" do
secret = "this-question-must-not-leak"
conn = %Plug.Conn{request_path: "/peah/ask", query_string: "question=#{secret}"}
sanitized = NoTrackingLogger.sanitized_path(conn)
refute sanitized =~ secret
refute sanitized =~ "question"
refute sanitized =~ "?"
end
test "sanitized_path preserves path class for /peah/azazel_log" do
conn = %Plug.Conn{request_path: "/peah/azazel_log", query_string: "since=2026-01-01"}
assert NoTrackingLogger.sanitized_path(conn) == "/peah/azazel_log"
end
test "sanitized_path preserves request_path on non-peah tiers" do
# Non-peah tiers also strip query string (the request_path itself
# doesn't carry it; query is in conn.query_string).
conn = %Plug.Conn{request_path: "/kodesh/health", query_string: "detail=full"}
assert NoTrackingLogger.sanitized_path(conn) == "/kodesh/health"
end
test "format_line shape: METHOD PATH STATUS DURATIONus" do
conn = %Plug.Conn{
method: "GET",
request_path: "/peah/ask",
query_string: "question=secret",
status: 200
}
line = NoTrackingLogger.format_line(conn, 1234)
assert line == "GET /peah/ask 200 1234us"
end
test "format_line never contains a query string for /peah/*" do
secret = "secret-question-content"
conn = %Plug.Conn{
method: "GET",
request_path: "/peah/ask",
query_string: "question=#{secret}",
status: 200
}
line = NoTrackingLogger.format_line(conn, 100)
refute line =~ secret
end
test "format_line never contains an Authorization header" do
# The format_line function takes only conn and duration. It does
# NOT extract headers. Verifying by inspection: the function
# signature gives no path for headers to enter the log.
bearer = "secret-bearer-token"
conn = %Plug.Conn{
method: "POST",
request_path: "/courtyard/offering",
query_string: "",
status: 200,
req_headers: [{"authorization", "Bearer #{bearer}"}]
}
line = NoTrackingLogger.format_line(conn, 100)
refute line =~ bearer
refute line =~ "Bearer"
refute line =~ "authorization"
end
test "format_line never contains conn.remote_ip even when set" do
conn = %Plug.Conn{
method: "GET",
request_path: "/peah/ask",
query_string: "",
status: 200,
remote_ip: {192, 0, 2, 1}
}
line = NoTrackingLogger.format_line(conn, 100)
refute line =~ "192.0.2.1"
refute line =~ "192"
end
# ============================================================
# CI INVARIANTS — Form 3 architectural enforcement
# ============================================================
# These tests walk the source tree and verify no module introduces
# a surveillance surface that would defeat the architectural
# commitment.
@vav_pipeline_lib "lib/vav_pipeline"
# NoTrackingLogger's own docstring mentions the forbidden module
# names as the things it defends against. Exclude the defender file
# from the CI scan to avoid self-detection. Tests are also excluded
# — they can legitimately reference the names in assertions.
@ci_invariant_exclusions [
"lib/vav_pipeline/no_tracking_logger.ex"
]
defp source_files do
Path.wildcard("#{@vav_pipeline_lib}/**/*.ex")
|> Enum.reject(fn path -> path in @ci_invariant_exclusions end)
end
test "Plug.Logger is NOT mounted in any router" do
offenders =
Enum.filter(source_files(), fn path ->
text = File.read!(path)
String.contains?(text, "plug Plug.Logger")
end)
assert offenders == [], (
"Plug.Logger is mounted in: #{inspect(offenders)}. The Form 3 " <>
"architectural commitment requires NoTrackingLogger as the " <>
"request-scoped logger; Plug.Logger logs unconfigurable details " <>
"(method+path+status+timing) without the path sanitization that " <>
"honors /peah/*'s no-tracking promise."
)
end
test "no module imports Plug.Session" do
offenders =
Enum.filter(source_files(), fn path ->
text = File.read!(path)
String.contains?(text, "Plug.Session") and
not String.contains?(text, "no module imports Plug.Session")
end)
assert offenders == [], (
"Plug.Session is imported in: #{inspect(offenders)}. Sessions " <>
"are per-caller persistent state — exactly the surveillance " <>
"surface Form 3 forbids. The system is stateless per-request " <>
"by architectural commitment."
)
end
test "no module imports Plug.Conn.Cookies" do
offenders =
Enum.filter(source_files(), fn path ->
text = File.read!(path)
String.contains?(text, "Plug.Conn.Cookies") and
not String.contains?(text, "no module imports Plug.Conn.Cookies")
end)
assert offenders == [], (
"Plug.Conn.Cookies imported in: #{inspect(offenders)}. Cookies " <>
"are per-caller persistent state — Form 3 surveillance " <>
"surface. The system is cookie-free by architectural " <>
"commitment."
)
end
test "no module reads remote IP from conn.remote_ip" do
# remote_ip captures the caller's IP — a per-caller identifier.
offenders =
Enum.filter(source_files(), fn path ->
text = File.read!(path)
String.contains?(text, "conn.remote_ip") and
not String.contains?(text, "no module reads remote IP")
end)
assert offenders == [], (
"Modules reading conn.remote_ip: #{inspect(offenders)}. The IP " <>
"is a caller identifier; persisting it would defeat the " <>
"kofer-nefesh anonymity (Shemot 30:13) and the lo-tasgir " <>
"refusal (Devarim 23:16)."
)
end
end