Skip to content

Add fleet_summary: a compact fleet-ready digest of a site's agent surface - #1

Merged
ilicfilip merged 1 commit into
mainfrom
feat/fleet-summary
Jul 28, 2026
Merged

ilicfilip merged 1 commit into
mainfrom
feat/fleet-summary

Conversation

@ilicfilip

Copy link
Copy Markdown
Collaborator

Why

ASA is single-site today, but agent exposure is inherently a fleet risk — one misconfigured mcp.public ability replicated across N managed sites is N problems. This adds the stable contract a fleet consumer needs to answer "how exposed is this one site?" without pulling the full per-ability report.

The immediate consumer is a MainWP Fleet Health Monitor signal: FHM now exposes an fhm_extra_signals filter (see ProgressPlanner/mainwp-fhm-dashboard#2) that takes a scored {sev, value, detail} — this field hands it exactly that. It's equally useful to a CI gate or any dashboard.

What

Audit_Runner::fleet_summary() projects the existing summary into a compact digest on the report:

"fleet_summary": {
  "sev": "crit",
  "highest_severity": "critical",
  "agent_reachable": 19,
  "agent_reachable_write": 3,
  "findings_by_severity": { "critical": 3, "high": 7, "medium": 9, "low": 6, "info": 1 },
  "analysis_errors": 0
}
  • Pure projection — every value derives from the already-computed summary; no new analysis, no I/O, no state.
  • sev is conservative (derive_sev()): critical/high → crit, medium/low → warn, info or no findings → ok. Info-only sites (e.g. a lone ASA011 awareness note) do not raise a grade.
  • Inherits the honesty invariant — the grade reflects the highest finding severity present: a smell signal, not a safety proof. A green tile is "no issues detected", never "safe".
  • Digest, not descriptors — carries counts + a grade only, deliberately minimizing what a future fleet transport would ship upstream. The full report stays put.
  • Optional on read — it rides the cached report, so a report cached just before an upgrade may briefly omit it; consumers should treat it as optional.

Scope (what this is not)

This is only the contract. The transport that carries fleet_summary from a managed site up to a dashboard (piggyback the existing PEM child, a dashboard pull, or a dedicated child plugin) is deliberately not in this PR — all three options read this same field, so the contract lands first. ASA stays single-site and its read-only / no-new-surface invariants remain literally true.

Testing

  • Unit (tests/Unit/fleet-summary-test.php) — the full severity→grade mapping, plus edge cases (multiple severities, info-only, no findings, malformed summary). Pure PHP via reflection, since the methods touch no WordPress.
  • Integration — asserts the field is a faithful projection of the real pipeline's summary and grades the critical-producing fixtures crit.
  • Verified live on WP 7.0.2 (Yoast + WP AI plugin): 19 agent-reachable, 3 reachable-write, sev=crit.
  • Gates: composer lint, composer check-cs (WPCS), composer phpstan (level 10), composer test (103 tests) all pass.

🤖 Generated with Claude Code

…rface

ASA is single-site today, but agent exposure is a fleet risk. This adds a
stable, transport-agnostic projection that fleet tooling can read to answer
"how exposed is this one site?" without the full per-ability report — the
contract a MainWP Fleet Health Monitor signal (fhm_extra_signals) or a CI
gate consumes.

- Audit_Runner::fleet_summary() projects the existing summary into
  { sev, highest_severity, agent_reachable, agent_reachable_write,
    findings_by_severity, analysis_errors }. Pure projection: no new
  analysis, no I/O, no state.
- derive_sev() maps the highest present finding severity to FHM's ok|warn|crit
  vocabulary, conservatively: critical/high -> crit, medium/low -> warn,
  info or none -> ok. Info-only sites do not raise a grade. The grade is a
  smell signal, not a safety proof (inherits the "no issues detected" != "safe"
  invariant).
- Digest, not descriptors: carries counts + a grade only, minimizing what a
  future transport would ship upstream.
- int_of() narrows the mixed summary counts for the analyzer.

Tests: pure-PHP unit coverage of the full severity->grade mapping (reflection,
since the methods are WP-free) + an integration assertion that the field is a
faithful projection of the real pipeline. README documents the field.

Verified live (WP 7.0.2, Yoast + WP AI plugin): 19 agent-reachable, 3
reachable-write, sev=crit from 3 criticals.

Gates: lint, check-cs (WPCS), phpstan (L10), test (103) all pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Signed-off-by: Filip Ilic <ilic.filip@gmail.com>
@ilicfilip
ilicfilip merged commit 084c995 into main Jul 28, 2026
12 checks passed
@ilicfilip
ilicfilip deleted the feat/fleet-summary branch July 28, 2026 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant