/teal-sea
teal-sea / zeta-labstate of record · compiled 02 Nov 2026 · revision b09fa4dd · source

Library · hunts/weil_propagation/c4_s2/modal/BRIEF.md

BRIEF: modal/, the compute follow-up (2026-09-24)

1,860 words · 210 lines · source

You are the compute worker. This folder runs the two compute proposals the mission left open (c4_s2/RESULTS.md line 4 (a) and (b)) on Modal. The operator approved it on 2026-09-24 with a hard cap of 25 USD. You run and record; you do not interpret. checker/ and two_adic/ grade the results in their own folders afterwards.

Rules that apply to you

Deliverables

modal/run_modal.py, modal/RUNS.md, modal/out/*.json (one file per unit), modal/test_modal_outputs.py, modal/RESULTS.md.

Step 1. The image and the tree (the guard must pass inside the container)

checker/'s snapshot guard (checker_glue._git, ts_key, _guard) runs git with check=True and refuses on any dirty input. So the container needs a real git checkout of the committed tree, clean.

Step 2. Calibrate and estimate BEFORE the batch (compute discipline rule 3)

Two calibration units, which are also positive controls of the pipeline:

  1. checker family: (nvec, S, N) = (200, 2400, 32), all three cells, built exactly as checker/run_checker_ts.py build_unit(nv, S, N) builds it (call it as a library; the new units are not in its UNITS list, so --units cannot reach them). Laptop time: 246.8 s. Its rows must match the existing entries in checker/checker_ts_snapshot.json (keys unit_key(c, 32, 40, 200, 2400)). State the max abs difference. If it exceeds 1e-10, stop and report.
  2. two_adic family: two_adic/ta_gram_probe.py at (nvec, S) = (80, 4800) (one process per (nvec, S), see its main(argv)). Laptop time about 107 s. Compare with the committed two_adic/ta_gram_probe.json entry for that pair; same threshold.

Then write the estimate to modal/RUNS.md before launching the batch:

If the worst case exceeds 25 USD, lower the timeouts only if the estimate still fits comfortably under them; otherwise orchestration ask and wait. Set memory= high enough (two_adic measured 2 to 5 GB at S = 4800; the N = 32 units at 240 modes and above are unmeasured, so start at 16 GiB and record the peak).

Step 3. The batch: one Modal call per unit, in parallel, checkpointed

checker family (N = 32, all three cells per unit, one build_unit call):

unitwhy
(240, 2400, 32)run_checker_ts.py CI_UNITS: the N = 32 row against more modes
(280, S_rule(2.9), 32)two_adic's default mode rule at c = 2.9 (the "280-mode check")
(319, S_rule(2.5), 32)the same rule at c = 2.5; part of the approved proposal (checker/ s7.6 "the default-rule rows at N = 32")
(364, S_rule(2.2), 32)the same rule at c = 2.2; run only if the worst case still fits under the cap

The mode rule is nvec = max(80, int(8 N / L) + 40), L = log c (checker/test_checker_ts.py::test_default_mode_rule_counts). S_rule is the S of the same default rule (checker/ s7.6 writes S = 24 pi N / L); derive it from two_adic/'s code, do not take it from this brief, and state where you found it.

two_adic family (ta_gram_probe.py, one process per unit): nvec 140, 160, 180, 200 at S = 4800, and 160 at S = 9600 (two_adic/ RESULTS s7b; Kmax is whatever the script chooses; record it).

Checkpointing: each remote function writes its result to a Modal Volume and commits it before returning, and the local entrypoint writes each result to modal/out/<unit>.json as it lands (map(..., order_outputs=False, return_exceptions=True) or spawn plus polling). A dropped session must not lose a finished unit. Output shape: checker units in the snapshot's shape ({unit_key: rows} plus diag, the digest, the tree commit, versions, wall and CPU seconds, peak memory); two_adic units in exactly the shape ta_gram_probe.py writes for one (nvec, S).

Run attached (modal run), watch it, and append to RUNS.md as units finish: wall time, CPU time, peak memory, cost so far. A unit that hits its timeout is recorded as "timed out at X s", not retried blindly; ask before any retry that raises a timeout.

Step 4. Close out

Acceptance

Follow-up 2, 2026-09-24: rebuild every checker/ unit under the fixed rho

Added by the coordinator. MISSION.md follow-up 2. two_adic/ replaced the explicit inverse in ta_mellin.rho by a QR of the Gram factor (c3dca00, eea7eab; its RESULTS s10). T_S's input digest moved from 1dcab230 to b2e7787bce7a, so checker/'s guard now refuses every old snapshot row. Everything above in this brief still applies unless changed here.

What changes.

Units (batch 1): all eleven checker/ units, one Modal call each, all three cells per call, built exactly as run_checker_ts.build_unit builds them (including dps (40, 60) at N = 8, as snapshot() does): the seven of run_checker_ts.UNITS ((80, 1200, 8), (120, 1600, 16), (200, 2400, 32), (80, 1600, 16), (120, 1200, 16), (80, 1200, 16), (160, 1600, 16)) and the four N = 32 units of the first follow-up ((240, 2400), (280, 2266.10), (319, 2633.16), (364, 3060.08), S as passed then). The N = 8 and 16 units are needed because the guard now refuses their old rows; they are cheap.

Calibration, threshold fixed now: build (80, 1200, 8) locally with the new code (seconds to a minute) and on Modal, and compare: max abs difference at most 1e−10. two_adic/'s A3 measured the platform-type drift under the new route at 3e−12; if the calibration misses 1e−10, stop and ask.

Estimate before launch, in RUNS.md: two_adic/ s10.5 estimates the five N = 32 units at about 4980 s wall and 0.45 USD; add the N = 8 and 16 units from their old wall times. Set per-unit timeouts well above the old unit times (the 364-mode unit took 1784 s; give it at least 3x). Worst case at the timeouts must fit the remaining cap: 25 − 0.741 = 24.26 USD for both batches together.

Batch 2 is not yours to decide. If checker/ finds the falsifier fails at 319 or 364 modes by about 1e−2, the coordinator will send the default-rule rows at S/nvec² = 0.04 (two_adic/ s10.5, about 0.59 USD). Do not run them unless asked.

Close-out as before: stop only your own app, record the billed cost from modal billing report --for today -r h --tz local --json, commit with pathspecs, no push. Ownership this time: modal/ only.