mirror of
https://github.com/razzant/ouroboros.git
synced 2026-10-03 04:07:04 +00:00
A direct turn renders as an activity block without a title placeholder and is never offered Turn into project (owner decision 14=A), so the light-model title the direct lane coined for every fresh Main turn — one paid call per message, a daemon thread with its own wall-clock bound and a late cost-refresh path — has no reader left. The lane no longer spawns it; spawn_proactive_namer and _refresh_root_cost_after_naming are deleted with the threading/contextvars /pathlib imports only they used, the two tests that exercised them, the terminal-writer inventory row and five test stubs that silenced the thread. Managed promotes and headless runs keep their admission names (admission_names, _admitted_suggested_name) and the task_named frame, so applySuggestedName still titles managed cards. The post-task checkpoint's same-terminal refresh stays (its own test covers it); its comments no longer attribute it to the retired namer. Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
231 lines
10 KiB
Python
231 lines
10 KiB
Python
"""Monotonic lifecycle guard for write_task_result (v6.7.0-rc.1; cancel redesign
|
|
phase A, 2026-08-11).
|
|
|
|
Pins the "ghost subagent" / status-corruption protections:
|
|
- a stale scheduled/running mirror cannot overwrite a terminal or a legacy latch
|
|
- a terminal status is sticky against a *different* terminal status — including
|
|
cancelled-over-completed: natural completion WINS (owner 4=A), there is no
|
|
explicit-cancellation override any more
|
|
- a LEGACY ``cancel_requested`` latch (pre-intent files) yields to ANY terminal,
|
|
including a racing ``completed``
|
|
- normal forward progress and same-status enrichment are unaffected
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from ouroboros import task_results as tr
|
|
|
|
|
|
@pytest.fixture()
|
|
def drive(tmp_path):
|
|
return tmp_path
|
|
|
|
|
|
def _status(drive, tid):
|
|
return tr.load_task_result(drive, tid)["status"]
|
|
|
|
|
|
def test_terminal_not_regressed_by_running(drive):
|
|
tr.write_task_result(drive, "t", tr.STATUS_CANCELLED, result="cancelled")
|
|
tr.write_task_result(drive, "t", tr.STATUS_RUNNING, result="stale mirror")
|
|
assert _status(drive, "t") == tr.STATUS_CANCELLED
|
|
|
|
|
|
def test_terminal_is_sticky_against_other_terminal(drive):
|
|
tr.write_task_result(drive, "t", tr.STATUS_CANCELLED)
|
|
tr.write_task_result(drive, "t", tr.STATUS_COMPLETED, result="late completion")
|
|
assert _status(drive, "t") == tr.STATUS_CANCELLED
|
|
|
|
tr.write_task_result(drive, "u", tr.STATUS_COMPLETED)
|
|
tr.write_task_result(drive, "u", tr.STATUS_FAILED)
|
|
assert _status(drive, "u") == tr.STATUS_COMPLETED
|
|
|
|
|
|
def test_terminal_sticky_against_unknown_status(drive):
|
|
# A typo / future / unranked status must NOT overwrite a terminal one.
|
|
tr.write_task_result(drive, "t", tr.STATUS_COMPLETED, result="done")
|
|
tr.write_task_result(drive, "t", "weird_unranked_status")
|
|
assert _status(drive, "t") == tr.STATUS_COMPLETED
|
|
|
|
|
|
def test_same_terminal_status_enrichment_allowed(drive):
|
|
tr.write_task_result(drive, "t", tr.STATUS_COMPLETED, result="first")
|
|
tr.write_task_result(drive, "t", tr.STATUS_COMPLETED, result="enriched", trace_summary="trace")
|
|
data = tr.load_task_result(drive, "t")
|
|
assert data["status"] == tr.STATUS_COMPLETED
|
|
assert data["result"] == "enriched"
|
|
assert data["trace_summary"] == "trace"
|
|
|
|
|
|
def test_replica_projector_keeps_terminal_lifecycle_guard(drive):
|
|
from ouroboros.post_task_checkpoint import project_replica_task_result_fields
|
|
|
|
tr.write_task_result(drive, "t", tr.STATUS_CANCELLED, result="cancelled")
|
|
result = tr.write_task_result(
|
|
drive,
|
|
"t",
|
|
tr.STATUS_COMPLETED,
|
|
_field_projector=project_replica_task_result_fields,
|
|
result="late child",
|
|
)
|
|
assert result["status"] == tr.STATUS_CANCELLED
|
|
assert result["result"] == "cancelled"
|
|
|
|
|
|
def test_writer_selects_current_review_before_locked_projector(drive):
|
|
panel = {"surface": "task_acceptance", "panel_id": "p", "panel_index": 0,
|
|
"task_attempt": 1, "publication_revision": 2, "superseded": True,
|
|
"aggregate_signal": "FAIL", "applied_source_ref": {"path": "original"}}
|
|
tr.write_task_result(drive, "review", tr.STATUS_COMPLETED, review_projection={"panels": [panel]})
|
|
stale = {**panel, "superseded": False, "aggregate_signal": "PASS",
|
|
"applied_source_ref": {"path": "stale"}}
|
|
calls = []
|
|
|
|
def project(current, fields):
|
|
assert (drive / "task_results" / "review.json.lock").exists()
|
|
assert fields["review_projection"] == current["review_projection"] == {"panels": [panel]}
|
|
calls.append(True)
|
|
return {**fields, "status": current["status"], "review_projection": {
|
|
"panels": [{**fields["review_projection"]["panels"][0],
|
|
"applied_source_ref": {"path": "promoted"}}]}}
|
|
|
|
saved = tr.write_task_result(drive, "review", tr.STATUS_RUNNING,
|
|
review_projection={"panels": [stale]}, _field_projector=project)
|
|
assert calls == [True]
|
|
assert saved["status"] == tr.STATUS_COMPLETED
|
|
assert saved["review_projection"] == {"panels": [{**panel, "applied_source_ref": {"path": "promoted"}}]}
|
|
|
|
|
|
def test_cancel_requested_blocks_running_but_allows_cancelled(drive):
|
|
tr.write_task_result(drive, "t", tr.STATUS_CANCEL_REQUESTED)
|
|
tr.write_task_result(drive, "t", tr.STATUS_RUNNING)
|
|
assert _status(drive, "t") == tr.STATUS_CANCEL_REQUESTED
|
|
tr.write_task_result(drive, "t", tr.STATUS_CANCELLED, result="done")
|
|
assert _status(drive, "t") == tr.STATUS_CANCELLED
|
|
|
|
|
|
def test_legacy_cancel_latch_yields_to_natural_completion(drive):
|
|
# Phase A (owner 4=A): natural completion WINS. A worker finishing after a
|
|
# LEGACY cancel latch flips the task to "completed" and keeps its result —
|
|
# cancel means "stop spending", never "discard the result".
|
|
tr.write_task_result(drive, "t", tr.STATUS_CANCEL_REQUESTED)
|
|
tr.write_task_result(drive, "t", tr.STATUS_COMPLETED, result="late success")
|
|
assert _status(drive, "t") == tr.STATUS_COMPLETED
|
|
# ...and once completed, a late cancelled write is refused (sticky terminal).
|
|
tr.write_task_result(drive, "t", tr.STATUS_CANCELLED)
|
|
assert _status(drive, "t") == tr.STATUS_COMPLETED
|
|
# A legacy latch still advances to the real teardown outcome when no natural
|
|
# completion raced it.
|
|
tr.write_task_result(drive, "u", tr.STATUS_CANCEL_REQUESTED)
|
|
tr.write_task_result(drive, "u", tr.STATUS_CANCELLED)
|
|
assert _status(drive, "u") == tr.STATUS_CANCELLED
|
|
|
|
|
|
def test_completed_result_survives_a_late_cancellation(drive):
|
|
# Phase A: the explicit-cancellation completed-overwrite is REMOVED. A late
|
|
# cancel must neither flip the status nor strip the completed payload
|
|
# (discarding a kept result is a separate explicit parent action).
|
|
tr.write_task_result(
|
|
drive,
|
|
"won-race",
|
|
tr.STATUS_COMPLETED,
|
|
result="real child result",
|
|
final_answer="real answer",
|
|
trace_summary="real trace",
|
|
artifacts=[{"name": "real.txt"}],
|
|
artifact_bundle={"status": "ready"},
|
|
outcome_axes={"objective": {"status": "solved"}},
|
|
review_evidence={"verdict": "PASS"},
|
|
root_phase_checkpoint={"post_task_synthesis": "completed"},
|
|
cost_usd=1.25,
|
|
parent_task_id="parent",
|
|
)
|
|
tr.write_task_result(
|
|
drive, "won-race", tr.STATUS_CANCELLED, result="owner cancelled",
|
|
)
|
|
kept = tr.load_task_result(drive, "won-race")
|
|
assert kept["status"] == tr.STATUS_COMPLETED
|
|
assert kept["result"] == "real child result"
|
|
assert kept["final_answer"] == "real answer"
|
|
assert kept["artifacts"] == [{"name": "real.txt"}]
|
|
# ABI-3 fix-round-2: stored under the honest name only (the write above
|
|
# used the legacy kwarg — deprecated-wins honored it, then stripped it).
|
|
assert kept["accounted_upper_bound_usd"] == 1.25
|
|
assert "cost_usd" not in kept
|
|
|
|
tr.write_task_result(drive, "failed", tr.STATUS_FAILED, result="real failure")
|
|
tr.write_task_result(drive, "failed", tr.STATUS_CANCELLED)
|
|
assert _status(drive, "failed") == tr.STATUS_FAILED
|
|
|
|
|
|
def test_normal_forward_progress_and_retry(drive):
|
|
tr.write_task_result(drive, "t", tr.STATUS_SCHEDULED)
|
|
tr.write_task_result(drive, "t", tr.STATUS_RUNNING)
|
|
tr.write_task_result(drive, "t", tr.STATUS_INTERRUPTED) # pre-requeue
|
|
tr.write_task_result(drive, "t", tr.STATUS_RUNNING) # retry
|
|
tr.write_task_result(drive, "t", tr.STATUS_COMPLETED)
|
|
assert _status(drive, "t") == tr.STATUS_COMPLETED
|
|
|
|
|
|
def test_updated_at_is_written(drive):
|
|
tr.write_task_result(drive, "t", tr.STATUS_SCHEDULED)
|
|
assert tr.load_task_result(drive, "t").get("updated_at")
|
|
|
|
|
|
def test_lock_timeout_never_falls_back_to_an_unlocked_authoritative_write(
|
|
drive, monkeypatch,
|
|
):
|
|
"""A timeout preserves prior lifecycle truth instead of accepting stale state."""
|
|
tr.write_task_result(drive, "locked", tr.STATUS_RUNNING, result="working")
|
|
|
|
def _timeout(*_args, **_kwargs):
|
|
raise TimeoutError("held by concurrent writer")
|
|
|
|
monkeypatch.setattr(tr, "update_json_locked", _timeout)
|
|
with pytest.raises(TimeoutError, match="concurrent writer"):
|
|
tr.write_task_result(drive, "locked", tr.STATUS_COMPLETED, result="done")
|
|
|
|
stored = tr.load_task_result(drive, "locked")
|
|
assert stored["status"] == tr.STATUS_RUNNING
|
|
assert stored["result"] == "working"
|
|
|
|
|
|
def test_llm_project_name_uses_cleaned_model_title():
|
|
"""v6.40: the real LLM naming path returns the model's title run through clean_model_title
|
|
(lexical clean — strips wrapping quotes, P5), not the raw model string."""
|
|
from ouroboros import project_naming
|
|
|
|
class _FakeClient:
|
|
def chat(self, **kw):
|
|
return ({"content": '"Cyber Racing Arena"'}, {"cost": 0.0})
|
|
|
|
name = project_naming.llm_project_name(
|
|
"build me a top-down neon racing game", llm_client=_FakeClient(),
|
|
)
|
|
assert name == "Cyber Racing Arena", f"expected cleaned title, got {name!r}"
|
|
|
|
|
|
def test_read_paths_do_not_create_task_results_dir(tmp_path):
|
|
"""v6.40.0: a READ/LIST scan of a never-provisioned root must NOT materialise the
|
|
``task_results`` directory (regression: an unguarded scan created stray dirs)."""
|
|
root = tmp_path / "never_provisioned"
|
|
assert tr.list_task_results(root) == []
|
|
assert tr.load_task_result(root, "missing") is None
|
|
assert not (root / "task_results").exists(), "read must not create the dir"
|
|
# WRITE still provisions it.
|
|
tr.write_task_result(root, "t", tr.STATUS_SCHEDULED)
|
|
assert (root / "task_results").is_dir()
|
|
|
|
|
|
def test_read_with_stub_root_leaks_no_cwd_dir(tmp_path, monkeypatch):
|
|
"""The exact pollution repro: a MagicMock-derived root (``MagicMock/mock``) reaching a
|
|
READ scan must not create a ``MagicMock`` tree in the cwd."""
|
|
import pathlib
|
|
from unittest.mock import MagicMock
|
|
|
|
monkeypatch.chdir(tmp_path)
|
|
stub_root = pathlib.Path(MagicMock()).parent # == Path("MagicMock/mock")
|
|
assert tr.list_task_results(stub_root) == []
|
|
assert tr.load_task_result(stub_root, "x") is None
|
|
leaked = [p.name for p in pathlib.Path(".").iterdir() if "MagicMock" in p.name]
|
|
assert leaked == [], f"read scan leaked mock-named paths: {leaked}"
|