diff --git a/docs/design/core-engine-compatibility-disposition-v0.8.0.json b/docs/design/core-engine-compatibility-disposition-v0.8.0.json index 318dbf1..24168cf 100644 --- a/docs/design/core-engine-compatibility-disposition-v0.8.0.json +++ b/docs/design/core-engine-compatibility-disposition-v0.8.0.json @@ -6,6 +6,45 @@ "ace.intelligence", "ace.application" ], + "deprecated_callsite_policies": { + "make_ship_arms": { + "import_prefixes": ["core.engine.arms"], + "allowed_caller_prefixes": ["core/engine/arms/"], + "allowed_callers": ["core/engine/mcp/tools.py"] + }, + "living_product_graph": { + "import_prefixes": [ + "core.engine.product.living_graph", + "core.engine.product.living_graph_store" + ], + "allowed_caller_prefixes": [], + "allowed_callers": [ + "core/engine/api/landscape.py", + "core/engine/cli/commands/landscape.py", + "core/engine/product/living_graph_store.py" + ] + }, + "broad_engine_mcp": { + "import_prefixes": ["core.engine.mcp"], + "allowed_caller_prefixes": ["core/engine/mcp/"], + "allowed_callers": [ + "core/engine/api/canvas.py", + "core/engine/api/codebase_qa.py", + "core/engine/api/diagnostics.py", + "core/engine/arms/code_planner.py", + "core/engine/arms/data_planner.py", + "core/engine/arms/design_planner.py", + "core/engine/arms/spec_reality.py", + "core/engine/arms/strategy/deep_phases.py", + "core/engine/arms/strategy/graph_classifier.py", + "core/engine/notifications/channels/discord.py", + "core/engine/product/spec_generator.py", + "core/engine/research/agent.py", + "core/engine/runtime/mid_session_observer.py", + "core/engine/runtime/tools/ace_tools.py" + ] + } + }, "dispositions": { "transport_adapter_host": { "owner": "application", diff --git a/docs/design/intelligence-os-runtime-boundary-v0.8.0-work-packet-v1.md b/docs/design/intelligence-os-runtime-boundary-v0.8.0-work-packet-v1.md index 2b8e75b..3a9f85e 100644 --- a/docs/design/intelligence-os-runtime-boundary-v0.8.0-work-packet-v1.md +++ b/docs/design/intelligence-os-runtime-boundary-v0.8.0-work-packet-v1.md @@ -1,6 +1,6 @@ # ACE 0.8.0 runtime-boundary realignment work packet -Status: **active 0.8B packet; B1 compatibility isolation and B2 ownership guards implemented** +Status: **active 0.8B packet; B1–B3 runtime isolation and ownership guards implemented** Public milestone: [issue #40](https://github.com/augmented-cognition-engine/core/issues/40) Accepted base: `main@bb7f4ba` (0.8A plus explicitly reviewed AM4 lifecycle semantics) @@ -63,6 +63,18 @@ owner and treatment fails the boundary suite. Product-era arms, product surfaces explicitly frozen compatibility applications; their presence does not make their vocabulary or dependency direction canonical. +## B3 — freeze deprecated callers and reproduce restart behavior + +The same disposition manifest freezes the current direct callers of the MAKE/SHIP-era arms, the +Living Product Graph compatibility projection, and the broad engine MCP host. A new caller fails +the ownership suite until an explicit compatibility review changes that allowlist; code cannot +quietly deepen the dependency while 0.8 introduces canonical resources. + +The cumulative 0.7 builder, exact activation plan, Watch behavior, AM3 authorized recall, and AM4 +lifecycle/erasure gates reproduce on this boundary. The real AM3 later-use and AM4 non-reappearance +checks also pass through fresh processes and disposable durable storage. This closes runtime +ownership without claiming that historical host directories have been deleted. + ## Acceptance B1 passes only when: @@ -78,14 +90,14 @@ B1 passes only when: ## Remaining 0.8B work -B1 and B2 do not close 0.8B. The remaining runtime-boundary packet must: +B1–B3 close the bounded 0.8B runtime realignment when their independent reviews and CI pass. They: - keep generic planning, authority, execution admission, assurance, outcomes, and erasure behind - Core ports; + public Core ports; - keep Observation-to-Feedback interpretation behind Intelligence and application services; -- verify artifact creation and external effects enter only through explicit strategy/adapter ports; -- prevent new direct callers of deprecated MAKE/SHIP, Living Product Graph category, broad MCP, and - legacy product-intelligence paths; and +- require artifact creation and external effects to enter through explicit strategy/adapter ports; +- prevent new direct callers of deprecated MAKE/SHIP, Living Product Graph category, broad MCP, + and legacy product-intelligence paths; and - reproduce Connect → Map → Watch → Brief → Activate plus AM3/AM4 behavior after restart. 0.8C may not depend on an undeclared legacy host route. diff --git a/tests/test_intelligence_os_ownership_boundary.py b/tests/test_intelligence_os_ownership_boundary.py index 9683bf7..ccd406c 100644 --- a/tests/test_intelligence_os_ownership_boundary.py +++ b/tests/test_intelligence_os_ownership_boundary.py @@ -115,3 +115,27 @@ def test_product_era_surface_is_explicitly_frozen_compatibility() -> None: assert legacy["owner"] == "application" assert "frozen" in legacy["treatment"] assert {"arms", "product", "product_state", "canvas"}.issubset(legacy["packages"]) + + +def test_deprecated_compatibility_surfaces_gain_no_new_direct_callers() -> None: + manifest = json.loads(DISPOSITION.read_text(encoding="utf-8")) + policies = manifest["deprecated_callsite_policies"] + assert set(policies) == {"make_ship_arms", "living_product_graph", "broad_engine_mcp"} + + for policy_name, policy in policies.items(): + imports = tuple(policy["import_prefixes"]) + allowed_callers = set(policy["allowed_callers"]) + allowed_prefixes = tuple(policy["allowed_caller_prefixes"]) + offenders: list[str] = [] + + for path in LEGACY_HOST.rglob("*.py"): + if "__pycache__" in path.parts: + continue + caller = path.relative_to(REPO).as_posix() + for line, imported in _imports(path): + if imported.startswith(imports) and not ( + caller in allowed_callers or caller.startswith(allowed_prefixes) + ): + offenders.append(f"{caller}:{line} ({imported})") + + assert sorted(offenders) == [], f"{policy_name} gained undeclared callers: {offenders}"