repo-manager/docs/adr-001-implementation-foundation.md
tegwick e02f5a258a docs(RMGR-WP-0001): complete T04 implementation foundation
Accept ADR-001: Python 3.12, FastAPI, Postgres/SQLAlchemy async, src layout,
uv/hatchling, pytest. Scaffold package, rmgr CLI stub, and version tests.
2026-08-09 22:41:26 +02:00

6.5 KiB
Raw Blame History

id type title status decided workplan_task deciders related
RMGR-ADR-001 architecture-decision-record Implementation foundation for Repo Manager accepted 2026-08-09 RMGR-WP-0001-T04
codex
project-convention
docs/repository-representation_v0.1.md
docs/observation-command-contracts_v0.1.md
docs/state-hub-extraction-inventory_v0.1.md
INTENT.md

ADR-001: Implementation foundation for Repo Manager

Status

Accepted (2026-08-09).

Context

RMGR-WP-0001 requires a runtime, persistence, packaging, migration, test, and deployment shape before substantial extraction from State Hub (T03 phases P0P5, T05 E2E). Choices must match ordinary HelixForge services so dual-run, operators, and agents do not face a one-off stack.

Reference platforms:

Repo Role Stack
state-hub Current repo index + consistency (extract source) Python 3.12, FastAPI, SQLAlchemy async, asyncpg, Alembic, uv, FastMCP
hub-core Shared library Python 3.12, FastAPI/SQLAlchemy primitives, hatchling
core-hub Production hub runtime Same + Docker/k8s
activity-core Schedulers/executors Python, FastAPI, SQLAlchemy async, Alembic, Temporal (domain-specific)

Repo Manager is a functional component (not a domain hub): service + CLI, own data plane for projections, Git as file authority.

Decision

1. Language and packaging

Choice Decision
Language Python 3.12+
Layout src/repo_manager/ (src-layout, hatchling)
Distribution Installable package repo-manager / import repo_manager
Tooling uv + Makefile (fleet norm)
Lint (phase 2) ruff (align with core-hub when CI lands)

2. Runtime surface

Choice Decision
HTTP API FastAPI (async) implementing helixforge.repo-manager 0.1
ASGI server uvicorn
Settings pydantic-settings
DTOs Pydantic v2 only at API boundary (no ORM leakage)
CLI Entry point rmgr (repo_manager.cli) — reconcile, register, later command
MCP Not day-1 — agents keep State Hub / hub-core MCP until dual-run; optional FastMCP adapter in a later WP
Schedulers None in-process — activity-core calls reconcile HTTP/CLI

3. Persistence

Choice Decision
Database PostgreSQL 16 (CNPG/fleet); dedicated DB/schema repo_manager
ORM SQLAlchemy 2.x asyncio + asyncpg
Migrations Alembic under src/repo_manager/migrations/ or repo-root migrations/
Metadata Own Base — never mix with hub-core or state-hub metadata (isolation)
SQLite Dev/test only optional via aiosqlite; production is Postgres

Rationale: Separate DB from State Hub so cutover does not share write contention or schema ownership. Files remain authority for work records; Postgres holds registry, index, findings, command/idempotency logs.

4. Git and files

Choice Decision
Git operations subprocess git (parity with consistency_check extract)
Parsing Port/adapt SH parsers → repo_manager.parse
Writeback Same commit evidence rules as contracts (git_sha required)

Avoid new Git bindings (GitPython) until a concrete need; subprocess matches extract source and SSH/forge setups already in production images.

5. Events and integration

Choice Decision
hub-core dependency Optional path/editable for utils only (slug/pagination) if useful; no shared tables
NATS Optional later — emit HTTP hooks or in-process event bus first; nats-py when hub-core event bus is standard
Authz Call hub-core policy port when available; dev allowlist scopes for local

6. Testing

Choice Decision
Runner pytest + pytest-asyncio (asyncio_mode = auto)
Unit parsers, transition matrix, DTOs
Integration Postgres test DB or ephemeral container; git fixtures in tests/fixtures/repos/
Compat Suites T-PARSE…T-DUAL-RUN from extraction inventory

7. Deployment

Choice Decision
Container Dockerfile (python:3.12-slim + git + openssh-client + uv) modeled on state-hub
Local make db migrate api / make test
Cluster Later Helm under railiance (not blocking T05); single replica first
Secrets DATABASE_URL / policy tokens via env or platform custody — never in repo

8. Initial package modules (target)

src/repo_manager/
  __init__.py
  config.py
  db.py                 # engine, session, Base
  models/               # private ORM
  schemas/              # public Pydantic DTOs
  api/                  # FastAPI routers
  parse/                # workplan/work-record parsers
  consistency/          # C-rules engine (extract)
  commands/             # command handlers
  gitops/               # subprocess git helpers
  cli.py
migrations/
tests/
pyproject.toml
Makefile
Dockerfile              # with first deployable slice

9. Explicit non-choices

Rejected Why
Haskell / IHP Retired path; fleet is Python for this class of service
Sharing State Hub database long-term Confuses authority and cutover
Embedding Temporal activity-core owns schedules
Day-1 full MCP surface Dual-run via existing SH tools first
Calling Repo Manager a hub Taxonomy: functional component

Consequences

Positive

  • Operators and extract PRs stay on known stack.
  • Clear dual-run: SH and RM side by side with same Git authority.
  • CLI rmgr reconcile can replace statehub fix-consistency gradually.

Negative / cost

  • Another Postgres database and migration chain to operate.
  • Temporary dual registration until SH registry is strangler-cut.

Follow-ons

  • T05: E2E on repo-manager itself (or a fixture repo) using P0/P1 slices.
  • STATE-WP-0079: point fix-consistency / MCP writebacks at RM adapters.
  • Optional: publish OpenAPI for helixforge.repo-manager 0.1 from FastAPI.

Compliance with prior docs

Doc How this ADR satisfies it
REP-0001 ORM private; snapshots are DTOs
CMD-0001 FastAPI + CLI implement observation/commands
EXTRACT-0001 Phases P0P2 map to modules above

Acceptance (T04)

  • Runtime chosen (FastAPI/uvicorn, Python 3.12)
  • Persistence chosen (Postgres + SQLAlchemy async + Alembic, own DB)
  • Package/layout chosen (src/repo_manager, uv, hatchling)
  • Test approach chosen (pytest-asyncio + fixtures)
  • Deploy approach chosen (Docker, make; Helm later)
  • Non-goals recorded