Introduces TPSC for tracking external service dependencies with GDPR
compliance maturity (CNIL/IAPP CMMI scale), pricing model, ToS, and
data retention information across all repos.
Primary data:
- canon/tpsc/{openai,anthropic,gemini,openrouter}-api.yaml — service definitions
- tpsc.yaml in each repo (llm-connect seeded with 4 services)
State-hub additions:
- Migration j7e8f9a0b1c2: tpsc_catalog + tpsc_snapshots + tpsc_entries
- api/models/tpsc.py, api/schemas/tpsc.py, api/routers/tpsc.py
- /tpsc/catalog/, /tpsc/ingest/, /tpsc/snapshots/, /tpsc/report/gdpr endpoints
- 4 MCP tools: register_service, list_services, ingest_tpsc_tool, get_gdpr_report
- scripts/ingest_tpsc.py + make ingest-tpsc[/-all] targets
- Dashboard: tpsc.md page + docs/tpsc.md
GDPR maturity scale: unknown | non_compliant | initial | developing | defined | managed | certified
Warnings triggered at: unknown, non_compliant, initial
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
5.2 KiB
id, type, title, domain, status, owner, topic_slug, created, updated, state_hub_workstream_id
| id | type | title | domain | status | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|
| CUST-WP-0023 | feature | Third-Party Services Catalog (TPSC) | custodian | done | custodian-agent | custodian | 2026-03-19 | 2026-03-20 | 23208a99-0ef6-4154-9454-a2f2065b6b19 |
TPSC — Third-Party Services Catalog
Track external service dependencies (APIs, SaaS, CLIs) across all repos.
Primary data lives in repos (tpsc.yaml) and a canon catalog
(canon/tpsc/<slug>.yaml). State-hub collects and reports.
GDPR maturity scale (CNIL/IAPP CMMI-aligned):
unknown | non_compliant | initial | developing | defined | managed | certified
Pricing model: free | paid | freemium | usage_based | unknown
Task: DB migration — tpsc_catalog, tpsc_snapshots, tpsc_entries
id: CUST-WP-0023-T01
status: done
priority: high
state_hub_task_id: "038a0284-bb76-4ce7-8861-1686667acbb5"
Create Alembic migration j7e8f9a0b1c2_tpsc.py.
Tables:
tpsc_catalog: id, slug (unique), name, provider, category, website_url, pricing_model, gdpr_maturity, gdpr_notes, dpa_available, tos_url, privacy_policy_url, data_processing_regions (JSON), data_retention_notes, status (active/deprecated), created_at, updated_attpsc_snapshots: id, repo_id (FK managed_repos nullable), snapshot_at, source_file, entry_counttpsc_entries: id, snapshot_id (FK), catalog_id (FK tpsc_catalog nullable), service_slug, purpose, auth_type, endpoint_override, notes
Task: SQLAlchemy models
id: CUST-WP-0023-T02
status: done
priority: high
state_hub_task_id: "990d4e58-35b0-45f0-8de6-8955049aa7d5"
Create api/models/tpsc.py with TPSCCatalog, TPSCSnapshot, TPSCEntry models.
Register in api/models/__init__.py.
Task: Pydantic schemas
id: CUST-WP-0023-T03
status: done
priority: high
state_hub_task_id: "5feeb161-b654-4e4a-8a6a-bb685c239ce5"
Create api/schemas/tpsc.py with Read/Create schemas for all three models.
Include GDPRMaturity and PricingModel string enums.
TPSCCatalog schema: include gdpr_warning: bool computed field
(True when gdpr_maturity in [unknown, non_compliant, initial]).
Task: FastAPI router /tpsc/
id: CUST-WP-0023-T04
status: done
priority: high
state_hub_task_id: "593471b4-cd3a-4251-8c5c-ee42b6a9e089"
Create api/routers/tpsc.py:
GET /tpsc/catalog/— list services (filter: gdpr_maturity, category, pricing_model)GET /tpsc/catalog/{slug}— single servicePOST /tpsc/catalog/— register/upsert servicePOST /tpsc/ingest/— accept snapshot + entries for a repoGET /tpsc/snapshots/— list snapshots (filter: repo_slug)GET /tpsc/report/gdpr— aggregated GDPR warnings across all repos
Register in api/main.py.
Task: MCP tools
id: CUST-WP-0023-T05
status: done
priority: high
state_hub_task_id: "7370d020-06cf-4ebe-9f78-619e41c4b85c"
Add to mcp_server/server.py:
register_service(slug, name, provider, pricing_model, gdpr_maturity, ...)list_services(gdpr_maturity?, category?, pricing_model?)ingest_tpsc_tool(repo_slug)— runs ingest_tpsc.py for the repoget_gdpr_report()— returns warning summary across all repos
Task: Ingest script
id: CUST-WP-0023-T06
status: done
priority: high
state_hub_task_id: "5ec305d3-fdfb-4f81-b3ab-1ea57a4ec0c5"
Create scripts/ingest_tpsc.py:
- Reads
tpsc.yamlfrom repo root (auto-detected via registered local_path) - Resolves catalog_id by slug for each entry
- POSTs snapshot + entries to
/tpsc/ingest/ --dry-runflag--repo SLUGor--allflags
Add Makefile targets:
make ingest-tpsc REPO=<slug>
make ingest-tpsc-all
Task: Canon service catalog seed files
id: CUST-WP-0023-T07
status: done
priority: medium
state_hub_task_id: "21c13b4d-585a-4a60-a283-29baa2dd6d7d"
Create canon/tpsc/ with YAML files for:
openai-api.yamlanthropic-api.yamlgemini-api.yamlopenrouter-api.yaml
Each file: slug, name, provider, category, pricing_model, gdpr_maturity, gdpr_notes, dpa_available, tos_url, privacy_policy_url, data_processing_regions, data_retention_notes.
Task: tpsc.yaml for llm-connect
id: CUST-WP-0023-T08
status: done
priority: medium
state_hub_task_id: "d658f81b-7408-456d-b4bd-440b44a67e43"
Create /home/worsch/llm-connect/tpsc.yaml declaring:
openai-api, anthropic-api (via claude_code CLI), gemini-api, openrouter-api.
Task: Dashboard page
id: CUST-WP-0023-T09
status: done
priority: medium
state_hub_task_id: "a5367fc4-ef12-4f52-b642-d33b91b7cc2c"
Create dashboard/src/tpsc.md:
- Service catalog table with GDPR maturity color coding (red: non_compliant/unknown, amber: initial/developing, green: defined+)
- Warning cards for repos using non-green services
- Per-repo breakdown table
- Pricing model summary
Add to observablehq.config.js nav.
Task: Documentation page
id: CUST-WP-0023-T10
status: done
priority: low
state_hub_task_id: "6cf1aaec-5c24-4cb5-a1aa-415caeaaca10"
Create dashboard/src/docs/tpsc.md explaining:
- TPSC concept and rationale
- tpsc.yaml format with full example
- GDPR maturity scale definitions (linked to CNIL/IAPP)
- How to add a new service to the canon catalog
Add to docs nav in observablehq.config.js.