--- id: REUSE-WP-0016 type: workplan title: "Interactive registry maintain with llm-connect automation" domain: helix_forge repo: reuse-surface status: finished owner: codex topic_slug: helix-forge created: "2026-06-16" updated: "2026-06-17" state_hub_workstream_id: "2a7565a4-2627-44ca-a856-6c3f18576f92" --- # Interactive registry maintain with llm-connect automation Follow-up to **REUSE-WP-0013** (`establish`, `update`, `stats`). Workstation rollout (**REUSE-WP-0014**) gave every sibling repo a registry scaffold; operators still maintain entries manually or run `reuse-surface update` as a **non-interactive report**. LLM maturity hints (`--suggest-maturity`) dump JSON for human review with no apply path. This workplan closes the **registry maintenance loop** from inside each domain repo: interactive prompting for judgment calls, full automation for safe and high-confidence changes, both backed by the existing **llm-connect** HTTP bridge. **Baseline vector:** `D5 / A4 / C5 / R3` **Target vector:** `D5 / A4 / C5–C6 / R3` (tooling depth; reliability unchanged until consumer telemetry program) ## Problem statement | Pain | Today (WP-0013) | Target | |---|---|---| | Update registry after code changes | `update` prints suggestions; user must remember `--apply` | Guided session with per-change prompts | | Maturity / evidence refresh | `--suggest-maturity` → JSON only | Structured LLM patches with review or auto-apply | | Publish hygiene | Manual validate → commit → publish-check | `maintain` chains update → validate → optional publish-check | | Agent vs human UX | Same stdout for both | TTY prompts for humans; JSON/event stream for agents | | Sibling repo friction | `validate` defaults to install root | Auto-detect `registry/` in cwd | ## Design principles 1. **Deterministic first** — vector drift, missing index rows, and cited artifact paths apply without LLM; same safe-apply list as WP-0013-T06, extended. 2. **Interactive by default in TTY** — `reuse-surface maintain` prompts before any non-deterministic write; non-TTY requires `--yes` or `--auto`. 3. **Full automation is explicit** — `--auto` applies deterministic patches plus LLM proposals that pass schema validation and evidence gates; never silent promotion above configured ceilings (default: no auto D/A/C/R jumps > 1 level). 4. **LLM optional** — deterministic-only paths work without `LLM_CONNECT_URL`; LLM steps skip gracefully with a clear message. 5. **Validate gate** — every write path ends with `reuse-surface validate --root `; failed validation rolls back the session batch (atomic apply). 6. **Evidence-bound promotions** — auto-apply for maturity changes requires cited repo paths (tests, workflows, docs) present on disk; align checks with `specs/CapabilityMaturityStandard.md`. 7. **Boundary** — reuse-surface does not host models; llm-connect owns routing and credentials (`POST {LLM_CONNECT_URL}/execute`). ## Proposed CLI surface ```bash # Interactive maintain (default in TTY) cd ~/state-hub export LLM_CONNECT_URL=http://127.0.0.1:8088 # optional reuse-surface maintain reuse-surface maintain --from-git-since origin/main reuse-surface maintain --capability capability.statehub.workstream-coordinate # Full automation (CI, agents, pre-commit) reuse-surface maintain --auto --from-git-since HEAD~1 reuse-surface maintain --auto --no-llm # deterministic only # Non-interactive apply-all-safe (current update behavior, preserved) reuse-surface update --all --from-git-since origin/main --apply # Federation publish helper (chains maintain + validate + publish-check) reuse-surface maintain --publish --raw-url https://gitea.../capabilities.yaml ``` ### Interactive prompt flow (TTY) ```text reuse-surface maintain → collect repo signals (git diff, index drift, roster stats) → deterministic suggestions (always listed first) → optional LLM patch proposals per capability (llm-connect) → for each pending change: [a]pply [s]kip [e]dit in $EDITOR [q]uit [A]pply all safe → atomic write + validate → summary: files changed, remaining manual items, publish reminder ``` ### Automation tiers (`--auto`) | Tier | Applies without prompt | |---|---| | `safe` | Deterministic patches (vector drift, evidence path append) | | `llm-metadata` | LLM `consumer_feedback`, `notes`, non-level field updates | | `llm-promote` | Single-step maturity bumps with on-disk evidence citations | Configure ceiling via `--auto-max-delta 1` (default) or `--auto-max-delta 0` to disable promotions. ## Suggested execution order ```text T01 registry-patch JSON schema + LLM prompt templates → T02 expand deterministic signal collectors → T03 interactive prompt module (TTY + non-TTY) → T04 maintain command (orchestrator) → T05 LLM patch apply path with evidence gates → T06 --auto mode + atomic batch apply/rollback → T07 validate cwd auto-detect; index.updated bump → T08 sibling integration (Makefile template, optional hook generator) → T09 docs, tests, gap-analysis priority 28 ``` ## Dependencies | Dependency | Owner | Notes | |---|---|---| | llm-connect | llm-connect | `LLM_CONNECT_URL`; mocked in pytest | | WP-0013 modules | reuse-surface | `registry_update.py`, `llm_bridge.py`, `establish.py` | | Maturity standard | reuse-surface | Promotion evidence rules in prompts and gates | | Sibling repo adoption | Domain owners | Run `maintain` in each checkout; optional CI step | --- ## Add Registry Patch Schema And LLM Templates ```task id: REUSE-WP-0016-T01 status: done priority: high state_hub_task_id: "f5daf384-ca4e-42ec-8530-bf5d46155284" ``` Define `schemas/registry-patch.schema.json` for structured update proposals (consumed by interactive and `--auto` paths): - `patches[]`: `{ capability_id, kind, confidence, rationale, field_path, value | append, promotion_history_entry }` - `kinds`: `vector_sync`, `evidence_append`, `artifact_append`, `maturity_promote`, `consumer_feedback`, `relation_add`, `index_row_add` - `evidence_citations[]`: repo-relative paths supporting each patch Add prompt builders in `reuse_surface/registry_update.py` (or `reuse_surface/maintain_llm.py`): - `build_maintain_prompt(repo_root, capability_id, git_since, context_files)` - Schema-constrained JSON via `request_json_object` + validator - Reuse maturity level definitions from `CapabilityMaturityStandard.md` in prompt context (summary table, not full doc) Pytest: fixture repo + mocked llm-connect returning valid/invalid patches. ## Expand Deterministic Signal Collectors ```task id: REUSE-WP-0016-T02 status: done priority: high state_hub_task_id: "55e6d943-6237-4332-9b01-2fa42aceff1f" ``` Extend `collect_deterministic_suggestions` in `registry_update.py`: | Signal | Suggested field | |---|---| | `.gitea/workflows/*.yml` changed | `evidence.tests` or `evidence.documentation` | | `docs/**` changed | `evidence.documentation` | | `pyproject.toml` / `[project.scripts]` added | `availability.current_artifacts` | | New `registry/capabilities/*.md` without index row | `index_row_add` patch | | `index.updated` stale vs last git touch on `registry/` | bump `updated` date | | Missing entry file for index row | `missing_entry` (blocking warning) | Keep `--apply` safe-list explicit in code (document in module docstring). Add regression tests in `tests/test_registry_update.py`. ## Implement Interactive Prompt Module ```task id: REUSE-WP-0016-T03 status: done priority: high state_hub_task_id: "fe3a2e99-8c40-48a7-9d70-0e92b48146d2" ``` New module `reuse_surface/interactive.py`: - Detect TTY (`sys.stdin.isatty()`) - `prompt_patch(patch) -> Literal["apply","skip","edit","quit"]` with short summary (kind, capability_id, rationale, field preview) - `prompt_batch(patches) -> list[patch]` supporting **Apply all safe** for deterministic kinds only - Non-TTY: raise unless `assume_yes` / `auto_mode` set; emit JSON lines (`{"event":"suggestion",...}`) for agent consumers - Optional `$EDITOR` flow: write temp YAML snippet, re-parse on save No llm-connect dependency. Pytest with stdin mocked via `io.StringIO`. ## Implement maintain Command ```task id: REUSE-WP-0016-T04 status: done priority: high state_hub_task_id: "6e3a7b3d-1037-49ed-ad7c-341d21c333da" ``` Add `reuse-surface maintain` in `cli.py` (or alias `update --interactive` if prefer fewer top-level verbs — default to **`maintain`** as the user-facing entry point): **Flags:** | Flag | Purpose | |---|---| | `--path` | Repo root (default cwd) | | `--capability` / `--all` | Scope | | `--from-git-since` | Git ref for change detection | | `--llm-url` | Override `LLM_CONNECT_URL` | | `--no-llm` | Skip LLM phase | | `--publish` | Run `establish --publish-check` after successful validate | | `--raw-url` | Required when `--publish` | | `--format json` | Machine-readable session result | **Flow:** 1. Run T02 collectors 2. If LLM enabled: run T01 prompts per capability in scope 3. Merge deterministic + LLM into ordered patch list (deterministic first) 4. T03 interactive selection (unless `--auto` — T06) 5. T05 apply + T06 atomic validate Preserve existing `update` command unchanged for scripting backward compatibility. ## LLM Patch Apply Path With Evidence Gates ```task id: REUSE-WP-0016-T05 status: done priority: medium state_hub_task_id: "f0baa772-b7f0-4143-9fd9-9c96db17f532" ``` Implement `apply_patches(repo_root, patches) -> list[str]`: - Reuse `apply_deterministic_suggestions` for overlapping kinds - New writers: `promotion_history` append, `maturity.*.current` with vector sync to index, `consumer_feedback` append, `relations.*` append (optional v1) - **Evidence gate:** for `maturity_promote`, require every `evidence_citations` path to exist under `repo_root`; reject patch if not - **Level gate:** refuse promotion if delta > `--auto-max-delta` unless interactive user confirms - Bump `registry/indexes/capabilities.yaml` `updated` field on any write Pytest: promote with/without evidence files; vector/index consistency after apply. ## Implement --auto Mode And Atomic Batch ```task id: REUSE-WP-0016-T06 status: done priority: medium state_hub_task_id: "bd8f6243-24a3-44f8-9824-4cc2518ad8d9" ``` `maintain --auto`: - Apply all `safe` deterministic patches - Apply LLM patches with `confidence >= --auto-confidence` (default `high`) and passing evidence gates - `--auto-max-delta` (default `1`) caps promotion steps per dimension per session - `--yes` on non-TTY equivalent to `--auto` with default thresholds **Atomic batch:** write all entry/index changes to temp files under `.reuse-surface-session/`; on validate success, rename into place; on failure, discard and print validator errors. Exit codes: `0` ok, `1` validation/schema failure, `2` partial skip (no writes). ## Validate Cwd Auto-Detect And Publish Helper ```task id: REUSE-WP-0016-T07 status: done priority: low state_hub_task_id: "a61c0843-f44b-4e75-9043-7d042087e015" ``` - When `--root` / `--path` omitted and `./registry/indexes/capabilities.yaml` exists, default repo root to cwd (validate, update, maintain, stats) - `maintain --publish --raw-url` chains: maintain session → validate → `establish.publish_check` → print pass/fail markdown - Document raw URL convention in session summary when `REUSE_SURFACE_RAW_URL` set ## Sibling Integration Templates ```task id: REUSE-WP-0016-T08 status: done priority: low state_hub_task_id: "ec2d58a3-c797-464b-9fb3-464f71360c9c" ``` Ship copy-paste artifacts (not installed into sibling repos automatically): - `templates/Makefile.registry.fragment` — `registry-maintain`, `registry-check` - `templates/git-hook.pre-commit.registry` — `maintain --auto --no-llm` when `registry/` changed - `establish --scaffold` append: optional `--hook` writes `.git/hooks/pre-commit` (refuse overwrite unless `--force`) Dogfood: run against `state-hub` checkout when available. ## Documentation, Tests, And Gap Note ```task id: REUSE-WP-0016-T09 status: done priority: low state_hub_task_id: "85f8f549-7df9-493c-b43b-f1b67af3ee6c" ``` - `tools/README.md` — `maintain` command reference; interactive vs `--auto` - `docs/RegistryFederation.md` — link maintain + publish to sibling onboarding - `registry/README.md` — operator checklist after `maintain` session - `docs/IntentScopeGapAnalysis.md` — add priority **28** (registry maintenance automation); mark open - `SCOPE.md` — extend "What Is Possible Now" when T04 ships - CI: `maintain --auto --no-llm` on reuse-surface self-registry (informational or gated); no live llm-connect in CI - Pytest count increase; `reuse-surface validate` unchanged for default path --- ## Acceptance - [x] `reuse-surface maintain` in TTY walks through suggestions with apply/skip/edit - [x] `maintain --auto --no-llm` applies deterministic patches and validates atomically - [x] LLM patches apply only with schema validation + evidence gates - [x] `maintain --publish --raw-url` reports federation publish pass/fail - [x] Non-TTY without `--auto`/`--yes` fails with clear message (no silent writes) - [x] `validate` defaults to cwd when local `registry/` index exists - [x] All new behavior documented; gap priority 28 recorded ## Completion notes (2026-06-17) - Modules: `maintain.py`, `maintain_llm.py`, `patches.py`, `interactive.py` - Schema: `schemas/registry-patch.schema.json` - Templates: `templates/Makefile.registry.fragment`, `templates/git-hook.pre-commit.registry` - CLI: `reuse-surface maintain`; `establish --scaffold --hook` - Tests: `tests/test_maintain.py`, `tests/test_interactive.py` (59 pytest total) ## Out of scope - Hub cache invalidation webhooks (gap priority from §3.1 — separate workplan) - Auto `hub register` (still operator step with token) - Embedding / ML overlap detection (keep `overlaps` heuristic) - llm-connect hosting or provider configuration inside reuse-surface - Fully unattended maturity promotion without evidence citations ## Dogfood target From `~/state-hub` (or any roster repo with `publish_check: pass`): ```bash export LLM_CONNECT_URL=http://127.0.0.1:8088 reuse-surface maintain --from-git-since origin/main reuse-surface maintain --auto --from-git-since HEAD~3 reuse-surface maintain --publish \ --raw-url https://gitea.coulomb.social/coulomb/state-hub/raw/main/registry/indexes/capabilities.yaml ``` Success: registry files updated, `validate --root .` passes, publish-check 200.