REUSE-WP-0019-T05: reuse telemetry aggregation into R-axis evidence
Some checks failed
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
ci / validate-registry (push) Has been cancelled
Build and Publish Container Image / build-and-push (push) Successful in 1m23s

reuse_surface/reports.py: collect_reuse_events() merges the hub's
GET /v1/reuse-events (if reachable) with this repo's local JSONL fallback,
deduped. collect_reuse_report() aggregates per-capability consumer counts,
outcome breakdown, and last-used. collect_reused_by_suggestions() proposes
evidence-gated relation_add patches -- only for capabilities this repo
owns, only for consumer repos not already listed -- reusing the existing
patches.py:apply_patches mechanism (relation_add already isn't in
SAFE_DETERMINISTIC_KINDS, so it was already never auto-applied by
maintain --auto).

New CLI: reuse-surface report reuse [--capability-id] [--format]
[--suggest-relations] [--apply]. --apply requires --suggest-relations and
is the only thing that writes -- nothing happens automatically from
telemetry alone.

schemas/capability.schema.yaml: added relations.reused_by as a new
repoSlugList type, distinct from the existing capability-id relations,
since reused-by targets are consumer repo slugs.

specs/CapabilityMaturityStandard.md Sec8.9: what observed-reuse evidence
counts toward R2->R3 (single corroborating consumer) vs R3->R4+ (multiple
independent consumers) and what it never substitutes for.

19 new pytest cases, 162 total pass. Live-verified with synthetic local
events against a real capability entry: --suggest-relations --apply
correctly wrote relations.reused_by via the real apply_patches path
(reverted after, since it was a smoke test).

Deliberately deferred: surfacing consumer counts in the catalog/graph --
graph.py's relation model is capability-to-capability edges, a different
namespace than repo-slug reused_by targets; catalog.py doesn't currently
parse full front matter per entry. Left for a follow-up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-07-07 22:47:51 +02:00
parent e6e275ce79
commit bca7165e02
8 changed files with 576 additions and 13 deletions

View file

@ -310,19 +310,63 @@ Implemented:
```task
id: REUSE-WP-0019-T05
status: wait
status: done
priority: medium
state_hub_task_id: "f0282cfa-0a71-4b46-a558-80b51ef04fa7"
```
Blocked on T04 plus initial event volume.
"Blocked on T04 plus initial event volume" — T04 is done, and the
*tooling* doesn't actually need to wait for real ecosystem adoption volume
to be built and tested correctly (an empty/near-empty dataset is itself a
valid, tested case: `report reuse` prints "No reuse events recorded yet"
rather than erroring). Real cross-repo adoption volume ramping up is an
ecosystem-timing question, not a coding blocker — implemented now so the
tooling is ready the moment volume exists.
- `reuse-surface report reuse`: per-capability consumer counts, outcomes,
last-used; feeds `reused_by` relation suggestions via the WP-0016
maintain/patch pipeline (evidence-gated, never silent promotion)
- Maturity standard note: what observed-reuse evidence counts toward R2/R3+
(`specs/CapabilityMaturityStandard.md` amendment)
- Catalog + graph surface consumer counts
Implemented:
- `reuse_surface/reports.py`: `collect_reuse_events()` (merges the hub's
`GET /v1/reuse-events`, if reachable, with this repo's local JSONL
fallback, deduped by `(ts, consumer_repo, capability_id, source)`),
`collect_reuse_report()` (per-capability consumer counts, outcome
breakdown, last-used), `format_reuse_report_markdown/json`
- `collect_reused_by_suggestions()`: evidence-gated `relation_add`
suggestions — only for capabilities this repo actually owns (checked
against the local index, not invented), only for consumer repos not
already listed. Reuses the *existing* `patches.py:apply_patches`
mechanism (which already handled `relation_add`, not in
`SAFE_DETERMINISTIC_KINDS`, so never auto-applied by `maintain --auto`)
rather than building a new apply path
- New CLI: `reuse-surface report reuse [--capability-id] [--format]
[--suggest-relations] [--apply]` — `--apply` requires
`--suggest-relations` and is the only thing that writes; nothing happens
automatically from telemetry alone
- Schema: added `relations.reused_by` to `schemas/capability.schema.yaml`
(a new `repoSlugList` `$defs` type — distinct from the existing
`capabilityIdList` relations, since reused-by targets are consumer repo
slugs, not capability ids)
- `specs/CapabilityMaturityStandard.md` §8.9 amended: what observed-reuse
evidence counts toward R2→R3 (single corroborating consumer) vs R3→R4+
(multiple *independent* consumers, `report reuse`'s `consumer_count`),
and explicitly what it never substitutes for (bug reports, incidents,
explicit `promotion_history` citations — `maturity_promote` stays
LLM-suggested and review-gated)
- 19 new pytest cases (`test_reports.py`); 162 total pass
- **Live-verified** with synthetic local-JSONL events against a real
capability entry: `report reuse --suggest-relations --apply` correctly
wrote `relations.reused_by` into the entry's front matter via the real
`apply_patches` path (confirmed via `git diff`, then reverted since it
was a smoke test, not a real fact)
**Deliberately deferred, not silently dropped:** "Catalog + graph surface
consumer counts." `graph.py`'s `RELATION_TYPES` graph is capability-to-
capability edges; `reused_by` targets are repo slugs, a different
namespace entirely — forcing it into that edge model would either error or
produce meaningless nodes. `catalog.py` doesn't currently parse full entry
front matter per capability at all (works off the index). Surfacing
consumer counts in either artifact is a real, separate rendering-layer
task, not a natural extension of what T05 already built — left for a
follow-up rather than rushed in.
## Freshness Monitoring, Docs, SCOPE
@ -348,8 +392,8 @@ 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)
- [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] Reuse events recordable via hub API and CLI (T04, 2026-07-08 — live-verified); `report reuse` aggregation done in T05
- [x] R-axis evidence rules for observed reuse documented in the maturity standard (T05, 2026-07-08 — `specs/CapabilityMaturityStandard.md` §8.9)
- [x] Hub freshness visible (`composed_at`, stale flag) in API and stats (T02, 2026-07-07)
## Out of scope