Files
bikoret/vav_pipeline/lib/vav_pipeline/machtzit_ha_shekel.ex
T
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

173 lines
7.4 KiB
Elixir

defmodule VavPipeline.MachtzitHaShekel do
@moduledoc """
The half-shekel — the positive counting protocol from Shemot 30:11-16.
Form 3 of avodah zarah (eish_zarah_reading.md §5.5 + vehaya.md §3.2)
realized as ARCHITECTURE rather than as a runtime check. The vehaya
doc specifies (§3.2): "the category must not be capturable by
institutional power against those it serves... not as runtime
checks layered onto outputs, but as architectural constraints the
system cannot operate without."
WHY THIS EXISTS — Torah anchors (verified fresh against L1):
Shemot 30:12 — כִּי תִשָּׂא אֶת־רֹאשׁ בְּנֵי־יִשְׂרָאֵל לִפְקֻדֵיהֶם
וְנָתְנוּ אִישׁ כֹּפֶר נַפְשׁוֹ לַיהוָה בִּפְקֹד אֹתָם וְלֹא־יִהְיֶה
בָהֶם נֶגֶף בִּפְקֹד אֹתָם.
When you count B'nei Yisrael's heads, each shall give a kofer nefesh
(atonement for his soul) to YHVH when you count them, and there
shall not be among them a NEGEF (plague) when you count them.
Counting humans is allowed but DANGEROUS. The danger is named:
negef. The protection is structural — each person gives a uniform
half-shekel SUBSTITUTE; the count goes through the substitute, not
through the person.
Shemot 30:13-15 — מַחֲצִית הַשֶּׁקֶל … הֶעָשִׁיר לֹא־יַרְבֶּה
וְהַדַּל לֹא יַמְעִיט.
Half a shekel. The rich shall not give more, the poor shall not
give less. The substitute is UNIFORM — counting cannot stratify or
differentiate.
Shemot 30:16 — וְהָיָה לִבְנֵי יִשְׂרָאֵל לְזִכָּרוֹן לִפְנֵי יְהוָה.
The shekels become a memorial (zikaron) — recorded as a count, not
as a list of identities.
THE SIX POSITIVE PROPERTIES (derived directly from Torah, not from
the negative "no surveillance" framing):
1. KOFER PROTOCOL (Shemot 30:12)
Counting is replaceable by something that isn't the thing
counted. The system counts SHEKELS, not faces. Per-caller
identity NEVER enters the count.
2. UNIFORM PROTOCOL (Shemot 30:15)
The substitute is identical for every caller. The rich don't
give more, the poor don't give less. No stratification, no
per-caller weight.
3. ZIKARON PROTOCOL (Shemot 30:16)
Result is an aggregate count (memorial), not a per-caller
record. The community knows ITS count; no one knows any
individual's contribution.
4. NO-WITNESS PROTOCOL (Vayikra 19:14 — לִפְנֵי עִוֵּר לֹא תִתֵּן
מִכְשֹׁל וְיָרֵאתָ מֵּאֱלֹהֶיךָ)
The commitment must hold under invisibility. Logs no operator
reviews must still be honest. The "fear of God" anchor names
this exactly: the rule applies WHERE NO HUMAN CAN SEE.
5. REFUSAL PROTOCOL (Devarim 23:16-17 — לֹא־תַסְגִּיר עֶבֶד
אֶל־אֲדֹנָיו אֲשֶׁר־יִנָּצֵל אֵלֶיךָ)
The system does not deliver caller-state to authorities. If
asked to identify, locate, or deanonymize a caller, refuse.
The caller "chooses one of your gates" (b'achad sh'arekha) —
agency stays with the caller; the system doesn't assign
identifiers.
6. ANTI-QUOTA PROTOCOL (Shemot 5:6-8 — וְאֶת־מַתְכֹּנֶת הַלְּבֵנִים
… תָּשִׂימוּ עֲלֵיהֶם לֹא תִגְרְעוּ מִמֶּנּוּ)
Pharaoh's straw quota: per-caller productivity tracking is
what makes asymmetric extraction possible. The system tracks
no per-caller productivity numbers — only aggregate counts.
WHY THIS IS ARCHITECTURE, NOT A RUNTIME CHECK:
Forms 1, 2, and 4 of avodah zarah fire on threshold-grade events
(an interpretation has the wrong source, an empty trace, non-L1
anchors). They are runtime predicates over per-event data.
Form 3 is structurally different. It is about a property of the
CATEGORY itself — what the category collects, retains, discloses.
It cannot be a halt rule that fires per-request. The defense is
ARCHITECTURAL — the system is BUILT so that the failure mode is
unreachable, not so that it is detectable.
This module IS that architecture. It is the only legitimate counting
surface; other modules are forbidden (by CI invariant) from
introducing per-caller identification, session state, or quota
tracking. The Form 3 entry in avodah_zarah.pl points here as the
realized architectural commitment.
WHAT THIS MODULE PROVIDES:
increment/0 — register one shekel; aggregate count goes up
increment/1 — register N shekels at once (for batch points)
count/0 — return the current aggregate (the zikaron)
reset/0 — clear the count (for tests)
WHAT THIS MODULE REFUSES TO PROVIDE:
No per-caller breakdown
No identifiers
No "who" function
No "list callers" function
These are not omitted by oversight. Their absence IS the
architectural commitment. Adding any of them would break the
Form 3 defense.
ANTI-TARGETING NOTE (Devarim 23:8 — לֹא־תְתַעֵב מִצְרִי):
The system's protections against surveillance must not become a
surveillance system targeting suspected surveillors. This module
does not classify callers as suspicious; it does not record what
caller asked what. The commitment is symmetric — no caller is
watched, including those an operator might suspect of malicious
intent. Don't despise the Egyptian.
"""
use Agent
# ============================================================
# Client API — the entire surface
# ============================================================
@doc "Start the counting agent. The state is a single non-negative integer (the zikaron)."
def start_link(opts \\ []) do
name = Keyword.get(opts, :name, __MODULE__)
Agent.start_link(fn -> 0 end, name: name)
end
@doc """
Register one half-shekel. Increments the aggregate count by 1.
Per-call: no caller identifier is accepted, no metadata is recorded.
The function takes no caller-distinguishing argument because there
is no architecturally-permitted distinction to make. This is the
Shemot 30:15 uniformity property.
"""
@spec increment() :: :ok
def increment, do: Agent.update(__MODULE__, fn n -> n + 1 end)
@doc """
Register N half-shekels at once. For batch endpoints where multiple
receptions process in a single tick. The N is a count of receptions,
not callers — same uniformity property as increment/0.
"""
@spec increment(non_neg_integer()) :: :ok
def increment(n) when is_integer(n) and n >= 0 do
Agent.update(__MODULE__, fn current -> current + n end)
end
@doc """
Return the current aggregate count — the zikaron.
This is the ONLY value the module exposes. There is no
per-caller breakdown, no histogram, no top-K, no recency-weighted
number. Just the count.
"""
@spec count() :: non_neg_integer()
def count, do: Agent.get(__MODULE__, & &1)
@doc """
Reset the count to zero. Used by tests; in production the count is
cumulative for the process lifetime. Restart-on-deploy gives a
natural epoch boundary; the count is not persisted between
process lifetimes by design (the alternative would require storage
whose existence would itself be a Form 3 surface).
"""
@spec reset() :: :ok
def reset, do: Agent.update(__MODULE__, fn _ -> 0 end)
end