The WordPress Client Report: I Found 30 Things And Reported 7.

I ran the same checks across six sites and got 30 findings. Only 7 belonged in a report. Here is the rule I used to cut the rest.

Aditya Sharma·9 min read

Short answer: a good WordPress client report is short because most findings are not news. I ran one pass of external checks across six of our own sites, got 30 findings, and judged 7 of them worth telling anyone about. The other 23 were true, unchanged since last month, and unchanged next month.

Collecting the data took under seven seconds a site. Deciding what to leave out took considerably longer, and that is the whole job.

What one pass actually turns up

Table of six sites with raw finding counts and how many were worth reporting. posimyth.com 4 findings 1 worth reporting, theplusaddons.com 6 and 2, nexterwp.com 5 and 1, uichemy.com 5 and 1, protuno.com 2 and 0, wpagentconnector.com 8 and 2
One site produced nothing worth reporting. That is a legitimate result and almost nobody

sends that report.*

SiteRaw findingsWorth reporting
posimyth.com41
theplusaddons.com62
nexterwp.com51
uichemy.com51
protuno.com20
wpagentconnector.com82

The row I want to defend is protuno.com. Two findings, zero reportable. If a client pays a retainer and the honest answer this month is “nothing needed your attention”, the report should say that, in one line, and stop.

Padding it out is how reports get long. Long reports get skimmed. Skimmed reports mean the one thing that did matter gets skimmed too.

The rule I used to cut 23 of them

Sort the findings by how many sites they appear on.

Table splitting the same 30 findings by prevalence. Missing DNSSEC on 6 of 6 sites, missing CAA on 5 of 6, no Content-Security-Policy on 5 of 6, no Referrer-Policy on 5 of 6. Usernames exposed via REST on 3 of 6 and DMARC not fully enforcing on 4 of 6 are site-specific and actionable
If something appears on every site you look after, it is a decision you have not made yet,

not a finding about any one site.*

FindingSites affectedWhat it actually is
missing DNSSEC6 of 6every site, a posture decision made once
missing CAA record5 of 6every site but one, same
no Content-Security-Policy5 of 6a project, not a monthly line item
no Referrer-Policy5 of 6same
usernames exposed via REST3 of 6site-specific, actionable, report it
DMARC not fully enforcing4 of 6site-specific, actionable, report it

Caveat: six sites, all ours, one pass. The specific counts are our portfolio’s, not a benchmark. The rule that survives the caveat is the sorting method itself: anything on every site is a standards conversation, not a finding, regardless of what the six numbers happen to be.

Missing DNSSEC turned up on all six. That is not six findings. It is one conversation about whether we run DNSSEC, held once, with an answer that applies to everything. Putting it in six monthly reports is six chances for a client to read a red item and do nothing, which trains them that red items do not require action.

The two that survived the cut are site-specific and have an obvious next step. Usernames readable through the REST API affected three sites and not the others, so something differs between them. DMARC not fully enforcing affected four, each for a different reason, and I wrote up what a policy at 5% is really doing separately.

Those go in the report. The other four go in a single note about portfolio standards.

Running the same pass again, and applying the same rule to what changed

I re-ran the checks across the same six sites while expanding this post, rather than assume the original 30-versus-7 split still describes our portfolio.

dig +short DS "$d"                              # DNSSEC
dig +short CAA "$d" | wc -l                      # CAA record count
dig +short TXT "_dmarc.$d"                       # DMARC policy and pct
curl -sI "https://$d/" | grep -iE 'content-security-policy|referrer-policy'
curl -s -o /dev/null -w '%{http_code}' "https://$d/wp-json/wp/v2/users"

DNSSEC is unchanged: zero of six domains publish a DS record, still a single standards conversation rather than six findings. CAA moved on exactly one site, posimyth.com, which now publishes a complete record with ten entries, the fix already documented in the nameserver diversity post. Applying this post’s own sorting rule to that change: one site out of six moving is still a portfolio pattern, five of six still missing CAA, still a standards conversation rather than five separate line items, just with different arithmetic behind the same one-paragraph note.

The REST-endpoint and DMARC readings are where this re-run earns its place, because they moved in ways worth reporting individually rather than folding into a portfolio note. posimyth.com, open in the original pass, now returns 401 on the users endpoint, fixed. theplusaddons.com and nexterwp.com remain open, and a domain not in the original six, wpagentconnector.com, is open too. DMARC enforcement varies site by site in a way that is itself the finding: nexterwp.com and protuno.com enforce at p=reject with no pct limit, full strength. uichemy.com sits at p=none, monitoring only. posimyth.com and theplusaddons.com both carry p=quarantine; pct=5, meaning the policy only actually acts on five percent of failing mail, a partial rollout that has apparently sat at five percent since before this post was first written rather than progressing toward full enforcement.

That last detail is exactly the kind of finding this post argues belongs in a report and not in a portfolio-wide footnote: it is specific to two sites, it has an obvious next step, raise the percentage, and it is not something a reader would guess from a bare “DMARC is configured” status line. A report reading “DMARC enforcing” on posimyth.com would be technically true and practically misleading, the same category of half-true status this post’s five-section structure is built to avoid.

Collecting the data was never the hard part

I timed it, because I wanted to know whether the reporting problem is a tooling problem.

Table of report steps with measured times. Fetching the site and reading headers about one second, querying users media comments and categories about 3.4 seconds, reading abilities and settings about 1.8 seconds, resolving DMARC CAA and DNSSEC about half a second, all automatable. Deciding which of it a client should read is not automatable
Under seven seconds a site. Across forty sites that is about four minutes.

Four minutes. That is the entire data collection cost for a forty site portfolio, using nothing but the REST API and public DNS.

So when a reporting tool sells you on gathering everything automatically, understand that it is solving the four minute problem. The expensive part is the last row of that table, and no tool I have used does it. They produce a longer document faster.

What I would actually put in a WordPress client report

Five report sections in order. What changed since last month, containing diffs not state. What I did about it, with before and after numbers. What needs your decision, usually one or two items. What I am watching, kept to two lines. Everything else, available on request and not in the report
Ordered by how likely the client is to read that far.

The first section is diffs. Not “SSL certificate valid”, which is state and is true every month, but “certificate renewed on the 14th”, which is a change. State belongs in a dashboard the client can open. A report is for things that moved.

The third section is where the retainer is justified. One or two items, each phrased as a question with options and a recommendation. Not “CSP not implemented” but “we can add a content security policy to the three sites running checkout; it needs about half a day each and may break two embeds we would have to test; want me to start with the busiest one?”

That is a paragraph a client can answer. The finding underneath it is the same finding either way.

The second section is worth one more sentence, because it is where most reports quietly cheat. “Optimised images” is activity. “Homepage went from 1.5MB to 640KB” is a result. If you cannot put a before and a after next to the work, either the work did not move a number or you did not measure it, and both of those are worth knowing before a client asks.

The fourth section exists to stop the third one growing. There is always a pile of things that are real but not yet worth acting on, and without somewhere to put them they either leak into the decision section or get dropped entirely. Two lines. A list of names, no detail.

And the fifth section is a link, not an appendix. Everything I collected in those seven seconds is available if anyone wants it. Almost nobody does, and offering it is what makes the short report credible rather than lazy.

The uncomfortable bit

Writing this meant auditing our own sites and publishing what came back, including the 10 usernames readable on two of them and a domain with no DMARC at all. I would rather do that than write a post about reporting standards using invented examples.

It also made the point better than an argument could. I ran the checks, got 30 findings, and my first instinct was to fix a few quietly and report the rest. That instinct is exactly what produces reports nobody trusts, and I do not think it comes from dishonesty. It comes from the report being treated as a performance review of the agency rather than a status update on the site.

That framing is worth naming out loud with a client, once, early. If the report is a scorecard, every finding is an accusation and the incentive is to send a clean one. If the report is a shared view of the estate, a finding is just work, and the useful version of the document becomes possible.

Protuno’s marketing agent, Echo, is built around the diff rather than the state, which is why the per-site checks store history instead of a current reading. Straight with you as on every post here: Echo is built and named but not live yet.

If you send client reports, try this next cycle: write the “what needs your decision” section first, and if it is empty, send a three line email instead. See whether anybody complains.

What this re-run would actually say in a report, written out

Worth finishing the exercise all the way to the document this post argues for, using the fresh numbers above, because describing the five sections in the abstract is a different exercise from actually writing one.

What changed since last month: CAA fixed on posimyth.com. REST user enumeration fixed on posimyth.com, still open on theplusaddons.com and nexterwp.com.

What I did about it: Published the CAA fix for posimyth.com; confirmed via a fresh ten-record read. No action yet on the two sites still exposing usernames.

What needs your decision: theplusaddons.com and posimyth.com’s DMARC policy has sat at pct=5 since before this was last reported, enforcing on one message in twenty. Raising it to 25%, then 50%, then full enforcement over the next few reporting cycles is the standard rollout path, and it needs someone to actually schedule the next step rather than leave it at the figure it was set to during initial rollout. Want me to move it to 25% this week and watch the DMARC aggregate reports for anything that breaks?

What I am watching: wpagentconnector.com’s REST users endpoint, newly checked, currently open, not yet triaged against the rest of the portfolio’s standard.

Everything else: the full six-site pass, all fields, available on request.

That is six lines, not thirty findings, and every one of them is either a change, a decision, or an explicit statement of what is being watched without yet requiring action. The DNSSEC and four-of-five-sites CAA gaps that this post’s original sorting rule already filtered out do not appear at all, correctly, because nothing about them changed and they remain a standards conversation rather than six repeated line items nobody reads past the third time.

Comments