diff --git a/README.md b/README.md index 1526fd4..40bd559 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,4 @@ Architecture: - [Repository representation v0.1](docs/repository-representation_v0.1.md) - [Observation and command contracts v0.1](docs/observation-command-contracts_v0.1.md) +- [State Hub extraction inventory v0.1](docs/state-hub-extraction-inventory_v0.1.md) diff --git a/docs/state-hub-extraction-inventory_v0.1.md b/docs/state-hub-extraction-inventory_v0.1.md new file mode 100644 index 0000000..1291b5b --- /dev/null +++ b/docs/state-hub-extraction-inventory_v0.1.md @@ -0,0 +1,236 @@ +--- +id: RMGR-INV-EXTRACT-0001 +type: inventory +title: "State Hub → Repo Manager extraction inventory v0.1" +status: draft-reviewable +version: "0.1" +created: "2026-08-09" +updated: "2026-08-09" +workplan_task: RMGR-WP-0001-T03 +related: + - docs/repository-representation_v0.1.md + - docs/observation-command-contracts_v0.1.md + - prj-state-hub-retirement/inventory/state-hub-disposition.yaml + - prj-state-hub-retirement/architecture/child-workplan-map_v0.1.md +source_repo: state-hub +source_rev_note: "Scanned 2026-08-09 checkout; re-diff before each extract PR" +--- + +# State Hub → Repo Manager extraction inventory v0.1 + +## Purpose + +Map State Hub surfaces that implement **repository registration, host paths, +workplan parsing, consistency, reconciliation, dependencies, file mutation, and +outbox** to **keep / adapt / replace / retire** dispositions for Repo Manager, +with **compatibility test** intents. + +This is the extraction plan for RMGR-WP-0001-T03. It aligns with project +inventory SHR-INV-0001 (≈167 items already owner=`repo-manager`) and contracts +`helixforge.repo-manager` 0.1. + +**Disposition legend** + +| Value | Meaning for extraction | +| --- | --- | +| **keep** | Move substantially intact (code/path may relocate) | +| **adapt** | Keep behavior; change APIs/names to RM contracts | +| **replace** | Same need; new implementation behind RM contract | +| **retire** | Not Repo Manager's job; leave in SH until other owner, or delete | + +--- + +## A. Capability rollup (from SHR-INV + this scan) + +| Capability | SHR disposition | RM extract stance | Notes | +| --- | --- | --- | --- | +| repository-registry | move | **adapt** | `managed_repos` + register paths | +| repo-onboarding | move | **adapt** | `statehub register` / onboard | +| repo-consistency | move | **keep/adapt** | `consistency_check.py` core | +| repo-reconciliation | move | **adapt** | UI/API state-change + file writeback | +| work-records-* | move | **adapt** | Index + writeback; files stay authority | +| work-records-deps | move | **adapt** | Parse + index deps | +| register-entries / TD / EP | move | **adapt** | File registers + index | +| sbom-inventory | move | **adapt** (phase 2) | After core work index | +| upstream-contributions | move | **adapt** (phase 2) | Contrib convention | +| repo-goals | move | **adapt** (phase 2) | File or projection | +| repo-doi | move | **adapt** (phase 2) | Signal engine | +| topic-spine | replace | **retire** for RM | Domain from classification | +| work-coordination-ui | replace | **retire** (dashboard) | Not RM core | +| write-idempotency | move (hub-core in SHR) | **adapt** subset | Commands only | + +--- + +## B. Module inventory + +### B1. Registration & classification + +| ID | Source | Behavior | Disposition | Target contract | Compat tests | +| --- | --- | --- | --- | --- | --- | +| E-REG-01 | `api/models/managed_repo.py` | Repo registry row | **adapt** | `RepositorySnapshot` | Field map vs REP-0001; no topic_id required | +| E-REG-02 | `api/routers/repos.py` GET/POST/PATCH | List/create/update repos | **adapt** | `List/GetRepository`, `repo.register` | CRUD parity on slug, host_paths, remote | +| E-REG-03 | `POST /repos/{slug}/paths` (host paths) | Multi-host paths | **keep** | `repo.set_host_path` | host_id → path resolve | +| E-REG-04 | `api/classification.py` | Validate classification | **keep** | observe classification | Reject invalid vocab | +| E-REG-05 | `scripts/register_from_classification.py` | Upsert from file | **adapt** | `repo.register` + classify | Idempotent re-run | +| E-REG-06 | `statehub_register.py` | Full bootstrap + WP seed | **adapt/split** | register only; **no auto WP id collision** | Must not mint conflicting WP ids | +| E-REG-07 | `POST /repos/onboard` | Onboard helper | **adapt** | CLI `rmgr register` | Single path registration | +| E-REG-08 | `topic_id` on repos | Legacy topic link | **retire** | domain + tags | Migration script nulls topic | + +### B2. Path resolution & multi-host + +| ID | Source | Behavior | Disposition | Target | Compat tests | +| --- | --- | --- | --- | --- | --- | +| E-PATH-01 | `resolve_repo_path` in consistency_check / workplan_files | host_paths[hostname] → path | **keep** | observation host context | Override hostname env | +| E-PATH-02 | Auto-register host path in fix-consistency | Writes host_paths | **adapt** | `repo.set_host_path` explicit or opt-in | No surprise writes without flag | +| E-PATH-03 | `local_path` single field | Legacy primary path | **adapt** | primary_local_path cache | Still works if host_paths empty | + +### B3. Workplan / work-record parsing + +| ID | Source | Behavior | Disposition | Target | Compat tests | +| --- | --- | --- | --- | --- | --- | +| E-PARSE-01 | `workplan_files.py` parse frontmatter + task blocks | File → structures | **keep** | index builder | Golden files from fleet WPs | +| E-PARSE-02 | `consistency_check` parse_task_blocks / frontmatter | Same + more kinds | **keep** (merge) | single parser module | Parity with SH on sample set | +| E-PARSE-03 | Work-record kinds C-31/C-32 | Registry validation | **keep** | work-record-types canon | Sidetrack detector | +| E-PARSE-04 | Intake/decision YAML blocks | Index non-WP records | **adapt** | ListWorkRecords kinds | Register writeback ids | +| E-PARSE-05 | Dependency frontmatter C-20 | Graph edges | **adapt** | deps in index | Round-trip deps | +| E-PARSE-06 | Prefix inference `infer_wp_prefix` | WP id convention | **keep** | registration metadata | Per-repo prefix | + +### B4. Consistency engine (C-rules) + +| ID | Rules / source | Disposition | Target command | Notes / tests | +| --- | --- | --- | --- | --- | +| E-C-01 | C-01…C-02 dir/parse | **keep** | `repo.reconcile` | FAIL class | +| E-C-02 | C-03…C-06, C-09…C-12, C-15, C-19, C-22 binding/drift | **adapt** | reconcile + writeback | Rename state_hub_* → neutral ids over time | +| E-C-03 | C-07 orphan active DB | **keep** | reconcile | ADR-001 | +| E-C-04 | C-08 orphan closed | **keep** | info only | | +| E-C-05 | C-13 auto-complete signal | **adapt** | signal only | Don't auto-finish without command | +| E-C-06 | C-14 ghost duplicate | **keep** | finding | | +| E-C-07 | C-16/C-17 git behind/ahead | **keep** | gates on writeback | Must block clobber | +| E-C-08 | C-24 classification missing | **keep** | finding | | +| E-C-09 | C-26/C-27 id prefix/collision | **keep** | finding | | +| E-C-10 | C-28/C-29 **inbox** rules | **retire** from RM | hub-core messaging | Do not extract | +| E-C-11 | C-25 blocked-on inbox | **retire** from RM | hub-core | Optional signal later via port | +| E-C-12 | C-30 SCOPE current state | **adapt** (optional) | finding | Low priority | +| E-C-13 | C-33 WORK-RECORDS.md gen | **keep** | reconcile side effect | Generated index | +| E-C-14 | C-34 quality DoR soft | **adapt** (phase 2) | quality signals | | +| E-C-15 | Brief `.custodian-brief.md` gen | **adapt** | optional generator | Or hub-core orientation | + +**Primary source file:** `scripts/consistency_check.py` (~2.5k+ lines) — extract as +`repo_manager.consistency` package; CLI becomes `rmgr reconcile` implementing +`repo.reconcile`. + +### B5. File mutation & writeback + +| ID | Source | Behavior | Disposition | Target command | Compat tests | +| --- | --- | --- | --- | --- | --- | +| E-WR-01 | `_patch_frontmatter_field` / task block patch | Status writeback | **keep** | `repo.work.update_*_status` | Golden patch fixtures | +| E-WR-02 | `_git_commit_writeback` | Commit evidence | **keep** | evidence.git_sha | Commit message has correlation | +| E-WR-03 | UUID inject C-06/C-11 | Writeback ids | **adapt** | `repo.work.writeback_ids` | Idempotent inject | +| E-WR-04 | `api/routers/reconciliation.py` StateChange | Classify write-through vs deferred | **adapt** | command policy layer | Status transition matrix | +| E-WR-05 | `api/services/reconciliation.py` | Transition classes | **keep** | internal policy | Same allow/deny matrix | +| E-WR-06 | MCP `update_task_status` (SH) | REST then progress | **replace** | RM command + hub progress event | Dual-run: same file result | + +### B6. Dependencies + +| ID | Source | Disposition | Target | Tests | +| --- | --- | --- | --- | --- | +| E-DEP-01 | workplan dependency frontmatter + DB graph | **adapt** | index edges + List deps | C-20 parity | +| E-DEP-02 | `/workplan-dependencies` routes (SH) | **adapt** | port.work reads | CRUD via files first | + +### B7. Sweep / jobs + +| ID | Source | Disposition | Target | Notes | +| --- | --- | --- | --- | --- | +| E-JOB-01 | `POST /consistency/sweep/remote-all` | **adapt** | activity-core calls `repo.reconcile` per repo | Owner activity-core schedule | +| E-JOB-02 | `api/services/consistency_sweep.py` | **adapt** | thin orchestrator | No domain logic in SH | +| E-JOB-03 | `cleanup_stale_tasks` | **retire** or **adapt** later | activity-core policy | Not day-1 RM | + +### B8. Outbox / edge + +| ID | Source | Disposition | Target | Notes | +| --- | --- | --- | --- | --- | +| E-OUT-01 | `api/edge/outbox.py` | **adapt** (optional) | offline command queue | Only if RM must work offline | +| E-OUT-02 | edge relay | **retire** from RM core | hub-core / state-hub edge | Connectivity not RM | + +Prefer: offline queue is a **client/edge** concern; RM server remains online API. +If dual-run needs outbox for writebacks, adapt behind command idempotency. + +### B9. Explicitly not extracting (wrong owner) + +| Surface | Owner | Disposition | +| --- | --- | --- | +| Agent messages / inbox | hub-core | retire from extract | +| Progress events | hub-core | retire | +| Domains registry (market) | hub-core | RM only *references* domain slug | +| Suggestions / WSJF | archive | retire | +| Fabric graph | fin-hub | retire | +| Token events | hub-core | retire | +| Dashboard Observable pages | projection UI | retire | +| Execution queue | activity-core | retire | +| Service catalog | ops-hub | retire | +| Legacy workstream 410 routes | archive | retire | + +--- + +## C. Data migration notes + +| Dataset | Authority after extract | Migration | +| --- | --- | --- | +| `managed_repos` | RM projection; files for classification | Copy rows → RM DB or re-register from checkouts | +| `workplans` / `tasks` / `decisions` / `intakes` | **Files**; RM index | Rebuild from files preferred; optional UUID seed from SH | +| `workplan_dependencies` | files + index | Rebuild from frontmatter | +| `write_idempotency_keys` | RM command store | Fresh or import recent window | +| `doi_cache` | signal cache | Rebuild | + +**Preferred path:** reindex from Git rather than dump/restore task rows (fewer ghosts). Seed UUIDs from SH when frontmatter already has ids. + +--- + +## D. Compatibility test plan (minimum) + +| Suite | Covers | Pass criteria | +| --- | --- | --- | +| **T-PARSE** | E-PARSE-* | Same parse trees on 20 golden workplans from fleet | +| **T-C-RULES** | E-C-01…09,13 | Same FAIL/WARN set as SH consistency_check on fixture repos (inbox rules excluded) | +| **T-WRITEBACK** | E-WR-* | Status change → file + git_sha; idempotent replay | +| **T-HOST** | E-PATH-* | Multi-host resolution | +| **T-REGISTER** | E-REG-* | register-from-classification idempotent; no WP id collision | +| **T-RECON-MATRIX** | E-WR-04/05 | Transition matrix matches SH for task/WP statuses | +| **T-DUAL-RUN** | adapters | Same repo after SH MCP update_task_status vs RM command | + +Automate under `tests/compat/` when T04 runtime exists; fixtures can be checked in earlier. + +--- + +## E. Extraction phases (suggested) + +| Phase | Deliver | Depends | +| --- | --- | --- | +| **P0** | Parser + reconcile CLI (read-only) | T01/T02 done | +| **P1** | Registry + host_paths + register-from-classification | P0 | +| **P2** | Writeback commands + git evidence | P1, T04 runtime | +| **P3** | Dual-run adapter for SH MCP/CLI | P2 | +| **P4** | SBOM/contrib/DOI/goals | after P3 stable | +| **P5** | SH strangler (STATE-WP-0079) cutover | P3 | + +--- + +## F. Risks + +| Risk | Mitigation | +| --- | --- | +| consistency_check monolith size | Extract package; keep CLI wrapper in SH during dual-run | +| UUID field rename (`state_hub_*`) | Accept both; write neutral fields; meter old | +| `statehub register` WP collision | Fixed policy in E-REG-06; never auto RMGR-WP-0001 style seed | +| Inbox C-rules pulled into RM | Explicit retire E-C-10/11 | +| Ghost workstreams | Prefer file rebuild; C-07/C-14 tests | + +--- + +## Acceptance (T03) + +- [x] Registration, host-path, parsing, consistency, reconciliation, deps, mutation, outbox covered +- [x] keep/adapt/replace/retire per candidate +- [x] Compatibility test suites named +- [x] Phased extraction order +- [x] Explicit non-extract list diff --git a/docs/state-hub-extraction-inventory_v0.1.yaml b/docs/state-hub-extraction-inventory_v0.1.yaml new file mode 100644 index 0000000..6964bc8 --- /dev/null +++ b/docs/state-hub-extraction-inventory_v0.1.yaml @@ -0,0 +1,144 @@ +# RMGR-INV-EXTRACT-0001 +id: RMGR-INV-EXTRACT-0001 +version: "0.1" +status: draft-reviewable +created: "2026-08-09" +document: docs/state-hub-extraction-inventory_v0.1.md +workplan_task: RMGR-WP-0001-T03 +source_repo: state-hub + +candidates: + - id: E-REG-01 + source: api/models/managed_repo.py + area: registration + disposition: adapt + contract: RepositorySnapshot + - id: E-REG-02 + source: api/routers/repos.py + area: registration + disposition: adapt + contract: [GetRepository, ListRepositories, repo.register] + - id: E-REG-03 + source: POST /repos/{slug}/paths + area: host_paths + disposition: keep + contract: repo.set_host_path + - id: E-REG-04 + source: api/classification.py + area: classification + disposition: keep + - id: E-REG-05 + source: scripts/register_from_classification.py + area: registration + disposition: adapt + - id: E-REG-06 + source: statehub_register.py + area: onboarding + disposition: adapt + notes: split register from workplan seed; no id collision + - id: E-REG-07 + source: POST /repos/onboard + area: onboarding + disposition: adapt + - id: E-REG-08 + source: managed_repos.topic_id + area: registration + disposition: retire + - id: E-PATH-01 + source: resolve_repo_path + area: host_paths + disposition: keep + - id: E-PATH-02 + source: auto host_paths in fix-consistency + area: host_paths + disposition: adapt + - id: E-PARSE-01 + source: api/services/workplan_files.py + area: parsing + disposition: keep + - id: E-PARSE-02 + source: scripts/consistency_check.py parsers + area: parsing + disposition: keep + - id: E-PARSE-03 + source: C-31 work-record registry + area: parsing + disposition: keep + - id: E-C-CORE + source: scripts/consistency_check.py C-01..C-27 (minus inbox) + area: consistency + disposition: keep + contract: repo.reconcile + - id: E-C-INBOX + source: C-28 C-29 C-25 + area: consistency + disposition: retire + owner: hub-core + - id: E-C-33 + source: WORK-RECORDS.md generator + area: consistency + disposition: keep + - id: E-WR-01 + source: frontmatter/task patch helpers + area: file_mutation + disposition: keep + contract: repo.work.update_task_status + - id: E-WR-02 + source: _git_commit_writeback + area: file_mutation + disposition: keep + - id: E-WR-03 + source: UUID inject writeback + area: file_mutation + disposition: adapt + contract: repo.work.writeback_ids + - id: E-WR-04 + source: api/routers/reconciliation.py + area: reconciliation + disposition: adapt + - id: E-WR-05 + source: api/services/reconciliation.py + area: reconciliation + disposition: keep + - id: E-DEP-01 + source: workplan dependencies + area: dependencies + disposition: adapt + - id: E-JOB-01 + source: POST /consistency/sweep/remote-all + area: jobs + disposition: adapt + owner_executor: activity-core + - id: E-OUT-01 + source: api/edge/outbox.py + area: outbox + disposition: adapt + notes: optional offline; prefer edge/client + - id: E-OUT-02 + source: api/edge/relay.py + area: outbox + disposition: retire + owner: hub-core-or-state-hub-edge + +compat_suites: + - T-PARSE + - T-C-RULES + - T-WRITEBACK + - T-HOST + - T-REGISTER + - T-RECON-MATRIX + - T-DUAL-RUN + +phases: + - id: P0 + name: parser_and_reconcile_readonly + - id: P1 + name: registry_and_host_paths + - id: P2 + name: writeback_commands + - id: P3 + name: dual_run_adapter + - id: P4 + name: sbom_contrib_doi_goals + - id: P5 + name: state_hub_strangler_cutover diff --git a/workplans/RMGR-WP-0001-foundation.md b/workplans/RMGR-WP-0001-foundation.md index ef3d55f..8c86575 100644 --- a/workplans/RMGR-WP-0001-foundation.md +++ b/workplans/RMGR-WP-0001-foundation.md @@ -69,7 +69,7 @@ Runtime OpenAPI deferred to T04/T05. ```task id: RMGR-WP-0001-T03 -status: todo +status: done priority: high state_hub_task_id: "deee10be-25e1-4ee7-b47e-93dc816916c9" ``` @@ -78,6 +78,10 @@ Map relevant State Hub repository registration, host-path, workplan parsing, consistency, reconciliation, dependency, file-mutation, and outbox behavior to keep/adapt/replace/retire dispositions with compatibility tests. +**Result (2026-08-09):** `docs/state-hub-extraction-inventory_v0.1.md` + YAML +(RMGR-INV-EXTRACT-0001). Module candidates E-REG/PATH/PARSE/C/WR/DEP/JOB/OUT; +inbox C-rules retired from RM; phases P0–P5; compat suites T-PARSE…T-DUAL-RUN. + ## Select the implementation foundation ```task @@ -110,6 +114,6 @@ projection. - [x] The authority and data model are explicit. - [x] Observation and command contracts are versioned and testable. - (semantics + catalog done; automated suite with runtime in T04/T05) -- [ ] State Hub extraction candidates have dispositions. +- [x] State Hub extraction candidates have dispositions. - [ ] The implementation foundation has a recorded decision. - [ ] One repository completes the end-to-end vertical slice.