Files
the-custodian/wiki/GEMS-StateHub-TypeRegistry.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

5.8 KiB

GEMS State-Hub Type Registry

Domain-specific instantiation of the Generic Entity Modelling System (wiki/GenericEntityModellingSystem.md) for the Custodian State Hub.

Status: Draft — subject to revision pending decision DEC-GEMS-001 through DEC-GEMS-006. Created: 2026-03-02


Hierarchy Overview

Ecosystem (implicit root — singleton)
  └── Domain (Complex)
        ├── Topic (Complex)              organizes focus areas
        └── Repository (Complex)
              ├── Workstream (Complex)   organizes tasks
              ├── SBOMSnapshot (Complex) organizes SBOM entries
              ├── Task (Atom)            ← secondary: Workstream
              ├── Decision (Atom)        ← secondary: Topic | Workstream
              ├── TechnicalDebt (Atom)
              ├── ExtensionPoint (Atom)
              ├── Contribution (Atom)
              └── ProgressEvent (Atom)   ← secondary: Workstream | Task | Decision

SBOMSnapshot
  └── SBOMEntry (Atom)

DependsOn (Relation, primary=Domain)
  from: Workstream → to: Workstream

Type Registry Table

Type Kind Primary Attachment Type Allowed Secondary Attachments Payload / Key Fields
Ecosystem Complex — (root) name, description
Domain Complex Ecosystem slug, name, status
Topic Complex Domain slug, title, status
Repository Complex Domain Topic (optional scope annotation) slug, name, local_path, remote_url
Workstream Complex Repository Topic (organizer) slug, title, status, owner, due_date
SBOMSnapshot Complex Repository snapshot_at, source
Task Atom Workstream title, status, priority, assignee, due_date
Decision Atom Repository Topic | Workstream (context) title, type, status, rationale, deadline
TechnicalDebt Atom Repository Topic | Workstream (context) td_id, debt_type, severity, status
ExtensionPoint Atom Repository Topic | Workstream (context) ep_id, ep_type, priority, status
Contribution Atom Repository type, target_org, target_repo, status
ProgressEvent Atom Workstream Task | Decision (context) summary, event_type, author
SBOMEntry Atom SBOMSnapshot package_name, version, ecosystem, license_spdx
DependsOn Relation Domain attachments[1]=from_ws, attachments[2]=to_ws, description

Validation Invariants

Following GEMS §5.2:

  1. Primary chain must be acyclic. No entity may be its own ancestor via primary attachments.

  2. Primary attachment kind/type must match the registry. A Task's primary must be a Workstream; a Workstream's primary must be a Repository, etc.

  3. Context-consistency for secondary attachments. If Task has a secondary attachment to a Workstream, that Workstream's primary must be the same Repository as the Task's context (inherited via Workstream.primary).

  4. Relation endpoint types must match the relation's type definition. DependsOn.from and DependsOn.to must both be Workstream entities within the same Domain.

  5. Relation primary must be a Complex. DependsOn.primary = Domain (the relation-space that "owns" the inter-workstream dependency graph).


Mapping: Current Tables → GEMS

Current Table Target GEMS Type Status Change Required
domains Domain (Complex) Correct None
topics Topic (Complex) Correct None
managed_repos Repository (Complex) Mostly correct Remove nullable topic_id; add optional secondary
workstreams Workstream (Complex) Broken Change primary from topic_id to repo_id
tasks Task (Atom) Correct None
decisions Decision (Atom) Ambiguous Change primary to repo_id; topic/workstream become secondaries
technical_debt TechnicalDebt (Atom) Broken domain string → repo_id FK
extension_points ExtensionPoint (Atom) Broken domain string → repo_id FK
contributions Contribution (Atom) Incomplete Add repo_id FK
progress_events ProgressEvent (Atom) Ambiguous Clarify primary vs. secondary
sbom_entries SBOMEntry (Atom) Broken Add SBOMSnapshot container
workstream_dependencies DependsOn (Relation) Acceptable Consider Relation entity model
(missing) SBOMSnapshot (Complex) Missing New table required
(missing) Ecosystem (Complex) Missing Optional singleton

Query Patterns Enabled

After full GEMS alignment:

# All workstreams in a domain
Workstream WHERE primary.primary.slug = "railiance"

# All open tasks for a given repo
Task WHERE primary.primary.slug = "activity-core" AND status != "done"

# Dependency graph for a domain
DependsOn WHERE primary.slug = "custodian"

# SBOM history for a repo
SBOMSnapshot WHERE primary.slug = "the-custodian" ORDER BY snapshot_at DESC

# All tech debt in a domain (currently broken — domain is a string)
TechnicalDebt WHERE primary.primary.slug = "custodian"

Notes

  • Topic and Repository are both children of Domain but are distinct organizers. Topic = "focus area / project agenda"; Repository = "git repo / code artefact boundary". A Topic may align with one or more repositories, but neither owns the other.

  • Workstream moving from Topic → Repository is the most disruptive change. It resolves the ADR-001 contradiction (workplans must live in repos, but workstreams live under topics).

  • ProgressEvent retains its multi-attach flexibility (topic, workstream, task, decision) but those become secondary attachments. The primary should be the Workstream (or Repository if no workstream context).