From d1b46ad2f32054a92dd5daa8427d64991dc1edbd Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 18 May 2026 22:40:53 +0200 Subject: [PATCH] Add fake external adapter packs --- README.md | 4 +- docs/external-adapter-packs.md | 57 +++++++ docs/service-readiness.md | 12 ++ src/phase_memory/__init__.py | 22 +++ src/phase_memory/external_adapters.py | 160 ++++++++++++++++++ tests/test_external_adapter_packs.py | 66 ++++++++ workplans/PMEM-MATURITY-SCORECARD.md | 48 ++++-- ...MEM-WP-0010-fake-external-adapter-packs.md | 116 +++++++++++++ 8 files changed, 472 insertions(+), 13 deletions(-) create mode 100644 docs/external-adapter-packs.md create mode 100644 src/phase_memory/external_adapters.py create mode 100644 tests/test_external_adapter_packs.py create mode 100644 workplans/PMEM-WP-0010-fake-external-adapter-packs.md diff --git a/README.md b/README.md index acffce3..f11590c 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ and a package compilation request for the `ContextPackageCompiler` boundary. - `phase_memory.activation`: Markitect-compatible activation selection planning. - `phase_memory.ports`: runtime port protocols. - `phase_memory.adapters`: deterministic in-memory test adapters. +- `phase_memory.external_adapters`: deterministic fake external adapter packs. - `phase_memory.runtime`: local runtime facade and stable operation envelopes. - `phase_memory.cli`: dependency-light command-line interface. @@ -93,5 +94,6 @@ policy and review gates, [docs/markitect-interop.md](docs/markitect-interop.md) for package bridge boundaries, [docs/activation-quality.md](docs/activation-quality.md) for retrieval and evaluation behavior, [docs/service-readiness.md](docs/service-readiness.md) for service and adapter contracts, [docs/lifecycle-rules.md](docs/lifecycle-rules.md) -for profile-driven lifecycle rules, and [SCOPE.md](SCOPE.md) for repository +for profile-driven lifecycle rules, [docs/external-adapter-packs.md](docs/external-adapter-packs.md) +for fake external integration packs, and [SCOPE.md](SCOPE.md) for repository boundaries. diff --git a/docs/external-adapter-packs.md b/docs/external-adapter-packs.md new file mode 100644 index 0000000..c2a05a4 --- /dev/null +++ b/docs/external-adapter-packs.md @@ -0,0 +1,57 @@ +# External Adapter Packs + +`phase-memory` can resolve runtime configuration values that declare adapter +mode `external`. Missing external adapters still fail resolution, but supplied +adapter packs can satisfy the public runtime ports. + +## Fake External Pack + +`phase_memory.external_adapters.fake_external_adapter_pack()` returns a local +fake pack for conformance and integration tests. It provides: + +- `FakeExternalGraphStore` +- `FakeExternalEventLog` +- `FakeExternalPolicyGateway` +- `FakeTelemetryAuditSink` +- `FakeMarkitectPackageCompiler` +- `FakeExternalSemanticIndex` +- `FakeKontextualRuntimeRegistry` + +The pack is not a production adapter. It is intentionally deterministic and +dependency-light so that service wiring, conformance helpers, and runtime +envelopes can be tested before live Markitect, Kontextual, or telemetry +services exist. + +## Runtime Wiring + +```python +from phase_memory.external_adapters import ( + fake_external_adapter_pack, + fake_external_runtime_config, +) +from phase_memory.service import runtime_from_config + +config = fake_external_runtime_config() +pack = fake_external_adapter_pack() +runtime = runtime_from_config(config, external_adapters=pack.adapters) +``` + +`resolve_runtime_adapters(config, external_adapters=pack.adapters)` returns a +`RuntimeAdapterBundle` with diagnostics. External declarations produce +`external_adapter_declared` warnings. Missing adapters produce +`missing_external_adapter` errors and block runtime construction. + +## Conformance + +The fake pack passes the same public helpers expected of live adapters: + +- `assert_graph_store_conformance` +- `assert_event_log_conformance` +- `assert_context_compiler_conformance` +- `assert_policy_gateway_conformance` +- `assert_audit_sink_conformance` +- `assert_semantic_index_conformance` +- `assert_runtime_registry_conformance` + +Live adapter packs should pass those helpers before being wired into a runtime +or service runner. diff --git a/docs/service-readiness.md b/docs/service-readiness.md index fe54aac..b7034f8 100644 --- a/docs/service-readiness.md +++ b/docs/service-readiness.md @@ -59,6 +59,18 @@ External adapter modes are valid configuration values, but they must be supplied explicitly by the caller. The local resolver reports `missing_external_adapter` instead of silently replacing them. +## External Adapter Packs + +`phase_memory.external_adapters.fake_external_adapter_pack()` supplies a +deterministic fake external pack for conformance and integration tests. It +includes fake Markitect package compilation, Kontextual-shaped graph/event and +runtime registry adapters, a fake semantic index, a fake policy gateway, and a +fake telemetry audit sink. + +Use it with `fake_external_runtime_config()` and +`resolve_runtime_adapters(config, external_adapters=pack.adapters)` to exercise +the external wiring path without live services. + ## Health `health_report` emits: diff --git a/src/phase_memory/__init__.py b/src/phase_memory/__init__.py index dbdadf1..c0a410b 100644 --- a/src/phase_memory/__init__.py +++ b/src/phase_memory/__init__.py @@ -10,6 +10,18 @@ from .bridge import ( package_response_envelope, ) from .contracts import graph_from_markitect, profile_from_markitect +from .external_adapters import ( + ExternalAdapterPack, + FakeExternalEventLog, + FakeExternalGraphStore, + FakeExternalPolicyGateway, + FakeExternalSemanticIndex, + FakeKontextualRuntimeRegistry, + FakeMarkitectPackageCompiler, + FakeTelemetryAuditSink, + fake_external_adapter_pack, + fake_external_runtime_config, +) from .lifecycle import ( LifecycleRuleConfig, PhaseTransitionRule, @@ -58,6 +70,14 @@ from .runtime import PhaseMemoryRuntime __all__ = [ "ActivationPlan", "Diagnostic", + "ExternalAdapterPack", + "FakeExternalEventLog", + "FakeExternalGraphStore", + "FakeExternalPolicyGateway", + "FakeExternalSemanticIndex", + "FakeKontextualRuntimeRegistry", + "FakeMarkitectPackageCompiler", + "FakeTelemetryAuditSink", "LifecycleAction", "LifecycleActionKind", "LifecycleState", @@ -101,6 +121,8 @@ __all__ = [ "plan_retention", "plan_retention_from_rules", "profile_from_markitect", + "fake_external_adapter_pack", + "fake_external_runtime_config", "path_event", "package_request_from_selection", "package_response_envelope", diff --git a/src/phase_memory/external_adapters.py b/src/phase_memory/external_adapters.py new file mode 100644 index 0000000..eadbe35 --- /dev/null +++ b/src/phase_memory/external_adapters.py @@ -0,0 +1,160 @@ +"""Fake external adapter pack for service-readiness integration tests.""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Any + +from .adapters import InMemoryMemoryEventLog, InMemoryMemoryGraphStore, InMemorySemanticIndex +from .models import PolicyDecision +from .service import RuntimeConfig +from .utils import stable_digest + + +@dataclass(frozen=True) +class ExternalAdapterPack: + name: str + adapters: dict[str, Any] + capabilities: tuple[str, ...] = () + metadata: dict[str, Any] = field(default_factory=dict) + + def to_dict(self) -> dict[str, Any]: + return { + "name": self.name, + "adapters": {key: value.__class__.__name__ for key, value in sorted(self.adapters.items())}, + "capabilities": list(self.capabilities), + "metadata": dict(self.metadata), + } + + +class FakeExternalGraphStore(InMemoryMemoryGraphStore): + """Kontextual-shaped graph store fake backed by deterministic memory.""" + + +class FakeExternalEventLog(InMemoryMemoryEventLog): + """Kontextual-shaped event log fake backed by deterministic memory.""" + + +class FakeExternalSemanticIndex(InMemorySemanticIndex): + """Permission-aware retrieval fake with the local deterministic index shape.""" + + +class FakeMarkitectPackageCompiler: + def compile_selection(self, selection: dict[str, Any]) -> dict[str, Any]: + selection_id = str(selection.get("id") or "selection") + package_id = f"fake-markitect:{stable_digest(selection)}" + return { + "package_id": package_id, + "package_ref": package_id, + "compiler": self.__class__.__name__, + "selection_id": selection_id, + "item_count": len(selection.get("nodes", ())) + len(selection.get("events", ())), + "diagnostics": [], + "selection": dict(selection), + } + + +class FakeExternalPolicyGateway: + def __init__(self, *, deny_actions: tuple[str, ...] = ()) -> None: + self.deny_actions = set(deny_actions) + + def authorize(self, *, action: str, resource: str, context: dict[str, Any] | None = None) -> PolicyDecision: + allowed = action not in self.deny_actions + return PolicyDecision( + allowed, + reason="fake external policy allowed" if allowed else "fake external policy denied", + metadata={ + "adapter": self.__class__.__name__, + "action": action, + "resource": resource, + "context": context or {}, + }, + ) + + +class FakeTelemetryAuditSink: + def __init__(self, *, retention_days: int = 30) -> None: + self.retention_days = retention_days + self.events: list[dict[str, Any]] = [] + + def record(self, event: dict[str, Any]) -> dict[str, Any]: + external_ref = f"fake-audit:{stable_digest([len(self.events), event])}" + stored = { + **dict(event), + "external_ref": external_ref, + "retention_days": self.retention_days, + } + self.events.append(stored) + return { + "recorded": True, + "external_ref": external_ref, + "retention_days": self.retention_days, + "event": stored, + } + + def query(self, *, operation: str | None = None) -> list[dict[str, Any]]: + if operation is None: + return list(self.events) + return [event for event in self.events if event.get("operation") == operation] + + +class FakeKontextualRuntimeRegistry: + def __init__(self) -> None: + self._envelopes: dict[str, dict[str, Any]] = {} + + def publish_runtime_envelope(self, envelope: dict[str, Any]) -> dict[str, Any]: + reference = f"fake-kontextual:{stable_digest(envelope)}" + stored = dict(envelope) + self._envelopes[reference] = stored + return { + "published": True, + "reference": reference, + "adapter": self.__class__.__name__, + "envelope": stored, + } + + def fetch_runtime_envelope(self, reference: str) -> dict[str, Any]: + return dict(self._envelopes[reference]) + + +def fake_external_adapter_pack() -> ExternalAdapterPack: + return ExternalAdapterPack( + name="fake-external", + adapters={ + "graph_store": FakeExternalGraphStore(), + "event_log": FakeExternalEventLog(), + "policy_gateway": FakeExternalPolicyGateway(), + "audit_sink": FakeTelemetryAuditSink(), + "package_compiler": FakeMarkitectPackageCompiler(), + "semantic_index": FakeExternalSemanticIndex(), + "runtime_registry": FakeKontextualRuntimeRegistry(), + }, + capabilities=( + "markitect.package.compile", + "kontextual.runtime.registry", + "kontextual.graph-store.fake", + "telemetry.audit.fake", + "semantic-index.fake", + ), + metadata={"intended_for": "local conformance and integration tests"}, + ) + + +def fake_external_runtime_config() -> RuntimeConfig: + return RuntimeConfig( + adapter_registry={ + "graph_store": "external", + "event_log": "external", + "policy_gateway": "external", + "audit_sink": "external", + "package_compiler": "external", + "semantic_index": "external", + "runtime_registry": "external", + }, + policy_mode="external", + audit_sink_mode="external", + package_compiler_mode="external", + semantic_index_mode="external", + runtime_registry_mode="external", + trust_zone_labels=("external",), + ) diff --git a/tests/test_external_adapter_packs.py b/tests/test_external_adapter_packs.py new file mode 100644 index 0000000..10ef319 --- /dev/null +++ b/tests/test_external_adapter_packs.py @@ -0,0 +1,66 @@ +import json +from pathlib import Path + +from phase_memory.external_adapters import fake_external_adapter_pack, fake_external_runtime_config +from phase_memory.service import ( + assert_audit_sink_conformance, + assert_context_compiler_conformance, + assert_event_log_conformance, + assert_graph_store_conformance, + assert_policy_gateway_conformance, + assert_runtime_registry_conformance, + assert_semantic_index_conformance, + health_report, + resolve_runtime_adapters, + runtime_from_config, +) + + +FIXTURES = Path(__file__).parent / "fixtures" + + +def _load(name: str): + return json.loads((FIXTURES / name).read_text(encoding="utf-8")) + + +def test_fake_external_adapter_pack_satisfies_public_conformance_helpers() -> None: + pack = fake_external_adapter_pack() + adapters = pack.adapters + + assert_graph_store_conformance(adapters["graph_store"]) + assert_event_log_conformance(adapters["event_log"]) + assert_context_compiler_conformance(adapters["package_compiler"]) + assert_policy_gateway_conformance(adapters["policy_gateway"]) + assert_audit_sink_conformance(adapters["audit_sink"]) + assert_semantic_index_conformance(adapters["semantic_index"]) + assert_runtime_registry_conformance(adapters["runtime_registry"]) + assert pack.to_dict()["adapters"]["package_compiler"] == "FakeMarkitectPackageCompiler" + + +def test_external_runtime_config_resolves_supplied_fake_pack() -> None: + config = fake_external_runtime_config() + pack = fake_external_adapter_pack() + bundle = resolve_runtime_adapters(config, external_adapters=pack.adapters) + runtime = runtime_from_config(config, external_adapters=pack.adapters) + + assert not [diagnostic for diagnostic in bundle.diagnostics if diagnostic.severity == "error"] + assert {diagnostic.code for diagnostic in bundle.diagnostics} == {"external_adapter_declared"} + + runtime.import_graph(_load("memory-graph.json"), source_ref="fake-external") + envelope = runtime.compile_package( + { + "schema_version": "markitect.memory.selection.v1", + "id": "selection.external", + "nodes": ["decision.boundary"], + "events": [], + } + ) + registry_receipt = bundle.runtime_registry.publish_runtime_envelope(envelope) + fetched = bundle.runtime_registry.fetch_runtime_envelope(registry_receipt["reference"]) + report = health_report(runtime, config=config) + + assert envelope["valid"] is True + assert envelope["data"]["package_response"]["package_ref"].startswith("fake-markitect:") + assert fetched["operation"] == "package.compile" + assert report["ok"] is True + assert report["adapters"]["package_compiler"] == "FakeMarkitectPackageCompiler" diff --git a/workplans/PMEM-MATURITY-SCORECARD.md b/workplans/PMEM-MATURITY-SCORECARD.md index a3378fd..7195a41 100644 --- a/workplans/PMEM-MATURITY-SCORECARD.md +++ b/workplans/PMEM-MATURITY-SCORECARD.md @@ -44,33 +44,33 @@ not what adjacent repositories may already provide. ## Current Baseline - 2026-05-18 -Overall maturity: **4.4 / 5** +Overall maturity: **4.5 / 5** The repo has crossed from intent-only into a working deterministic library foundation, a usable local runtime facade, a CLI, a file-backed local workspace, first-slice policy/review/audit gates, a concrete Markitect package bridge, deterministic activation quality helpers, and first-slice service -readiness contracts with profile-driven runtime adapter resolution and -profile-derived lifecycle rules. +readiness contracts with profile-driven runtime adapter resolution, +profile-derived lifecycle rules, and fake external adapter packs. | Dimension | Current | Target | Evidence | Needed Next | | --- | ---: | ---: | --- | --- | | Intent and boundaries | 4.0 | 5.0 | `INTENT.md`, `SCOPE.md`, `README.md`, architecture doc, PMEM-WP-0001 closure | Keep boundaries current as runtime behavior expands. | | Package foundation | 4.0 | 4.0 | Python package, exports, runtime facade, CLI entrypoint, config, service contracts, dependency-light tests | Maintain public API compatibility as adapters expand. | | Profile contract ingress | 3.2 | 4.0 | Markitect-compatible profile loading, diagnostics, runtime envelopes, profile-derived runtime config, local adapter alias normalization | Add richer compatibility coverage. | -| Graph/event contract ingress | 3.5 | 4.0 | Graph loading, edge endpoint diagnostics, event model, JSONL event log, export, repair diagnostics, service import/export contracts | Add broader external adapter fixtures. | +| Graph/event contract ingress | 3.7 | 4.0 | Graph loading, edge endpoint diagnostics, event model, JSONL event log, export, repair diagnostics, service import/export contracts, fake external graph/event adapters | Add broader external adapter fixtures. | | Phase domain model | 3.4 | 4.0 | Phases, memory kinds, lifecycle states, actions, explicit path records, profile-derived transition rules | Add migration semantics. | -| Profile execution planning | 3.8 | 4.0 | Adapter plan, capabilities, policy gates, fallback behavior, CLI output, snapshot fixture, service contract, config-driven local adapter resolution | Add external adapter injection coverage. | +| Profile execution planning | 4.0 | 4.0 | Adapter plan, capabilities, policy gates, fallback behavior, CLI output, snapshot fixture, service contract, config-driven local and fake external adapter resolution | Maintain compatibility as live adapters land. | | Lifecycle planning | 3.6 | 4.0 | Transition, retention, refresh, compaction dry-run plans, profile-driven lifecycle rules, review-gated local apply | Add service apply contracts and migration semantics. | | Activation planning | 3.8 | 5.0 | Budgeted selection, Markitect-compatible selection output, package request envelope, graph neighborhoods, event paths, ranking, metadata preservation, metrics | Add semantic-index adapters and broader evaluation corpora. | | Local persistence | 3.0 | 4.0 | Versioned local workspace, file-backed graph store, JSONL event log, JSONL audit sink | Add migration/repair utilities and stronger durability semantics. | -| Policy and audit | 3.2 | 5.0 | Operation points, policy gateway checks, audit schema, review records, redaction, activation denials | Add external policy adapters and richer audit retention behavior. | -| Observability and diagnostics | 3.5 | 4.0 | Planner diagnostics, runtime diagnostics, event log corruption checks, repair diagnostics, policy denial diagnostics, health envelopes, adapter status | Add production telemetry adapters. | -| Markitect interop | 3.5 | 4.0 | Compatible contract ingress, optional validation boundary, enriched selection metadata, package request/response envelopes | Add live optional Markitect compiler adapter when available. | -| Kontextual/Infospace interop | 2.5 | 4.0 | Boundaries documented, small derived fixtures, activation quality report fixture, Kontextual delegation envelope | Add live fake/real delegation adapters and broader Infospace reports. | -| Testing and evaluation | 4.0 | 4.0 | 58 deterministic tests over planners, adapters, runtime envelopes, CLI, snapshots, file-store round trips, lifecycle rules, apply denial, review records, audit schema, policy redaction, Markitect bridge fixtures, retrieval, activation metrics, service contracts, config, health, conformance, and adapter resolution | Add broader evaluation corpora. | -| Service readiness | 3.9 | 4.0 | Runtime ports, service contracts, config model, profile-derived adapter resolution, health checks, local service runner lifecycle support, adapter conformance helpers | Add framework-specific bindings and production adapter packs. | -| Developer experience | 3.6 | 4.0 | README quick start, package map, runtime facade docs, CLI examples, local persistence guide, service adapter resolution docs, lifecycle rule docs | Add troubleshooting and richer examples. | +| Policy and audit | 3.5 | 5.0 | Operation points, policy gateway checks, audit schema, review records, redaction, activation denials, fake external policy/audit adapters | Add richer audit retention behavior and live policy adapters. | +| Observability and diagnostics | 3.8 | 4.0 | Planner diagnostics, runtime diagnostics, event log corruption checks, repair diagnostics, policy denial diagnostics, health envelopes, adapter status, fake telemetry audit sink | Add production telemetry adapters. | +| Markitect interop | 3.7 | 4.0 | Compatible contract ingress, optional validation boundary, enriched selection metadata, package request/response envelopes, fake Markitect package compiler | Add live optional Markitect compiler adapter when available. | +| Kontextual/Infospace interop | 3.0 | 4.0 | Boundaries documented, small derived fixtures, activation quality report fixture, Kontextual delegation envelope, fake Kontextual runtime registry | Add live delegation adapters and broader Infospace reports. | +| Testing and evaluation | 4.0 | 4.0 | 60 deterministic tests over planners, adapters, runtime envelopes, CLI, snapshots, file-store round trips, lifecycle rules, apply denial, review records, audit schema, policy redaction, Markitect bridge fixtures, retrieval, activation metrics, service contracts, config, health, conformance, adapter resolution, and fake external packs | Add broader evaluation corpora. | +| Service readiness | 4.0 | 4.0 | Runtime ports, service contracts, config model, profile-derived adapter resolution, health checks, local service runner lifecycle support, adapter conformance helpers, fake external adapter pack | Add framework-specific bindings and production adapter packs. | +| Developer experience | 3.7 | 4.0 | README quick start, package map, runtime facade docs, CLI examples, local persistence guide, service adapter resolution docs, lifecycle rule docs, external adapter pack docs | Add troubleshooting and richer examples. | ## Progress Update - PMEM-WP-0002 @@ -194,6 +194,27 @@ Remaining maturity blockers: - Live external adapter implementations. - Broader evaluation corpora. +## Progress Update - PMEM-WP-0010 + +Closed on 2026-05-18: + +- Added `ExternalAdapterPack`. +- Added deterministic fake external graph and event adapters. +- Added fake Markitect package compiler. +- Added fake external policy gateway. +- Added fake telemetry audit sink with retention metadata. +- Added fake semantic index and fake Kontextual runtime registry. +- Added `fake_external_adapter_pack()` and `fake_external_runtime_config()`. +- Added conformance tests and all-external runtime wiring tests. +- Added external adapter pack documentation and README links. + +Remaining maturity blockers: + +- Live external adapter implementations. +- Broader evaluation corpora. +- Framework-specific service bindings. +- Production audit retention and telemetry integrations. + ## Progress Update - PMEM-WP-0004 Closed on 2026-05-18: @@ -259,6 +280,7 @@ flowchart TD WP7["PMEM-WP-0007\nService readiness and adapters"] WP8["PMEM-WP-0008\nProfile-driven runtime config"] WP9["PMEM-WP-0009\nProfile-driven lifecycle rules"] + WP10["PMEM-WP-0010\nFake external adapter packs"] WP1 --> WP2 WP2 --> WP3 @@ -277,6 +299,8 @@ flowchart TD WP2 --> WP9 WP4 --> WP9 WP8 --> WP9 + WP7 --> WP10 + WP8 --> WP10 ``` ## Next Tracking Cadence diff --git a/workplans/PMEM-WP-0010-fake-external-adapter-packs.md b/workplans/PMEM-WP-0010-fake-external-adapter-packs.md new file mode 100644 index 0000000..e24c5e0 --- /dev/null +++ b/workplans/PMEM-WP-0010-fake-external-adapter-packs.md @@ -0,0 +1,116 @@ +--- +id: PMEM-WP-0010 +type: workplan +title: "Fake External Adapter Packs" +domain: markitect +repo: phase-memory +status: finished +owner: codex +topic_slug: phase-memory +created: "2026-05-18" +updated: "2026-05-18" +--- + +# PMEM-WP-0010: Fake External Adapter Packs + +## Goal + +Provide a deterministic fake external adapter pack that exercises the same +adapter injection path live Markitect, Kontextual, semantic index, policy, and +telemetry integrations will use. + +This refines the external adapter workplan direction into a testable first +slice: no live service dependency, but no silent fallback either. + +## Current Evidence + +PMEM-WP-0008 made `external` adapter modes explicit and blocked unresolved +external adapters. PMEM-WP-0009 added profile-driven lifecycle planning. The +remaining service-readiness gap was a supplied external adapter pack that could +pass public conformance helpers and run through the service/runtime wiring. + +## Non-Goals + +- Call live Markitect, Kontextual, telemetry, or policy services. +- Add credentials, network dependencies, or deployment configuration. +- Replace the local file-backed adapters. + +## Implementation Update - 2026-05-18 + +Implemented the fake external adapter pack: + +- Added `ExternalAdapterPack`. +- Added fake external graph store and event log adapters. +- Added fake Markitect package compiler. +- Added fake external policy gateway. +- Added fake telemetry audit sink with retention metadata. +- Added fake semantic index and Kontextual runtime registry. +- Added `fake_external_adapter_pack()` and `fake_external_runtime_config()`. +- Added conformance and runtime wiring tests. +- Added docs and README links. + +## T01 - Add fake external adapter pack model + +```task +id: PMEM-WP-0010-T01 +status: done +priority: high +``` + +Add a small pack record with adapter instances, capabilities, and metadata. + +## T02 - Add fake Markitect and Kontextual adapters + +```task +id: PMEM-WP-0010-T02 +status: done +priority: high +``` + +Provide fake package compiler and runtime registry adapters that match the +public ports. + +## T03 - Add fake policy, audit, semantic, graph, and event adapters + +```task +id: PMEM-WP-0010-T03 +status: done +priority: high +``` + +Provide deterministic fake implementations for the remaining runtime ports. + +## T04 - Prove external config wiring + +```task +id: PMEM-WP-0010-T04 +status: done +priority: high +``` + +Resolve an all-external runtime config with the supplied fake pack and verify +runtime package compilation plus registry publication. + +## T05 - Document adapter pack usage + +```task +id: PMEM-WP-0010-T05 +status: done +priority: medium +``` + +Document fake pack usage, conformance expectations, and the relationship to +future live adapters. + +## Acceptance Criteria + +- The fake pack satisfies all public conformance helpers. +- An all-external runtime config resolves when the pack is supplied. +- Missing external adapter behavior remains unchanged. +- Runtime envelopes can compile packages through the fake Markitect adapter. +- Runtime envelopes can be published through the fake Kontextual registry. + +## Closure Review - 2026-05-18 + +Closed after adding fake external adapter implementations, adapter pack helpers, +runtime wiring coverage, and documentation.