mirror of
https://github.com/razzant/ouroboros.git
synced 2026-10-03 04:07:04 +00:00
Merge pull request #695 from razzant/fixfwd/stand-post-task-seed
Some checks are pending
CI / quick-test (push) Waiting to run
CI / benchmark-methodology (push) Waiting to run
CI / full-test (macos-latest) (push) Waiting to run
CI / full-test (ubuntu-latest) (push) Waiting to run
CI / full-test (windows-latest) (push) Waiting to run
CI / betterleaks-platform-smoke (macos-latest) (push) Waiting to run
CI / betterleaks-platform-smoke (ubuntu-latest) (push) Waiting to run
CI / betterleaks-platform-smoke (windows-latest) (push) Waiting to run
CI / ui-smoke (push) Waiting to run
CI / integration-test (push) Waiting to run
CI / skill-smoke (macos-latest) (push) Waiting to run
CI / skill-smoke (ubuntu-latest) (push) Waiting to run
CI / skill-smoke (windows-latest) (push) Waiting to run
CI / marker-guards (push) Waiting to run
CI / docker-ui-smoke (push) Waiting to run
CI / docker-portable-test (push) Waiting to run
CI / system-e2e-mock (push) Waiting to run
CI / e2e-live (SM1 x1 — largest subset feasible under the $30 cap) (push) Waiting to run
CI / release-preflight (push) Blocked by required conditions
CI / build (dmg, macos-latest, macos-arm64, syft_1.50.0_darwin_arm64.tar.gz, syft, e32fdb9d47823fa633748a1efca2528fd77c37469ea93c9e40ab835da44e4cce) (push) Blocked by required conditions
CI / build (tar.gz, ubuntu-latest, linux-x86_64, syft_1.50.0_linux_amd64.tar.gz, syft, bf7b29ff57f06da30918266a0e1c2885a8f99784798d1bdb1628886aa015d788) (push) Blocked by required conditions
CI / build (zip, windows-latest, windows-x64, syft_1.50.0_windows_amd64.zip, syft.exe, 815ee6973ec5dff6a671d7f41b0e78835a8c45b91d5a39f4743ea1cee833d3be) (push) Blocked by required conditions
CI / vendor-package-smoke (push) Blocked by required conditions
CI / release (push) Blocked by required conditions
Claudexor platform gate (API keys — subscription auth NOT covered) / fixture · macos-latest · exact managed runtime, fake harness, no model (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / fixture · ubuntu-latest · exact managed runtime, fake harness, no model (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / fixture · windows-latest · exact managed runtime, fake harness, no model (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / live · macos-latest · claude · API key only, subscription NOT covered (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / live · ubuntu-latest · claude · API key only, subscription NOT covered (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / live · windows-latest · claude · API key only, subscription NOT covered (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / live · macos-latest · codex · API key only, subscription NOT covered (push) Waiting to run
Some checks are pending
CI / quick-test (push) Waiting to run
CI / benchmark-methodology (push) Waiting to run
CI / full-test (macos-latest) (push) Waiting to run
CI / full-test (ubuntu-latest) (push) Waiting to run
CI / full-test (windows-latest) (push) Waiting to run
CI / betterleaks-platform-smoke (macos-latest) (push) Waiting to run
CI / betterleaks-platform-smoke (ubuntu-latest) (push) Waiting to run
CI / betterleaks-platform-smoke (windows-latest) (push) Waiting to run
CI / ui-smoke (push) Waiting to run
CI / integration-test (push) Waiting to run
CI / skill-smoke (macos-latest) (push) Waiting to run
CI / skill-smoke (ubuntu-latest) (push) Waiting to run
CI / skill-smoke (windows-latest) (push) Waiting to run
CI / marker-guards (push) Waiting to run
CI / docker-ui-smoke (push) Waiting to run
CI / docker-portable-test (push) Waiting to run
CI / system-e2e-mock (push) Waiting to run
CI / e2e-live (SM1 x1 — largest subset feasible under the $30 cap) (push) Waiting to run
CI / release-preflight (push) Blocked by required conditions
CI / build (dmg, macos-latest, macos-arm64, syft_1.50.0_darwin_arm64.tar.gz, syft, e32fdb9d47823fa633748a1efca2528fd77c37469ea93c9e40ab835da44e4cce) (push) Blocked by required conditions
CI / build (tar.gz, ubuntu-latest, linux-x86_64, syft_1.50.0_linux_amd64.tar.gz, syft, bf7b29ff57f06da30918266a0e1c2885a8f99784798d1bdb1628886aa015d788) (push) Blocked by required conditions
CI / build (zip, windows-latest, windows-x64, syft_1.50.0_windows_amd64.zip, syft.exe, 815ee6973ec5dff6a671d7f41b0e78835a8c45b91d5a39f4743ea1cee833d3be) (push) Blocked by required conditions
CI / vendor-package-smoke (push) Blocked by required conditions
CI / release (push) Blocked by required conditions
Claudexor platform gate (API keys — subscription auth NOT covered) / fixture · macos-latest · exact managed runtime, fake harness, no model (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / fixture · ubuntu-latest · exact managed runtime, fake harness, no model (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / fixture · windows-latest · exact managed runtime, fake harness, no model (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / live · macos-latest · claude · API key only, subscription NOT covered (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / live · ubuntu-latest · claude · API key only, subscription NOT covered (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / live · windows-latest · claude · API key only, subscription NOT covered (push) Waiting to run
Claudexor platform gate (API keys — subscription auth NOT covered) / live · macos-latest · codex · API key only, subscription NOT covered (push) Waiting to run
e2e_live: --self-mod seeds the owner id only, never a campaign Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
This commit is contained in:
commit
560f7d71d2
3 changed files with 28 additions and 23 deletions
|
|
@ -93,7 +93,7 @@ PROCFS_AVAILABLE = os.path.isdir("/proc") # the orphan scan reads /proc enviro
|
|||
LANE_BUDGET_FLOOR_USD = 0.01
|
||||
RESERVATION_RULE = (f"max({LANE_BUDGET_FLOOR_USD:g}, per_task_usd x (root_tasks + 1 if --self-mod else root_tasks)) — the "
|
||||
"runtime fences each root task tree at OUROBOROS_PER_TASK_COST_USD and --self-mod adds one root for the "
|
||||
"evolution cycle (rc.14: up to two cycles per lane, one at t=0 and one post-task, under the same lane fence). "
|
||||
"one post-task evolution cycle (the lane seeds no campaign: the promotion enables a one-shot one). "
|
||||
"The lane's TOTAL_BUDGET is that reservation — the true fence — so settled spend + in-flight ceilings <= cap")
|
||||
|
||||
|
||||
|
|
@ -257,8 +257,7 @@ class RunBudget:
|
|||
Reservation rule, per attempt: ``per_task_usd x (root_tasks + int(self_mod))`` — the runtime fences each ROOT
|
||||
task tree at ``OUROBOROS_PER_TASK_COST_USD`` and children spend under their root's ceiling, so SW1 (one root,
|
||||
two scouts) reserves for one root, SK1 (author + dispatch) for two, and ``--self-mod`` adds one root for the
|
||||
evolution cycle: rc.14 showed up to TWO cycles per lane, one at t=0 next to the scenario task and one
|
||||
post-task, all under the lane fence — the lane's TOTAL_BUDGET is the true fence. Admission asks, PER attempt:
|
||||
one post-task evolution cycle, all under the lane fence — the true fence. Admission asks, PER attempt:
|
||||
``spent + reservation > cap`` — it can NEVER fit, refused and recorded ``not_run`` (a later, smaller attempt is
|
||||
asked on its own; nothing halts the run); otherwise it reserves only when no earlier-dispatched attempt is
|
||||
still asking (FIFO by ``dispatch_index``, see ``admit``) and ``spent + reserved(in flight) + reservation <=
|
||||
|
|
@ -705,7 +704,8 @@ def run_lane(job: tuple[str, int], args: argparse.Namespace, out: pathlib.Path,
|
|||
row["budget"] = {"reservation_usd": budget.reservation(scenario.root_tasks),
|
||||
"lane_total_budget_usd": cfg["TOTAL_BUDGET"], "per_task_usd": float(args.per_task_usd)}
|
||||
sha = write_settings(settings_path, cfg)
|
||||
seed_owner_state(data_root, evolution_enabled=args.self_mod)
|
||||
# Owner id only, never a campaign: the task's post-task promotion enables the one-shot one (rc.15 run2 pin).
|
||||
seed_owner_state(data_root, evolution_enabled=False)
|
||||
from supervisor import state as sstate
|
||||
(data_root / sstate.ISOLATED_BENCHMARK_SENTINEL).write_text("isolated e2e_live data root\n", encoding="utf-8")
|
||||
oracle = harness.ArtifactOracle(data_root)
|
||||
|
|
|
|||
|
|
@ -1296,8 +1296,8 @@ refuses below `--min-credit-usd`. `--total-budget` (default 100) is the RUN-WIDE
|
|||
cap: a ledger sums the lanes' durable `llm_usage` costs, reserves
|
||||
`max(0.01, --per-task-usd × (root tasks + 1 with --self-mod))` per attempt (SM1 and SW1 one root — scouts spend
|
||||
under their root's `OUROBOROS_PER_TASK_COST_USD` fence — SK1 two; with `--self-mod` the
|
||||
evolution cycle is one more root: the rc.14 paid run showed up to TWO cycles per lane, one
|
||||
starting at t=0 next to the scenario task and one post-task, all under the lane fence — SM1_a1
|
||||
one post-task evolution cycle is one more root (the rc.14 paid run showed a second, generic
|
||||
cycle at t=0 from the benchmark campaign the lane pre-seeded then), all under the lane fence — SM1_a1
|
||||
task $3.84 + cycles $12.40 + $2.84 of $20; the lane's TOTAL_BUDGET is the true fence and the
|
||||
+1 root is its reservation), admits an
|
||||
attempt only while `spent + reserved(in flight) + reservation ≤ cap` — an attempt that
|
||||
|
|
@ -1366,7 +1366,12 @@ server and resolves `-n auto` to the host CPU count, so the stand sets
|
|||
`preflight_runner._preflight_env` still scrubs it from the candidate suite) and
|
||||
records the applied value as `extra.preflight_test_workers` in the manifest and
|
||||
`preflight_test_workers` in every lane row. `--self-mod` enables post-task evolution with the real
|
||||
re-exec restart and REQUIRES a confirmed absorb per lane whose scenario
|
||||
re-exec restart — a settings fact (`OUROBOROS_POST_TASK_EVOLUTION` + cadence `every_n:1`) while the
|
||||
lane seeds `owner_chat_id` ONLY, never a campaign: the scenario task's post-task promotion
|
||||
(`apply_pending_request`) enables the one-shot campaign whose cycle lands, restarts and absorbs.
|
||||
A pre-seeded active campaign (the benchmark helper's form, rc.15 paid run2) runs generic cycles from
|
||||
t=0, gets the promotion refused (evolution already enabled) and its kept request file blocks the
|
||||
`no_promotion` exit of the absorb wait. `--self-mod` REQUIRES a confirmed absorb per lane whose scenario
|
||||
`expects_absorb` (SM1, the one that lands a commit): a pre-task snapshot
|
||||
(clone HEAD, served sha, uptime, absorbed-cycle counter) and, afterwards, the
|
||||
counter advanced, the served sha moved, the uptime reset and the server ready;
|
||||
|
|
|
|||
|
|
@ -388,9 +388,8 @@ def test_admission_is_fifo_by_dispatch_index_and_a_refused_head_frees_the_line(t
|
|||
|
||||
|
||||
def test_reservation_counts_roots_plus_the_evolution_root_and_is_the_lane_total_budget(tmp_path, monkeypatch):
|
||||
"""EQUALITY pins of the rc.14/rc.15 finding: the reservation is per-task x root tasks, +1 with --self-mod (rc.14
|
||||
showed up to TWO evolution cycles per lane, one at t=0 next to the scenario task and one post-task, all under the
|
||||
lane fence: SM1_a1 task $3.84 + cycles $12.40 + $2.84 of $20 — the lane's TOTAL_BUDGET is the true fence); the 2x
|
||||
"""EQUALITY pins of the rc.14/rc.15 finding: the reservation is per-task x root tasks, +1 with --self-mod (the one
|
||||
post-task cycle; rc.14: SM1_a1 task $3.84 + cycles $12.40 + $2.84 of $20 — the lane's TOTAL_BUDGET is the fence); the 2x
|
||||
factor and its product import are gone and no bench budget profile is projected. Per-task $20 and one root reserve
|
||||
$20 ($40 with --self-mod, $60 for SK1 + evolution) and that exact number reaches the lane's settings file as
|
||||
TOTAL_BUDGET through ``run_lane`` (never the run-wide cap)."""
|
||||
|
|
@ -398,7 +397,7 @@ def test_reservation_counts_roots_plus_the_evolution_root_and_is_the_lane_total_
|
|||
rule = run_live_lanes.RESERVATION_RULE
|
||||
assert not hasattr(run_live_lanes, "HARD_STOP_INVERSE") and rule == run_live_lanes.RunBudget(1, 1).snapshot()["reservation_rule"]
|
||||
assert rule.startswith("max(0.01, per_task_usd x (root_tasks + 1 if --self-mod else root_tasks))")
|
||||
assert "up to two cycles per lane" in rule and "the true fence" in rule and "cost_hard_stop" not in rule
|
||||
assert "one post-task evolution cycle" in rule and "the true fence" in rule and "cost_hard_stop" not in rule
|
||||
budget = run_live_lanes.RunBudget(100.0, 20.0, reader=lambda root: (0.0, 0))
|
||||
assert budget.reservation(1) == 20.0 and budget.reservation(2) == 40.0 and not budget.self_mod
|
||||
evolving = run_live_lanes.RunBudget(100.0, 20.0, reader=lambda root: (0.0, 0), self_mod=True)
|
||||
|
|
@ -408,10 +407,7 @@ def test_reservation_counts_roots_plus_the_evolution_root_and_is_the_lane_total_
|
|||
ok, facts = budget.admit(job, 1, out / "lanes" / "SM1_a1" / "data", dispatch_index=0)
|
||||
assert ok and facts["reservation_usd"] == 20.0 and budget.ceiling(job) == 20.0
|
||||
|
||||
class _NoServer: # the real path up to the written settings, then stop
|
||||
def __init__(self, *_a, **_k) -> None:
|
||||
self.base_url = "http://127.0.0.1:0"
|
||||
|
||||
class _NoServer(_NoopServer): # the real path up to the written settings, then stop
|
||||
def start(self, **_k) -> None:
|
||||
raise RuntimeError("no server in this pin: the settings file on disk is the evidence")
|
||||
|
||||
|
|
@ -877,8 +873,8 @@ def test_lane_with_a_dead_browser_target_is_checks_failed_not_infra_error(tmp_pa
|
|||
def test_absorb_wait_and_check_follow_the_scenarios_expects_absorb(tmp_path, monkeypatch):
|
||||
"""The rc.15 paid stand (2026-09-05, SK1_a1): every ``--self-mod`` lane waited ``--task-timeout`` for an absorb
|
||||
only SM1's commit could trigger, then failed ``self_mod_absorb_confirmed`` by construction. Now SM1 waits and
|
||||
carries the check; SW1/SK1 stop right after the scenario with ``{"expected": False}``, no check, and post-task
|
||||
evolution still ON in their settings (the campaign may run during the scenario; the stand does not wait)."""
|
||||
carries the check; SW1/SK1 stop right after the scenario with ``{"expected": False}``, no check, post-task
|
||||
evolution ON in their settings; every lane seeds ``owner_chat_id`` ONLY, never a campaign (run2's t=0 cycles)."""
|
||||
waits: list = []
|
||||
monkeypatch.setattr(run_live_lanes, "resolve_ui_client", lambda base_url: (None, "ui_unavailable:test"))
|
||||
monkeypatch.setattr(run_live_lanes, "self_mod_snapshot", lambda server, clone, data_root: {"pre": True})
|
||||
|
|
@ -887,12 +883,16 @@ def test_absorb_wait_and_check_follow_the_scenarios_expects_absorb(tmp_path, mon
|
|||
sm1 = _attempt_row(tmp_path, monkeypatch, "SM1", flags="--self-mod")
|
||||
assert waits == [{"pre": True}] and sm1["status"] == "fail" and sm1["checks"]["self_mod_absorb_confirmed"] is False
|
||||
assert sm1["self_mod_absorb"] == {"expected": True, "confirmed": False, "reason": "no_promotion", "healthy": True}
|
||||
for sid in ("SW1", "SK1"):
|
||||
row = _attempt_row(tmp_path, monkeypatch, sid, flags="--self-mod")
|
||||
assert row["status"] == "pass" and "self_mod_absorb_confirmed" not in row["checks"], row["checks"]
|
||||
assert row["self_mod_absorb"] == {"expected": False} and row["self_mod"] is True and waits == [{"pre": True}]
|
||||
applied = json.loads((tmp_path / sid / "out" / "lanes" / f"{sid}_a1" / "data" / "settings.json").read_text())
|
||||
assert applied["OUROBOROS_POST_TASK_EVOLUTION"] == "true"
|
||||
for sid in ("SM1", "SW1", "SK1"):
|
||||
if sid != "SM1":
|
||||
row = _attempt_row(tmp_path, monkeypatch, sid, flags="--self-mod")
|
||||
assert row["status"] == "pass" and "self_mod_absorb_confirmed" not in row["checks"], row["checks"]
|
||||
assert row["self_mod_absorb"] == {"expected": False} and row["self_mod"] is True and waits == [{"pre": True}]
|
||||
lane = tmp_path / sid / "out" / "lanes" / f"{sid}_a1" / "data"
|
||||
state = json.loads((lane / "state" / "state.json").read_text(encoding="utf-8"))
|
||||
assert json.loads((lane / "settings.json").read_text())["OUROBOROS_POST_TASK_EVOLUTION"] == "true"
|
||||
assert state["owner_chat_id"] == 1 and "evolution_mode_enabled" not in state, state
|
||||
assert not (lane / "state" / "evolution_campaign.json").exists(), sid
|
||||
|
||||
|
||||
def test_wait_task_namespaces_checks_per_task_and_check_refuses_overwrites():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue