REUSE-WP-0019-T04: reuse telemetry store and recording
Implements the hub side of the shared reuse-event schema (already drafted in WP-0018-T01, schemas/reuse-event.schema.json): a SQLite reuse_events table, POST /v1/reuse-events (token-auth), GET /v1/reuse-events?capability_id= (read-only). reuse_surface/plan_check.py: refactored record_outcome around a new shared post_or_fallback_reuse_event() helper -- tries the hub first, falls back to the local JSONL only on failure/unreachability, never both. New record_manual_reuse_event() backs a new CLI command, reuse-surface record-reuse, for retroactive facts recorded outside plan-check. Privacy/scope (repo slugs and capability ids only, no code, no secrets) is enforced structurally via the schema's additionalProperties: false, not just by convention. 21 new pytest cases, 145 total pass. Live-verified against a real running hub instance: POST/GET /v1/reuse-events directly, record-reuse and plan-check --record-outcome both posting successfully to the hub, and -- after actually killing the hub process -- confirmed the fallback path writes correctly to the local JSONL instead of erroring. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
2fcc91f2aa
commit
d181043717
12 changed files with 562 additions and 32 deletions
|
|
@ -267,18 +267,44 @@ whenever a future deploy wants to switch registries.
|
|||
|
||||
```task
|
||||
id: REUSE-WP-0019-T04
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "c8e9064e-5c39-4c84-80e9-8b255f8edaec"
|
||||
```
|
||||
|
||||
- Implement the shared schema from WP-0018-T01: reuse events
|
||||
`{ts, consumer_repo, capability_id, verdict, outcome?, source: plan-check|manual|hub}`
|
||||
- Hub: `POST /v1/reuse-events` (token-auth) + local JSONL fallback when hub
|
||||
unreachable; `GET /v1/reuse-events?capability_id=` for aggregation
|
||||
- `plan-check --record-outcome` (WP-0018) posts here; manual
|
||||
`reuse-surface record-reuse` for retroactive facts
|
||||
- Privacy/scope: repo slugs and capability ids only — no code, no secrets
|
||||
The shared schema (`schemas/reuse-event.schema.json`) already existed from
|
||||
WP-0018-T01 drafting — this task implemented the hub side and wired
|
||||
`plan-check`/manual recording against it, rather than designing it fresh.
|
||||
|
||||
Implemented:
|
||||
|
||||
- `reuse_surface/hub/store.py`: `reuse_events` SQLite table (append-only),
|
||||
`record_reuse_event()` (schema-validated, raises `ValueError` on a bad
|
||||
shape rather than silently accepting drift), `list_reuse_events(capability_id=None)`
|
||||
- `reuse_surface/hub/app.py`: `POST /v1/reuse-events` (token-auth, 201/400),
|
||||
`GET /v1/reuse-events?capability_id=` (no auth, read-only, same posture
|
||||
as `GET /v1/federated`)
|
||||
- `reuse_surface/hub_client.py`: `hub_record_reuse_event`/`hub_list_reuse_events`
|
||||
- `reuse_surface/plan_check.py`: refactored `record_outcome` around a new
|
||||
shared `post_or_fallback_reuse_event()` — tries `POST /v1/reuse-events`
|
||||
first, falls back to the local JSONL only on failure/unreachability
|
||||
(never both, per the design: "+ local JSONL fallback when hub
|
||||
unreachable", not a dual-write). New `record_manual_reuse_event()` for
|
||||
retroactive facts, sharing the same post-or-fallback path
|
||||
- New CLI command `reuse-surface record-reuse --consumer-repo --capability-id
|
||||
--verdict --outcome [--hub-url] [--format]`
|
||||
- `plan-check --record-outcome`'s help text and JSON output updated
|
||||
(`recorded_reuse_event` field); `schemas/plan-check-result.schema.json`
|
||||
extended for the new field
|
||||
- Privacy/scope enforced structurally: the schema's `additionalProperties: false`
|
||||
means a caller literally cannot attach code or secrets to an event, only
|
||||
the declared fields (repo slug, capability id, verdict, outcome, source)
|
||||
- 21 new pytest cases (hub store/API, plan_check dual-path, CLI); 145 total pass
|
||||
- **Live-verified** against a real locally-running hub instance: `POST`/`GET
|
||||
/v1/reuse-events` directly, `record-reuse` CLI posting to the hub,
|
||||
`plan-check --record-outcome` posting to the hub, and — after actually
|
||||
killing the hub process — confirmed the fallback path writes correctly
|
||||
to the local JSONL instead of erroring
|
||||
|
||||
## Telemetry Aggregation Into R-Axis Evidence
|
||||
|
||||
|
|
@ -322,7 +348,7 @@ state_hub_task_id: "a9f44d45-91e2-4b43-909f-30a5f906cf3b"
|
|||
- [x] No hardcoded forge host in code or sources.yaml; `migrate-host` tested (T01, 2026-07-07)
|
||||
- [x] Push to a sibling repo's `registry/indexes/` recomposes the hub index without manual action (webhook), with scheduled fallback in place (T02/T03, 2026-07-07 — both live-verified end to end)
|
||||
- [x] This repo's CI runs on Forgejo Actions (`.forgejo/workflows/`) (T03, 2026-07-07 — `ci.yml`/`ci-smoke.yaml`/`image.yaml` all verified green on the live push)
|
||||
- [ ] Reuse events recordable via hub API and CLI; `report reuse` aggregates them
|
||||
- [x] Reuse events recordable via hub API and CLI (T04, 2026-07-08 — live-verified); `report reuse` aggregation is T05
|
||||
- [ ] R-axis evidence rules for observed reuse documented in the maturity standard
|
||||
- [x] Hub freshness visible (`composed_at`, stale flag) in API and stats (T02, 2026-07-07)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue