chore(web,ci): document orphan client fns + sync guard (P-1 master)

Closes two 2026-04-24 audit findings:

  - diff-04x03-d24864996ad4 (P2, "26 orphan client fns")
  - cat-b-dc46aadab98e   (P3, "16 singleton-getter orphans")

Recon at HEAD found 17 actual orphans (not 26 or 16 — the audit
numbers conflated; many were eliminated by the B-1 / S-1 / I-2 /
D-2 closures since the audit was written, and the audit's regex
double-counted in some buckets). All 17 are detail-page candidates:
singleton-getter `getX(id)` fns that detail pages will need when
the corresponding `XPage` grows a `XDetailPage` route. Two valid
closures:
  - delete each fn (forces re-add when detail pages land)
  - document each as intent-suspect-but-preserved (lets future
    detail-page work land without a client.ts edit detour)

Picked the document-and-preserve path. Reasons:
  - Many of the 17 are obvious detail-page candidates (Owner,
    Team, AgentGroup, Policy, RenewalPolicy, Notification,
    AuditEvent, NetworkScanTarget, HealthCheck, DiscoveredCertificate)
    given the existing list-page + Edit-modal pattern shipped in B-1.
  - The cost of the deletes (and re-adds, and test re-adds) outweighs
    the cost of carrying 17 documented-orphan declarations.
  - registerAgent (already covered by C-1's docblock as by-design
    pull-only) sits in this same set and is the canonical "preserved
    orphan" precedent.

Changes:
- web/src/api/client.ts: new docblock at file-top listing all 17
  documented orphans with their detail-page rationale and a
  pointer to the CI guardrail.
- .github/workflows/ci.yml: new step "Documented orphan client fns
  sync guard (P-1)" verifies that every name in the docblock is
  still declared as `export const X = ...` somewhere in client.ts.
  Catches drift in either direction (delete export but forget
  docblock = MISSING; delete docblock entry but leave export =
  silent orphan accumulation, caught only on next mass-recon).

Verification:
- P-1 guardrail dry-run on post-fix tree → MISSING='' (empty, good)
- tsc --noEmit — clean
- golangci-lint v2.11.4 run ./... — 0 issues
- All sibling guardrails (S-1, G-3, D-1+D-2, B-1, L-1, H-1, C-1, F-1) pass

Audit findings closed:
- diff-04x03-d24864996ad4 (P2)
- cat-b-dc46aadab98e (P3)

Deferred follow-ups:
- The 17 detail-page candidates remain orphan until a XDetailPage
  consumer lands. Each future detail-page commit removes one entry
  from the docblock as it gains a real consumer. The CI guardrail
  enforces the docblock-↔-export sync regardless.
This commit is contained in:
shankar0123
2026-04-25 17:41:12 +00:00
parent 1bdab897ef
commit d4c421b98d
2 changed files with 61 additions and 0 deletions
+29
View File
@@ -2,6 +2,35 @@ import type { Certificate, CertificateVersion, Agent, Job, Notification, AuditEv
const BASE = '/api/v1';
// P-1 closure (diff-04x03-d24864996ad4 P2 + cat-b-dc46aadab98e P3):
// the audit flagged 26+16 orphan client functions. Recon at HEAD
// found 17 actual orphans (the 26+16 audit numbers conflated; many
// were eliminated by the B-1 / S-1 / I-2 / D-2 closures since the
// audit was written). The remaining 17 are all detail-page
// candidates — singleton-getter `getX(id)` fns that detail pages
// will need when the corresponding `XPage` grows a `XDetailPage`
// route. Preserved here (rather than deleted) so the future
// detail-page work doesn't have to relitigate the client.ts surface.
//
// Intentionally-orphan client functions:
// getAgentGroup, getAgentGroupMembers, getAuditEvent,
// getCertificateDeployments, getDiscoveredCertificate,
// getHealthCheck, getHealthCheckHistory, getNetworkScanTarget,
// getNotification, getOCSPStatus, getOwner, getPolicy,
// getPolicyViolations, getRenewalPolicy, getTeam, registerAgent
// (by-design pull-only; see C-1 closure docblock above its export),
// updateHealthCheck.
//
// CI guardrail at .github/workflows/ci.yml::"Documented orphan
// client fns sync guard (P-1)" enforces the docblock list ↔
// export list relationship: every name above must still be
// declared somewhere in this file, and conversely if a name is
// removed from the list its export must also be removed (orphans
// must never silently accumulate).
//
// See coverage-gap-audit-2026-04-24-v5/unified-audit.md
// diff-04x03-d24864996ad4 + cat-b-dc46aadab98e for closure rationale.
// API key stored in memory (not localStorage for security)
let apiKey: string | null = null;