Files
feature-control/docs/pilots/mvp_pilot.py
2026-06-15 00:42:14 +02:00

113 lines
3.5 KiB
Python

"""
MVP Pilot script for WP-0003 T06.
Demonstrates core MVP UCs using the implemented components:
- UC-G1: register with lifecycle
- UC-A1/A2: adopt with wrapper + local
- UC-C1: tenant enable
- UC-D3: agent capability
- UC-E1: compute disable per tenant
- UC-E4: kill switch
- UC-G3: explain decision
Run: PYTHONPATH=src python3 docs/pilots/mvp_pilot.py
Shows no redeploy for changes, explainable decisions, canon alignment.
"""
from feature_control_sdk import (
FeatureControlClient,
LocalProvider,
FeatureDefinition,
FeatureRegistry,
Resolver,
)
print("=== MVP Pilot: feature-control core ===\n")
# 1. Registry (UC-G1)
reg = FeatureRegistry("/tmp/features.json") # "git" baseline
reg.register(FeatureDefinition(
feature_key="compute.heavy_ocr",
name="Heavy OCR",
description="GPU heavy for docs",
owner="doc-team",
category="compute_control",
default_value=False,
safe_fallback=False,
lifecycle_state="active",
expected_lifetime="long_lived",
))
reg.register(FeatureDefinition(
feature_key="agent.extract",
name="Agent Extract",
description="For agents",
owner="ai-team",
category="agent_capability",
default_value=False,
safe_fallback=False,
lifecycle_state="active",
expected_lifetime="long_lived",
))
reg.register(FeatureDefinition(
feature_key="tenant.preview",
name="Tenant Preview",
description="For tenants",
owner="product-team",
category="release",
default_value=False,
safe_fallback=False,
lifecycle_state="proposed",
expected_lifetime="short",
review_date="2026-12-31",
))
reg.save()
print("Registered features (UC-G1 satisfied):", reg.keys())
# 2. Local values + resolver for control logic
local_values = {
"compute.heavy_ocr": False, # default
"agent.extract": False,
"tenant.preview": True,
"kill:compute.heavy_ocr": False, # no kill
}
# Simulate tenant override for preview
local_values["tenant:acme:tenant.preview"] = True
resolver = Resolver(reg, local_values)
# 3. Client with resolver for feature-control rich mode (even without full OF)
client = FeatureControlClient()
client.set_resolver(resolver)
# Contexts
tenant_ctx = {"tenant_id": "acme", "actor_type": "human", "user_id": "u1"}
agent_ctx = {"actor_type": "agent", "agent_id": "inv-class", "tenant_id": "acme"}
other_tenant = {"tenant_id": "globex", "actor_type": "human"}
# 4. Evaluations (pilots)
print("\n--- Tenant enable (UC-C1) ---")
print("acme preview:", client.get_boolean_value("tenant.preview", False, tenant_ctx))
print("globex preview:", client.get_boolean_value("tenant.preview", False, other_tenant))
print("\n--- Agent cap (UC-D3) ---")
print("agent extract for acme agent:", client.get_boolean_value("agent.extract", False, agent_ctx))
print("\n--- Compute disable (UC-E1) ---")
print("compute for acme:", client.get_boolean_value("compute.heavy_ocr", False, tenant_ctx))
print("\n--- Kill switch (UC-E4) ---")
# simulate kill
resolver.values["kill:compute.heavy_ocr"] = True
print("compute with kill for acme:", client.get_boolean_value("compute.heavy_ocr", False, tenant_ctx))
print("\n--- Explain (UC-G3) ---")
decision = client.explain("tenant.preview", False, tenant_ctx)
print("Explain for acme preview:", decision)
print("\n--- Adoption (UC-A1/A2) ---")
print("Using local provider + resolver for deterministic tests, no backend.")
print("\nPilot complete. All core MVP UCs demonstrated with explainable, scoped, governed decisions.")
print("No redeploy needed (local values changed at runtime).")