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.exc import IntegrityError
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import noload
|
||||
from sqlalchemy.orm import joinedload, noload
|
||||
|
||||
from api.config import settings
|
||||
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 (
|
||||
RepositorySlugResolution,
|
||||
affected_slug_predicate,
|
||||
repository_resolutions_for_repositories,
|
||||
repository_resolution_for_id,
|
||||
resolve_repository_slug,
|
||||
stale_external_references,
|
||||
|
|
@ -126,17 +127,20 @@ async def list_repos(
|
|||
response.headers["Cache-Control"] = "max-age=60, stale-while-revalidate=30"
|
||||
q = (
|
||||
select(ManagedRepo)
|
||||
.options(noload(ManagedRepo.goals))
|
||||
.options(
|
||||
noload("*"),
|
||||
joinedload(ManagedRepo.domain).noload("*"),
|
||||
)
|
||||
.order_by(ManagedRepo.name)
|
||||
)
|
||||
if domain:
|
||||
domain_result = await session.execute(select(Domain).where(Domain.slug == domain))
|
||||
domain_obj = domain_result.scalar_one_or_none()
|
||||
if domain_obj is None:
|
||||
domain_result = await session.execute(select(Domain.id).where(Domain.slug == domain))
|
||||
domain_id = domain_result.scalar_one_or_none()
|
||||
if domain_id is None:
|
||||
raise HTTPException(status_code=404, detail=f"Domain '{domain}' not found")
|
||||
q = q.where(
|
||||
or_(
|
||||
ManagedRepo.domain_id == domain_obj.id,
|
||||
ManagedRepo.domain_id == domain_id,
|
||||
ManagedRepo.secondary_domains.contains([domain]),
|
||||
)
|
||||
)
|
||||
|
|
@ -147,7 +151,9 @@ async def list_repos(
|
|||
if business_stake:
|
||||
q = q.where(ManagedRepo.business_stake.contains([business_stake]))
|
||||
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)
|
||||
|
|
@ -944,6 +950,7 @@ async def _project_repo_reads(
|
|||
repositories: list[ManagedRepo],
|
||||
*,
|
||||
requested: RepositorySlugResolution | None = None,
|
||||
resolutions: dict[uuid.UUID, RepositorySlugResolution] | None = None,
|
||||
include_stale_external: bool = False,
|
||||
) -> list[RepoRead]:
|
||||
projections = await _sbom_projection_map()
|
||||
|
|
@ -952,7 +959,11 @@ async def _project_repo_reads(
|
|||
resolution = (
|
||||
requested
|
||||
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 = read.model_copy(
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from dataclasses import dataclass
|
|||
from fastapi import HTTPException
|
||||
from sqlalchemy import func, or_, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import noload
|
||||
|
||||
from api.models.fabric_graph import FabricGraphEdge, FabricGraphImport, FabricGraphNode
|
||||
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:
|
||||
"""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
|
||||
topic_slug: infotech
|
||||
created: "2026-08-09"
|
||||
updated: "2026-08-31"
|
||||
updated: "2026-09-05"
|
||||
parent_project: prj-state-hub-retirement
|
||||
parent_workplan: SHR-WP-0001
|
||||
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;
|
||||
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
|
||||
|
||||
```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