Skip to content

python-math #15: feat(delphi): Clojure timing probe (Spec C) - #2643

Draft
jucor wants to merge 1 commit into
spr/edge/bbb74f71from
spr/edge/96c1f19e
Draft

python-math #15: feat(delphi): Clojure timing probe (Spec C)#2643
jucor wants to merge 1 commit into
spr/edge/bbb74f71from
spr/edge/96c1f19e

Conversation

@jucor

@jucor jucor commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds scripts/clj_timing_probe.py (Spec C) — a click CLI that measures how long the Clojure engine takes at increasing conversation sizes, so replay runs can be sized to a wall-clock budget. It runs the Clojure Mode A replay driver (math/dev/replay.clj, which replays a recorded vote schedule through the Clojure engine) at increasing vote-count sizes, records wall-clock seconds and final-blob success per size, fits runtime ~ a + b*N^k by log-log least squares (with a, the fixed JVM-startup cost, estimated from the smallest run), and recommends the largest N that stays within the wall-clock budget.

Testing

TDD: tests/replay_harness/test_timing_probe.py mocks the clojure subprocess for all unit tests (CSV truncation, schedule shape, fit recovery on synthetic power-law data, recommendation math, stdout line budget, CLI end-to-end), plus one real-subprocess integration test gated on clojure being on PATH and RUN_CLJ_INTEGRATION=1.

commit-id:96c1f19e


Stack:


⚠️ Part of a stack created by spr. Do not merge manually using the UI - doing so may have unexpected results.

This was referenced Jul 22, 2026
@jucor
jucor marked this pull request as draft July 22, 2026 00:51
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 02:01
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 02:02
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 02:10
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 02:10
@jucor
jucor changed the base branch from spr/edge/bbb74f71 to edge July 22, 2026 03:54
@jucor
jucor changed the base branch from edge to spr/edge/bbb74f71 July 22, 2026 03:54
This was referenced Jul 27, 2026
@jucor
jucor force-pushed the spr/edge/96c1f19e branch from 427982d to b58f018 Compare July 28, 2026 00:11
@jucor jucor changed the title feat(delphi): Clojure timing probe (Spec C) python-math #15: feat(delphi): Clojure timing probe (Spec C) Jul 28, 2026
jucor added a commit that referenced this pull request Jul 28, 2026
…Python math engine to math/

The Clojure implementation leaves the working tree, and the Python math
engine takes its place: `delphi/polismath/` -> `math/polismath/`, now its
own installable package. `delphi/` keeps the umap/narrative service and
the ENTIRE math test estate (tests, real_data datasets + goldens, replay
stores) and depends on the engine as a package.

What moved / changed:
- DELETED: the Clojure tree (math/src, math/test, math/dev, deps.edn,
  Dockerfile, ...) — 60 tracked files. It remains in git history as the
  certification oracle (`git log -- math/`); math/README.md documents the
  `git archive` restore recipe (NOT `git checkout -- math/`, which
  clobbers jj-colocated working copies). test-clojure.yml deleted with it.
- MOVED: delphi/polismath -> math/polismath (import name unchanged:
  `import polismath`). New math/pyproject.toml (hatchling; deps = the
  math-relevant subset of delphi's pins; `run-math-pipeline` console
  script moved here; py.typed added). The poller entry
  delphi/scripts/math_poller.py became polismath/poller/__main__.py —
  service command is now `python -m polismath.poller`.
- PACKAGING: delphi depends on `polismath` via
  `[tool.uv.sources] polismath = { path = "../math", editable = true }` —
  ONE shared environment (delphi/.venv), `cd delphi && uv sync` as
  before. delphi's wheel/sdist no longer bundle polismath; delphi pyright
  include drops it (math/pyproject.toml carries its own [tool.pyright]).
- PATH ANCHORS: new polismath/paths.py (REPO_ROOT / DELPHI_ROOT /
  REAL_DATA_ROOT / CLJ_TREE_ROOT / PACKAGE_ROOT). Eight modules derived
  the delphi root from their own __file__ (`parents[2]`) — after the move
  that arithmetic lands on math/ silently. All eight now assign their
  historical module-level names (_DELPHI_ROOT, REAL_DATA_ROOT,
  _MATH_ROOT, ...) from paths.py, so test monkeypatching is unchanged.
  certify's engine-tree cache-key root became an explicit seam
  (_ENGINE_TREE_ROOT = paths.PACKAGE_ROOT).
- ORACLE UX: certify's clj cache-key hashing now raises CertifyError
  "clj-oracle" with restore instructions when math/dev/replay.clj is
  absent (was: bare FileNotFoundError). New test pins it. The
  requires_math_tree guards (folded into #2643/#2647) now skip
  everywhere the oracle is absent — including local runs on this tree
  (5 tests: 4 certify + 1 timing probe).
- DOCKER: delphi/Dockerfile no longer COPYs polismath from its own
  context; the engine source arrives via a NAMED ADDITIONAL BUILD
  CONTEXT (`COPY --from=mathsrc . /math-src` + `uv pip install --no-deps
  /math-src`). All four compose build blocks (docker-compose.yml +
  docker-compose.test.yml x delphi/math-python) declare
  `additional_contexts: mathsrc: ./math`. requirements.lock unchanged
  (polismath's deps are a subset; it installs --no-deps from source).
- CI: python-ci.yml paths gain math/**; its run_math_pipeline.py cp line
  repointed. Local suite after the move: 1197 passed / 28 skipped /
  44 xfailed / 2 xpassed (baseline 1171/22: +31 shadow-compare tests
  from Step #1, +1 oracle-error test, -5 passes now skipping as oracle
  guards, +1 env-conditional skip).
- run_delphi.py invokes the pipeline as `python -m
  polismath.run_math_pipeline` (was a file path under /app).

SUPPLY-CHAIN NOTE: the name "polismath" is never resolved from a package
index — Docker installs it `--no-deps` from the copied source and uv
resolves it from [tool.uv.sources]; the Dockerfile test stage's
`.[dev]` resolution finds it already installed. If the package is ever
published, register or rename first (the PyPI name is not ours).

MERGE GATE (checklist — after Step #3 has soaked):
- [ ] Verify the PROD math/delphi hosts' compose supports BuildKit named
      additional build contexts (docker compose >= 2.17 with BuildKit;
      after_install.sh calls /usr/local/bin/docker-compose — if that is
      compose v1, upgrade it BEFORE merging this or the on-host image
      build fails on `COPY --from=mathsrc`).
- [ ] python-ci green on this PR's branch (workflow_dispatch).
- [ ] Docker image builds verified once (compose build delphi
      math-python) on a host/runner with BuildKit.
- [ ] Team OK that certify re-replay now requires the documented oracle
      restore (cached pairs unaffected).

KNOWN/ACCEPTED:
- 10 pre-existing pyright reportArgumentType hits in certify.py /
  test_certify.py (verified byte-identical code at the pre-cutover tree
  — latent noise, not introduced here; not fixed to keep this PR pure
  reorg).
- Docs under delphi/docs still say "delphi/polismath" in historical
  narratives; forward-looking docs (README, runbook, quirks header)
  follow in the wind-down docs pass / post-cutover queue.

ROLLBACK: revert this PR — pure source reorganization; no DB or runtime
coupling (the built image contains the same installed packages either
way). Nothing about the flip (Steps #2-#3) depends on this PR.

Part of the cutover PR series (delphi/docs/HANDOFF_CUTOVER_EXECUTION.md
+ CUTOVER_RUNBOOK.md). NOTHING merges without Julien's explicit go.

commit-id:45664936
jucor added a commit that referenced this pull request Jul 28, 2026
…ython math engine to math/

The Clojure implementation leaves the working tree, and the Python math
engine takes its place: `delphi/polismath/` -> `math/polismath/`, now its
own installable package. `delphi/` keeps the umap/narrative service and
the ENTIRE math test estate (tests, real_data datasets + goldens, replay
stores) and depends on the engine as a package.

What moved / changed:
- DELETED: the Clojure tree (math/src, math/test, math/dev, deps.edn,
  Dockerfile, ...) — 60 tracked files. It remains in git history as the
  certification oracle (`git log -- math/`); math/README.md documents the
  `git archive` restore recipe (NOT `git checkout -- math/`, which
  clobbers jj-colocated working copies). test-clojure.yml deleted with it.
- MOVED: delphi/polismath -> math/polismath (import name unchanged:
  `import polismath`). New math/pyproject.toml (hatchling; deps = the
  math-relevant subset of delphi's pins; `run-math-pipeline` console
  script moved here; py.typed added). The poller entry
  delphi/scripts/math_poller.py became polismath/poller/__main__.py —
  service command is now `python -m polismath.poller`.
- PACKAGING: delphi depends on `polismath` via
  `[tool.uv.sources] polismath = { path = "../math", editable = true }` —
  ONE shared environment (delphi/.venv), `cd delphi && uv sync` as
  before. delphi's wheel/sdist no longer bundle polismath; delphi pyright
  include drops it (math/pyproject.toml carries its own [tool.pyright]).
- PATH ANCHORS: new polismath/paths.py (REPO_ROOT / DELPHI_ROOT /
  REAL_DATA_ROOT / CLJ_TREE_ROOT / PACKAGE_ROOT). Eight modules derived
  the delphi root from their own __file__ (`parents[2]`) — after the move
  that arithmetic lands on math/ silently. All eight now assign their
  historical module-level names (_DELPHI_ROOT, REAL_DATA_ROOT,
  _MATH_ROOT, ...) from paths.py, so test monkeypatching is unchanged.
  certify's engine-tree cache-key root became an explicit seam
  (_ENGINE_TREE_ROOT = paths.PACKAGE_ROOT).
- ORACLE UX: certify's clj cache-key hashing now raises CertifyError
  "clj-oracle" with restore instructions when math/dev/replay.clj is
  absent (was: bare FileNotFoundError). New test pins it. The
  requires_math_tree guards (folded into #2643/#2647) now skip
  everywhere the oracle is absent — including local runs on this tree
  (5 tests: 4 certify + 1 timing probe).
- DOCKER: delphi/Dockerfile no longer COPYs polismath from its own
  context; the engine source arrives via a NAMED ADDITIONAL BUILD
  CONTEXT (`COPY --from=mathsrc . /math-src` + `uv pip install --no-deps
  /math-src`). All four compose build blocks (docker-compose.yml +
  docker-compose.test.yml x delphi/math-python) declare
  `additional_contexts: mathsrc: ./math`. requirements.lock unchanged
  (polismath's deps are a subset; it installs --no-deps from source).
- CI: python-ci.yml paths gain math/**; its run_math_pipeline.py cp line
  repointed. Local suite after the move: 1197 passed / 28 skipped /
  44 xfailed / 2 xpassed (baseline 1171/22: +31 shadow-compare tests
  from Step 1, +1 oracle-error test, -5 passes now skipping as oracle
  guards, +1 env-conditional skip).
- run_delphi.py invokes the pipeline as `python -m
  polismath.run_math_pipeline` (was a file path under /app).

SUPPLY-CHAIN NOTE: the name "polismath" is never resolved from a package
index — Docker installs it `--no-deps` from the copied source and uv
resolves it from [tool.uv.sources]; the Dockerfile test stage's
`.[dev]` resolution finds it already installed. If the package is ever
published, register or rename first (the PyPI name is not ours).

MERGE GATE (checklist — after Step 3 has soaked):
- [ ] Verify the PROD math/delphi hosts' compose supports BuildKit named
      additional build contexts (docker compose >= 2.17 with BuildKit;
      after_install.sh calls /usr/local/bin/docker-compose — if that is
      compose v1, upgrade it BEFORE merging this or the on-host image
      build fails on `COPY --from=mathsrc`).
- [ ] python-ci green on this PR's branch (workflow_dispatch).
- [ ] Docker image builds verified once (compose build delphi
      math-python) on a host/runner with BuildKit.
- [ ] Team OK that certify re-replay now requires the documented oracle
      restore (cached pairs unaffected).

KNOWN/ACCEPTED:
- 10 pre-existing pyright reportArgumentType hits in certify.py /
  test_certify.py (verified byte-identical code at the pre-cutover tree
  — latent noise, not introduced here; not fixed to keep this PR pure
  reorg).
- Docs under delphi/docs still say "delphi/polismath" in historical
  narratives; forward-looking docs (README, runbook, quirks header)
  follow in the wind-down docs pass / post-cutover queue.

ROLLBACK: revert this PR — pure source reorganization; no DB or runtime
coupling (the built image contains the same installed packages either
way). Nothing about the flip (Steps #2-#3) depends on this PR.

Part of the cutover PR series (delphi/docs/HANDOFF_CUTOVER_EXECUTION.md
+ CUTOVER_RUNBOOK.md). NOTHING merges without Julien's explicit go.

commit-id:45664936
## What

Adds `scripts/clj_timing_probe.py` (Spec C) — a click CLI that measures how long the Clojure engine takes at increasing conversation sizes, so replay runs can be sized to a wall-clock budget. It runs the Clojure Mode A replay driver (`math/dev/replay.clj`, which replays a recorded vote schedule through the Clojure engine) at increasing vote-count sizes, records wall-clock seconds and final-blob success per size, fits runtime ~ a + b*N^k by log-log least squares (with a, the fixed JVM-startup cost, estimated from the smallest run), and recommends the largest N that stays within the wall-clock budget.

## Testing

TDD: `tests/replay_harness/test_timing_probe.py` mocks the clojure subprocess for all unit tests (CSV truncation, schedule shape, fit recovery on synthetic power-law data, recommendation math, stdout line budget, CLI end-to-end), plus one real-subprocess integration test gated on `clojure` being on PATH and `RUN_CLJ_INTEGRATION=1`.

commit-id:96c1f19e
@jucor
jucor force-pushed the spr/edge/96c1f19e branch from b58f018 to cfcc9e1 Compare July 28, 2026 01:10
@jucor
jucor force-pushed the spr/edge/bbb74f71 branch from 187c549 to 736211a Compare July 28, 2026 01:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants