# 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).