generated from coulomb/repo-seed
Complete State Hub bootstrap workplans (WP-0001)
- Review integration files; fill SCOPE where templated - Document dev workflow in stack-and-commands.md - Seed WP-0002 implementation workplan; mark bootstrap finished - Hub sync via fix-consistency
This commit is contained in:
418
scripts/complete_statehub_bootstrap.py
Normal file
418
scripts/complete_statehub_bootstrap.py
Normal file
@@ -0,0 +1,418 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Complete ready statehub-bootstrap workplans (T01–T03) for attached repos."""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
HOME = Path("/home/worsch")
|
||||
|
||||
REGISTRY_STACK = """## Stack
|
||||
|
||||
- **Language:** Markdown-first registry and planning repo (no application runtime yet)
|
||||
- **Key deps:** State Hub ADR-001 workplans, `registry/indexes/capabilities.yaml`
|
||||
|
||||
## Dev Commands
|
||||
|
||||
```bash
|
||||
# Orient (offline-safe)
|
||||
cat .custodian-brief.md
|
||||
cat INTENT.md
|
||||
cat SCOPE.md
|
||||
ls workplans/
|
||||
|
||||
# After workplan or registry edits — from ~/state-hub
|
||||
make fix-consistency REPO={repo_slug}
|
||||
|
||||
# Sanity-check markdown / registry edits
|
||||
git diff --check
|
||||
```
|
||||
"""
|
||||
|
||||
DOCS_STACK = """## Stack
|
||||
|
||||
- **Language:** Markdown-first control/planning repository (no application runtime)
|
||||
- **Key deps:** State Hub workplans, agent instructions, optional `registry/` scaffold
|
||||
|
||||
## Dev Commands
|
||||
|
||||
```bash
|
||||
cat .custodian-brief.md
|
||||
cat INTENT.md
|
||||
ls workplans/
|
||||
|
||||
# After workplan edits — from ~/state-hub
|
||||
make fix-consistency REPO={repo_slug}
|
||||
```
|
||||
"""
|
||||
|
||||
|
||||
def wp0002_template(
|
||||
*,
|
||||
prefix: str,
|
||||
num: str,
|
||||
slug: str,
|
||||
title: str,
|
||||
domain: str,
|
||||
repo: str,
|
||||
topic_slug: str,
|
||||
summary: str,
|
||||
task_title: str,
|
||||
task_body: str,
|
||||
) -> str:
|
||||
wid = f"{prefix}-{num}"
|
||||
return f"""---
|
||||
id: {wid}
|
||||
type: workplan
|
||||
title: "{title}"
|
||||
domain: {domain}
|
||||
repo: {repo}
|
||||
status: ready
|
||||
owner: codex
|
||||
topic_slug: {topic_slug}
|
||||
created: "2026-06-22"
|
||||
updated: "2026-06-22"
|
||||
---
|
||||
|
||||
# {title}
|
||||
|
||||
{summary}
|
||||
|
||||
## {task_title}
|
||||
|
||||
```task
|
||||
id: {wid}-T01
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
{task_body}
|
||||
"""
|
||||
|
||||
|
||||
def close_wp0001(path: Path, *, t01_note: str, t02_note: str, t03_note: str) -> None:
|
||||
text = path.read_text(encoding="utf-8")
|
||||
text = re.sub(r"^status: ready$", "status: finished", text, count=1, flags=re.M)
|
||||
text = re.sub(r"^(updated: ).*$", r'\1"2026-06-22"', text, count=1, flags=re.M)
|
||||
for tid, note in [
|
||||
("T01", t01_note),
|
||||
("T02", t02_note),
|
||||
("T03", t03_note),
|
||||
]:
|
||||
text = re.sub(
|
||||
rf"(id: [A-Z0-9-]+-{tid}\nstatus: )todo",
|
||||
r"\1done",
|
||||
text,
|
||||
count=1,
|
||||
)
|
||||
pattern = rf"(```task\nid: [A-Z0-9-]+-{tid}\nstatus: done\n.*?```)"
|
||||
block = re.search(pattern, text, re.DOTALL)
|
||||
if block and note:
|
||||
after = f"{block.group(1)}\n\nResult 2026-06-22: {note}"
|
||||
if note not in text:
|
||||
text = text.replace(block.group(1), after, 1)
|
||||
path.write_text(text, encoding="utf-8")
|
||||
|
||||
|
||||
def fill_scope_template(path: Path, *, oneliner: str, core: str, in_scope: list[str], out_scope: list[str]) -> None:
|
||||
text = path.read_text(encoding="utf-8")
|
||||
if "<!-- Describe the purpose" not in text:
|
||||
return
|
||||
in_lines = "\n".join(f"- {line}" for line in in_scope)
|
||||
out_lines = "\n".join(f"- {line}" for line in out_scope)
|
||||
replacement = f"""# SCOPE
|
||||
|
||||
> Lightweight boundary for agents and contributors.
|
||||
|
||||
---
|
||||
|
||||
## One-liner
|
||||
|
||||
{oneliner}
|
||||
|
||||
---
|
||||
|
||||
## Core Idea
|
||||
|
||||
{core}
|
||||
|
||||
---
|
||||
|
||||
## In Scope
|
||||
|
||||
{in_lines}
|
||||
|
||||
---
|
||||
|
||||
## Out of Scope
|
||||
|
||||
{out_lines}
|
||||
"""
|
||||
path.write_text(replacement + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
CONFIGS: dict[str, dict] = {
|
||||
"audit-core": {
|
||||
"stack": """## Stack
|
||||
|
||||
- **Language:** Python 3.11+
|
||||
- **Key deps:** stdlib + pytest (see `pyproject.toml`)
|
||||
|
||||
## Dev Commands
|
||||
|
||||
```bash
|
||||
# Install (editable)
|
||||
pip install -e ".[dev]" # or: python3 -m pip install pytest
|
||||
|
||||
# Run tests
|
||||
make test
|
||||
python3 -m pytest -q
|
||||
|
||||
# Mock audit backend smoke / cleanup
|
||||
make mock-audit-smoke
|
||||
make mock-audit-cleanup
|
||||
python3 -m audit_core emit --help
|
||||
```
|
||||
""",
|
||||
"wp0002": ("0002", "pluggable-audit-backend", "Pluggable audit backend contract",
|
||||
"Define the replaceable audit backend interface beyond the mock JSONL writer and document retention guarantees.",
|
||||
"Author backend interface contract",
|
||||
"Document `AuditBackend` protocol, event schema, retention policy, and migration path from the mock file backend in `docs/` or module docstrings."),
|
||||
"close_notes": ("INTENT.md and SCOPE.md reviewed; AGENTS.md and brief confirmed.", "Documented Python/pytest workflow in stack-and-commands.md.", "Created AUDIT-WP-0002."),
|
||||
},
|
||||
"binect-js": {
|
||||
"stack": """## Stack
|
||||
|
||||
- **Language:** TypeScript (ESM)
|
||||
- **Key deps:** Vitest; publishes `@binect/js`
|
||||
|
||||
## Dev Commands
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run build
|
||||
npm test
|
||||
npm run test:e2e
|
||||
npm run typecheck
|
||||
npm run clean
|
||||
```
|
||||
""",
|
||||
"wp0002": ("0002", "sdk-publication-readiness", "SDK publication and consumer validation",
|
||||
"Prepare `@binect/js` for npm publication and validate the Explorer against live API flows.",
|
||||
"Publication readiness checklist",
|
||||
"Verify build output, types, e2e tests, and document npm publish + consumer install path in README."),
|
||||
"close_notes": ("Integration files reviewed.", "Documented npm/vitest workflow.", "Created BINECT-WP-0002."),
|
||||
},
|
||||
"binect-chrome": {
|
||||
"stack": None,
|
||||
"wp0002": ("0002", "release-smoke-path", "Extension release smoke path",
|
||||
"Establish repeatable build, load-unpacked, and PDF-send smoke verification before store submission.",
|
||||
"Release smoke checklist",
|
||||
"Document and automate smoke steps: build, load `dist/`, trigger PDF detection, verify Binect upload metadata-only path."),
|
||||
"close_notes": ("SCOPE.md and INTENT.md reviewed; AGENTS.md regenerated.", "Stack commands already documented.", "Created BINECT-CHROME-WP-0002."),
|
||||
},
|
||||
"tele-mcp": {
|
||||
"stack": """## Stack
|
||||
|
||||
- **Language:** Python (FastAPI MCP bridge) + Ansible/Helm/K8s deploy assets
|
||||
- **Key deps:** FastAPI, uvicorn, httpx; kube-prometheus-stack, Loki, Promtail
|
||||
|
||||
## Dev Commands
|
||||
|
||||
```bash
|
||||
# Deploy observability stack (from repo root)
|
||||
cd ansible && ansible-playbook -i inventories/local.ini playbook.yml
|
||||
|
||||
# MCP bridge (local)
|
||||
cd mcp-telemetry-bridge
|
||||
pip install -r requirements.txt
|
||||
uvicorn app.main:app --reload --port 8080
|
||||
|
||||
# Smoke (requires cluster access)
|
||||
kubectl get pods -n monitoring
|
||||
kubectl port-forward -n mcp svc/mcp-telemetry-bridge 8080:80
|
||||
curl http://localhost:8080/healthz
|
||||
curl http://localhost:8080/mcp/schema | jq .
|
||||
```
|
||||
""",
|
||||
"wp0002": ("0002", "mcp-bridge-local-verification", "MCP bridge local verification loop",
|
||||
"Harden the local dev/test loop for `mcp-telemetry-bridge` independent of full cluster deploy.",
|
||||
"Local verification harness",
|
||||
"Add documented local run path, health/schema smoke tests, and agent-oriented quickstart in README."),
|
||||
"close_notes": ("INTENT.md, SCOPE.md, AGENTS.md reviewed.", "Documented Ansible/kubectl/uvicorn workflow.", "Created TELE-WP-0002."),
|
||||
},
|
||||
"coordination-engine": {
|
||||
"stack": REGISTRY_STACK,
|
||||
"scope": ("Framework for goal-driven digital coordination as communication.",
|
||||
"coordination-engine captures coordination models, specs, and registry entries for how actors align on shared goals.",
|
||||
["Coordination specs, history, and registry indexes", "State Hub workplans and agent instructions", "Capability registration when coordination patterns stabilize"],
|
||||
["Runtime orchestration engine implementation (future repos)", "Replacing issue trackers or chat systems"]),
|
||||
"wp0002": ("0002", "coordination-model-spec", "Coordination model specification baseline",
|
||||
"Draft the first coordination ontology and message lifecycle spec for the engine.",
|
||||
"Author coordination spec v0.1",
|
||||
"Write `spec/coordination-model-v0.1.md` covering actors, goals, commitments, and observation loops."),
|
||||
"close_notes": ("Filled SCOPE.md from INTENT.", "Registry-oriented dev workflow documented.", "Created COORDINATION-WP-0002."),
|
||||
},
|
||||
"domain-tree": {
|
||||
"stack": REGISTRY_STACK,
|
||||
"scope": ("Domain capability tree for navigating and classifying repository domains.",
|
||||
"domain-tree maintains the hierarchical view of domains, topics, and capability relationships.",
|
||||
["Domain tree registry indexes and documentation", "Alignment with State Hub domain/topic model", "Workplans for tree evolution"],
|
||||
["Owning individual domain implementations", "Replacing State Hub domain administration"]),
|
||||
"wp0002": ("0002", "domain-tree-index-foundation", "Domain tree index foundation",
|
||||
"Populate the initial domain tree registry index linked to State Hub topics.",
|
||||
"Seed domain tree index",
|
||||
"Define `registry/indexes/domain-tree.yaml` structure and seed entries for active infotech domains."),
|
||||
"close_notes": ("Filled SCOPE.md.", "Registry workflow documented.", "Created DOMAIN-WP-0002."),
|
||||
},
|
||||
"human-resources": {
|
||||
"stack": REGISTRY_STACK,
|
||||
"scope": ("Strategic human-resources planning and antifragile people-system design.",
|
||||
"human-resources captures HR intent, workflows, and registry entries for people operations amplified by automation.",
|
||||
["HR intent, policies-in-draft, and workplans", "Registry scaffold for HR capabilities", "State Hub coordination for HR initiatives"],
|
||||
["Payroll/HRIS product implementation", "Legal employment contract generation"]),
|
||||
"wp0002": ("0002", "hr-workflow-registry-scaffold", "HR workflow registry scaffold",
|
||||
"Define the first HR workflow registry entries and assessment loop.",
|
||||
"HR workflow registry draft",
|
||||
"Add initial workflow entries to `registry/` and link to INTENT phases (assessment, automation roadmap)."),
|
||||
"close_notes": ("Filled SCOPE.md from INTENT.", "Registry workflow documented.", "Created HUMAN-WP-0002."),
|
||||
},
|
||||
"open-reuse": {
|
||||
"stack": REGISTRY_STACK,
|
||||
"scope": ("Managed continuity for valuable open-source integrations.",
|
||||
"open-reuse turns proven OSS integrations into structured, maintainable assets with clear boundaries and update loops.",
|
||||
["Integration analysis docs, registry, and workplans", "Reuse modes and continuity policies", "State Hub progress and decisions"],
|
||||
["Hosting forked upstream code long-term without policy", "Replacing package registries"]),
|
||||
"wp0002": ("0002", "integration-asset-registry", "Integration asset registry foundation",
|
||||
"Establish registry format for managed OSS integration assets.",
|
||||
"Registry format v0.1",
|
||||
"Define integration asset schema in `registry/` and document analyze→classify→refactor→maintain loop."),
|
||||
"close_notes": ("Filled SCOPE.md from INTENT.md.", "Registry workflow documented.", "Created OPEN-WP-0002."),
|
||||
},
|
||||
"repo-seed": {
|
||||
"stack": REGISTRY_STACK,
|
||||
"scope": ("Git repository template to bootstrap coulomb projects.",
|
||||
"repo-seed is the canonical template for new repos: agent instructions, registry scaffold, and onboarding conventions.",
|
||||
["Template files for new repo bootstrap", "Documentation for statehub_register usage", "Registry capability entry for template capability"],
|
||||
["Application runtime code", "Owning downstream project implementations"]),
|
||||
"wp0002": ("0002", "template-validation-checklist", "Template consumer validation checklist",
|
||||
"Validate repo-seed against statehub_register output and document consumer steps.",
|
||||
"Template validation checklist",
|
||||
"Author checklist for new repo bootstrap: register, agent files, first workplan, fix-consistency."),
|
||||
"close_notes": ("Filled SCOPE.md; README is canonical intent.", "Template workflow documented.", "Created REPO-WP-0002."),
|
||||
},
|
||||
"vantage-point": {
|
||||
"stack": REGISTRY_STACK,
|
||||
"scope": ("Generic system for exploring dependency structures as network-based graph models (NBGM).",
|
||||
"Vantage Point unifies entity/relationship inspection and reasoning across arbitrary domains.",
|
||||
["NBGM specs, registry, and exploratory docs", "State Hub workplans for graph exploration features", "Alignment with repo-scoping and fabric graph models"],
|
||||
["Production graph database hosting", "Replacing railiance-fabric ingestion"]),
|
||||
"wp0002": ("0002", "nbgm-spec-baseline", "NBGM model specification baseline",
|
||||
"Author the network-based graph model specification baseline.",
|
||||
"NBGM spec v0.1",
|
||||
"Write spec covering nodes, edges, attributes, provenance, and inspection operations."),
|
||||
"close_notes": ("Filled SCOPE.md from INTENT.", "Registry workflow documented.", "Created VANTAGE-WP-0002."),
|
||||
},
|
||||
"tegwick-control": {
|
||||
"stack": DOCS_STACK,
|
||||
"wp0002": ("0002", "personal-project-intake", "Personal project intake scaffold",
|
||||
"Establish the personal control-plane intake pattern for projects and commitments.",
|
||||
"Intake scaffold",
|
||||
"Define folder/layout for `agent-tasks/`, decision log, and first prioritized workstream."),
|
||||
"close_notes": ("INTENT.md and SCOPE.md reviewed.", "Docs-oriented workflow documented.", "Created TEGWICK-WP-0002."),
|
||||
},
|
||||
"whynot-control": {
|
||||
"stack": DOCS_STACK,
|
||||
"wp0002": ("0002", "beta-signal-intake", "Beta signal intake pipeline",
|
||||
"Structure how prototype signals, betas, and feedback enter the whynot organization.",
|
||||
"Beta intake pipeline",
|
||||
"Document intake stages from prototype → beta → signal → promotion decision; seed first agent-tasks/ entries."),
|
||||
"close_notes": ("INTENT.md reviewed.", "Control-repo workflow documented.", "Created WHYNOT-WP-0002."),
|
||||
},
|
||||
"markitect-main": {
|
||||
"stack": """## Stack
|
||||
|
||||
- **Language:** Python 3.12+ (monorepo) + JavaScript UI (testdrive-jsui)
|
||||
- **Key deps:** uv/pip, pytest, npm; see `pyproject.toml`, `package.json`, `Makefile`
|
||||
|
||||
## Dev Commands
|
||||
|
||||
```bash
|
||||
make setup
|
||||
make test
|
||||
make test-js
|
||||
make test-all
|
||||
make lint
|
||||
make build
|
||||
make help
|
||||
```
|
||||
""",
|
||||
"wp0002": None,
|
||||
"close_notes": ("SCOPE.md and INTRODUCTION.md reviewed; AGENTS.md confirmed.", "Documented make-based Python/JS workflow.", "MARKITECT-WP-0002 already exists (TestDrive npm publication)."),
|
||||
},
|
||||
"whynot-design": {
|
||||
"stack": None,
|
||||
"wp0002": None,
|
||||
"close_notes": ("INTENT.md, SCOPE.md, AGENTS.md reviewed.", "Stack commands already complete.", "WHYNOT-WP-0002 already exists (designbook stack adapters)."),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def process_repo(repo_slug: str) -> None:
|
||||
repo_path = HOME / repo_slug
|
||||
wp1_files = list((repo_path / "workplans").glob("*-WP-0001-statehub-bootstrap.md"))
|
||||
if not wp1_files:
|
||||
raise SystemExit(f"No bootstrap workplan in {repo_slug}")
|
||||
wp1 = wp1_files[0]
|
||||
fm = wp1.read_text(encoding="utf-8").split("---")[1]
|
||||
domain = re.search(r"^domain:\s*(\S+)", fm, re.M).group(1)
|
||||
topic = re.search(r"^topic_slug:\s*(\S+)", fm, re.M).group(1)
|
||||
prefix = re.search(r"^id:\s*([A-Z0-9-]+)-0001", fm, re.M).group(1)
|
||||
|
||||
cfg = CONFIGS[repo_slug]
|
||||
if cfg.get("scope"):
|
||||
oneliner, core, ins, outs = cfg["scope"]
|
||||
fill_scope_template(repo_path / "SCOPE.md", oneliner=oneliner, core=core, in_scope=ins, out_scope=outs)
|
||||
|
||||
stack_path = repo_path / ".claude" / "rules" / "stack-and-commands.md"
|
||||
stack = cfg.get("stack")
|
||||
if stack:
|
||||
content = stack.format(repo_slug=repo_slug) if "{repo_slug}" in stack else stack
|
||||
stack_path.write_text(content.strip() + "\n", encoding="utf-8")
|
||||
|
||||
wp2 = cfg.get("wp0002")
|
||||
if wp2:
|
||||
num, slug, title, summary, task_title, task_body = wp2
|
||||
wp2_path = repo_path / "workplans" / f"{prefix}-{num}-{slug}.md"
|
||||
if not wp2_path.exists():
|
||||
wp2_path.write_text(
|
||||
wp0002_template(
|
||||
prefix=prefix,
|
||||
num=num,
|
||||
slug=slug,
|
||||
title=title,
|
||||
domain=domain,
|
||||
repo=repo_slug,
|
||||
topic_slug=topic,
|
||||
summary=summary,
|
||||
task_title=task_title,
|
||||
task_body=task_body,
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
n1, n2, n3 = cfg["close_notes"]
|
||||
close_wp0001(wp1, t01_note=n1, t02_note=n2, t03_note=n3)
|
||||
print(f"OK {repo_slug}")
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
repos = argv[1:] or list(CONFIGS)
|
||||
for repo in repos:
|
||||
process_repo(repo)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main(sys.argv))
|
||||
Reference in New Issue
Block a user