This repository has been archived on 2026-07-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
the-custodian/workplans/CUST-WP-0007-gems-migration.md
tegwick 8ab6e6c9c5 feat(gems): three-pass schema migration aligning state-hub with GEMS
Implements CUST-WP-0007. Resolves inconsistencies I-1, I-2, I-5, I-6
identified in the GEMS audit (GenericEntityModellingSystem.md).

Pass 1 (e1f2a3b4c5d6): domain_id FK on extension_points and
technical_debt (replaces raw string column); repo_id FK on contributions.
Fixes domain-filtering bugs in EP/TD dashboard pages.

Pass 2 (f2a3b4c5d6e7): repo_id nullable FK on workstreams, aligning
the GEMS primary attachment with ADR-001 (repo > topic). Dashboard
pages updated to prefer repo->domain over topic->domain.

Pass 3 (a3b4c5d6e7f8): SBOMSnapshot container entity (GEMS Complex
between Repository and SBOMEntry). Ingest is now additive — each call
creates a new snapshot; history is retained. List/report endpoints
filter to latest snapshot per repo via _latest_snapshot_ids_subquery().
New endpoints: GET /sbom/snapshots/, GET /sbom/snapshots/{id}/.
Dashboard gains a Snapshot History section.

Also adds GEMS analysis artefacts: wiki/GEMS-StateHub-TypeRegistry.md,
wiki/GEMS-StateHub-SWOT.md, workplans/CUST-WP-0006 (analysis),
workplans/CUST-WP-0007 (migration, now completed).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 23:39:17 +01:00

6.5 KiB

id, type, title, domain, status, owner, topic_slug, repo_slug, created, updated, state_hub_workstream_id
id type title domain status owner topic_slug repo_slug created updated state_hub_workstream_id
CUST-WP-0007 workplan GEMS Migration — Three-Pass State-Hub Alignment custodian completed custodian the-custodian the-custodian 2026-03-02 2026-03-02 22e18151-fc83-438c-b732-10e056e64a20

CUST-WP-0007 — GEMS Migration: Three-Pass State-Hub Alignment

Implements the migration decided in CUST-WP-0006. Fixes all structural inconsistencies identified in the GEMS audit (I-1 through I-6) in three independently releasable passes.

Decisions resolved: DEC-GEMS-001 (Option C), DEC-GEMS-002, DEC-GEMS-003, DEC-GEMS-004. DEC-GEMS-005 and DEC-GEMS-006 deferred.


Pass 1 — Fix Domain FK Inconsistencies

Scope: Resolve I-1 and I-6. No API breaking changes. Fixes observable dashboard domain-filtering bugs on EP/TD pages.

Alembic migration ID: e1f2a3b4c5d6 (down_revision: d3e4f5a6b7c8)

Task T01: Alembic migration — Pass 1

id: T01
status: done
priority: critical
assignee: custodian

Operations:

  1. Add domain_id UUID FK (nullable) to extension_points
  2. Add domain_id UUID FK (nullable) to technical_debt
  3. Add repo_id UUID FK (nullable) to contributions
  4. Backfill extension_points.domain_id from domains.slug match
  5. Backfill technical_debt.domain_id from domains.slug match
  6. Make domain_id NOT NULL on both tables (all rows must be backfilled first)
  7. Drop domain String column from extension_points
  8. Drop domain String column from technical_debt

Task T02: Update ExtensionPoint and TechnicalDebt models

id: T02
status: done
priority: critical
assignee: custodian

Replace domain: Mapped[str] with domain_id: Mapped[uuid.UUID] FK + domain: Mapped["Domain"] relationship. Add domain_slug property.

Task T03: Update Contribution model

id: T03
status: done
priority: high
assignee: custodian

Add repo_id: Mapped[uuid.UUID | None] nullable FK to managed_repos.

Task T04: Update EP and TD routers

id: T04
status: done
priority: high
assignee: custodian
  • Filter by domain_id FK instead of domain string
  • Accept domain slug in create/filter params, resolve to domain_id

Task T05: Update MCP EP/TD tools

id: T05
status: done
priority: high
assignee: custodian

register_extension_point and register_technical_debt still accept domain as a slug string. Router resolves to domain_id FK.

Task T06: Update EP/TD dashboard pages

id: T06
status: done
priority: medium
assignee: custodian

extensions.md and techdept.md load domain list from /domains/ API and use domain_id FK for filtering. Remove reliance on string comparison.


Pass 2 — Align Workstream with ADR-001

Scope: Resolve I-2. Breaking change to workstream schema. topic_id becomes a nullable secondary annotation; repo_id becomes the primary FK. Workplan frontmatter format gains repo_slug field.

Alembic migration ID: f2a3b4c5d6e7 (down_revision: e1f2a3b4c5d6)

Task T07: Alembic migration — Pass 2

id: T07
status: done
priority: critical
assignee: custodian

Operations:

  1. Add repo_id UUID FK (nullable) to workstreams
  2. Backfill repo_id using heuristic: workstream → topic → domain → first repo for that domain (adequate for current data; all custodian workstreams map to the-custodian repo)
  3. For topics without a repo: leave nullable (MCP tooling handles this)

Task T08: Update Workstream model

id: T08
status: done
priority: critical
assignee: custodian

Add repo_id: Mapped[uuid.UUID | None] nullable FK to managed_repos. Keep topic_id as nullable secondary. Add repo relationship.

Task T09: Update workstream router and MCP tools

id: T09
status: done
priority: high
assignee: custodian
  • create_workstream MCP tool: add optional repo_id / repo_slug param
  • Workstream read schema: expose repo_id and repo_slug
  • Dependency resolution in state/summary uses repo.domain when available

Task T10: Update workplan frontmatter format

id: T10
status: done
priority: high
assignee: custodian

Add repo_slug field to ADR-001 workplan frontmatter spec. Update existing workplan files (CUST-WP-0001 through CUST-WP-0006) to include repo_slug.

Task T11: Update Dependencies dashboard domain resolution

id: T11
status: done
priority: high
assignee: custodian

dependencies.md currently resolves domain via topicMap[w.topic_id]?.domain_slug. Change to prefer wsMap[w.id]?.repo?.domain_slug when available.


Pass 3 — SBOMSnapshot Container

Scope: Resolve I-5. Adds sbom_snapshots as a container entity between Repository and SBOMEntry. Enables snapshot history and diff queries.

Alembic migration ID: a3b4c5d6e7f8 (down_revision: f2a3b4c5d6e7)

Task T12: Alembic migration — Pass 3

id: T12
status: done
priority: critical
assignee: custodian

Operations:

  1. Create sbom_snapshots table (id, repo_id FK, snapshot_at, source, created_at)
  2. Add snapshot_id UUID FK (nullable) to sbom_entries
  3. Backfill: for each (repo_id, snapshot_at) group in sbom_entries, create one sbom_snapshots row; set snapshot_id on all matching entries
  4. Make snapshot_id NOT NULL on sbom_entries
  5. Consider: drop repo_id from sbom_entries (reachable via snapshot)

Task T13: Add SBOMSnapshot model

id: T13
status: done
priority: critical
assignee: custodian

New model api/models/sbom_snapshot.py with FK to managed_repos.

Task T14: Update SBOMEntry model

id: T14
status: done
priority: critical
assignee: custodian

Add snapshot_id FK to sbom_snapshots. Update repo relationship to go via snapshot.

Task T15: Update SBOM router and ingest API

id: T15
status: done
priority: high
assignee: custodian
  • Ingest creates/finds a snapshot record, then creates entries under it
  • New endpoints: GET /sbom/snapshots/, GET /sbom/snapshots/{id}/
  • Existing GET /sbom/ still returns flat entries for backward compatibility

Task T16: Update MCP ingest tool and SBOM resources

id: T16
status: done
priority: high
assignee: custodian

ingest_sbom_tool returns snapshot_id in result. New MCP resource: state://sbom/snapshots/{repo_slug}.

Task T17: Update SBOM dashboard

id: T17
status: done
priority: medium
assignee: custodian

sbom.md "By Repo" section adds a snapshot history row showing ingest dates with package count delta from previous snapshot.