ouroboros/tests/_extension_loader_shared.py
Ouroboros d32c99798f v7next F1: domain D14 - extension_loader six-leaf and skill_review four-leaf splits from tip bytes; upstream cycles re-home honored
Module side (41 D14 owners at tip): 15 byte-identical across tip/reference/
base (event_bus, extension_isolated_deps, extension_reconcile_queue,
marketplace/{__init__,adapter,clawhub,fetcher,install,install_specs,
isolated_deps}, skill_owner_attestation, skill_readiness,
skill_repair_admission, skill_review_status, skill_token); 16 pure upstream
drift - upstream bytes stand (extension_companion, extension_health,
extension_process_runner, extension_ui_validation,
marketplace/{ouroboroshub,provenance}, skill_dependencies,
skill_lifecycle_queue, skill_loader, skill_publish_eligibility,
skill_review_history, skill_review_passes, skill_review_runner,
tools/skill_{exec,preflight,publish}); 8 NEW post-cutoff upstream modules
with no ledger rows - untouched (betterleaks_runtime, skill_payload_binding,
skill_publish_{github,result,scanner,snapshot} of 8cc2ac69,
skill_review_cycles of 386e9417, skill_review_usage of f18da8c3). The
reference's unrowed failure_kind delta on extension_process_runner is NOT
replayed (typed-dispatch family, F3 territory); the supervised-future leak
in PluginAPIImpl is preserved per plan (F3-acceptance carries the direct
regression test). PluginAPI semantics untouched - mechanical byte-preserving
splits only.

The splits: extension_loader.py 2194 -> 960 into six leaves per ledger rows
2467-2519 (registry_state 87, surface_names 132, child_catalog 109,
import_staging 173, liveness 242, plugin_api 744); 49/53 spans
byte-identical to the oracle leaves, 4 byte-falsified by pure upstream drift
(widget-geometry promotion, durable companion-health overlay) and re-emitted
from tip bytes; two unrowed tip riders travel with their readers
(_widget_geometry_from_render -> surface_names beside its rowed sibling,
_apply_durable_extension_health -> liveness). skill_review.py 1600 -> 841
into four leaves (packs 166, rebuttals 127, prompt 376, output 245); 25/31
ledger rows executed from tip bytes, 6 SUPERSEDED by upstream's own re-home
into skill_review_cycles (386e9417) - upstream ownership stands, the facade
keeps the historical aliases and the identity suite pins them.
_ws_broadcaster deliberately not aliased on the facade (rebindable global
keeps one binding at its owner - the reference contract, pinned). Proof
green: transplant-tool --check per leaf - ast=tokens=bytes=True on all 80
spans, undeclared_top_level=[], leaf_invariants=[], exit 0; facade audit:
17+14 retained top-level statements byte-identical to tip, every tip name
accounted, every moved name re-imported (minus the pinned _ws_broadcaster);
import smoke + shared-registry object-identity checks green.

Test side: identity suites carried - test_extension_loader_extraction.py
(+2 rider rows) and test_skill_review_extraction.py (tool_module_inventory
clauses reverse-mapped out: v7-only mechanism absent at this tip;
cycles-alias identity clause added; facade size bound 800 -> 900 for the
tip-retained lifecycle members, which join the patchable-seams pin).
test_extension_loader.py 1717 -> 359 split into 4 siblings +
_extension_loader_shared.py per 45 ledger rows (zero upstream drift on the
file; 43/45 moved bodies byte-identical, 1 oracle dual-supervisor-patch
adaptation kept, 1 reverse-mapped to the tip spelling supervisor/workers.py
- the reference's worker_process.py is the still-pending D08 split).
test_skill_review.py 1943 -> 579 into 5 siblings + _skill_review_shared.py
per 65 rows (58 byte-identical, 3 re-emitted from tip test drift, 3
patch-retarget adaptations kept; the upstream-deleted advisory test is not
resurrected - its f8d87c69 successors stay in the remainder on tip bytes,
theme re-home deferred to F5). Lossless both families: 52==52 and 74==74
test names, zero duplicate names, no new ast-identical bodies (10
pre-existing review_cycles duplicates at base noted, untouched). Dead-patch
class closed: the remainder's advisory pre-review patch -> prompt owner,
extension_companion supervisor patch doubled onto the plugin_api owner
(single-module patch proven dead by a red run); every other facade patch
site of moved names verified live (production consumers do call-time facade
imports).

size-ratchet manifest regenerated with the official tool (extension_loader,
test_extension_loader, test_skill_review leave GIANT_PATHS; no new band
entries); --check exact; ratchet 5 passed; ruff F clean tree-wide.
Receipts: 12 identity + 126 split-family + 1751 targeted/-n16-loadscope +
full CI-shape battery 11950 parallel + 618 serial, all rc=0; HEAD held and
worktree status unchanged through every pytest run. Ledger corrections:
docs/v7next/LEDGER_CORRECTIONS.md D14 section, entries 1-10.

(cherry picked from commit c7e3d04df95eb9470f5ca3ad824485083a201fe4)
2026-08-30 20:40:34 +00:00

145 lines
4.9 KiB
Python

"""Extension-skill builders and the loader-state fixture shared by the extension_loader suites.
Split out of ``tests/test_extension_loader.py`` when that module was divided by
theme; every definition is verbatim, so each sibling suite (and the pre-existing
importers ``test_extension_surfaces.py``, ``test_extension_isolated_deps.py``,
``test_extension_process_runner.py``, ``test_tool_catalog.py`` and
``test_tool_capabilities_readonly_subagent.py``, which keep reaching these
helpers through the parent module's re-export) keeps the exact skill payloads
and review state it was written against. ``_clear_loader_state`` is autouse, so
importing it into a test module re-applies it there — every sibling suite
imports it.
"""
from __future__ import annotations
import json
import pathlib
import sys
import pytest
from ouroboros.skill_loader import SkillReviewState, save_enabled, save_review_state
from tests._shared import clean_extension_runtime_state
@pytest.fixture(autouse=True)
def _clear_loader_state(monkeypatch):
"""Reset the module-level registries between tests."""
monkeypatch.setenv("OUROBOROS_RUNTIME_MODE", "advanced")
clean_extension_runtime_state()
yield
clean_extension_runtime_state()
def _write_ext_skill(
repo_root: pathlib.Path,
name: str,
*,
plugin_body: str,
permissions: list[str],
env_from_settings: list[str] | None = None,
entry: str = "plugin.py",
extra_frontmatter: str = "",
) -> pathlib.Path:
skill_dir = repo_root / name
skill_dir.mkdir(parents=True, exist_ok=True)
perms_yaml = json.dumps(permissions)
env_yaml = json.dumps(env_from_settings or [])
(skill_dir / "SKILL.md").write_text(
(
"---\n"
f"name: {name}\n"
"description: Phase 4 extension.\n"
"version: 0.1.0\n"
"type: extension\n"
f"entry: {entry}\n"
f"permissions: {perms_yaml}\n"
f"env_from_settings: {env_yaml}\n"
f"{extra_frontmatter}"
"---\n"
"body\n"
),
encoding="utf-8",
)
entry_path = skill_dir / entry
entry_path.parent.mkdir(parents=True, exist_ok=True)
entry_path.write_text(plugin_body, encoding="utf-8")
return skill_dir
def _prepare_extension(
tmp_path: pathlib.Path,
name: str,
plugin_body: str,
permissions: list[str],
env_from_settings: list[str] | None = None,
extra_frontmatter: str = "",
):
"""Write + enable + PASS-review an extension so the loader accepts it."""
from ouroboros.skill_loader import find_skill
repo_root = tmp_path / "skills"
drive_root = tmp_path / "drive"
drive_root.mkdir(exist_ok=True)
_write_ext_skill(
repo_root,
name,
plugin_body=plugin_body,
permissions=permissions,
env_from_settings=env_from_settings,
extra_frontmatter=extra_frontmatter,
)
loaded = find_skill(drive_root, name, repo_path=str(repo_root))
assert loaded is not None
save_enabled(drive_root, name, True)
save_review_state(
drive_root,
name,
SkillReviewState(status="pass", content_hash=loaded.content_hash),
)
# Refetch with fresh state on the loaded struct.
loaded = find_skill(drive_root, name, repo_path=str(repo_root))
assert loaded is not None
return loaded, repo_root, drive_root
def _mark_isolated_deps_installed(drive_root: pathlib.Path, loaded) -> None:
from ouroboros.marketplace.install_specs import install_specs_hash
from ouroboros.marketplace.isolated_deps import FINGERPRINT_FILENAME, isolated_env_dir
from ouroboros.skill_dependencies import auto_install_specs_for_skill
from ouroboros.skill_loader import skill_state_dir
auto_specs = auto_install_specs_for_skill(drive_root, loaded)
assert auto_specs
payload = {
"status": "installed",
"specs_hash": install_specs_hash(auto_specs),
"installed": auto_specs,
}
state_dir = skill_state_dir(drive_root, loaded.name)
state_dir.mkdir(parents=True, exist_ok=True)
(state_dir / "deps.json").write_text(json.dumps(payload), encoding="utf-8")
env_dir = isolated_env_dir(loaded.skill_dir)
env_dir.mkdir(parents=True, exist_ok=True)
(env_dir / FINGERPRINT_FILENAME).write_text(json.dumps(payload), encoding="utf-8")
def _isolated_site_packages_dir(loaded) -> pathlib.Path:
return (
loaded.skill_dir
/ ".ouroboros_env"
/ "python"
/ "lib"
/ f"python{sys.version_info.major}.{sys.version_info.minor}"
/ "site-packages"
)
def _add_fake_native_dep(loaded, package_name: str = "dummy_pkg") -> pathlib.Path:
site_dir = _isolated_site_packages_dir(loaded)
pkg_dir = site_dir / package_name
pkg_dir.mkdir(parents=True, exist_ok=True)
(pkg_dir / "__init__.py").write_text("VALUE = 'isolated-native-risk'\n", encoding="utf-8")
(site_dir / "fake_native.so").write_bytes(b"not a real shared object; scan marker only")
return site_dir