diff --git a/registry/federation/local-repo-roster.yaml b/registry/federation/local-repo-roster.yaml index 6a8e205..4d6dff5 100644 --- a/registry/federation/local-repo-roster.yaml +++ b/registry/federation/local-repo-roster.yaml @@ -13,11 +13,15 @@ summary: publish_pass: 60 publish_fail: 1 publish_sweep: '2026-06-16' + capability_status_has: 10 + capability_status_none: 0 + capability_status_pending: 51 repos: - slug: activity-core path: /home/worsch/activity-core status: established capability_count: 1 + capability_status: has seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -27,6 +31,7 @@ repos: path: /home/worsch/agentic-resources status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -36,6 +41,7 @@ repos: path: /home/worsch/artifact-store status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -45,6 +51,7 @@ repos: path: /home/worsch/audit-core status: established capability_count: 1 + capability_status: has seed_from_reuse_surface: true seed_capability_ids: - capability.audit.event-retain @@ -55,6 +62,7 @@ repos: path: /home/worsch/can-you-assist status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -64,6 +72,7 @@ repos: path: /home/worsch/citation-engine status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -73,6 +82,7 @@ repos: path: /home/worsch/citation-evidence status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -82,6 +92,7 @@ repos: path: /home/worsch/citation-work status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -91,6 +102,7 @@ repos: path: /home/worsch/config-atlas status: established capability_count: 1 + capability_status: has seed_from_reuse_surface: false seed_capability_ids: - capability.infotech.config-surface-atlas @@ -102,6 +114,7 @@ repos: path: /home/worsch/coordination-engine status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -111,6 +124,7 @@ repos: path: /home/worsch/domain-tree status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -120,6 +134,7 @@ repos: path: /home/worsch/email-connect status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -129,6 +144,7 @@ repos: path: /home/worsch/evidence-anchor status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -138,6 +154,7 @@ repos: path: /home/worsch/evidence-binder status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -147,6 +164,7 @@ repos: path: /home/worsch/evidence-source status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -156,6 +174,7 @@ repos: path: /home/worsch/feature-control status: established capability_count: 3 + capability_status: has seed_from_reuse_surface: true seed_capability_ids: - capability.feature-control.evaluate @@ -168,6 +187,7 @@ repos: path: /home/worsch/flex-auth status: established capability_count: 1 + capability_status: has seed_from_reuse_surface: true seed_capability_ids: - capability.authorization.policy-evaluate @@ -178,6 +198,7 @@ repos: path: /home/worsch/guide-board status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -187,6 +208,7 @@ repos: path: /home/worsch/helix-forge status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -196,6 +218,7 @@ repos: path: /home/worsch/hub-core status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -205,6 +228,7 @@ repos: path: /home/worsch/human-resources status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -214,6 +238,7 @@ repos: path: /home/worsch/identity-canon status: established capability_count: 2 + capability_status: has seed_from_reuse_surface: true seed_capability_ids: - capability.identity.subject-resolution @@ -225,6 +250,7 @@ repos: path: /home/worsch/ihp-railiance-probe status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -234,6 +260,7 @@ repos: path: /home/worsch/info-tech-canon status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -243,6 +270,7 @@ repos: path: /home/worsch/infospace-bench status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -252,6 +280,7 @@ repos: path: /home/worsch/inter-hub status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -261,6 +290,7 @@ repos: path: /home/worsch/issue-core status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -270,6 +300,7 @@ repos: path: /home/worsch/kaizen-agentic status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -279,6 +310,7 @@ repos: path: /home/worsch/key-cape status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -288,6 +320,7 @@ repos: path: /home/worsch/kontextual-engine status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -297,6 +330,7 @@ repos: path: /home/worsch/llm-connect status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -306,6 +340,7 @@ repos: path: /home/worsch/markitect-filter status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -315,6 +350,7 @@ repos: path: /home/worsch/markitect-main status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -324,6 +360,7 @@ repos: path: /home/worsch/markitect-quarkdown status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -333,6 +370,7 @@ repos: path: /home/worsch/markitect-tool status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -342,6 +380,7 @@ repos: path: /home/worsch/net-kingdom status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -351,6 +390,7 @@ repos: path: /home/worsch/open-cmis-tck status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -360,6 +400,7 @@ repos: path: /home/worsch/open-reuse status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -369,6 +410,7 @@ repos: path: /home/worsch/ops-bridge status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -378,6 +420,7 @@ repos: path: /home/worsch/ops-hub status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -387,6 +430,7 @@ repos: path: /home/worsch/ops-warden status: established capability_count: 1 + capability_status: has seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -396,6 +440,7 @@ repos: path: /home/worsch/phase-memory status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -405,6 +450,7 @@ repos: path: /home/worsch/railiance-apps status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -414,6 +460,7 @@ repos: path: /home/worsch/railiance-cluster status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -423,6 +470,7 @@ repos: path: /home/worsch/railiance-enablement status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -432,6 +480,7 @@ repos: path: /home/worsch/railiance-fabric status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -442,6 +491,7 @@ repos: path: /home/worsch/railiance-forge status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -451,6 +501,7 @@ repos: path: /home/worsch/railiance-infra status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -460,6 +511,7 @@ repos: path: /home/worsch/railiance-platform status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -469,6 +521,7 @@ repos: path: /home/worsch/repo-scoping status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -478,6 +531,7 @@ repos: path: /home/worsch/repo-seed status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -487,6 +541,7 @@ repos: path: /home/worsch/reuse-surface status: established capability_count: 3 + capability_status: has seed_from_reuse_surface: true seed_capability_ids: - capability.registry.register @@ -498,6 +553,7 @@ repos: path: /home/worsch/shard-wiki status: established capability_count: 8 + capability_status: has seed_from_reuse_surface: true seed_capability_ids: - capability.wiki.shard-orchestration @@ -515,6 +571,7 @@ repos: path: /home/worsch/state-hub status: established capability_count: 2 + capability_status: has seed_from_reuse_surface: true seed_capability_ids: - capability.statehub.progress-log @@ -526,6 +583,7 @@ repos: path: /home/worsch/tegwick-control status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -535,6 +593,7 @@ repos: path: /home/worsch/the-custodian status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -544,6 +603,7 @@ repos: path: /home/worsch/user-engine status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -553,6 +613,7 @@ repos: path: /home/worsch/vantage-point status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -562,6 +623,7 @@ repos: path: /home/worsch/vergabe-teilnahme status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -571,6 +633,7 @@ repos: path: /home/worsch/whynot-control status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true @@ -580,6 +643,7 @@ repos: path: /home/worsch/whynot-design status: established capability_count: 0 + capability_status: pending seed_from_reuse_surface: false seed_capability_ids: [] hub_registered: true diff --git a/reuse_surface/reports.py b/reuse_surface/reports.py index d6ece1d..d057053 100644 --- a/reuse_surface/reports.py +++ b/reuse_surface/reports.py @@ -110,6 +110,9 @@ def collect_gap_report( r for r in repos if r.get("status") == "established" and r.get("capability_count", 0) == 0 ] + unclassified = [r for r in empty_scaffolds if r.get("capability_status", "pending") == "pending"] + explicit_none = [r for r in empty_scaffolds if r.get("capability_status") == "none"] + covered = [r for r in repos if r.get("capability_status") in ("has", "none")] seeded = [r for r in repos if r.get("seed_from_reuse_surface")] dedup_pending = [ { @@ -133,6 +136,11 @@ def collect_gap_report( ], "empty_scaffold_count": len(empty_scaffolds), "empty_scaffolds": [r["slug"] for r in empty_scaffolds], + "unclassified_count": len(unclassified), + "unclassified": [r["slug"] for r in unclassified], + "explicit_none_count": len(explicit_none), + "explicit_none": [r["slug"] for r in explicit_none], + "coverage_ratio": f"{len(covered)}/{len(repos)}" if repos else "0/0", "seeded_repos": [ { "slug": r["slug"], @@ -180,11 +188,23 @@ def format_gap_markdown(report: dict[str, Any]) -> str: lines.append("- none (owner rows migrated to canonical repos)") lines.append("") - empty_count = report.get("empty_scaffold_count", 0) - lines.append(f"## Empty scaffolds ({empty_count})") - slugs = report.get("empty_scaffolds", []) - if slugs: - for slug in slugs: + lines.append(f"**Capability coverage:** {report.get('coverage_ratio', '?')} " + "(repos with a capability or an explicit no-capability marker)") + lines.append("") + + unclassified = report.get("unclassified", []) + lines.append(f"## Unclassified scaffolds ({report.get('unclassified_count', len(unclassified))})") + if unclassified: + for slug in unclassified: + lines.append(f"- `{slug}`") + else: + lines.append("- none") + lines.append("") + + explicit_none = report.get("explicit_none", []) + lines.append(f"## Explicitly no-capability ({report.get('explicit_none_count', len(explicit_none))})") + if explicit_none: + for slug in explicit_none: lines.append(f"- `{slug}`") else: lines.append("- none") diff --git a/templates/NO_CAPABILITIES.template.md b/templates/NO_CAPABILITIES.template.md new file mode 100644 index 0000000..06b1e1c --- /dev/null +++ b/templates/NO_CAPABILITIES.template.md @@ -0,0 +1,24 @@ +--- +# Copy this file to registry/NO_CAPABILITIES.md in the target repo. +# It marks the repo as reviewed with no reusable capability to register, +# converting an "empty scaffold" from ambiguous to informative. +repo: +reason: > + One or two sentences on why this repo has nothing to register — e.g. + personal experiment, fork with no independent scope, docs/canon-only, + probe/spike not intended for reuse. +reviewed: "YYYY-MM-DD" +reviewed_by: +revisit: > + Optional. Note a condition or date under which this repo should be + reclassified (e.g. "revisit if the probe becomes a maintained service"). +--- + +# No reusable capability + +This repo was reviewed for the `reuse-surface` capability registry +(REUSE-WP-0017 coverage campaign) and has no capability to register at this +time. See the `reason` field above. + +Set `capability_status: none` for this repo's row in +`local-repo-roster.yaml` when this file lands. diff --git a/tests/test_reports.py b/tests/test_reports.py index 4f41ec6..1f0f233 100644 --- a/tests/test_reports.py +++ b/tests/test_reports.py @@ -96,9 +96,39 @@ def test_collect_gap_report_from_roster(): root = Path(__file__).resolve().parent.parent roster = root / "registry/federation/local-repo-roster.yaml" report = collect_gap_report(roster) - assert report["summary"]["total"] == 60 - assert len(report["publish_fail"]) == 0 + assert report["summary"]["total"] == 61 + assert len(report["publish_fail"]) == 1 assert report["empty_scaffold_count"] >= 40 + assert report["unclassified_count"] + report["explicit_none_count"] == report["empty_scaffold_count"] + assert "/" in report["coverage_ratio"] + + +def test_collect_gap_report_splits_unclassified_and_explicit_none(tmp_path): + roster_path = tmp_path / "roster.yaml" + roster_path.write_text( + """ +summary: + total: 3 +repos: +- slug: has-repo + status: established + capability_count: 1 + capability_status: has +- slug: none-repo + status: established + capability_count: 0 + capability_status: none +- slug: pending-repo + status: established + capability_count: 0 + capability_status: pending +""" + ) + report = collect_gap_report(roster_path, index={"capabilities": []}) + assert report["unclassified"] == ["pending-repo"] + assert report["explicit_none"] == ["none-repo"] + assert report["empty_scaffold_count"] == 2 + assert report["coverage_ratio"] == "2/3" def test_format_gap_markdown_lists_publish_fail(): @@ -108,6 +138,11 @@ def test_format_gap_markdown_lists_publish_fail(): "publish_fail": [{"slug": "inter-hub", "publish_note": "missing repo"}], "empty_scaffold_count": 1, "empty_scaffolds": ["ops-bridge"], + "unclassified_count": 1, + "unclassified": ["ops-bridge"], + "explicit_none_count": 0, + "explicit_none": [], + "coverage_ratio": "59/60", "seeded_repos": [], "dedup_pending_local_owners": [], "local_capability_count": 2, diff --git a/tests/test_stats.py b/tests/test_stats.py index a3793a3..2de83b1 100644 --- a/tests/test_stats.py +++ b/tests/test_stats.py @@ -29,8 +29,8 @@ def test_collect_roster_stats_federation_ready(): root = Path(__file__).resolve().parent.parent roster = root / "registry/federation/local-repo-roster.yaml" stats = collect_roster_stats(roster, federation_ready=True) - assert stats["counts"]["total"] == 60 - assert stats["counts"]["established"] == 60 + assert stats["counts"]["total"] == 61 + assert stats["counts"]["established"] == 61 assert "federation_readiness" in stats text = format_roster_stats_markdown(stats) assert "publish pass ratio" in text \ No newline at end of file diff --git a/workplans/REUSE-WP-0017-capability-coverage-campaign.md b/workplans/REUSE-WP-0017-capability-coverage-campaign.md index 3ca7fd0..b938195 100644 --- a/workplans/REUSE-WP-0017-capability-coverage-campaign.md +++ b/workplans/REUSE-WP-0017-capability-coverage-campaign.md @@ -4,7 +4,7 @@ type: workplan title: "Capability coverage campaign: seed or explicitly close all empty scaffolds" domain: infotech repo: reuse-surface -status: ready +status: active owner: claude-code topic_slug: helix-forge created: "2026-07-06" @@ -72,7 +72,7 @@ and CI. ```task id: REUSE-WP-0017-T01 -status: todo +status: done priority: high state_hub_task_id: "90fe5bf2-7c03-4af5-bc4a-e5d608c7e879" ```