discovery.py python
123 lines 4.1 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 13 hours ago
1 """Org glance discovery + repo eligibility (§HGD.4.2)."""
2
3 from __future__ import annotations
4
5 from dataclasses import dataclass
6
7 from tools.hosted_dashboard.adapters.github import GitHubAdapters, RepoMeta
8 from tools.hosted_dashboard.config import HostedDashboardConfig
9 from tools.hosted_dashboard.http_client import UpstreamError
10
11
12 ELIGIBILITY_ELIGIBLE = "eligible"
13 ELIGIBILITY_UNREADABLE = "unreadable"
14 ELIGIBILITY_NO_MARKER = "no_marker"
15
16
17 @dataclass(frozen=True)
18 class RepoSummary:
19 owner: str
20 name: str
21 full_name: str
22 default_branch: str
23 eligibility: str
24 marker_present: bool
25
26
27 def build_org_summary(adapters: GitHubAdapters, config: HostedDashboardConfig) -> list[RepoSummary]:
28 """Return allowlisted / discovered repo summaries; empty allowlist → zero repos."""
29 if not config.org_allowlist:
30 return []
31
32 candidates: list[RepoMeta] = []
33 seen: set[str] = set()
34
35 for owner, repo in config.allowlist_pairs:
36 if repo is not None:
37 full = f"{owner}/{repo}"
38 if full in seen:
39 continue
40 seen.add(full)
41 try:
42 meta = adapters.get_repo_meta(owner, repo)
43 candidates.append(meta)
44 except UpstreamError:
45 candidates.append(
46 RepoMeta(
47 owner=owner,
48 name=repo,
49 full_name=full,
50 default_branch="",
51 private=False,
52 )
53 )
54 else:
55 try:
56 enumerated = adapters.list_org_repos(owner)
57 except UpstreamError:
58 continue
59 for meta in enumerated:
60 if meta.full_name in seen:
61 continue
62 seen.add(meta.full_name)
63 candidates.append(meta)
64
65 summaries: list[RepoSummary] = []
66 for meta in candidates:
67 if not meta.default_branch:
68 summaries.append(
69 RepoSummary(
70 owner=meta.owner,
71 name=meta.name,
72 full_name=meta.full_name,
73 default_branch="",
74 eligibility=ELIGIBILITY_UNREADABLE,
75 marker_present=False,
76 )
77 )
78 continue
79 try:
80 marker = adapters.fetch_marker_summary(meta.owner, meta.name, ref=meta.default_branch)
81 except UpstreamError:
82 summaries.append(
83 RepoSummary(
84 owner=meta.owner,
85 name=meta.name,
86 full_name=meta.full_name,
87 default_branch=meta.default_branch,
88 eligibility=ELIGIBILITY_UNREADABLE,
89 marker_present=False,
90 )
91 )
92 continue
93
94 # Explicit owner/repo allowlist entries appear even without marker, but
95 # org-only discovery requires marker (§HGD.4.2).
96 explicit = any(
97 o == meta.owner and r == meta.name for o, r in config.allowlist_pairs if r is not None
98 )
99 if not marker.present and not explicit:
100 eligibility = ELIGIBILITY_NO_MARKER
101 elif not marker.present and explicit:
102 # Explicit allowlist without marker: still listed, eligibility no_marker
103 # so glance does not fabricate green — operator sees the gap.
104 eligibility = ELIGIBILITY_NO_MARKER
105 else:
106 eligibility = ELIGIBILITY_ELIGIBLE
107
108 # Filter org-discovery-only repos without marker out of the glance list.
109 org_discovered = any(o == meta.owner and r is None for o, r in config.allowlist_pairs)
110 if org_discovered and not explicit and not marker.present:
111 continue
112
113 summaries.append(
114 RepoSummary(
115 owner=meta.owner,
116 name=meta.name,
117 full_name=meta.full_name,
118 default_branch=meta.default_branch,
119 eligibility=eligibility,
120 marker_present=marker.present,
121 )
122 )
123 return summaries
File History 1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 13 hours ago