Skip to content

The serving entrypoint arms the spend ceiling itself - #16

Closed
LeavesJ wants to merge 1 commit into
mainfrom
fix/web-entrypoint-ceiling
Closed

LeavesJ wants to merge 1 commit into
mainfrom
fix/web-entrypoint-ceiling

Conversation

@LeavesJ

@LeavesJ LeavesJ commented Sep 3, 2026

Copy link
Copy Markdown
Owner

A peer session's offline checker (scripts/check_spend_ceiling.py, untracked, unmodified) pops ELENCHUS_MAX_CALLS and drives every launch path through _TimedMessages with a fake client until refused. On main as served:

BOUNDED     scripts/serve_invitee.py      refused after 500; second model got 0
EXEMPT      scripts/smoke_server.py
UNBOUNDED   src/elenchus/web/__main__.py  20000 calls, no refusal

Line one independently confirms ebfa3fb's per-process fix. Line three is the hole: python -m elenchus.web — the constitution's own documented launch command — served unbounded when nothing was exported, because from_env returns None when unset and only serve_invitee's setdefault ever armed it. The live beta was bounded only because it happens to be launched the other way.

model_factory_for_this_process() now falls back to Budget(DEFAULT_MAX_CALLS). Offline callers (AnthropicModel(budget=None)) are unchanged. The test that asserted _budget is None on the web factory was asserting the hole.

Re-ran the checker from this tree: BOUNDED / EXEMPT / BOUNDED, exit 0. Suite 1440 / 35 in the worktree, felix gate pass. Recommend the checker itself be tracked and added to the gate — its author's call.

…not be launched unbounded

Found by a peer session's offline checker, scripts/check_spend_ceiling.py (untracked, not mine),
which enumerates every launch path, pops ELENCHUS_MAX_CALLS on the principle that the PATH must arm
the ceiling rather than whoever ran it, and drives a fake client through _TimedMessages until
something refuses. Its verdict on main as served:

    BOUNDED     scripts/serve_invitee.py      refused after 500; a second model got 0
    EXEMPT      scripts/smoke_server.py
    UNBOUNDED   src/elenchus/web/__main__.py  20000 calls with no refusal

The first line is independent confirmation, through an instrument I did not write, that ebfa3fb's
per-process fix holds. The third is a real hole: `python -m elenchus.web` is the constitution's own
documented launch command, and with nothing exported `from_env` returned None -- correct for an
offline caller building a model, wrong for the one entrypoint that serves the public. Only
serve_invitee's setdefault ever armed it, which is why the live beta was bounded and a direct
launch behind a tunnel would not have been.

`model_factory_for_this_process()` now falls back to Budget(DEFAULT_MAX_CALLS). Offline semantics
are unchanged: AnthropicModel(budget=None) is still unbounded for the CLI, the probes and the
suite. The test that asserted `_budget is None` on the web factory was asserting the hole; it now
asserts the default. Re-ran the peer's checker from this tree: three rows, none UNBOUNDED, exit 0.

felix gate pass.
LeavesJ added a commit that referenced this pull request Oct 2, 2026
`python -m elenchus.web` served the unauthenticated surface with no ceiling on
paid model calls. `spend.from_env` returns None, meaning unbounded, when nothing
is exported. That is right for the CLI, the probes and the suite, and only
scripts/serve_invitee.py exported a value, so the documented `python -m` path
was not bounded at all. web/__main__.py now does the same setdefault, after
_load_dotenv and before create_app, so precedence is export, then .env, then
the default floor.

The ordering is the fix. model_factory_for_this_process samples the environment
at create_app time and __main__ builds the app at import, so the same line one
place lower satisfies every grep for the variable and leaves the process
exactly as unbounded. The test is behavioural: it seizes control inside
create_app and reads the factory the entrypoint actually arrived with, and it
enumerates entrypoints off the tree so a third one is covered the day it lands.
It was watched red first and mutation-tested twice (the line moved below
create_app; setdefault swapped for assignment).

This is e625a88 of 2026-09-03 without its CI-pin hunk: main already pins
felix-home at cb3a72ce (#26), and a workflow change is the founder's to merge.
The founder chose this commit over PR #16 on 2026-10-01 ("whichever is the most
recent"). #16 arms the choke point in app.py, touches no file this change
touches, and its own author called it the stronger on the property; it stays
open for the founder to close or land.

Co-authored-by: Jarron Deng <jarrondeng@berkeley.edu>
@LeavesJ

LeavesJ commented Oct 2, 2026

Copy link
Copy Markdown
Owner Author

Closed as not needed after #28 (merged as 69ad94c), per the founder's choice on 2026-10-01 of the more recent fix (e625a88, landed as #28) over this one, and his word that this one could be closed if not needed. #28 arms the ceiling in web/main.py, so the documented 'python -m elenchus.web' path is bounded; scripts/serve_invitee.py already bounded the launcher path. This PR armed the same ceiling at the create_app choke point in app.py, which would also cover a future caller that skips both entrypoints, so the branch (fix/web-entrypoint-ceiling, bd37377) is kept and the PR can be reopened if that defense in depth is wanted. Recorded by the 'Felix dev work landing review' session.

@LeavesJ LeavesJ closed this Oct 2, 2026
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.

1 participant