15J (native route through the REAL send_task path — TUI input →
RuneOperator.send_task → construction hook → classifier → activation →
durable state):
- 6 held-outs (tests/test_native_default.py): PROJECT_BUILD without any
command; EXISTING attaches Rune authority; LOCAL_CHANGE light; NOT_
CONSTRUCTION touches nothing; UNKNOWN probes without invention; manual
override (/scaffold-mode <MODE>) through the SAME classify_mode with
user provenance
- classifier: explicit FILE mentions ('the README', 'scheduler.js') now
bind scoped targets — deterministic lexical evidence + the ONE surface
authority (classify_surface), lazily imported (cycle-safe)
15K (bypass prevention):
- /build start hardened: classifies through the canonical machinery
BEFORE BuildManager mints any state; NOT_CONSTRUCTION refused;Build-
Manager remains execution vehicle, no longer a construction authority
- inventory: BuildManager provably creates NO canonical scaffolds
Process repairs caught during the stage (15X evidence):
- os.chdir pollution from a test leaked cwd into later tests (bare
os.chdir → monkeypatch.chdir)
- construction-hook tests were making REAL model calls (42s, provider
quota burned, starved stage-telemetry's model call → GATE_FAILED):
send_task's _execute_on_model now stubbed in hook tests — suite 144s
→ 54s and deterministic
- S110 noqa for the deliberate classifier degrade; new modules mapped
into config/umbrellas.json (perception: event_wait, stage_guards)
- suite: 1835 passed, 0 failed
110 lines
4.8 KiB
Python
110 lines
4.8 KiB
Python
"""12D tests: Rune-native activation through send_task."""
|
|
import json
|
|
import os
|
|
import sys
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "scripts"))
|
|
|
|
from rune import construction_mode as cm # noqa: E402
|
|
|
|
|
|
@pytest.fixture
|
|
def native_operator(tmp_path, monkeypatch):
|
|
"""A RuneOperator whose construction store points at a tmp scaffold via
|
|
the documented env override; send_task's downstream model call is
|
|
stubbed so the test exercises only the construction hook."""
|
|
store = tmp_path / ".rune" / "scaffold"
|
|
monkeypatch.setenv("RUNE_CONSTRUCTION_STORE", str(store))
|
|
# §15X: hook tests exercise the construction hook, not the provider —
|
|
# stub the downstream model execution (send_task otherwise makes REAL
|
|
# model calls, burning quota and coupling unit tests to provider health)
|
|
from rune.tool_protocol import OperatorResponse
|
|
monkeypatch.setattr(
|
|
"rune.rune_operator.RuneOperator._execute_on_model",
|
|
lambda self, *a, **k: OperatorResponse(success=True,
|
|
user_text="stubbed"))
|
|
from rune import scaffold as sc
|
|
sc.Scaffold(store, "rune").init(purpose="rune native test")
|
|
import rune.rune_operator as ro
|
|
op = ro.RuneOperator()
|
|
return op, store
|
|
|
|
|
|
class TestRuneNativeActivation:
|
|
def test_project_build_via_send_task(self, native_operator):
|
|
"""12D.A: normal input → PROJECT_BUILD → durable scaffold."""
|
|
op, store = native_operator
|
|
result = op.send_task(
|
|
"Build me a new standalone practice scheduler")
|
|
assert result is not None # task path completed normally
|
|
doc = json.loads((store / "current.json").read_text())
|
|
activated = [o for o in doc.get("observations", [])
|
|
if o.get("kind") == "construction_activated"]
|
|
assert activated, "no construction_activated observation"
|
|
modes = {o["mode"] for o in activated}
|
|
assert "PROJECT_BUILD" in modes or any(
|
|
o["mode"] == "PROJECT_BUILD" for o in activated)
|
|
|
|
|
|
class TestRuneNativeMatrix:
|
|
"""§12D full matrix through the REAL send_task backend path."""
|
|
|
|
def _last_activated(self, store):
|
|
doc = json.loads((store / "current.json").read_text())
|
|
return [o for o in doc.get("observations", [])
|
|
if o.get("kind") == "construction_activated"]
|
|
|
|
def test_existing_project_change(self, native_operator):
|
|
op, store = native_operator
|
|
op.send_task("Add CSV export to the existing Rune project")
|
|
activated = self._last_activated(store)
|
|
assert activated and activated[-1]["mode"] == "EXISTING_PROJECT_CHANGE"
|
|
|
|
def test_local_change(self, native_operator):
|
|
op, store = native_operator
|
|
op.send_task("Fix this typo in the existing module")
|
|
activated = self._last_activated(store)
|
|
assert activated and activated[-1]["mode"] == "LOCAL_CHANGE"
|
|
|
|
def test_non_construction_no_activation(self, native_operator):
|
|
op, store = native_operator
|
|
before = len(self._last_activated(store))
|
|
op.send_task("Make me a list of chord substitutions")
|
|
activated = self._last_activated(store)
|
|
new = [o for o in activated if o["activated"]]
|
|
assert all(o["mode"] == "NOT_CONSTRUCTION" or not o["activated"]
|
|
for o in activated[before:] or activated)
|
|
|
|
def test_unknown_probes_not_activation(self, native_operator):
|
|
op, store = native_operator
|
|
op.send_task("Build something that helps with this")
|
|
activated = self._last_activated(store)
|
|
last = activated[-1]
|
|
assert last["mode"] == "UNKNOWN"
|
|
assert last["activated"] is False
|
|
|
|
def test_fresh_process_resume(self, tmp_path, native_operator):
|
|
"""§17: after PROJECT_BUILD activation, a fresh process recovers
|
|
the bootstrap from the durable scaffold alone."""
|
|
op, store = native_operator
|
|
op.send_task("Build me a new standalone practice scheduler")
|
|
# fresh: find the bootstrapped project scaffold (slug derived from
|
|
# the objective — locate it, don't hardcode)
|
|
projects = store / "projects"
|
|
candidates = sorted(projects.glob("*/current.json")) \
|
|
if projects.exists() else []
|
|
assert candidates, "no project scaffold bootstrapped"
|
|
from rune import scaffold as sc, structural_store as ss
|
|
pdoc = sc.Scaffold(candidates[0].parent,
|
|
candidates[0].parent.name).load()
|
|
projects_found = [e for e in pdoc["entities"]
|
|
if e["kind"] == "project"]
|
|
assert projects_found
|
|
p = projects_found[0]
|
|
assert p["ext"]["bootstrap"] == "initialized"
|
|
assert p["ext"]["repository"] == "undecided"
|