#!/usr/bin/env python3 """File-based TAC Product Factory MVP.""" from __future__ import annotations import json import re import sys from datetime import datetime, timezone from pathlib import Path ROOT = Path(__file__).resolve().parent CATALOG = ROOT / "catalog.json" EVENT_DIR = ROOT / ".events" PRODUCTS_DIR = ROOT / "generated" DASHBOARD = ROOT / "DASHBOARD.md" PLANS_DIR = ROOT.parent / "plans" RECEIPTS_DIR = ROOT / "receipts" RSI_EVIDENCE_RECEIPT = "packages/pi-real-engineering/docs/receipts/rsi-proof-20260619T093724Z.md" LOCAL_RSI_EVIDENCE_RECEIPT = "products/receipts/rsi-proof-20260619T093724Z.md" RSI_DECISION = "healthy_but_autopatch_unproven" RSI_CLAIM = ( "Factory RSI is healthy at 65/65 with cron, skill_health, factory_watcher, " "and deploy_route present; auto_patch_proven=false until a degraded-skill " "recovery receipt exists; rsi_canary evidence is tracked separately" ) FACTORY_STATE = { "factory_phase": 4, "agent_rsi_phases": "A-D operational", "containers": 25, "agents": 6, "infra": 14, "monitoring_deploy": 5, "skills": 63, "latest_score": "65/65", "factory_watcher": True, "deploy_route_present": True, "root_commit": "55bdf3f", "hermes_agent_commit": "fd3053b", } LOOP_ENGINEERING = { "agent_loop": "ADW phases run tools until product task completion", "verification_loop": "plan validation, pytest checks, verifier_result, and receipts gate readiness", "event_driven_loop": "GitHub webhooks, cron skill_health, event JSONL, and dashboard refresh trigger work", "hill_climbing_loop": "skill_health/SkillOpt can propose signed action patches; guarded by receipts and rollback", } def slugify(text: str) -> str: slug = re.sub(r"[^a-zA-Z0-9]+", "-", text.lower()).strip("-") return slug[:60] or "product" def load_catalog() -> list[dict]: return json.loads(CATALOG.read_text(encoding="utf-8")) if CATALOG.exists() else [] def log_event(kind: str, **data) -> Path: EVENT_DIR.mkdir(parents=True, exist_ok=True) path = EVENT_DIR / f"{datetime.now(timezone.utc).date().isoformat()}.jsonl" event = {"ts": datetime.now(timezone.utc).isoformat(), "kind": kind, **data} with path.open("a", encoding="utf-8") as f: f.write(json.dumps(event, ensure_ascii=False) + "\n") return path def living_plan_metadata(product_id: str) -> dict: return { "plan_id": product_id, "plan_ref": f"plans/{product_id}/plan.md", "format": ["markdown", "html-first", "append-only-amendments"], "required_sections": ["purpose", "problem", "solution", "files", "phases", "validation", "references", "notes"], "deploy_endpoint": "git-proxy:8099/deploy", "legacy_internal": ["deploy-webhook:8098"], "rsi_decision": RSI_DECISION, "auto_patch_proven": False, "rsi_canary_recovery_evidence": True, "rsi_evidence_receipt": RSI_EVIDENCE_RECEIPT, "local_rsi_evidence_receipt": LOCAL_RSI_EVIDENCE_RECEIPT, "rsi_claim": RSI_CLAIM, "factory_state": FACTORY_STATE, "loop_engineering": LOOP_ENGINEERING, } def render_plan_md(product_id: str, purpose: str) -> str: return f"""--- product_id: {product_id} purpose: {purpose} references: - products/AGENT_PRODUCTS.md --- ## Purpose {purpose} ## Problem Define the product problem before build. ## Solution Build the smallest agent-run product that satisfies the plan. ## Files - products/generated/{product_id}/spec.json - products/generated/{product_id}/README.md ## Phases - [ ] Plan - [ ] Build - [ ] Test - [ ] Verify - [ ] Signed deploy ## Validation - uv run --with pytest pytest -q ## References - products/AGENT_PRODUCTS.md ## Notes Plan F3 living artifact. Amendments append below. """ def render_plan_html(product_id: str, purpose: str) -> str: return f"""

{product_id}

Purpose

{purpose}

Problem

Define the product problem before build.

Solution

Build the smallest agent-run product that satisfies the plan.

Files

See plan.md.

Phases

Validation

uv run --with pytest pytest -q

References

products/AGENT_PRODUCTS.md

Notes

Plan F3 living artifact.

""" def create_plan(product_id: str, purpose: str, overwrite: bool = False) -> Path: path = PLANS_DIR / product_id path.mkdir(parents=True, exist_ok=True) md = path / "plan.md" html = path / "plan.html" if md.exists() and not overwrite: raise FileExistsError(f"plan already exists: {md}") md.write_text(render_plan_md(product_id, purpose), encoding="utf-8") html.write_text(render_plan_html(product_id, purpose), encoding="utf-8") return md def validate_product_plan(product_id: str) -> dict: from products.plan_validator import validate_plan return validate_plan(PLANS_DIR / product_id / "plan.md", strict=True) def run_adw_pipeline(product_id: str, zte: bool = False) -> dict: try: from adw_modules.adw_pipeline import run_pipeline return run_pipeline(product_id, zte=zte) except Exception as exc: return {"ok": False, "error": str(exc), "phases": []} def latest_event(kind: str | None = None) -> dict | None: if not EVENT_DIR.exists(): return None for path in sorted(EVENT_DIR.glob("*.jsonl"), reverse=True): for line in reversed(path.read_text(encoding="utf-8").splitlines()): event = json.loads(line) if kind is None or event.get("kind") == kind: return event return None def write_receipt(product_id: str, status: str, checks_ok: bool, plan_ok: bool, deploy_route: str) -> Path: RECEIPTS_DIR.mkdir(parents=True, exist_ok=True) ts = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ") path = RECEIPTS_DIR / f"{ts}-{product_id}.json" receipt = { "product_id": product_id, "status": status, "checks_ok": checks_ok, "plan_ok": plan_ok, "deploy_route": deploy_route, "rsi_decision": RSI_DECISION, "auto_patch_proven": False, "rsi_canary_recovery_evidence": True, "rsi_evidence_receipt": RSI_EVIDENCE_RECEIPT, "local_rsi_evidence_receipt": LOCAL_RSI_EVIDENCE_RECEIPT, "rsi_claim": RSI_CLAIM, "factory_state": FACTORY_STATE, "loop_engineering": LOOP_ENGINEERING, } path.write_text(json.dumps(receipt, indent=2, ensure_ascii=False), encoding="utf-8") return path def create_product(idea: str, overwrite: bool = False) -> dict: product_id = slugify(idea) path = PRODUCTS_DIR / product_id if path.exists() and not overwrite: raise FileExistsError(f"product already exists: {product_id}") event_path = log_event("idea_received", product_id=product_id, idea=idea) path.mkdir(parents=True, exist_ok=True) plan_path = create_plan(product_id, idea, overwrite=overwrite) plan_check = validate_product_plan(product_id) spec = { "id": product_id, "idea": idea, "spine": ["plan", "build", "test", "verify", "signed-deploy", "observe", "improve"], "skills": [ "agent-chain", "agent-team", "verifier-builder", "confidence-ladder", "damage-control", "tool-call-tracer", "experiment-loop", "tilldone", ], "agents": ["planner", "builder", "reviewer", "executor", "tracker"], "deploy_actions": ["patch_skill_from_pr"], "status": "specified", "living_plan": living_plan_metadata(product_id), "plan_valid": plan_check["ok"], "singularity": { "class": 3, "grade": 3, "layer": "orchestrator-adw", "principle": "build the system that builds the system", }, } (path / "spec.json").write_text(json.dumps(spec, indent=2, ensure_ascii=False), encoding="utf-8") (path / "README.md").write_text(render_readme(spec), encoding="utf-8") log_event("product_spec_created", product_id=product_id, idea=idea, spec=str(path / "spec.json")) log_event( "plan_written", product_id=product_id, plan=str(plan_path), plan_id=product_id, plan_ref=living_plan_metadata(product_id)["plan_ref"], plan_ok=plan_check["ok"], ) log_event("adw_pipeline_started", product_id=product_id) pipeline_result = run_adw_pipeline(product_id) checks = ["plan", "build", "test", "review", "document", "ship"] checks_ok = bool(pipeline_result.get("ok")) and plan_check["ok"] log_event( "checks_run", product_id=product_id, checks=checks, checks_ok=checks_ok, plan_ok=plan_check["ok"], plan_id=product_id, plan_ref=living_plan_metadata(product_id)["plan_ref"], ) log_event("verifier_result", product_id=product_id, ok=checks_ok) deploy_route = "git-proxy:8099/deploy" log_event("deploy_action_requested", product_id=product_id, action="patch_skill_from_pr", route=deploy_route) status = "ready" if checks_ok else "needs_attention" receipt_path = write_receipt(product_id, status, checks_ok, plan_check["ok"], deploy_route) log_event("outcome", product_id=product_id, status=status, receipt=str(receipt_path)) render_dashboard() return {"product_id": product_id, "path": str(path), "plan": str(plan_path), "receipt": str(receipt_path), "event_log": str(event_path)} def render_readme(spec: dict) -> str: return f"""# {spec['id']} Idea: {spec['idea']} ## Agent spine `{' -> '.join(spec['spine'])}` ## Skills {chr(10).join(f"- `{s}`" for s in spec['skills'])} ## Deploy Only signed factory actions are allowed: {chr(10).join(f"- `{a}`" for a in spec['deploy_actions'])} ## Living plan Plan ref: `{spec['living_plan']['plan_ref']}` Deploy endpoint: `{spec['living_plan']['deploy_endpoint']}` RSI claim: {spec['living_plan']['rsi_claim']}. RSI evidence receipt: `{spec['living_plan']['rsi_evidence_receipt']}`. Local evidence mirror: `{spec['living_plan']['local_rsi_evidence_receipt']}`. ## Factory state {chr(10).join(f"- `{k}`: {v}" for k, v in spec['living_plan']['factory_state'].items())} ## Loop engineering {chr(10).join(f"- `{k}`: {v}" for k, v in spec['living_plan']['loop_engineering'].items())} ## Singularity ladder Class {spec['singularity']['class']}, Grade {spec['singularity']['grade']}: `{spec['singularity']['layer']}` Principle: {spec['singularity']['principle']}. """ def render_ladder() -> str: rows = ["| Product | Class | Grade | Agentic layer |", "|---|---:|---:|---|"] for item in load_catalog(): rows.append( f"| {item['name']} | {item.get('singularity_class', '')} | " f"{item.get('singularity_grade', '')} | {item.get('agentic_layer', '')} |" ) return "\n".join(rows) def render_dashboard() -> str: rows = [ "| Product | Price | Status | Class | Grade | Agentic layer | Skills | Deploy actions |", "|---|---:|---|---:|---:|---|---:|---|", ] for item in load_catalog(): rows.append( f"| {item['name']} | ${item.get('price', 0)} | {item.get('status', '')} | " f"{item.get('singularity_class', '')} | {item.get('singularity_grade', '')} | " f"{item.get('agentic_layer', '')} | {len(item.get('skills', []))} | " f"{', '.join(item.get('deploy_actions', [])) or 'none'} |" ) generated = sorted((PRODUCTS_DIR).glob("*/spec.json")) if PRODUCTS_DIR.exists() else [] last_check = latest_event("checks_run") outcome = latest_event("outcome") last_check_text = ( f"- `{last_check['product_id']}`: checks_ok=`{last_check.get('checks_ok')}` plan_ok=`{last_check.get('plan_ok')}` checks={', '.join(last_check.get('checks', []))}" if last_check else "- No checks logged yet" ) readiness_text = ( f"- `{outcome['product_id']}`: {outcome.get('status', 'unknown')} via signed `git-proxy:8099/deploy`; receipt={outcome.get('receipt', 'missing')}" if outcome else "- No outcome logged yet" ) text = f"""# TAC Products Dashboard {chr(10).join(rows)} ## Generated products {chr(10).join(f'- `{p.parent.name}`' for p in generated) or '- none yet'} ## Last check {last_check_text} ## Deploy readiness {readiness_text} ## Plan status - Plans live in `plans//plan.md` and must validate before build/deploy. - Amendments are append-only via `## Amendment `. ## Open risks - Do not overclaim arbitrary self-improvement; only verified canary/receipts belong here. - Legacy direct `:8098` deploy-webhook is internal/stale for guarded deploy; use `:8099/deploy`. ## Current factory truth - RSI status: live factory reports {FACTORY_STATE['latest_score']} healthy, cron + skill_health present, factory_watcher active, deploy_route present, and `auto_patch_proven=false`; `rsi_canary` recovery evidence is linked at `{RSI_EVIDENCE_RECEIPT}` and mirrored at `{LOCAL_RSI_EVIDENCE_RECEIPT}`. - Engine factory memory: {FACTORY_STATE['containers']} containers, {FACTORY_STATE['agents']} agents, {FACTORY_STATE['infra']} infra, {FACTORY_STATE['monitoring_deploy']} monitoring/deploy, {FACTORY_STATE['skills']} skills. - Commit evidence: root `{FACTORY_STATE['root_commit']}`, hermes-agent `{FACTORY_STATE['hermes_agent_commit']}`. - Deploy path must use signed actions through git-proxy `:8099/deploy`, not raw shell or direct legacy `:8098` deploy. ## Loop engineering - Loop 1 agent: ADW planner/builder/tester/reviewer/deployer phases run tools until done. - Loop 2 verification: plan validation, pytest, verifier events, and receipts gate readiness. - Loop 3 event-driven: GitHub webhooks, cron `skill_health`, JSONL events, and dashboard refresh trigger work. - Loop 4 hill-climbing: SkillOpt/skill_health can request signed patches, but broader auto-patch autonomy stays unproven without degraded-skill recovery receipts. ## Next action ```bash python products/product_factory.py "agent-powered customer support triage product" python products/product_factory.py ladder uv run --with pytest pytest -q ``` """ DASHBOARD.write_text(text, encoding="utf-8") return text def main(argv: list[str] | None = None) -> int: argv = argv or sys.argv[1:] if argv == ["dashboard"]: print(render_dashboard()) return 0 if argv == ["ladder"]: print(render_ladder()) return 0 if not argv: print("usage: python products/product_factory.py '' | dashboard | ladder", file=sys.stderr) return 2 print(json.dumps(create_product(" ".join(argv)), indent=2)) return 0 if __name__ == "__main__": raise SystemExit(main())