fix: bound repository collection identity projection
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ed7-828d-7ca0-a8d4-0c3e5a0c4102
This commit is contained in:
parent
4cef58cd98
commit
3578dc2f32
10 changed files with 3331 additions and 9 deletions
|
|
@ -13,7 +13,7 @@ from fastapi import APIRouter, Depends, HTTPException, Response, status
|
||||||
from sqlalchemy import case, func, or_, select
|
from sqlalchemy import case, func, or_, select
|
||||||
from sqlalchemy.exc import IntegrityError
|
from sqlalchemy.exc import IntegrityError
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import noload
|
from sqlalchemy.orm import joinedload, noload
|
||||||
|
|
||||||
from api.config import settings
|
from api.config import settings
|
||||||
from api.database import get_session
|
from api.database import get_session
|
||||||
|
|
@ -57,6 +57,7 @@ from api.services.repository_identity import stage_initial_repository_identity
|
||||||
from api.services.repository_aliases import (
|
from api.services.repository_aliases import (
|
||||||
RepositorySlugResolution,
|
RepositorySlugResolution,
|
||||||
affected_slug_predicate,
|
affected_slug_predicate,
|
||||||
|
repository_resolutions_for_repositories,
|
||||||
repository_resolution_for_id,
|
repository_resolution_for_id,
|
||||||
resolve_repository_slug,
|
resolve_repository_slug,
|
||||||
stale_external_references,
|
stale_external_references,
|
||||||
|
|
@ -126,17 +127,20 @@ async def list_repos(
|
||||||
response.headers["Cache-Control"] = "max-age=60, stale-while-revalidate=30"
|
response.headers["Cache-Control"] = "max-age=60, stale-while-revalidate=30"
|
||||||
q = (
|
q = (
|
||||||
select(ManagedRepo)
|
select(ManagedRepo)
|
||||||
.options(noload(ManagedRepo.goals))
|
.options(
|
||||||
|
noload("*"),
|
||||||
|
joinedload(ManagedRepo.domain).noload("*"),
|
||||||
|
)
|
||||||
.order_by(ManagedRepo.name)
|
.order_by(ManagedRepo.name)
|
||||||
)
|
)
|
||||||
if domain:
|
if domain:
|
||||||
domain_result = await session.execute(select(Domain).where(Domain.slug == domain))
|
domain_result = await session.execute(select(Domain.id).where(Domain.slug == domain))
|
||||||
domain_obj = domain_result.scalar_one_or_none()
|
domain_id = domain_result.scalar_one_or_none()
|
||||||
if domain_obj is None:
|
if domain_id is None:
|
||||||
raise HTTPException(status_code=404, detail=f"Domain '{domain}' not found")
|
raise HTTPException(status_code=404, detail=f"Domain '{domain}' not found")
|
||||||
q = q.where(
|
q = q.where(
|
||||||
or_(
|
or_(
|
||||||
ManagedRepo.domain_id == domain_obj.id,
|
ManagedRepo.domain_id == domain_id,
|
||||||
ManagedRepo.secondary_domains.contains([domain]),
|
ManagedRepo.secondary_domains.contains([domain]),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -147,7 +151,9 @@ async def list_repos(
|
||||||
if business_stake:
|
if business_stake:
|
||||||
q = q.where(ManagedRepo.business_stake.contains([business_stake]))
|
q = q.where(ManagedRepo.business_stake.contains([business_stake]))
|
||||||
result = await session.execute(q)
|
result = await session.execute(q)
|
||||||
return await _project_repo_reads(session, list(result.scalars().all()))
|
repositories = list(result.scalars().all())
|
||||||
|
resolutions = await repository_resolutions_for_repositories(session, repositories)
|
||||||
|
return await _project_repo_reads(session, repositories, resolutions=resolutions)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/", response_model=RepoRead, status_code=status.HTTP_201_CREATED)
|
@router.post("/", response_model=RepoRead, status_code=status.HTTP_201_CREATED)
|
||||||
|
|
@ -944,6 +950,7 @@ async def _project_repo_reads(
|
||||||
repositories: list[ManagedRepo],
|
repositories: list[ManagedRepo],
|
||||||
*,
|
*,
|
||||||
requested: RepositorySlugResolution | None = None,
|
requested: RepositorySlugResolution | None = None,
|
||||||
|
resolutions: dict[uuid.UUID, RepositorySlugResolution] | None = None,
|
||||||
include_stale_external: bool = False,
|
include_stale_external: bool = False,
|
||||||
) -> list[RepoRead]:
|
) -> list[RepoRead]:
|
||||||
projections = await _sbom_projection_map()
|
projections = await _sbom_projection_map()
|
||||||
|
|
@ -952,7 +959,11 @@ async def _project_repo_reads(
|
||||||
resolution = (
|
resolution = (
|
||||||
requested
|
requested
|
||||||
if requested is not None and requested.repo.id == repository.id
|
if requested is not None and requested.repo.id == repository.id
|
||||||
else await repository_resolution_for_id(session, repository)
|
else (
|
||||||
|
resolutions[repository.id]
|
||||||
|
if resolutions is not None
|
||||||
|
else await repository_resolution_for_id(session, repository)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
read = RepoRead.model_validate(repository)
|
read = RepoRead.model_validate(repository)
|
||||||
read = read.model_copy(
|
read = read.model_copy(
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ from dataclasses import dataclass
|
||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
from sqlalchemy import func, or_, select
|
from sqlalchemy import func, or_, select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from sqlalchemy.orm import noload
|
||||||
|
|
||||||
from api.models.fabric_graph import FabricGraphEdge, FabricGraphImport, FabricGraphNode
|
from api.models.fabric_graph import FabricGraphEdge, FabricGraphImport, FabricGraphNode
|
||||||
from api.models.managed_repo import ManagedRepo
|
from api.models.managed_repo import ManagedRepo
|
||||||
|
|
@ -95,6 +96,79 @@ async def resolve_repository_slug(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def repository_resolutions_for_repositories(
|
||||||
|
session: AsyncSession,
|
||||||
|
repositories: list[ManagedRepo],
|
||||||
|
) -> dict[uuid.UUID, RepositorySlugResolution]:
|
||||||
|
"""Resolve a repository collection with one slug-registry query.
|
||||||
|
|
||||||
|
Collection callers already hold canonical ``ManagedRepo`` rows. Resolving
|
||||||
|
every row through :func:`resolve_repository_slug` would issue two identity
|
||||||
|
queries per repository. Load the complete alias sets once instead while
|
||||||
|
retaining the pre-registry compatibility behavior.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not repositories:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
repository_ids = [repository.id for repository in repositories]
|
||||||
|
records = list(
|
||||||
|
(
|
||||||
|
await session.execute(
|
||||||
|
select(RepositorySlug)
|
||||||
|
.options(
|
||||||
|
noload(RepositorySlug.repo),
|
||||||
|
noload(RepositorySlug.source_operation),
|
||||||
|
)
|
||||||
|
.where(RepositorySlug.repo_id.in_(repository_ids))
|
||||||
|
.order_by(RepositorySlug.repo_id, RepositorySlug.kind.desc(), RepositorySlug.slug)
|
||||||
|
)
|
||||||
|
).scalars()
|
||||||
|
)
|
||||||
|
records_by_repository: dict[uuid.UUID, list[RepositorySlug]] = {
|
||||||
|
repository_id: [] for repository_id in repository_ids
|
||||||
|
}
|
||||||
|
for record in records:
|
||||||
|
records_by_repository[record.repo_id].append(record)
|
||||||
|
|
||||||
|
resolutions: dict[uuid.UUID, RepositorySlugResolution] = {}
|
||||||
|
for repository in repositories:
|
||||||
|
repository_records = records_by_repository[repository.id]
|
||||||
|
requested_record = next(
|
||||||
|
(record for record in repository_records if record.slug == repository.slug),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
if requested_record is None:
|
||||||
|
# Compatibility for databases upgraded before the identity backfill.
|
||||||
|
resolutions[repository.id] = RepositorySlugResolution(
|
||||||
|
repo=repository,
|
||||||
|
requested_slug=repository.slug,
|
||||||
|
canonical_slug=repository.slug,
|
||||||
|
slug_status="canonical",
|
||||||
|
aliases=(),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
canonicals = [record for record in repository_records if record.kind == "canonical"]
|
||||||
|
if len(canonicals) != 1 or canonicals[0].slug != repository.slug:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=409,
|
||||||
|
detail=f"Repository '{repository.id}' has inconsistent canonical slug state",
|
||||||
|
)
|
||||||
|
resolutions[repository.id] = RepositorySlugResolution(
|
||||||
|
repo=repository,
|
||||||
|
requested_slug=repository.slug,
|
||||||
|
canonical_slug=repository.slug,
|
||||||
|
slug_status=requested_record.kind,
|
||||||
|
aliases=tuple(
|
||||||
|
record.slug for record in repository_records if record.kind == "alias"
|
||||||
|
),
|
||||||
|
source_operation_id=requested_record.source_operation_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
return resolutions
|
||||||
|
|
||||||
|
|
||||||
async def canonicalize_repository_slug(session: AsyncSession, value: str) -> str:
|
async def canonicalize_repository_slug(session: AsyncSession, value: str) -> str:
|
||||||
"""Canonicalize a value only when it is a registered repository identity."""
|
"""Canonicalize a value only when it is a registered repository identity."""
|
||||||
|
|
||||||
|
|
|
||||||
722
docs/evidence/legacy-meter-weekly-review-20260901.json
Normal file
722
docs/evidence/legacy-meter-weekly-review-20260901.json
Normal file
|
|
@ -0,0 +1,722 @@
|
||||||
|
{
|
||||||
|
"captured_at": "2026-09-01T06:00:07.767985+00:00",
|
||||||
|
"api_base": "http://127.0.0.1:8000",
|
||||||
|
"workplan": "STATE-WP-0070",
|
||||||
|
"retired_interfaces": [],
|
||||||
|
"weekly_review": {
|
||||||
|
"generated_at": "2026-09-01T06:00:08.728877Z",
|
||||||
|
"window_start": "2026-08-25T06:00:08.596463Z",
|
||||||
|
"window_end": "2026-09-01T06:00:08.596463Z",
|
||||||
|
"cadence": "weekly",
|
||||||
|
"activity_core_handoff": {
|
||||||
|
"activity_id": "statehub-legacy-interface-review",
|
||||||
|
"cadence": "weekly",
|
||||||
|
"source_endpoint": "/legacy-meter/weekly-review",
|
||||||
|
"state_owner": "state-hub",
|
||||||
|
"scheduler_owner": "activity-core"
|
||||||
|
},
|
||||||
|
"interfaces": [
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "8051fb40-66c9-4dc4-a413-13e8573e04a3",
|
||||||
|
"interface_key": "event_subject:org.statehub.workstream.completed",
|
||||||
|
"interface_kind": "event_subject",
|
||||||
|
"legacy_since": "2026-06-04T06:09:42.198193Z",
|
||||||
|
"replacement_ref": "org.statehub.workplan.completed",
|
||||||
|
"owner_component": "state-hub.events",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:06.871333Z",
|
||||||
|
"created_at": "2026-06-04T06:09:42.198193Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:06.756087Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 247,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 247
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 247
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"state-hub.events": 247
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-07-13T13:22:00.748140Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "cd9342fd-27e7-4a46-a1be-d41499e106a3",
|
||||||
|
"interface_key": "rest_api:DELETE /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-06T17:28:13.052813Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.200322Z",
|
||||||
|
"created_at": "2026-06-06T17:28:13.052813Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.089714Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-06-06T17:28:13.047529Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "d0294dce-7913-4268-94c3-1b2502aefb0f",
|
||||||
|
"interface_key": "rest_api:GET /sbom/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:38.703608Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:38.703608Z",
|
||||||
|
"updated_at": "2026-08-22T17:23:43.730661Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 6,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 6
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 6
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 2,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-31T08:18:41.571768Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "2 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "2f77ac12-8c97-4974-a2f9-2996927982d1",
|
||||||
|
"interface_key": "rest_api:GET /sbom/report/licences/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:41.978426Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:41.978426Z",
|
||||||
|
"updated_at": "2026-08-22T17:23:44.794796Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 5,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 5
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 5
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-28T18:46:10.642164Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "1 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "b627edf5-3302-4366-ba2e-547d32f634b5",
|
||||||
|
"interface_key": "rest_api:GET /sbom/snapshots/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:37.057774Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:37.057774Z",
|
||||||
|
"updated_at": "2026-08-22T17:22:15.080213Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 7,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 2,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-28T18:46:10.694185Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "2 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "d03ee274-cd6f-4cd5-8f22-e4d298416299",
|
||||||
|
"interface_key": "rest_api:GET /sbom/snapshots/{snapshot_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:23:45.969876Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.470106Z",
|
||||||
|
"created_at": "2026-08-22T17:23:45.969876Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.456139Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-22T17:23:45.967492Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "a6cb291e-8312-42f8-8a66-fde369482881",
|
||||||
|
"interface_key": "rest_api:GET /sbom/{repo_slug}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:23:45.089542Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.754914Z",
|
||||||
|
"created_at": "2026-08-22T17:23:45.089542Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.750826Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-22T17:23:45.670511Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "cad13f19-ddb1-49b9-86d0-8789b7599f3a",
|
||||||
|
"interface_key": "rest_api:GET /tasks/?workstream_id",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-29T10:01:31.546213Z",
|
||||||
|
"replacement_ref": "/tasks/?workplan_id=<workplan_id>",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-29T10:01:31.546213Z",
|
||||||
|
"updated_at": "2026-08-29T10:01:31.546213Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 7,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 7,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-31T22:03:49.543354Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "7 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "3e4a3d0b-08fa-45c3-91e2-4f514a914b97",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:26:14.533764Z",
|
||||||
|
"replacement_ref": "/workplans/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:26:14.533764Z",
|
||||||
|
"updated_at": "2026-06-04T00:26:14.533764Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 830269,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 830269
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 830269
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 830269
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-21T13:50:37.994459Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 10d of 60d required for 830269 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "e4c140ec-7479-46f9-b185-4b533f19d639",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/workplan-index",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T05:20:58.321869Z",
|
||||||
|
"replacement_ref": "/workplans/index",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.939572Z",
|
||||||
|
"created_at": "2026-06-04T05:20:58.321869Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.933482Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 39,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 39
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 39
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 39
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-07-08T05:20:33.378203Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "3a00b19e-e7db-4403-98aa-a77c9ab61ecc",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:25:59.014966Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:25:59.014966Z",
|
||||||
|
"updated_at": "2026-06-04T00:25:59.014966Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 3411470,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 3411470
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 3411470
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 3411470
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-21T13:50:32.103349Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 10d of 60d required for 3411470 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "69e1a255-a8b9-4101-8a68-b1bed23abfda",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/{workstream_id}/dependencies/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:25:59.291135Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}/dependencies/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:25:59.291135Z",
|
||||||
|
"updated_at": "2026-06-04T00:25:59.291135Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1643952,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1643952
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1643952
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1643952
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-21T13:50:30.082480Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 10d of 60d required for 1643952 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "b1aae931-b51f-4a85-a723-865dd65f6132",
|
||||||
|
"interface_key": "rest_api:PATCH /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T06:09:41.901035Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T06:09:41.901035Z",
|
||||||
|
"updated_at": "2026-06-04T06:09:41.901035Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 584,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 584
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 584
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 584
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-16T16:33:34.045078Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 15d of 30d required for 584 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "ed6451c9-d2cc-4486-9afe-d3852782cabc",
|
||||||
|
"interface_key": "rest_api:POST /workstreams/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T07:40:24.168535Z",
|
||||||
|
"replacement_ref": "/workplans/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T07:40:24.168535Z",
|
||||||
|
"updated_at": "2026-06-04T07:40:24.168535Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 811,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 811
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 811
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 811
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-16T01:03:41.093965Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 16d of 30d required for 811 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "281fd706-b192-4194-8055-2d8733c115f9",
|
||||||
|
"interface_key": "rest_api:POST /workstreams/{workstream_id}/dependencies/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T22:57:37.149207Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}/dependencies/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:09.130713Z",
|
||||||
|
"created_at": "2026-06-04T22:57:37.149207Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:09.123888Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 4975,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 4975
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 4975
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 4975
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-07-07T20:31:35.389791Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"retirement_candidates": []
|
||||||
|
},
|
||||||
|
"days": 7
|
||||||
|
}
|
||||||
734
docs/evidence/legacy-meter-weekly-review-20260902.json
Normal file
734
docs/evidence/legacy-meter-weekly-review-20260902.json
Normal file
|
|
@ -0,0 +1,734 @@
|
||||||
|
{
|
||||||
|
"captured_at": "2026-09-02T14:00:08.045192+00:00",
|
||||||
|
"api_base": "http://127.0.0.1:8000",
|
||||||
|
"workplan": "STATE-WP-0070",
|
||||||
|
"retired_interfaces": [],
|
||||||
|
"weekly_review": {
|
||||||
|
"generated_at": "2026-09-02T14:00:09.170309Z",
|
||||||
|
"window_start": "2026-08-26T14:00:08.717330Z",
|
||||||
|
"window_end": "2026-09-02T14:00:08.717330Z",
|
||||||
|
"cadence": "weekly",
|
||||||
|
"activity_core_handoff": {
|
||||||
|
"activity_id": "statehub-legacy-interface-review",
|
||||||
|
"cadence": "weekly",
|
||||||
|
"source_endpoint": "/legacy-meter/weekly-review",
|
||||||
|
"state_owner": "state-hub",
|
||||||
|
"scheduler_owner": "activity-core"
|
||||||
|
},
|
||||||
|
"interfaces": [
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "8051fb40-66c9-4dc4-a413-13e8573e04a3",
|
||||||
|
"interface_key": "event_subject:org.statehub.workstream.completed",
|
||||||
|
"interface_kind": "event_subject",
|
||||||
|
"legacy_since": "2026-06-04T06:09:42.198193Z",
|
||||||
|
"replacement_ref": "org.statehub.workplan.completed",
|
||||||
|
"owner_component": "state-hub.events",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:06.871333Z",
|
||||||
|
"created_at": "2026-06-04T06:09:42.198193Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:06.756087Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 247,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 247
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 247
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"state-hub.events": 247
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-07-13T13:22:00.748140Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "cd9342fd-27e7-4a46-a1be-d41499e106a3",
|
||||||
|
"interface_key": "rest_api:DELETE /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-06T17:28:13.052813Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.200322Z",
|
||||||
|
"created_at": "2026-06-06T17:28:13.052813Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.089714Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-06-06T17:28:13.047529Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "d0294dce-7913-4268-94c3-1b2502aefb0f",
|
||||||
|
"interface_key": "rest_api:GET /sbom/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:38.703608Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:38.703608Z",
|
||||||
|
"updated_at": "2026-08-22T17:23:43.730661Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 6,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 6
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 6
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 2,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-31T08:18:41.571768Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "2 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "2f77ac12-8c97-4974-a2f9-2996927982d1",
|
||||||
|
"interface_key": "rest_api:GET /sbom/report/licences/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:41.978426Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:41.978426Z",
|
||||||
|
"updated_at": "2026-08-22T17:23:44.794796Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 5,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 5
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 5
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-28T18:46:10.642164Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "1 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "b627edf5-3302-4366-ba2e-547d32f634b5",
|
||||||
|
"interface_key": "rest_api:GET /sbom/snapshots/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:37.057774Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:37.057774Z",
|
||||||
|
"updated_at": "2026-08-22T17:22:15.080213Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 7,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 2,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-28T18:46:10.694185Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "2 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "d03ee274-cd6f-4cd5-8f22-e4d298416299",
|
||||||
|
"interface_key": "rest_api:GET /sbom/snapshots/{snapshot_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:23:45.969876Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.470106Z",
|
||||||
|
"created_at": "2026-08-22T17:23:45.969876Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.456139Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-22T17:23:45.967492Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "a6cb291e-8312-42f8-8a66-fde369482881",
|
||||||
|
"interface_key": "rest_api:GET /sbom/{repo_slug}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:23:45.089542Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.754914Z",
|
||||||
|
"created_at": "2026-08-22T17:23:45.089542Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.750826Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-22T17:23:45.670511Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "cad13f19-ddb1-49b9-86d0-8789b7599f3a",
|
||||||
|
"interface_key": "rest_api:GET /tasks/?workstream_id",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-29T10:01:31.546213Z",
|
||||||
|
"replacement_ref": "/tasks/?workplan_id=<workplan_id>",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-29T10:01:31.546213Z",
|
||||||
|
"updated_at": "2026-08-29T10:01:31.546213Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 10,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 10,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-09-01T22:58:15.354257Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "10 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "3e4a3d0b-08fa-45c3-91e2-4f514a914b97",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:26:14.533764Z",
|
||||||
|
"replacement_ref": "/workplans/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:26:14.533764Z",
|
||||||
|
"updated_at": "2026-06-04T00:26:14.533764Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 830269,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 830269
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 830269
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 830269
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-21T13:50:37.994459Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 12d of 60d required for 830269 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "e4c140ec-7479-46f9-b185-4b533f19d639",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/workplan-index",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T05:20:58.321869Z",
|
||||||
|
"replacement_ref": "/workplans/index",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.939572Z",
|
||||||
|
"created_at": "2026-06-04T05:20:58.321869Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.933482Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 40,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 40
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 40
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 40
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-09-01T18:42:55.879795Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "3a00b19e-e7db-4403-98aa-a77c9ab61ecc",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:25:59.014966Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:25:59.014966Z",
|
||||||
|
"updated_at": "2026-06-04T00:25:59.014966Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 3411471,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 3411471
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 3411471
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 3411471
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-09-01T18:43:07.476120Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "1 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "69e1a255-a8b9-4101-8a68-b1bed23abfda",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/{workstream_id}/dependencies/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:25:59.291135Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}/dependencies/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:25:59.291135Z",
|
||||||
|
"updated_at": "2026-06-04T00:25:59.291135Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1643952,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1643952
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1643952
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1643952
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-21T13:50:30.082480Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 12d of 60d required for 1643952 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "b1aae931-b51f-4a85-a723-865dd65f6132",
|
||||||
|
"interface_key": "rest_api:PATCH /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T06:09:41.901035Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T06:09:41.901035Z",
|
||||||
|
"updated_at": "2026-06-04T06:09:41.901035Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 584,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 584
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 584
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 584
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-16T16:33:34.045078Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 16d of 30d required for 584 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "ed6451c9-d2cc-4486-9afe-d3852782cabc",
|
||||||
|
"interface_key": "rest_api:POST /workstreams/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T07:40:24.168535Z",
|
||||||
|
"replacement_ref": "/workplans/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T07:40:24.168535Z",
|
||||||
|
"updated_at": "2026-06-04T07:40:24.168535Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 811,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 811
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 811
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 811
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-16T01:03:41.093965Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 17d of 30d required for 811 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "281fd706-b192-4194-8055-2d8733c115f9",
|
||||||
|
"interface_key": "rest_api:POST /workstreams/{workstream_id}/dependencies/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T22:57:37.149207Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}/dependencies/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:09.130713Z",
|
||||||
|
"created_at": "2026-06-04T22:57:37.149207Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:09.123888Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 4975,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 4975
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 4975
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 4975
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-07-07T20:31:35.389791Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"retirement_candidates": []
|
||||||
|
},
|
||||||
|
"days": 7
|
||||||
|
}
|
||||||
734
docs/evidence/legacy-meter-weekly-review-20260903.json
Normal file
734
docs/evidence/legacy-meter-weekly-review-20260903.json
Normal file
|
|
@ -0,0 +1,734 @@
|
||||||
|
{
|
||||||
|
"captured_at": "2026-09-02T22:00:08.180858+00:00",
|
||||||
|
"api_base": "http://127.0.0.1:8000",
|
||||||
|
"workplan": "STATE-WP-0070",
|
||||||
|
"retired_interfaces": [],
|
||||||
|
"weekly_review": {
|
||||||
|
"generated_at": "2026-09-02T22:00:09.989497Z",
|
||||||
|
"window_start": "2026-08-26T22:00:09.857120Z",
|
||||||
|
"window_end": "2026-09-02T22:00:09.857120Z",
|
||||||
|
"cadence": "weekly",
|
||||||
|
"activity_core_handoff": {
|
||||||
|
"activity_id": "statehub-legacy-interface-review",
|
||||||
|
"cadence": "weekly",
|
||||||
|
"source_endpoint": "/legacy-meter/weekly-review",
|
||||||
|
"state_owner": "state-hub",
|
||||||
|
"scheduler_owner": "activity-core"
|
||||||
|
},
|
||||||
|
"interfaces": [
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "8051fb40-66c9-4dc4-a413-13e8573e04a3",
|
||||||
|
"interface_key": "event_subject:org.statehub.workstream.completed",
|
||||||
|
"interface_kind": "event_subject",
|
||||||
|
"legacy_since": "2026-06-04T06:09:42.198193Z",
|
||||||
|
"replacement_ref": "org.statehub.workplan.completed",
|
||||||
|
"owner_component": "state-hub.events",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:06.871333Z",
|
||||||
|
"created_at": "2026-06-04T06:09:42.198193Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:06.756087Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 247,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 247
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 247
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"state-hub.events": 247
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-07-13T13:22:00.748140Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "cd9342fd-27e7-4a46-a1be-d41499e106a3",
|
||||||
|
"interface_key": "rest_api:DELETE /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-06T17:28:13.052813Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.200322Z",
|
||||||
|
"created_at": "2026-06-06T17:28:13.052813Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.089714Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-06-06T17:28:13.047529Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "d0294dce-7913-4268-94c3-1b2502aefb0f",
|
||||||
|
"interface_key": "rest_api:GET /sbom/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:38.703608Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:38.703608Z",
|
||||||
|
"updated_at": "2026-08-22T17:23:43.730661Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 6,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 6
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 6
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 2,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-31T08:18:41.571768Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "2 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "2f77ac12-8c97-4974-a2f9-2996927982d1",
|
||||||
|
"interface_key": "rest_api:GET /sbom/report/licences/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:41.978426Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:41.978426Z",
|
||||||
|
"updated_at": "2026-08-22T17:23:44.794796Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 5,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 5
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 5
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-28T18:46:10.642164Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "1 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "b627edf5-3302-4366-ba2e-547d32f634b5",
|
||||||
|
"interface_key": "rest_api:GET /sbom/snapshots/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:37.057774Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:37.057774Z",
|
||||||
|
"updated_at": "2026-08-22T17:22:15.080213Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 7,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 2,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-28T18:46:10.694185Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "2 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "d03ee274-cd6f-4cd5-8f22-e4d298416299",
|
||||||
|
"interface_key": "rest_api:GET /sbom/snapshots/{snapshot_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:23:45.969876Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.470106Z",
|
||||||
|
"created_at": "2026-08-22T17:23:45.969876Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.456139Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-22T17:23:45.967492Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "a6cb291e-8312-42f8-8a66-fde369482881",
|
||||||
|
"interface_key": "rest_api:GET /sbom/{repo_slug}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:23:45.089542Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.754914Z",
|
||||||
|
"created_at": "2026-08-22T17:23:45.089542Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.750826Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-22T17:23:45.670511Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "cad13f19-ddb1-49b9-86d0-8789b7599f3a",
|
||||||
|
"interface_key": "rest_api:GET /tasks/?workstream_id",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-29T10:01:31.546213Z",
|
||||||
|
"replacement_ref": "/tasks/?workplan_id=<workplan_id>",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-29T10:01:31.546213Z",
|
||||||
|
"updated_at": "2026-08-29T10:01:31.546213Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 10,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 10,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-09-01T22:58:15.354257Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "10 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "3e4a3d0b-08fa-45c3-91e2-4f514a914b97",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:26:14.533764Z",
|
||||||
|
"replacement_ref": "/workplans/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:26:14.533764Z",
|
||||||
|
"updated_at": "2026-06-04T00:26:14.533764Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 830269,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 830269
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 830269
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 830269
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-21T13:50:37.994459Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 12d of 60d required for 830269 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "e4c140ec-7479-46f9-b185-4b533f19d639",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/workplan-index",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T05:20:58.321869Z",
|
||||||
|
"replacement_ref": "/workplans/index",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.939572Z",
|
||||||
|
"created_at": "2026-06-04T05:20:58.321869Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.933482Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 40,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 40
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 40
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 40
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-09-01T18:42:55.879795Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "3a00b19e-e7db-4403-98aa-a77c9ab61ecc",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:25:59.014966Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:25:59.014966Z",
|
||||||
|
"updated_at": "2026-06-04T00:25:59.014966Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 3411471,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 3411471
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 3411471
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 3411471
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-09-01T18:43:07.476120Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "1 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "69e1a255-a8b9-4101-8a68-b1bed23abfda",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/{workstream_id}/dependencies/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:25:59.291135Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}/dependencies/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:25:59.291135Z",
|
||||||
|
"updated_at": "2026-06-04T00:25:59.291135Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1643952,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1643952
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1643952
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1643952
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-21T13:50:30.082480Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 12d of 60d required for 1643952 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "b1aae931-b51f-4a85-a723-865dd65f6132",
|
||||||
|
"interface_key": "rest_api:PATCH /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T06:09:41.901035Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T06:09:41.901035Z",
|
||||||
|
"updated_at": "2026-06-04T06:09:41.901035Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 584,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 584
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 584
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 584
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-16T16:33:34.045078Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 17d of 30d required for 584 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "ed6451c9-d2cc-4486-9afe-d3852782cabc",
|
||||||
|
"interface_key": "rest_api:POST /workstreams/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T07:40:24.168535Z",
|
||||||
|
"replacement_ref": "/workplans/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T07:40:24.168535Z",
|
||||||
|
"updated_at": "2026-06-04T07:40:24.168535Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 811,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 811
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 811
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 811
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-16T01:03:41.093965Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 17d of 30d required for 811 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "281fd706-b192-4194-8055-2d8733c115f9",
|
||||||
|
"interface_key": "rest_api:POST /workstreams/{workstream_id}/dependencies/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T22:57:37.149207Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}/dependencies/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:09.130713Z",
|
||||||
|
"created_at": "2026-06-04T22:57:37.149207Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:09.123888Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 4975,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 4975
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 4975
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 4975
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-07-07T20:31:35.389791Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"retirement_candidates": []
|
||||||
|
},
|
||||||
|
"days": 7
|
||||||
|
}
|
||||||
734
docs/evidence/legacy-meter-weekly-review-20260904.json
Normal file
734
docs/evidence/legacy-meter-weekly-review-20260904.json
Normal file
|
|
@ -0,0 +1,734 @@
|
||||||
|
{
|
||||||
|
"captured_at": "2026-09-04T14:00:09.844360+00:00",
|
||||||
|
"api_base": "http://127.0.0.1:8000",
|
||||||
|
"workplan": "STATE-WP-0070",
|
||||||
|
"retired_interfaces": [],
|
||||||
|
"weekly_review": {
|
||||||
|
"generated_at": "2026-09-04T14:00:12.141508Z",
|
||||||
|
"window_start": "2026-08-28T14:00:10.416532Z",
|
||||||
|
"window_end": "2026-09-04T14:00:10.416532Z",
|
||||||
|
"cadence": "weekly",
|
||||||
|
"activity_core_handoff": {
|
||||||
|
"activity_id": "statehub-legacy-interface-review",
|
||||||
|
"cadence": "weekly",
|
||||||
|
"source_endpoint": "/legacy-meter/weekly-review",
|
||||||
|
"state_owner": "state-hub",
|
||||||
|
"scheduler_owner": "activity-core"
|
||||||
|
},
|
||||||
|
"interfaces": [
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "8051fb40-66c9-4dc4-a413-13e8573e04a3",
|
||||||
|
"interface_key": "event_subject:org.statehub.workstream.completed",
|
||||||
|
"interface_kind": "event_subject",
|
||||||
|
"legacy_since": "2026-06-04T06:09:42.198193Z",
|
||||||
|
"replacement_ref": "org.statehub.workplan.completed",
|
||||||
|
"owner_component": "state-hub.events",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:06.871333Z",
|
||||||
|
"created_at": "2026-06-04T06:09:42.198193Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:06.756087Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 247,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 247
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 247
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"state-hub.events": 247
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-07-13T13:22:00.748140Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "cd9342fd-27e7-4a46-a1be-d41499e106a3",
|
||||||
|
"interface_key": "rest_api:DELETE /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-06T17:28:13.052813Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.200322Z",
|
||||||
|
"created_at": "2026-06-06T17:28:13.052813Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.089714Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-06-06T17:28:13.047529Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "d0294dce-7913-4268-94c3-1b2502aefb0f",
|
||||||
|
"interface_key": "rest_api:GET /sbom/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:38.703608Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:38.703608Z",
|
||||||
|
"updated_at": "2026-08-22T17:23:43.730661Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 6,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 6
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 6
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 2,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-31T08:18:41.571768Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "2 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "2f77ac12-8c97-4974-a2f9-2996927982d1",
|
||||||
|
"interface_key": "rest_api:GET /sbom/report/licences/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:41.978426Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:41.978426Z",
|
||||||
|
"updated_at": "2026-08-22T17:23:44.794796Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 5,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 5
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 5
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-28T18:46:10.642164Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "1 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "b627edf5-3302-4366-ba2e-547d32f634b5",
|
||||||
|
"interface_key": "rest_api:GET /sbom/snapshots/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:06:37.057774Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-22T17:06:37.057774Z",
|
||||||
|
"updated_at": "2026-08-22T17:22:15.080213Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 7,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 2,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 2
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-28T18:46:10.694185Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "2 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "d03ee274-cd6f-4cd5-8f22-e4d298416299",
|
||||||
|
"interface_key": "rest_api:GET /sbom/snapshots/{snapshot_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:23:45.969876Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.470106Z",
|
||||||
|
"created_at": "2026-08-22T17:23:45.969876Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.456139Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-22T17:23:45.967492Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "a6cb291e-8312-42f8-8a66-fde369482881",
|
||||||
|
"interface_key": "rest_api:GET /sbom/{repo_slug}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-22T17:23:45.089542Z",
|
||||||
|
"replacement_ref": "sbom-nexus:/sbom/",
|
||||||
|
"owner_component": "state-hub.sbom-compat",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.754914Z",
|
||||||
|
"created_at": "2026-08-22T17:23:45.089542Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.750826Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-22T17:23:45.670511Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "cad13f19-ddb1-49b9-86d0-8789b7599f3a",
|
||||||
|
"interface_key": "rest_api:GET /tasks/?workstream_id",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-08-29T10:01:31.546213Z",
|
||||||
|
"replacement_ref": "/tasks/?workplan_id=<workplan_id>",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-08-29T10:01:31.546213Z",
|
||||||
|
"updated_at": "2026-08-29T10:01:31.546213Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 10,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 10,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 10
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-09-01T22:58:15.354257Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "10 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "3e4a3d0b-08fa-45c3-91e2-4f514a914b97",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:26:14.533764Z",
|
||||||
|
"replacement_ref": "/workplans/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:26:14.533764Z",
|
||||||
|
"updated_at": "2026-06-04T00:26:14.533764Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 830269,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 830269
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 830269
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 830269
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-21T13:50:37.994459Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 14d of 60d required for 830269 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "e4c140ec-7479-46f9-b185-4b533f19d639",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/workplan-index",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T05:20:58.321869Z",
|
||||||
|
"replacement_ref": "/workplans/index",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:08.939572Z",
|
||||||
|
"created_at": "2026-06-04T05:20:58.321869Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:08.933482Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 40,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 40
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 40
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 40
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 1,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-09-01T18:42:55.879795Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "3a00b19e-e7db-4403-98aa-a77c9ab61ecc",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:25:59.014966Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:25:59.014966Z",
|
||||||
|
"updated_at": "2026-06-04T00:25:59.014966Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 3411477,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 3411477
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 3411477
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 3411477
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 7,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 7
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-09-03T22:02:35.348363Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "7 call(s) in review window"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "69e1a255-a8b9-4101-8a68-b1bed23abfda",
|
||||||
|
"interface_key": "rest_api:GET /workstreams/{workstream_id}/dependencies/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T00:25:59.291135Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}/dependencies/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T00:25:59.291135Z",
|
||||||
|
"updated_at": "2026-06-04T00:25:59.291135Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 1643952,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 1643952
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 1643952
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 1643952
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-21T13:50:30.082480Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 14d of 60d required for 1643952 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "b1aae931-b51f-4a85-a723-865dd65f6132",
|
||||||
|
"interface_key": "rest_api:PATCH /workstreams/{workstream_id}",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T06:09:41.901035Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T06:09:41.901035Z",
|
||||||
|
"updated_at": "2026-06-04T06:09:41.901035Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 584,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 584
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 584
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 584
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-16T16:33:34.045078Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 18d of 30d required for 584 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "ed6451c9-d2cc-4486-9afe-d3852782cabc",
|
||||||
|
"interface_key": "rest_api:POST /workstreams/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T07:40:24.168535Z",
|
||||||
|
"replacement_ref": "/workplans/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "legacy",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": null,
|
||||||
|
"retired_at": null,
|
||||||
|
"created_at": "2026-06-04T07:40:24.168535Z",
|
||||||
|
"updated_at": "2026-06-04T07:40:24.168535Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 811,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 811
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 811
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 811
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-08-16T01:03:41.093965Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "quiet 19d of 30d required for 811 all-time call(s)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"interface": {
|
||||||
|
"id": "281fd706-b192-4194-8055-2d8733c115f9",
|
||||||
|
"interface_key": "rest_api:POST /workstreams/{workstream_id}/dependencies/",
|
||||||
|
"interface_kind": "rest_api",
|
||||||
|
"legacy_since": "2026-06-04T22:57:37.149207Z",
|
||||||
|
"replacement_ref": "/workplans/{workplan_id}/dependencies/",
|
||||||
|
"owner_component": "state-hub.api",
|
||||||
|
"status": "retired",
|
||||||
|
"replacement_verified": true,
|
||||||
|
"manual_hold": false,
|
||||||
|
"hold_reason": null,
|
||||||
|
"notes": "Retired by STATE-WP-0069 closeout",
|
||||||
|
"retired_at": "2026-08-31T08:55:09.130713Z",
|
||||||
|
"created_at": "2026-06-04T22:57:37.149207Z",
|
||||||
|
"updated_at": "2026-08-31T08:55:09.123888Z"
|
||||||
|
},
|
||||||
|
"all_time": {
|
||||||
|
"calls": 4975,
|
||||||
|
"tenant_count": 1,
|
||||||
|
"user_count": 1,
|
||||||
|
"component_count": 1,
|
||||||
|
"tenants": {
|
||||||
|
"unknown": 4975
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"unknown": 4975
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"unknown": 4975
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"calls": 0,
|
||||||
|
"tenant_count": 0,
|
||||||
|
"user_count": 0,
|
||||||
|
"component_count": 0,
|
||||||
|
"tenants": {},
|
||||||
|
"users": {},
|
||||||
|
"components": {}
|
||||||
|
},
|
||||||
|
"last_seen_at": "2026-07-07T20:31:35.389791Z",
|
||||||
|
"retirement_candidate": false,
|
||||||
|
"retirement_reason": "already retired"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"retirement_candidates": []
|
||||||
|
},
|
||||||
|
"days": 7
|
||||||
|
}
|
||||||
47
docs/evidence/repository-collection-projection-20260905.md
Normal file
47
docs/evidence/repository-collection-projection-20260905.md
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Repository collection query bound — 2026-09-05
|
||||||
|
|
||||||
|
STATE-WP-0087 review of the pending patch found a second loading path to bound:
|
||||||
|
`ManagedRepo.domain` could eagerly fetch domain topics/goals, and resolving a
|
||||||
|
filter with a full `Domain` object could load its entire repository graph.
|
||||||
|
The collection now joins only the domain row needed for `domain_slug`, suppresses
|
||||||
|
other relationships, and resolves domain filters with a scalar ID query.
|
||||||
|
Canonical/alias records are fetched together in one registry query.
|
||||||
|
|
||||||
|
## Production-shaped measurement
|
||||||
|
|
||||||
|
Command: `uv run pytest -q -s tests/test_repository_collection_projection.py`
|
||||||
|
|
||||||
|
Real local PostgreSQL (`custodian_test`), FastAPI through HTTPX ASGITransport,
|
||||||
|
with canonical slug records, an alias, and a pre-backfill repository. Measurements
|
||||||
|
cover HTTP handling and serialization, excluding fixture setup. These are single
|
||||||
|
local samples, not deployed-service latency or a percentile benchmark. The
|
||||||
|
regression asserts SQL counts rather than timing thresholds.
|
||||||
|
|
||||||
|
| Repository count | Domain filter | SQL SELECTs | Request seconds |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 4 | No | 2 | 0.0377 |
|
||||||
|
| 131 | No | 2 | 0.0627 |
|
||||||
|
| 501 | No | 2 | 0.1751 |
|
||||||
|
| 4 | Yes | 3 | 0.0480 |
|
||||||
|
| 131 | Yes | 3 | 0.0642 |
|
||||||
|
| 501 | Yes | 3 | 0.1686 |
|
||||||
|
|
||||||
|
Exactly one SELECT reads `repository_slugs` in each nonempty case. The 501-row
|
||||||
|
case exceeds SQLAlchemy's usual select-in batch size and guards against
|
||||||
|
accidentally restoring eager relationship batching. An empty collection skips
|
||||||
|
the registry query. Tests also compare collection/detail behavior for absent
|
||||||
|
registry entries, missing canonicals, and mismatched canonicals; classification
|
||||||
|
and secondary-domain filters retain their existing behavior.
|
||||||
|
|
||||||
|
This bounds database round trips, not response size: the existing unpaginated
|
||||||
|
list still requires memory and serialization proportional to the fleet size.
|
||||||
|
The optional SBOM owner read remains unchanged. No deployment was performed.
|
||||||
|
|
||||||
|
## Regression validation
|
||||||
|
|
||||||
|
`uv run pytest -q tests/test_repository_collection_projection.py
|
||||||
|
tests/test_routers_core.py tests/test_repository_alias_routing.py
|
||||||
|
tests/test_repository_rename_api.py tests/test_repository_rename_persistence.py
|
||||||
|
tests/test_sbom_nexus_compat.py`
|
||||||
|
|
||||||
|
Result: **102 passed in 129.14s**. `git diff --check` passed.
|
||||||
168
tests/test_repository_collection_projection.py
Normal file
168
tests/test_repository_collection_projection.py
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import time
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from sqlalchemy import delete, event, update
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
||||||
|
|
||||||
|
from api.models.managed_repo import ManagedRepo
|
||||||
|
from api.models.repository_rename import RepositorySlug
|
||||||
|
from tests.conftest import create_test_domain, create_test_repo
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.parametrize("repository_count", [4, 131, 501])
|
||||||
|
@pytest.mark.parametrize("filter_domain", [False, True])
|
||||||
|
async def test_repository_collection_projects_identities_with_one_registry_query(
|
||||||
|
client, test_engine, monkeypatch, repository_count, filter_domain
|
||||||
|
):
|
||||||
|
domain = await create_test_domain(client)
|
||||||
|
repositories = [
|
||||||
|
ManagedRepo(
|
||||||
|
id=uuid.uuid4(),
|
||||||
|
domain_id=uuid.UUID(domain["id"]),
|
||||||
|
slug=f"bounded-repo-{index}",
|
||||||
|
name=f"Bounded repo {index:04d}",
|
||||||
|
)
|
||||||
|
for index in range(repository_count)
|
||||||
|
]
|
||||||
|
|
||||||
|
factory = async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False)
|
||||||
|
async with factory() as session:
|
||||||
|
session.add_all(repositories)
|
||||||
|
await session.flush()
|
||||||
|
session.add_all([
|
||||||
|
RepositorySlug(repo_id=repo.id, slug=repo.slug, kind="canonical")
|
||||||
|
for repo in repositories[:-1]
|
||||||
|
])
|
||||||
|
session.add(
|
||||||
|
RepositorySlug(
|
||||||
|
repo_id=repositories[0].id,
|
||||||
|
slug="bounded-repo-old-name",
|
||||||
|
kind="alias",
|
||||||
|
protected=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
await session.commit()
|
||||||
|
|
||||||
|
async def reject_per_repository_resolution(*_args, **_kwargs):
|
||||||
|
raise AssertionError("collection must not resolve repository identities one at a time")
|
||||||
|
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"api.routers.repos.repository_resolution_for_id",
|
||||||
|
reject_per_repository_resolution,
|
||||||
|
)
|
||||||
|
|
||||||
|
statements: list[str] = []
|
||||||
|
|
||||||
|
def capture_statement(_conn, _cursor, statement, _parameters, _context, _executemany):
|
||||||
|
statements.append(statement)
|
||||||
|
|
||||||
|
event.listen(test_engine.sync_engine, "before_cursor_execute", capture_statement)
|
||||||
|
try:
|
||||||
|
started = time.perf_counter()
|
||||||
|
response = await client.get("/repos/", params={"domain": domain["slug"]} if filter_domain else {})
|
||||||
|
elapsed = time.perf_counter() - started
|
||||||
|
finally:
|
||||||
|
event.remove(test_engine.sync_engine, "before_cursor_execute", capture_statement)
|
||||||
|
|
||||||
|
assert response.status_code == 200, response.text
|
||||||
|
assert len(response.json()) == repository_count
|
||||||
|
assert all(repo["domain_slug"] == domain["slug"] for repo in response.json())
|
||||||
|
by_slug = {repository["slug"]: repository for repository in response.json()}
|
||||||
|
assert by_slug["bounded-repo-0"]["aliases"] == ["bounded-repo-old-name"]
|
||||||
|
assert by_slug["bounded-repo-0"]["slug_status"] == "canonical"
|
||||||
|
assert by_slug[repositories[-1].slug]["aliases"] == []
|
||||||
|
assert by_slug[repositories[-1].slug]["canonical_slug"] == repositories[-1].slug
|
||||||
|
|
||||||
|
registry_selects = [
|
||||||
|
statement
|
||||||
|
for statement in statements
|
||||||
|
if statement.lstrip().upper().startswith("SELECT")
|
||||||
|
and "repository_slugs" in statement.lower()
|
||||||
|
]
|
||||||
|
assert len(registry_selects) == 1
|
||||||
|
|
||||||
|
selects = [statement for statement in statements if statement.lstrip().upper().startswith("SELECT")]
|
||||||
|
assert len(selects) == (3 if filter_domain else 2), selects
|
||||||
|
print(f"\ncollection: repositories={repository_count}, filtered={filter_domain}, selects={len(selects)}, elapsed_seconds={elapsed:.4f}")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_empty_repository_collection_skips_registry_query(client, test_engine):
|
||||||
|
statements = []
|
||||||
|
|
||||||
|
def capture(_conn, _cursor, statement, *_args):
|
||||||
|
statements.append(statement)
|
||||||
|
|
||||||
|
event.listen(test_engine.sync_engine, "before_cursor_execute", capture)
|
||||||
|
try:
|
||||||
|
response = await client.get("/repos/")
|
||||||
|
finally:
|
||||||
|
event.remove(test_engine.sync_engine, "before_cursor_execute", capture)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.json() == []
|
||||||
|
assert not any("repository_slugs" in statement for statement in statements)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.parametrize("registry_state", ["missing", "alias_only", "canonical_mismatch"])
|
||||||
|
async def test_collection_matches_detail_identity_compatibility(
|
||||||
|
client, test_engine, registry_state
|
||||||
|
):
|
||||||
|
domain = await create_test_domain(client)
|
||||||
|
repo = await create_test_repo(client, domain_slug=domain["slug"])
|
||||||
|
factory = async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False)
|
||||||
|
async with factory() as session:
|
||||||
|
if registry_state == "missing":
|
||||||
|
await session.execute(delete(RepositorySlug).where(RepositorySlug.repo_id == repo["id"]))
|
||||||
|
else:
|
||||||
|
await session.execute(
|
||||||
|
update(RepositorySlug).where(RepositorySlug.repo_id == repo["id"]).values(kind="alias")
|
||||||
|
)
|
||||||
|
if registry_state == "canonical_mismatch":
|
||||||
|
session.add(RepositorySlug(repo_id=repo["id"], slug="different-canonical", kind="canonical"))
|
||||||
|
await session.commit()
|
||||||
|
detail = await client.get(f"/repos/{repo['slug']}")
|
||||||
|
collection = await client.get("/repos/")
|
||||||
|
if registry_state == "missing":
|
||||||
|
assert detail.status_code == collection.status_code == 200
|
||||||
|
for field in ("canonical_slug", "requested_slug", "aliases", "slug_status"):
|
||||||
|
assert collection.json()[0][field] == detail.json()[field]
|
||||||
|
else:
|
||||||
|
assert detail.status_code == collection.status_code == 409
|
||||||
|
assert collection.json() == detail.json()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_collection_filters_secondary_domain_and_classification(client, test_engine):
|
||||||
|
primary = await create_test_domain(client)
|
||||||
|
secondary = await create_test_domain(client, slug="secondary", name="Secondary")
|
||||||
|
factory = async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False)
|
||||||
|
async with factory() as session:
|
||||||
|
session.add_all([
|
||||||
|
ManagedRepo(
|
||||||
|
domain_id=uuid.UUID(primary["id"]), slug="included", name="Included",
|
||||||
|
secondary_domains=[secondary["slug"]], category="service",
|
||||||
|
capability_tags=["projection"], business_stake=["internal"],
|
||||||
|
),
|
||||||
|
ManagedRepo(
|
||||||
|
domain_id=uuid.UUID(primary["id"]), slug="excluded", name="Excluded",
|
||||||
|
category="service", capability_tags=["projection"], business_stake=["internal"],
|
||||||
|
),
|
||||||
|
])
|
||||||
|
await session.commit()
|
||||||
|
params = {"domain": secondary["slug"], "category": "service",
|
||||||
|
"capability_tag": "projection", "business_stake": "internal"}
|
||||||
|
response = await client.get("/repos/", params=params)
|
||||||
|
assert response.status_code == 200, response.text
|
||||||
|
assert [repo["slug"] for repo in response.json()] == ["included"]
|
||||||
|
assert response.json()[0]["domain_slug"] == primary["slug"]
|
||||||
|
for key in ("category", "capability_tag", "business_stake"):
|
||||||
|
response = await client.get("/repos/", params={**params, key: "absent"})
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.json() == []
|
||||||
|
response = await client.get("/repos/", params={"domain": "missing"})
|
||||||
|
assert response.status_code == 404
|
||||||
|
|
@ -8,7 +8,7 @@ status: blocked
|
||||||
owner: codex
|
owner: codex
|
||||||
topic_slug: infotech
|
topic_slug: infotech
|
||||||
created: "2026-08-09"
|
created: "2026-08-09"
|
||||||
updated: "2026-08-31"
|
updated: "2026-09-05"
|
||||||
parent_project: prj-state-hub-retirement
|
parent_project: prj-state-hub-retirement
|
||||||
parent_workplan: SHR-WP-0001
|
parent_workplan: SHR-WP-0001
|
||||||
related:
|
related:
|
||||||
|
|
@ -529,6 +529,13 @@ the two workstream mutations have 14/30 and 15/30 quiet days. A future review
|
||||||
must recapture central-primary evidence and apply the existing volume ladder;
|
must recapture central-primary evidence and apply the existing volume ladder;
|
||||||
calendar passage alone is not retirement evidence.
|
calendar passage alone is not retirement evidence.
|
||||||
|
|
||||||
|
**Repository review 2026-09-05.** Reviewed the four existing daily captures
|
||||||
|
`docs/evidence/legacy-meter-weekly-review-20260901.json` through
|
||||||
|
`legacy-meter-weekly-review-20260904.json`: each reports 6 retired interfaces,
|
||||||
|
9 legacy interfaces, and zero retirement candidates. These captures corroborate
|
||||||
|
the existing hold; no additional retirement is justified. T04/T05/T06 remain
|
||||||
|
`wait` with their existing owner and quiet-window dependencies.
|
||||||
|
|
||||||
## Stabilization window and archive prep
|
## Stabilization window and archive prep
|
||||||
|
|
||||||
```task
|
```task
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
---
|
||||||
|
id: STATE-WP-0087
|
||||||
|
type: workplan
|
||||||
|
title: "Bound the repository collection projection"
|
||||||
|
domain: infotech
|
||||||
|
repo: state-hub
|
||||||
|
status: finished
|
||||||
|
owner: codex
|
||||||
|
topic_slug: infotech
|
||||||
|
created: "2026-09-04"
|
||||||
|
updated: "2026-09-05"
|
||||||
|
origin: "intake:01a06e0c-3feb-7920-a6f2-961b03dc170d"
|
||||||
|
origin_ref: STATE-WP-0081
|
||||||
|
quality_dor: DoR-Ok
|
||||||
|
quality_dor_at: "2026-09-04"
|
||||||
|
quality_dor_by: codex
|
||||||
|
quality_dor_note: >-
|
||||||
|
The live 131-repository collection exceeds 15 seconds and the implementation
|
||||||
|
reveals per-repository identity queries. Scope, owner, dependency-free patch,
|
||||||
|
and query-bound regression signal are explicit.
|
||||||
|
quality_dod: DoD-Ok
|
||||||
|
quality_dod_at: "2026-09-05"
|
||||||
|
quality_dod_by: codex
|
||||||
|
quality_dod_note: >-
|
||||||
|
Bulk identity projection and domain-loading bounds are covered by 102 passing
|
||||||
|
repository/router regressions. Production-shaped PostgreSQL timing and SQL
|
||||||
|
counts are recorded in docs/evidence/repository-collection-projection-20260905.md.
|
||||||
|
reviewed_at: "2026-09-05"
|
||||||
|
reviewed_against_commit: "4cef58c"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Bound the repository collection projection
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Make `GET /repos/` complete with a database-query count that does not grow with
|
||||||
|
the number of repositories, while preserving its existing list response and
|
||||||
|
alias metadata. This promotes residual intake
|
||||||
|
`01a06e0c-3feb-7920-a6f2-961b03dc170d` from `STATE-WP-0081`.
|
||||||
|
|
||||||
|
Scope includes the repository collection query, identity/alias projection, and
|
||||||
|
focused regression tests. Pagination and changes to the public response shape
|
||||||
|
are out of scope because removing the N+1 projection makes the existing fleet
|
||||||
|
read bounded without a collection-contract migration. Dependencies: none.
|
||||||
|
|
||||||
|
## Bulk-project repository identities
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: STATE-WP-0087-T01
|
||||||
|
status: done
|
||||||
|
priority: high
|
||||||
|
quality_dor: DoR-Ok
|
||||||
|
quality_dor_at: "2026-09-04"
|
||||||
|
quality_dor_by: codex
|
||||||
|
```
|
||||||
|
|
||||||
|
Load canonical and alias slug records once for the collection, construct the
|
||||||
|
existing identity response from that bulk result, and suppress unrelated eager
|
||||||
|
relationships. Preserve compatibility for repositories created before the slug
|
||||||
|
registry backfill. Done when focused API tests prove alias fidelity and a
|
||||||
|
constant repository-slug query count, and the full repository router suite is
|
||||||
|
green.
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
|
||||||
|
- [x] Collection identity projection does not issue queries per repository.
|
||||||
|
- [x] Canonical, alias, and pre-backfill compatibility responses are preserved.
|
||||||
|
- [x] Focused and repository router tests pass.
|
||||||
|
- [x] Live or production-shaped timing evidence is recorded.
|
||||||
|
|
||||||
|
## Completion — 2026-09-05
|
||||||
|
|
||||||
|
Reviewed and completed the pending collection patch. The collection performs one
|
||||||
|
repository/domain SELECT and one registry SELECT; a domain filter adds one
|
||||||
|
scalar domain-ID SELECT. Suppressing eager domain relationships also prevents
|
||||||
|
unrelated topics, goals, repositories, and rename history from being loaded.
|
||||||
|
The response shape, aliases, pre-backfill behavior, conflict responses, and
|
||||||
|
classification filters are preserved.
|
||||||
|
|
||||||
|
Validation: `uv run pytest -q tests/test_repository_collection_projection.py
|
||||||
|
tests/test_routers_core.py tests/test_repository_alias_routing.py
|
||||||
|
tests/test_repository_rename_api.py tests/test_repository_rename_persistence.py
|
||||||
|
tests/test_sbom_nexus_compat.py` — **102 passed in 129.14s**. `git diff --check`
|
||||||
|
also passed. Production-shaped timing evidence:
|
||||||
|
`docs/evidence/repository-collection-projection-20260905.md` (4, 131, and 501
|
||||||
|
repositories; constant two/three SELECTs without/with a domain filter).
|
||||||
|
|
||||||
|
No implementation residuals. This closes the scope promoted from intake
|
||||||
|
`01a06e0c-3feb-7920-a6f2-961b03dc170d`. Deployment is outside this source-change
|
||||||
|
workplan; the timing evidence uses the local test database, not the running
|
||||||
|
central service. The separate retirement and HA workplans retain their gates.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue