feat: freeze repository navigation contract
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0230c-b06c-7641-808a-e191b6d1da49
This commit is contained in:
parent
b27de6e5bf
commit
a701dc89cf
15 changed files with 1053 additions and 4 deletions
|
|
@ -5,6 +5,8 @@ from importlib.resources.abc import Traversable
|
|||
|
||||
CONTRACT_ID = "helixforge.hub-extension"
|
||||
CONTRACT_VERSION = "0.1.0"
|
||||
REPOSITORY_NAVIGATION_CONTRACT_ID = "helixforge.repository-navigation"
|
||||
REPOSITORY_NAVIGATION_CONTRACT_VERSION = "1.0.0"
|
||||
|
||||
|
||||
def extension_contract_root() -> Traversable:
|
||||
|
|
@ -13,4 +15,17 @@ def extension_contract_root() -> Traversable:
|
|||
return files("hub_core.contracts.helixforge_hub_extension.v0_1_0")
|
||||
|
||||
|
||||
__all__ = ["CONTRACT_ID", "CONTRACT_VERSION", "extension_contract_root"]
|
||||
def repository_navigation_contract_root() -> Traversable:
|
||||
"""Return the packaged root for the repository-navigation contract."""
|
||||
|
||||
return files("hub_core.contracts.repository_navigation.v1_0_0")
|
||||
|
||||
|
||||
__all__ = [
|
||||
"CONTRACT_ID",
|
||||
"CONTRACT_VERSION",
|
||||
"REPOSITORY_NAVIGATION_CONTRACT_ID",
|
||||
"REPOSITORY_NAVIGATION_CONTRACT_VERSION",
|
||||
"extension_contract_root",
|
||||
"repository_navigation_contract_root",
|
||||
]
|
||||
|
|
|
|||
1
hub_core/contracts/repository_navigation/__init__.py
Normal file
1
hub_core/contracts/repository_navigation/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
"""Versioned repository-navigation contracts."""
|
||||
24
hub_core/contracts/repository_navigation/v1_0_0/README.md
Normal file
24
hub_core/contracts/repository_navigation/v1_0_0/README.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# helixforge.repository-navigation 1.0.0
|
||||
|
||||
This package freezes hub-core's receiving and read contracts for Repo Manager
|
||||
classification projections:
|
||||
|
||||
- `schemas/repository-classification-page.schema.json` validates full and
|
||||
incremental input pages;
|
||||
- `schemas/repository-navigation-projection.schema.json` defines the derived
|
||||
repository, facet, provenance, diagnostic, cursor, and legacy-alias output;
|
||||
- `openapi/repository-navigation.openapi.json` defines the read-only
|
||||
`port.projection.query` routes;
|
||||
- `fixtures/` supplies a valid full input page and its representative output;
|
||||
- `compatibility-matrix.json` records the only accepted input version and the
|
||||
temporary State Hub topic adapter.
|
||||
|
||||
Repository files are classification authority and Repo Manager is the
|
||||
validator/publisher. Hub-core requires the registrar's stable repository UUID,
|
||||
derives indexes, and never accepts classification writes. Host-local paths and
|
||||
work-record contents do not cross this contract.
|
||||
|
||||
Normative cursor, rebuild, failure, filtering, provenance, and alias rules are
|
||||
documented in `docs/repository-navigation-contract.md`. Breaking authority,
|
||||
identity, deletion, rebuild, cursor, or facet changes require a new major
|
||||
contract and a dual-run window.
|
||||
|
|
@ -0,0 +1 @@
|
|||
"""Repository-navigation contract version 1.0.0."""
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"contract_id": "helixforge.repository-navigation",
|
||||
"current_version": "1.0.0",
|
||||
"accepted_inputs": [
|
||||
{
|
||||
"contract_id": "helixforge.repository-classification-projection",
|
||||
"version": "1.0.0",
|
||||
"classification_contract_id": "RMGR-CONTRACT-CLASSIFICATION-0001",
|
||||
"classification_contract_version": "1.0",
|
||||
"status": "current",
|
||||
"coercion": false
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"status": "current",
|
||||
"compatible_min": "1.0.0",
|
||||
"compatible_max": "1.0.0",
|
||||
"breaking": false
|
||||
}
|
||||
],
|
||||
"legacy_adapters": [
|
||||
{
|
||||
"source": "state-hub.topic",
|
||||
"target": "legacy_topic_aliases",
|
||||
"status": "temporary-read-only",
|
||||
"authority": false,
|
||||
"required_metadata": ["expires_at", "residual_owner"],
|
||||
"notes": "An alias points to one derived facet. It cannot create or mutate repository classification and must be removed after its residual owner completes the cutover."
|
||||
}
|
||||
],
|
||||
"change_policy": {
|
||||
"patch": "Clarifications and compatible constraint corrections only.",
|
||||
"minor": "Additive optional fields, query filters, and diagnostics.",
|
||||
"major": "Changed authority, identity, cursor, rebuild, deletion, facet, or compatibility semantics; removed or renamed fields; or narrowed enums. Requires a dual-run window."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"contract_id": "helixforge.repository-classification-projection",
|
||||
"contract_version": "1.0.0",
|
||||
"source": {
|
||||
"system": "repo-manager",
|
||||
"classification_contract_id": "RMGR-CONTRACT-CLASSIFICATION-0001",
|
||||
"classification_contract_version": "1.0",
|
||||
"producer_version": "0.4.0"
|
||||
},
|
||||
"snapshot": {
|
||||
"snapshot_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"mode": "full",
|
||||
"generated_at": "2026-08-22T12:00:00Z",
|
||||
"source_revision": "0123456789abcdef0123456789abcdef01234567",
|
||||
"page_cursor": null,
|
||||
"next_cursor": null,
|
||||
"final_page": true,
|
||||
"total_repository_count": 2
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"operation": "upsert",
|
||||
"repository_id": "11111111-1111-4111-8111-111111111111",
|
||||
"slug": "hub-core",
|
||||
"lifecycle": "active",
|
||||
"classification": {
|
||||
"category": "tooling",
|
||||
"domain": "infotech",
|
||||
"secondary_domains": ["agents"],
|
||||
"capability_tags": ["hub-runtime", "repository-navigation"],
|
||||
"business_stake": ["technology"],
|
||||
"business_mechanics": ["coordination"]
|
||||
},
|
||||
"revision": {
|
||||
"head_sha": "1111111111111111111111111111111111111111",
|
||||
"source_fingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"observed_at": "2026-08-22T11:59:00Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"operation": "upsert",
|
||||
"repository_id": "22222222-2222-4222-8222-222222222222",
|
||||
"slug": "repo-manager",
|
||||
"lifecycle": "active",
|
||||
"classification": {
|
||||
"category": "tooling",
|
||||
"domain": "infotech",
|
||||
"secondary_domains": [],
|
||||
"capability_tags": ["repository-governance"],
|
||||
"business_stake": ["operations", "technology"],
|
||||
"business_mechanics": ["control", "coordination"]
|
||||
},
|
||||
"revision": {
|
||||
"head_sha": "2222222222222222222222222222222222222222",
|
||||
"source_fingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
"observed_at": "2026-08-22T11:59:30Z"
|
||||
}
|
||||
}
|
||||
],
|
||||
"diagnostics": []
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
{
|
||||
"contract_id": "helixforge.repository-navigation",
|
||||
"contract_version": "1.0.0",
|
||||
"projection_id": "repository_navigation",
|
||||
"projection_status": "current",
|
||||
"source_snapshot": {
|
||||
"snapshot_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"source_system": "repo-manager",
|
||||
"source_contract_id": "RMGR-CONTRACT-CLASSIFICATION-0001",
|
||||
"source_contract_version": "1.0",
|
||||
"source_revision": "0123456789abcdef0123456789abcdef01234567",
|
||||
"generated_at": "2026-08-22T12:00:00Z"
|
||||
},
|
||||
"source_checked_at": "2026-08-22T12:00:03Z",
|
||||
"rebuilt_at": "2026-08-22T12:00:02Z",
|
||||
"content_hash": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
|
||||
"repositories": [
|
||||
{
|
||||
"repository_id": "11111111-1111-4111-8111-111111111111",
|
||||
"slug": "hub-core",
|
||||
"lifecycle": "active",
|
||||
"primary_domain": "infotech",
|
||||
"secondary_domains": ["agents"],
|
||||
"category": "tooling",
|
||||
"capability_tags": ["hub-runtime", "repository-navigation"],
|
||||
"business_stake": ["technology"],
|
||||
"business_mechanics": ["coordination"],
|
||||
"provenance": {
|
||||
"source_system": "repo-manager",
|
||||
"source_ref": "repo-manager://repositories/11111111-1111-4111-8111-111111111111",
|
||||
"classification_contract_version": "1.0",
|
||||
"repository_revision": "1111111111111111111111111111111111111111",
|
||||
"source_fingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"observed_at": "2026-08-22T11:59:00Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"repository_id": "22222222-2222-4222-8222-222222222222",
|
||||
"slug": "repo-manager",
|
||||
"lifecycle": "active",
|
||||
"primary_domain": "infotech",
|
||||
"secondary_domains": [],
|
||||
"category": "tooling",
|
||||
"capability_tags": ["repository-governance"],
|
||||
"business_stake": ["operations", "technology"],
|
||||
"business_mechanics": ["control", "coordination"],
|
||||
"provenance": {
|
||||
"source_system": "repo-manager",
|
||||
"source_ref": "repo-manager://repositories/22222222-2222-4222-8222-222222222222",
|
||||
"classification_contract_version": "1.0",
|
||||
"repository_revision": "2222222222222222222222222222222222222222",
|
||||
"source_fingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
"observed_at": "2026-08-22T11:59:30Z"
|
||||
}
|
||||
}
|
||||
],
|
||||
"facets": [
|
||||
{
|
||||
"kind": "primary_domain",
|
||||
"value": "infotech",
|
||||
"repository_count": 2,
|
||||
"repository_ids": [
|
||||
"11111111-1111-4111-8111-111111111111",
|
||||
"22222222-2222-4222-8222-222222222222"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "secondary_domain",
|
||||
"value": "agents",
|
||||
"repository_count": 1,
|
||||
"repository_ids": ["11111111-1111-4111-8111-111111111111"]
|
||||
},
|
||||
{
|
||||
"kind": "category",
|
||||
"value": "tooling",
|
||||
"repository_count": 2,
|
||||
"repository_ids": [
|
||||
"11111111-1111-4111-8111-111111111111",
|
||||
"22222222-2222-4222-8222-222222222222"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "capability_tag",
|
||||
"value": "repository-navigation",
|
||||
"repository_count": 1,
|
||||
"repository_ids": ["11111111-1111-4111-8111-111111111111"]
|
||||
},
|
||||
{
|
||||
"kind": "business_stake",
|
||||
"value": "technology",
|
||||
"repository_count": 2,
|
||||
"repository_ids": [
|
||||
"11111111-1111-4111-8111-111111111111",
|
||||
"22222222-2222-4222-8222-222222222222"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "business_mechanic",
|
||||
"value": "coordination",
|
||||
"repository_count": 2,
|
||||
"repository_ids": [
|
||||
"11111111-1111-4111-8111-111111111111",
|
||||
"22222222-2222-4222-8222-222222222222"
|
||||
]
|
||||
}
|
||||
],
|
||||
"legacy_topic_aliases": [
|
||||
{
|
||||
"legacy_topic_id": "33333333-3333-4333-8333-333333333333",
|
||||
"legacy_topic_slug": "infotech",
|
||||
"facet_kind": "primary_domain",
|
||||
"facet_value": "infotech",
|
||||
"status": "active",
|
||||
"expires_at": "2026-09-30T23:59:59Z",
|
||||
"residual_owner": "STATE-WP-0079"
|
||||
}
|
||||
],
|
||||
"diagnostics": [],
|
||||
"next_cursor": null,
|
||||
"total_repository_count": 2
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {
|
||||
"title": "HelixForge repository navigation projection",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"/ports/projections/repository-navigation/repositories": {
|
||||
"get": {
|
||||
"operationId": "queryRepositoryNavigation",
|
||||
"x-port-id": "port.projection.query",
|
||||
"x-direction": "out",
|
||||
"summary": "Query the derived repository navigation projection",
|
||||
"parameters": [
|
||||
{"$ref": "#/components/parameters/PrimaryDomain"},
|
||||
{"$ref": "#/components/parameters/SecondaryDomain"},
|
||||
{"$ref": "#/components/parameters/Category"},
|
||||
{"$ref": "#/components/parameters/CapabilityTag"},
|
||||
{"$ref": "#/components/parameters/BusinessStake"},
|
||||
{"$ref": "#/components/parameters/BusinessMechanic"},
|
||||
{"$ref": "#/components/parameters/Cursor"},
|
||||
{"$ref": "#/components/parameters/Limit"}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Snapshot-bound page in stable repository UUID order",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "../schemas/repository-navigation-projection.schema.json"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {"$ref": "#/components/responses/BadRequest"},
|
||||
"409": {"$ref": "#/components/responses/CursorMismatch"},
|
||||
"503": {"$ref": "#/components/responses/DependencyUnavailable"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ports/projections/repository-navigation/facets/{facet_kind}/{facet_value}": {
|
||||
"get": {
|
||||
"operationId": "getRepositoryNavigationFacet",
|
||||
"x-port-id": "port.projection.query",
|
||||
"x-direction": "out",
|
||||
"summary": "Resolve one derived navigation facet",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "facet_kind",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {"$ref": "#/components/schemas/FacetKind"}
|
||||
},
|
||||
{
|
||||
"name": "facet_value",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {"type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"}
|
||||
},
|
||||
{"$ref": "#/components/parameters/Cursor"},
|
||||
{"$ref": "#/components/parameters/Limit"}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Repositories in the selected derived facet",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "../schemas/repository-navigation-projection.schema.json"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {"$ref": "#/components/responses/BadRequest"},
|
||||
"404": {"description": "Facet not found"},
|
||||
"409": {"$ref": "#/components/responses/CursorMismatch"},
|
||||
"503": {"$ref": "#/components/responses/DependencyUnavailable"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ports/projections/repository-navigation/legacy-topic-aliases/{legacy_topic_id}": {
|
||||
"get": {
|
||||
"operationId": "resolveLegacyRepositoryTopicAlias",
|
||||
"x-port-id": "port.projection.query",
|
||||
"x-direction": "out",
|
||||
"summary": "Resolve temporary read-only State Hub topic compatibility metadata",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "legacy_topic_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {"type": "string", "format": "uuid"}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Active alias and its derived facet target",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "../schemas/repository-navigation-projection.schema.json#/$defs/legacyTopicAlias"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "Alias not found"},
|
||||
"410": {"description": "Alias expired; response identifies the residual owner"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"FacetKind": {
|
||||
"enum": [
|
||||
"primary_domain",
|
||||
"secondary_domain",
|
||||
"category",
|
||||
"capability_tag",
|
||||
"business_stake",
|
||||
"business_mechanic"
|
||||
]
|
||||
},
|
||||
"Error": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["code", "message"],
|
||||
"properties": {
|
||||
"code": {"type": "string"},
|
||||
"message": {"type": "string"},
|
||||
"retryable": {"type": "boolean"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"PrimaryDomain": {"name": "primary_domain", "in": "query", "schema": {"type": "array", "items": {"type": "string"}}, "explode": true},
|
||||
"SecondaryDomain": {"name": "secondary_domain", "in": "query", "schema": {"type": "array", "items": {"type": "string"}}, "explode": true},
|
||||
"Category": {"name": "category", "in": "query", "schema": {"type": "array", "items": {"type": "string"}}, "explode": true},
|
||||
"CapabilityTag": {"name": "capability_tag", "in": "query", "schema": {"type": "array", "items": {"type": "string"}}, "explode": true},
|
||||
"BusinessStake": {"name": "business_stake", "in": "query", "schema": {"type": "array", "items": {"type": "string"}}, "explode": true},
|
||||
"BusinessMechanic": {"name": "business_mechanic", "in": "query", "schema": {"type": "array", "items": {"type": "string"}}, "explode": true},
|
||||
"Cursor": {"name": "cursor", "in": "query", "schema": {"type": "string", "maxLength": 1000}},
|
||||
"Limit": {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 500, "default": 100}}
|
||||
},
|
||||
"responses": {
|
||||
"BadRequest": {
|
||||
"description": "Invalid filter or cursor",
|
||||
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
|
||||
},
|
||||
"CursorMismatch": {
|
||||
"description": "Cursor belongs to a superseded projection snapshot",
|
||||
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
|
||||
},
|
||||
"DependencyUnavailable": {
|
||||
"description": "No accepted projection is available",
|
||||
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.helixforge.local/repository-navigation/1.0.0/repository-classification-page.schema.json",
|
||||
"title": "Repo Manager classification projection page",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"contract_id",
|
||||
"contract_version",
|
||||
"source",
|
||||
"snapshot",
|
||||
"repositories",
|
||||
"diagnostics"
|
||||
],
|
||||
"properties": {
|
||||
"contract_id": {"const": "helixforge.repository-classification-projection"},
|
||||
"contract_version": {"const": "1.0.0"},
|
||||
"source": {"$ref": "#/$defs/source"},
|
||||
"snapshot": {"$ref": "#/$defs/snapshot"},
|
||||
"repositories": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/change"}
|
||||
},
|
||||
"diagnostics": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/diagnostic"}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"source": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"system",
|
||||
"classification_contract_id",
|
||||
"classification_contract_version",
|
||||
"producer_version"
|
||||
],
|
||||
"properties": {
|
||||
"system": {"const": "repo-manager"},
|
||||
"classification_contract_id": {"const": "RMGR-CONTRACT-CLASSIFICATION-0001"},
|
||||
"classification_contract_version": {"const": "1.0"},
|
||||
"producer_version": {"type": "string", "minLength": 1, "maxLength": 80}
|
||||
}
|
||||
},
|
||||
"snapshot": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"snapshot_id",
|
||||
"mode",
|
||||
"generated_at",
|
||||
"source_revision",
|
||||
"page_cursor",
|
||||
"next_cursor",
|
||||
"final_page",
|
||||
"total_repository_count"
|
||||
],
|
||||
"properties": {
|
||||
"snapshot_id": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
|
||||
"mode": {"enum": ["full", "incremental"]},
|
||||
"generated_at": {"type": "string", "format": "date-time"},
|
||||
"source_revision": {"type": "string", "pattern": "^[a-f0-9]{7,64}$"},
|
||||
"page_cursor": {"type": ["string", "null"], "maxLength": 1000},
|
||||
"next_cursor": {"type": ["string", "null"], "maxLength": 1000},
|
||||
"final_page": {"type": "boolean"},
|
||||
"total_repository_count": {"type": ["integer", "null"], "minimum": 0}
|
||||
}
|
||||
},
|
||||
"revision": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["head_sha", "source_fingerprint", "observed_at"],
|
||||
"properties": {
|
||||
"head_sha": {"type": ["string", "null"], "pattern": "^[a-f0-9]{40,64}$"},
|
||||
"source_fingerprint": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
|
||||
"observed_at": {"type": "string", "format": "date-time"}
|
||||
}
|
||||
},
|
||||
"classification": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["category", "domain"],
|
||||
"properties": {
|
||||
"category": {"enum": ["experimental", "research", "project", "tooling", "product", "business"]},
|
||||
"domain": {"$ref": "#/$defs/domain"},
|
||||
"secondary_domains": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/domain"},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"capability_tags": {
|
||||
"type": "array",
|
||||
"items": {"type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", "maxLength": 120},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"business_stake": {
|
||||
"type": "array",
|
||||
"items": {"enum": ["execution", "intelligence", "finance", "legal", "sales", "experience", "technology", "operations", "product", "people", "procurement", "sustainability", "automation"]},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"business_mechanics": {
|
||||
"type": "array",
|
||||
"items": {"enum": ["intention", "control", "coordination", "operation", "adaptation"]},
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"upsert": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["operation", "repository_id", "slug", "lifecycle", "classification", "revision"],
|
||||
"properties": {
|
||||
"operation": {"const": "upsert"},
|
||||
"repository_id": {"type": "string", "format": "uuid"},
|
||||
"slug": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$", "maxLength": 120},
|
||||
"lifecycle": {"enum": ["active", "archived", "retired"]},
|
||||
"classification": {"$ref": "#/$defs/classification"},
|
||||
"revision": {"$ref": "#/$defs/revision"}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["operation", "repository_id", "slug", "revision"],
|
||||
"properties": {
|
||||
"operation": {"const": "delete"},
|
||||
"repository_id": {"type": "string", "format": "uuid"},
|
||||
"slug": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$", "maxLength": 120},
|
||||
"revision": {"$ref": "#/$defs/revision"}
|
||||
}
|
||||
},
|
||||
"change": {"oneOf": [{"$ref": "#/$defs/upsert"}, {"$ref": "#/$defs/delete"}]},
|
||||
"diagnostic": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["severity", "code", "message"],
|
||||
"properties": {
|
||||
"severity": {"enum": ["info", "warning", "error"]},
|
||||
"code": {"type": "string", "pattern": "^[a-z][a-z0-9_.-]*$", "maxLength": 120},
|
||||
"message": {"type": "string", "minLength": 1, "maxLength": 1000},
|
||||
"repository_id": {"type": "string", "format": "uuid"},
|
||||
"field": {"type": "string", "maxLength": 160}
|
||||
}
|
||||
},
|
||||
"domain": {
|
||||
"enum": ["infotech", "financials", "communication", "consumer", "health", "industrials", "energy", "utilities", "materials", "realestate", "crypto", "agents", "space", "government"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://schemas.helixforge.local/repository-navigation/1.0.0/repository-navigation-projection.schema.json",
|
||||
"title": "Hub repository navigation projection",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"contract_id",
|
||||
"contract_version",
|
||||
"projection_id",
|
||||
"projection_status",
|
||||
"source_snapshot",
|
||||
"source_checked_at",
|
||||
"rebuilt_at",
|
||||
"content_hash",
|
||||
"repositories",
|
||||
"facets",
|
||||
"legacy_topic_aliases",
|
||||
"diagnostics",
|
||||
"next_cursor",
|
||||
"total_repository_count"
|
||||
],
|
||||
"properties": {
|
||||
"contract_id": {"const": "helixforge.repository-navigation"},
|
||||
"contract_version": {"const": "1.0.0"},
|
||||
"projection_id": {"const": "repository_navigation"},
|
||||
"projection_status": {"enum": ["current", "stale"]},
|
||||
"source_snapshot": {"$ref": "#/$defs/sourceSnapshot"},
|
||||
"source_checked_at": {"type": "string", "format": "date-time"},
|
||||
"rebuilt_at": {"type": "string", "format": "date-time"},
|
||||
"content_hash": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
|
||||
"repositories": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/repository"}
|
||||
},
|
||||
"facets": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/facet"}
|
||||
},
|
||||
"legacy_topic_aliases": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/legacyTopicAlias"}
|
||||
},
|
||||
"diagnostics": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/diagnostic"}
|
||||
},
|
||||
"next_cursor": {"type": ["string", "null"], "maxLength": 1000},
|
||||
"total_repository_count": {"type": "integer", "minimum": 0}
|
||||
},
|
||||
"$defs": {
|
||||
"sourceSnapshot": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"snapshot_id",
|
||||
"source_system",
|
||||
"source_contract_id",
|
||||
"source_contract_version",
|
||||
"source_revision",
|
||||
"generated_at"
|
||||
],
|
||||
"properties": {
|
||||
"snapshot_id": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
|
||||
"source_system": {"const": "repo-manager"},
|
||||
"source_contract_id": {"const": "RMGR-CONTRACT-CLASSIFICATION-0001"},
|
||||
"source_contract_version": {"const": "1.0"},
|
||||
"source_revision": {"type": "string", "pattern": "^[a-f0-9]{7,64}$"},
|
||||
"generated_at": {"type": "string", "format": "date-time"}
|
||||
}
|
||||
},
|
||||
"provenance": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"source_system",
|
||||
"source_ref",
|
||||
"classification_contract_version",
|
||||
"repository_revision",
|
||||
"source_fingerprint",
|
||||
"observed_at"
|
||||
],
|
||||
"properties": {
|
||||
"source_system": {"const": "repo-manager"},
|
||||
"source_ref": {"type": "string", "pattern": "^repo-manager://repositories/[0-9a-f-]{36}$"},
|
||||
"classification_contract_version": {"const": "1.0"},
|
||||
"repository_revision": {"type": ["string", "null"], "pattern": "^[a-f0-9]{40,64}$"},
|
||||
"source_fingerprint": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
|
||||
"observed_at": {"type": "string", "format": "date-time"}
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"repository_id",
|
||||
"slug",
|
||||
"lifecycle",
|
||||
"primary_domain",
|
||||
"secondary_domains",
|
||||
"category",
|
||||
"capability_tags",
|
||||
"business_stake",
|
||||
"business_mechanics",
|
||||
"provenance"
|
||||
],
|
||||
"properties": {
|
||||
"repository_id": {"type": "string", "format": "uuid"},
|
||||
"slug": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$", "maxLength": 120},
|
||||
"lifecycle": {"enum": ["active", "archived", "retired"]},
|
||||
"primary_domain": {"$ref": "#/$defs/domain"},
|
||||
"secondary_domains": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/domain"},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"category": {"$ref": "#/$defs/category"},
|
||||
"capability_tags": {
|
||||
"type": "array",
|
||||
"items": {"type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", "maxLength": 120},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"business_stake": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/businessStake"},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"business_mechanics": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/businessMechanic"},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"provenance": {"$ref": "#/$defs/provenance"}
|
||||
}
|
||||
},
|
||||
"facetKind": {
|
||||
"enum": [
|
||||
"primary_domain",
|
||||
"secondary_domain",
|
||||
"category",
|
||||
"capability_tag",
|
||||
"business_stake",
|
||||
"business_mechanic"
|
||||
]
|
||||
},
|
||||
"facet": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["kind", "value", "repository_count", "repository_ids"],
|
||||
"properties": {
|
||||
"kind": {"$ref": "#/$defs/facetKind"},
|
||||
"value": {"type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", "maxLength": 120},
|
||||
"repository_count": {"type": "integer", "minimum": 0},
|
||||
"repository_ids": {
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "uuid"},
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"legacyTopicAlias": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"legacy_topic_id",
|
||||
"legacy_topic_slug",
|
||||
"facet_kind",
|
||||
"facet_value",
|
||||
"status",
|
||||
"expires_at",
|
||||
"residual_owner"
|
||||
],
|
||||
"properties": {
|
||||
"legacy_topic_id": {"type": "string", "format": "uuid"},
|
||||
"legacy_topic_slug": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$", "maxLength": 120},
|
||||
"facet_kind": {"$ref": "#/$defs/facetKind"},
|
||||
"facet_value": {"type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", "maxLength": 120},
|
||||
"status": {"enum": ["active", "expired"]},
|
||||
"expires_at": {"type": "string", "format": "date-time"},
|
||||
"residual_owner": {"type": "string", "minLength": 1, "maxLength": 160}
|
||||
}
|
||||
},
|
||||
"diagnostic": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["severity", "code", "message"],
|
||||
"properties": {
|
||||
"severity": {"enum": ["info", "warning", "error"]},
|
||||
"code": {"type": "string", "pattern": "^[a-z][a-z0-9_.-]*$", "maxLength": 120},
|
||||
"message": {"type": "string", "minLength": 1, "maxLength": 1000},
|
||||
"repository_id": {"type": "string", "format": "uuid"},
|
||||
"field": {"type": "string", "maxLength": 160}
|
||||
}
|
||||
},
|
||||
"category": {"enum": ["experimental", "research", "project", "tooling", "product", "business"]},
|
||||
"domain": {
|
||||
"enum": ["infotech", "financials", "communication", "consumer", "health", "industrials", "energy", "utilities", "materials", "realestate", "crypto", "agents", "space", "government"]
|
||||
},
|
||||
"businessStake": {
|
||||
"enum": ["execution", "intelligence", "finance", "legal", "sales", "experience", "technology", "operations", "product", "people", "procurement", "sustainability", "automation"]
|
||||
},
|
||||
"businessMechanic": {"enum": ["intention", "control", "coordination", "operation", "adaptation"]}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue