feat: execution-limit admission (#1773-#1786) - #1792
Merged
Merged
Conversation
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
A saved JSON null is corrupt, not an unrestricted allowance to narrow. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EzUPkXKdmnZYeJ1sqjpnp9
Joins the requested-limit refusal, typed account ceiling storage and the launch preflight that resolves a request against the current account ceiling. Resolution keeps the execution_limits_widen error clause and drops a duplicate ExecutionLimits alias, matching the resolution CI already verified on #1788. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EzUPkXKdmnZYeJ1sqjpnp9
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EzUPkXKdmnZYeJ1sqjpnp9
This was referenced Sep 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Combines the reviewed and approved execution-limit admission stack — #1773 through #1786, minus the host-ceiling work — into one PR against
main.What this is
Execution limits (
wall_time_seconds,max_model_turns,max_estimated_cost_usd) get a typed policy resolver, versioned per-conversation storage, owner-scoped write operations, and a refusal at every door that could otherwise promise a bounded execution it cannot deliver.Nothing is enforced yet, and that is the point. Every control is refused end-to-end via
require_controls(limits, []), so a saved allowance is always%{}today. The stack makes it impossible to accept a limit the runtime cannot honour, ahead of the runtime work that will honour them.What it contains
Fountain.Conversations.ExecutionLimits— the pure resolver: validate, inherit ceilings, narrow, refuse wideningexecution_allowances— versioned storage, opaque revision, optimistic lockingRehydrator.spawn_server/1nullis corrupt, not an unrestricted allowance to narrowConversations.narrow_execution_allowance/4— owner-scoped, auditedusersConversations.create_execution_allowance/4— owner-scoped, auditedTwo new migrations:
20260909090000_create_execution_allowances,20260910020000_add_account_execution_limits.What it deliberately excludes
#1787 (host ceilings /
FOUNTAIN_EXECUTION_LIMITS) is left out — it has changes requested for a missing.env.exampleentry. #1788 (the two-stack join) is made moot by this PR. #1789 through #1791 (allowance persistence at launch, rotation) also have changes requested, mostly about row locks taken inside the global fleet advisory lock.How the merge was built
Three merges on top of the #1786 chain: #1782, then the #1784 -> #1774 -> #1785 chain, then current
main.Only one textual conflict, in
fallback_controller.ex— resolved by keeping theexecution_limits_widenclause, plus dropping a duplicateExecutionLimitsalias inconversations.ex. Both match the resolution CI already verified on #1788.The result was checked structurally rather than by eye: the merged tree equals #1788's CI-verified tree minus #1787's commit plus #1782's commit, with both deltas fully accounted for and nothing else. All eight guard call sites survive the
mainmerge intact.#1774's commit appears once, not twice —71ce96c8andd4ea7e76have identical patch-ids, and the copy on the #1785 chain is the one included.Validation
Run locally on the merged tree, on a dedicated database:
mix compile --warnings-as-errors— cleanmix format --check-formattedat the root and inapps/fountain— clean, exit 0mix credo --strict— 769 files, 6963 mods/funs, no issuesmix deps.unlock --unused— cleanmain's two new commits touched (conversations_start,conversations_context,changeset,conversation_controller,conversations_wake,conversation_server_acp) — 0 failuresunboxed_runrace fixtures clean up their committed rowsCloses #1773
Closes #1774
Closes #1775
Closes #1776
Closes #1777
Closes #1778
Closes #1779
Closes #1780
Closes #1781
Closes #1782
Closes #1783
Closes #1784
Closes #1785
Closes #1786
🤖 Generated with Claude Code
https://claude.ai/code/session_01EzUPkXKdmnZYeJ1sqjpnp9