Rubric version: v4 · Last updated 2026-10-06
This document exists so that any score ActiScore produces can be explained, challenged and independently verified. If a prospect disputes a grade, this is the page to hand them.
It is deliberately explicit about which checks rest on published standards, which rest on industry convention, and which are ActiScore's own editorial judgment. Conflating those three is how scoring tools lose credibility.
1. How a score is produced
fetch page → extract signals → apply deduction table → weight categories → grade
(deterministic) (deterministic)- The target page is fetched server-side once, following up to 5 redirects, over ports 80/443 only, capped at 5 MB, HTML content types only.
- Signals are extracted from the response body and headers — presence, counts and lengths of well-known tags and headers. No JavaScript is executed and the page is not rendered.
- Each category starts at 100. Every failed check subtracts a fixed deduction. Category scores are floored at 0.
- The composite is a weighted mean of the ten category scores (weights in section 3), rounded.
- Letter grades are assigned from fixed score bands.
Scores are pure arithmetic. A language model writes the explanatory text and the remediation advice, and is given the already-final scores with instructions that it may not change or reinterpret them. It has no path to alter a number.
2. Reproducibility
Verified: 25 real domains × 200 iterations = 5,000 scoring runs produced byte-identical output every time. Scoring is also insensitive to the key order of the input object. There is no use of the clock, randomness, locale formatting or environment state anywhere in the scoring path.
The honest caveat. That guarantee is "same signals → same score." It is not "same website next week → same score," because the website controls what it returns. A CDN node serving a different Cache-Control, an A/B test, geographic routing, bot detection or personalisation can all change the signals legitimately. In practice two independent live captures of all 25 baseline domains produced identical scores — encouraging, but that is two samples, not a study.
Every scan is stored with its full result and its rubric version, so any past score can be reconstructed exactly and shown to have been computed correctly.
3. Category weights
| Category | Weight |
|---|---|
| Security | 24% |
| SEO | 15% |
| Performance | 14% |
| Mobile Usability | 10% |
| Local SEO | 8% |
| AEO | 8% |
| Accessibility | 8% |
| Content & UX | 6% |
| Trust | 4% |
| Best Practices | 3% |
These weights are ActiScore's editorial judgment, not an industry standard. No standards body publishes a weighting for website quality. Security leads because ActiScore is used by managed service providers whose value to a client is security posture first. A marketing agency would reasonably weight this differently, and the weights live in one constant so they can be changed.
v4 added Content & UX and Trust and took their weight proportionally from the other eight. A report scored from signals recorded before v4 has neither new category; it is not given a free 100 in them — they are left out and the other weights re-normalised.
Before v2 the composite was an unweighted mean of six categories. That let a nearly empty page score 58 (a D) by riding a fast, unremarkable Performance score and a Best Practices score it could not fail.
4. Grade bands
| Grade | Composite |
|---|---|
| A | 93–100 |
| B | 80–92 |
| C | 65–79 |
| D | 45–64 |
| F | 0–44 |
These bands are arbitrary — they mirror US academic grading because it is instantly legible, not because it is derived from data.
They are also demonstrably harsh. Across the 24 baseline sites captured on 2026-10-06, including Stripe, GitHub, Cloudflare and Mozilla, exactly one reached an A (securafy.com, run by Securafy, which uses ActiScore every day). Stripe scores 80. This is a known open question, recorded rather than hidden.
5. The checks
104 checks across ten categories. Each check lists the maximum deduction and its basis:
- Standard — a published specification or documented platform requirement.
- Convention — widely-followed industry practice with no published authority.
- Judgment — ActiScore's own choice.
Deduction magnitudes are judgment in every case, even where the check itself is a standard. A check marked v4 was added on 2026-10-06; on a scan whose signals were recorded before then it reads not checked and deducts nothing.
Security — 24% of composite
Scored two ways, and the report always says which. When DNS and TLS have been measured for a domain the full rubric below applies and the category is marked measured. On a cold first scan — before the background lookup has landed — only the response headers and the page are available, the header-only weights apply, and the category is marked inferred with a note saying so. A settled report is always measured, because the settle pass performs the lookups itself.
Full rubric (measured). Deductions total exactly 100.
| Check | Max ded. | Basis | Notes |
|---|---|---|---|
| HTTPS | 20 | Standard | Scheme of the final URL after redirects. Always a critical finding |
| DMARC Policy | 16 | Standard — RFC 7489 | p=reject passes; p=quarantine −4; p=none −11 as monitoring, not protection; absent −16, always a fail |
| SPF Record | 10 | Standard — RFC 7208 | -all passes, ~all −4, permissive −8, none −10. Over 10 DNS lookups, or naming a domain that does not exist, scores as none |
| Content-Security-Policy | 7 | Standard — W3C CSP | Presence only |
| TLS Certificate | 7 | Standard — RFC 5280 | Expired or unreachable −7; judgment: within 21 days of expiry −5 |
| Strict-Transport-Security | 6 | Standard — RFC 6797 | Presence only |
| DKIM Signing | 5 | Standard — RFC 6376 | Judgment: common selectors are probed; a miss is not proof DKIM is absent |
| Mixed Content (v4) | 5 | Standard — W3C Mixed Content | Scripts, images, frames or stylesheets loaded over http:// on an HTTPS page |
| Form Submission Security (v4) | 5 | Standard | A form whose action is an http:// URL |
| X-Frame-Options | 4 | Standard — RFC 7034 | Passes on SAMEORIGIN or DENY |
| X-Content-Type-Options | 4 | Standard — WHATWG Fetch | Passes when it contains nosniff |
| Referrer-Policy | 3 | Standard — W3C | Presence only |
| Software Version Disclosure | 3 | Judgment | Server or X-Powered-By contains a version number |
| Permissions-Policy | 2 | Standard — W3C draft | Presence only |
| Secure Cookies (v4) | 2 | Standard — RFC 6265 | A cookie set without the Secure flag |
| Cross-Origin-Opener-Policy (v4) | 1 | Standard — HTML | Presence only |
Header-only rubric (inferred). HTTPS 30, CSP 19, HSTS 13, X-Frame-Options 8, X-Content-Type-Options 7, Referrer-Policy 5, Permissions-Policy 5, plus the four v4 page checks at the weights above — 100 in total.
A check that could not be completed never deducts. An unreachable resolver is reported as not checked — it is not evidence about the domain. This is distinguished from an authoritative "no such record", which is a real finding.
Limitations. These are presence and configuration checks, not a security assessment. A site can score 100 here and still be vulnerable — this does not test for injection, authentication flaws, open ports or anything requiring active probing.
SEO — 15% of composite
| Check | Max ded. | Basis | Notes |
|---|---|---|---|
| Title tag | 20 | Standard (presence) / Convention (length) | Full marks at 45–65 characters |
| Meta description | 15 | Convention | Full marks at 120–160 characters |
| Single H1 | 15 | Convention | HTML5 permits multiple H1s in sectioning content |
| Schema markup | 12 | Standard (schema.org) / Judgment (count) | Full marks at 5+ distinct types |
| Canonical URL | 10 | Standard — RFC 6596 | Presence |
| Canonical host (v4) | 8 | Standard — RFC 6596 | An absolute canonical naming another site tells search engines to rank that site |
| Image alt text | 6 | Standard — WCAG 1.1.1 | Scaled; Accessibility scores it in full |
| Subheadings (v4) | 5 | Convention | At least one H2 |
| Internal links (v4) | 5 | Judgment | At least 5 |
| Distinct meta description (v4) | 4 | Convention | Fails when it repeats the title |
| Open Graph tags | 3 | Convention | og:title |
| Open Graph image (v4) | 3 | Convention | og:image |
| H1 length (v4) | 3 | Judgment | Over 70 characters |
Limitations. The character-length windows are the softest numbers in the whole rubric. Google has never published a title or description length limit; these ranges come from observed search-result truncation.
Performance — 14% of composite
Measured whenever PageSpeed data is available; every report states which path produced the score.
#### Measured path — real Core Web Vitals
Thresholds are Google's published Core Web Vitals bands, not ours:
| Metric | Good | Needs improvement | Poor | Deduction |
|---|---|---|---|---|
| Largest Contentful Paint | ≤ 2.5 s | ≤ 4.0 s | > 4.0 s | 0 / 15 / 30 |
| Cumulative Layout Shift | ≤ 0.1 | ≤ 0.25 | > 0.25 | 0 / 10 / 20 |
| Interaction to Next Paint | ≤ 200 ms | ≤ 500 ms | > 500 ms | 0 / 10 / 20 |
| Total Blocking Time | ≤ 200 ms | ≤ 600 ms | > 600 ms | 0 / 8 / 15 |
A metric absent from the payload is skipped rather than penalised.
#### Inferred path — static fallback
| Check | Max ded. | Basis | Notes |
|---|---|---|---|
Render-blocking scripts in <head> | 30 | Convention | External scripts without async or defer |
| HTML document size | 30 | Convention | <75 KB earns full marks |
| Cache-Control | 18 | Standard (header) / Judgment (scoring) | Rewards max-age/public |
| Text compression (v4) | 12 | Standard — HTTP Content-Encoding | gzip, Brotli, deflate or zstd |
| Lazy-loaded images (v4) | 6 | Standard — HTML loading | Only with 6+ images and none lazy |
| Stylesheet count (v4) | 6 | Judgment | More than 6 stylesheets |
The report labels an inferred score "estimated from page structure", so an estimate is never presented as a measurement.
Mobile Usability — 10% of composite
Deductions total 100.
| Check | Max ded. | Basis | Notes |
|---|---|---|---|
| Viewport meta tag | 32 | Standard — W3C | Requires width=device-width |
| Pinch-zoom not disabled | 24 | Standard — WCAG 1.4.4 | |
| Responsive images | 24 | Standard — HTML srcset | |
| Plugin content (v4) | 8 | Convention | <object>, <embed> or <applet>, which phones cannot run; images embedded this way (often SVG) are not counted |
| Click-to-call (v4) | 8 | Convention | A phone number shown but not a tel: link |
| Legible font sizes (v4) | 4 | Judgment | Three or more inline font sizes under 12px |
Limitations. Static analysis only — tap-target sizing and horizontal overflow need a rendered page and are not assessed.
Local SEO — 8% of composite
| Check | Max ded. | Basis | Notes |
|---|---|---|---|
| Google Business Profile | 40 | Convention | No discoverable profile; the only check when none is found |
| Review count | 25 | Judgment | 20+ passes; 5–19 −8; 1–4 −15; none −25 |
| Average rating | 20 | Judgment | 4.5+ passes, down to −20 under 3.0 |
| Review recency | 20 | Judgment | Last review within 90 days passes, down to −20 after 18 months |
| Name, address, phone consistency | 15 | Convention | The page's phone against the profile's |
| Business hours | 10 | Convention | Listed on the profile |
| Profile photos | 8 | Convention | Present on the profile |
AEO (Answer Engine Optimisation) — 8% of composite
| Check | Max ded. | Basis |
|---|---|---|
| Structured data coverage | 25 | Judgment |
| FAQ content present | 15 | Judgment |
| Author signals | 10 | Judgment |
| Blog / content presence | 10 | Judgment |
| FAQPage or HowTo schema | 10 | Convention — schema.org types |
| Organization schema (v4) | 8 | Convention — schema.org Organization and subtypes |
| Question headings (v4) | 6 | Judgment — an H2 or H3 phrased as a question |
| Lists (v4) | 4 | Judgment |
| Content dates (v4) | 4 | Convention — datePublished/dateModified, <time> |
| Breadcrumb schema (v4) | 4 | Convention — schema.org BreadcrumbList |
This category measures readiness — whether a page carries the markup and content patterns answer engines are known to consume. It does not measure whether the brand appears in AI answers; that is measured separately, by asking the assistants themselves — see section 6.
Accessibility — 8% of composite
Checked from markup only. Colour contrast, focus visibility and screen-reader order need a rendered page and are not assessed, and the report says so.
| Check | Max ded. | Basis |
|---|---|---|
| Image alt text | 20 | Standard — WCAG 1.1.1, scaled by share of images affected |
| Form labels | 20 | Standard — WCAG 1.3.1 / 4.1.2, scaled by share of fields affected |
| Page language | 12 | Standard — WCAG 3.1.1 |
| Heading structure | 12 | Standard — WCAG 1.3.1; no H1 −12, skipped levels −6 |
| Landmarks | 8 | Standard — WCAG 1.3.1 |
| Link names (v4) | 6 | Standard — WCAG 2.4.4; −3 for one or two, −6 for more |
| Page title (v4) | 6 | Standard — WCAG 2.4.2 |
| Skip link | 4 | Standard — WCAG 2.4.1 |
| Frame titles | 4 | Standard — WCAG 4.1.2 |
| Focus order | 4 | Standard — WCAG 2.4.3; positive tabindex |
| Button names (v4) | 4 | Standard — WCAG 4.1.2 |
| Autoplaying media (v4) | 4 | Standard — WCAG 1.4.2; video with sound, or audio, playing on load |
| Timed refresh (v4) | 4 | Standard — WCAG 2.2.1; <meta http-equiv="refresh"> |
| Valid language code (v4) | 3 | Standard — BCP 47 |
| Data table headers (v4) | 3 | Standard — WCAG 1.3.1 |
| Image button text (v4) | 3 | Standard — WCAG 1.1.1 |
| Moving text (v4) | 2 | Standard — WCAG 2.2.2; <marquee>, <blink> |
Content & UX — 6% of composite (v4)
Whether a visitor finds enough to read, a way around, and an obvious next step. Read from markup, so it finds what is missing, not whether the writing is good. Deductions total 100, and every threshold is judgment.
| Check | Max ded. | Notes |
|---|---|---|
| Content depth | 25 | Under 150 words −25; under 300 −12 |
| Call to action | 20 | No link or button reading like contact, quote, book, call, sign up, buy |
| Contact path | 15 | No contact link, tel: or mailto: |
| Navigation menu | 10 | No <nav> or navigation role |
| Readable sentences | 10 | Average sentence length in paragraph text: over 25 words −10; over 20 −5. Needs three sentences to judge |
| Site footer | 5 | No <footer> or contentinfo role |
| Paragraphs | 5 | Fewer than three |
| Content structure | 5 | Over 600 words with fewer than two subheadings |
| Visual media | 5 | No images or video |
Trust — 4% of composite (v4)
What a first-time visitor looks for before handing over a phone number or a card. Read from links and copy, so it finds whether a signal exists, not how convincing it is. Deductions total 100.
| Check | Max ded. | Basis |
|---|---|---|
| Privacy policy | 25 | Convention — and a legal requirement wherever personal data is collected |
| Contact information | 15 | Convention — a phone number or email shown |
| Terms of service | 10 | Convention |
| About page | 10 | Convention |
| Physical address | 10 | Convention — <address>, schema PostalAddress, or a street address in the copy |
| Customer testimonials | 10 | Judgment |
| Social profiles | 10 | Judgment |
| Copyright year | 10 | Judgment — two or more years behind the scan; a range ending in "present" is current, and a page with no copyright line is not penalised |
Long pages keep these signals in the footer, so the last 256 KB of a page is read for them as well as the first 512 KB.
Content & UX and Trust read the page's HTML as served. A page that builds itself in the browser can carry almost no text in that HTML; when it has under 50 words both categories say so on the report, because their scores may understate it.
Best Practices — 3% of composite
| Check | Max ded. | Basis | Notes |
|---|---|---|---|
| Robots meta tag | 20 | Standard | noindex is the heavy deduction |
| Outdated JavaScript library (v4) | 10 | Standard — CVE-2020-11022/11023 | jQuery before 3.5, read from script URLs |
| Doctype (v4) | 8 | Standard — HTML | Missing doctype puts browsers in quirks mode |
| Third-party scripts (v4) | 8 | Judgment | More than 8 outside script hosts −4; more than 15 −8 |
| Twitter Card | 5 | Convention | Presence |
| Link structure | 5 | Judgment | Passes above 10 total links |
| Character encoding (v4) | 5 | Standard — HTML | <meta charset> or a charset in Content-Type |
| Deprecated markup (v4) | 5 | Standard — HTML | <font> or <center> |
6. AI visibility and the Deep AI Audit
Whether AI assistants actually name a business is measured by asking them, never estimated from the page. It is reported beside the score, not folded into it: a grade moves only when the website changes, and assistants' answers move on their own.
On every report. Each configured assistant (ChatGPT, Claude, Gemini and Perplexity where the keys exist) is asked five buyer questions for the business's industry and location, each assistant separately. The report shows which answers named the business and which competitors were named instead. Up to eight of those competitors are then graded with this same rubric and shown side by side. Results are kept for seven days, so repeat reports in that window show the same answers.
The Deep AI Audit goes further, on request:
- Twenty-five questions: seventeen that never name the business, the way a buyer actually asks ("who should I call for…"), and eight that do, to see what the assistants say about it.
- Up to eight assistants, each asked directly through its own service: ChatGPT, Claude, Gemini and Perplexity with live web search; Grok and DeepSeek from what the model knows, without search, so they cite no sources by design; and Google AI Overviews and AI Mode, read from Google's real results page through DataForSEO, never imitated with another model.
- For every answer it records whether the business was named, its position in the answer, the tone when named (positive, neutral or negative), the competitors named, and the sources cited.
- Results stay per assistant. There is no blended visibility score: "named by Perplexity but not by Gemini" is the finding, and an average would hide it.
- A search where Google shows no AI answer — common for local searches, which get a map instead — is left out of that surface's rate, not counted as a miss. A failed request is retried, and one that still fails is shown as unrecorded.
Limitations. Assistants' answers vary from one asking to the next, so a single audit is a sample, not a permanent ranking; comparing audits over time is more reliable than any one result. Whether an answer names the business is decided by a fixed brand-name matcher, not by a model, so the headline count cannot drift with a model's judgment; a business whose name is a common word can still be matched where it was not meant. The order of the businesses named and the tone are read by a language model, which can misjudge an ambiguous answer. Copilot is not measured: it answers from OpenAI's models and offers no API that returns what its users see.
7. Outreach threshold
A composite below 70 sets a triggerOutreach flag, used to mark a scanned site as worth a sales conversation.
This is a sales heuristic, not a quality judgment. It was tuned against the 25-domain baseline: the previous threshold of 80 fired on 72% of real sites including Cloudflare and Mozilla, which makes the signal useless and the sender look uninformed. At 70 it fires on 32%.
8. What ActiScore does not do
Stated plainly, because the absences matter as much as the checks:
- Does not execute JavaScript or render the page. A single-page app that builds its head tags client-side will score poorly on signals that are present after hydration.
- Does not run its own speed test. Performance uses Google's Lighthouse measurements; a first scan without them is estimated and labelled as such.
- Does not score more than one page. The headline is always the homepage's score. The multi-page crawl on paid plans shows which issues repeat across interior pages without changing that number.
- Does not perform a penetration test. Security reads response headers, DNS mail-authentication records and the TLS certificate — no active probing, port scanning, vulnerability testing or credential checks.
- Does not blend AI visibility into the score. It is measured and reported separately — see section 6.
- Does not judge content quality, design, or commercial effectiveness.
9. Change control
The rubric is changed in place rather than versioned per tenant, because Securafy's public grader and every tenant embed share one scoring core — a fix should reach both at once.
To make that safe:
- 25 real domains have their extracted signals and resulting scores frozen as a committed baseline, spanning grades A through F and including Securafy's own sites and real prospect domains.
- An automated gate fails the build on any scoring change, printing a per-domain, per-category old-to-new table.
- A rubric change is reviewed against that table before deploy, and any letter-grade move on a live prospect domain is flagged individually.
- Every stored scan records the rubric version that produced it, and the history view refuses to silently compare scores computed under different versions.
The v1→v2 delta table is recorded in docs/plans/2026-08-15-rubric-change-delta.txt, and v3→v4 in docs/plans/2026-10-06-rubric-v4-delta.txt: on identical input the composite moved a mean of 0.0 points, no site changed letter grade, and the largest single move was 5 points.
10. Open questions
Tracked honestly rather than quietly:
- Grade A is close to unreachable — 1 of 24 real sites in the October 2026 capture, and that one is a site tuned against this rubric. The A boundary may need lowering or the deduction tables loosening. Still open.
- Length windows for title and meta description rest on the softest evidence in the rubric and deserve a review against current search-result behaviour.
- AEO should be renamed to reflect that it measures readiness, not visibility. Real visibility is now measured separately (section 6), which makes the distinction easier to blur and the rename more pressing.
Closed in v3: Performance moved from inference to measurement; the favicon check left Performance and the cookie-banner check left Security.