A real audit, run on our own site
This is the assessment a client receives, in full and unedited — the same rubric, the same checks, the same arithmetic. We run it on our own site first, and publish the result whatever it says.
Nothing in it predicts a ranking or forecasts traffic. It measures what is there, names what is missing, and publishes the weights behind every figure so that any number in it can be recomputed from its own appendices.
The scan behind it ran on 9 September 2026 and returned output for 93 of the 125 checks in the published rubric: 81 of its 104 scored checks, 7 of them not applicable to this site, and 12 of its 21 reported-only checks. The other 32 were not run on this scan; every check is listed on the rubric page.
Technical assessment · HDB Calculator SG
93 checks. Two fail, seven carry a warning, and the business is not linked to its profiles elsewhere.
Prepared for HDB Calculator SG · hdbcalculator.com
Assessment date 9 September 2026 · Reference SPECIMEN · Rubric 0.3.0 · test map 0.2.0
Search SEO
AI Visibility
74 scored checks · 12 reported, not scored · 7 not applicable
T7 — sitemap <lastmod>
1/27 missing lastmod. One of two failed checks.
Reading the two numbers together. They are never averaged. Search SEO (89.8) measures how well the site is built to be crawled, indexed and ranked; AI Visibility (92.4) measures how well it can be read, understood and cited by an assistant. Neither predicts a ranking, and neither is a forecast: they describe what was measurable on 9 September 2026, against published criteria reproduced in Appendix A.
About this document
Contents, basis and control
- Sec. 1Scores and the three actionsWhere the site stands, what recovers most, and what the score covers3
- Sec. 2Where the site stands, by areaEvery category of the rubric, its shape and its contribution4
- Sec. 3Findings and recommendationsEvery open finding, with evidence, effort and owner6
- Sec. 4Risk and business impactWhat the open findings put at stake for a site of this size11
- App. AHow the score is builtFormula, weights, bands, severities and the two rules that move a letter12
- App. BTest results in fullAll 74 scored checks, grouped by category, each with its own output14
- App. CReported but not scoredThe 19 checks excluded from the arithmetic, and why18
- App. DBasis of preparationScope, method, crawlers named, limits, responsibilities19
Scope and basis
This report states the result of an automated technical assessment of hdbcalculator.com, run on 9 September 2026 against published criteria (Rubric 0.3.0 · test map 0.2.0, reproduced in Appendix A). All 27 URLs declared in the sitemap were fetched for status and for the link graph. The tests that read a page in depth — structured data, headings, answer structure, authorship, fact density — read the homepage and a 5-page sample. Every figure in this document is a check's own output or arithmetic on those outputs. No figure was produced by a language model.
Document control
- Reference
- SPECIMEN
- Version
- 1.0 — issued 9 September 2026
- Prepared by
- Olivier Jobert, AIqSight
- Prepared for
- HDB Calculator SG (owner)
- Distribution
- Published as a specimen
- Criteria
- Rubric 0.3.0 · test map 0.2.0
- Supersedes
- Nothing — first issue
How to read it
Each section carries a so-what line in italic under its title: read only those and you have the argument. Every finding carries a reference (EN2, S4, I3 …) which is the check's own identifier and is stable between reports, so a re-scan can be compared row by row.
Colour is used once and consistently — red is a failed check, amber is a warning, green is a pass, grey is excluded from the score, and teal is this document's own voice.
What this report does not do
It does not predict a ranking, promise a position, or forecast traffic or revenue. It measures what was there on 9 September 2026, names what is missing, and publishes the arithmetic so that any figure in it can be recomputed from Appendix A and Appendix B without asking us.
Section 1 of 4 · Scores
Scores and the three actions
65 of 74 scored checks pass and two fail. The three actions below recover 5.0 Search SEO and 5.4 points of AI Visibility; all 9 together recover 10.2 and 7.6.
What the two scores cover — read this before the numbers
Both scores are crawl-only: no Search Console, no analytics, no backlink data and no field performance data — no LCP, INP or CLS was measured. All 27 URLs reached; 6 read in depth; the scope in full is in Appendix D.
Where the site stands. Search SEO reads band B and AI Visibility band A (the band table is in Appendix A). The rubric drops a letter at 8 open findings on an axis — this site has 7 on Search SEO and 4 on AI Visibility — and the cap binds only on a severity-5 failure, where the most severe failure here is severity 2.
Where it fails. T7 — sitemap <lastmod>. 1/27 missing lastmod. It recovers 1.3 Search SEO points and is minutes of work.
What I recommend, in this order
| Ref. | Action | Search pts | AI pts | Effort | Owner |
|---|---|---|---|---|---|
| EN2 | The business is not linked to its profiles elsewhere identity links (sameAs) — no sameAs on the primary entity | — | +4.0 | minutes | Web developer |
| S4 | Articles are not marked up as articles article schema type — WebApplication, FAQPage, BreadcrumbList | +1.0 | +1.4 | minutes | Web developer |
| I3 | Some sitemap pages are not linked from the pages we read orphan detection — 1 orphan(s) | +4.0 | — | days | Web developer |
| Three actions | +5.0 | +5.4 | days | Remaining 6: Section 3 |
Points are not additive. Each figure above is what that fix recovers on its own; two fixes in one category share a denominator. Fixing all 9 recovers 10.2 and 7.6 points — computed once, not added up (Appendix A).
If you do one thing this week
In the homepage's Organization or LocalBusiness JSON-LD block, add a sameAs array listing the profiles the business actually controls or appears in, starting with the ones that identify rather than merely present: the company register entry and LinkedIn before the social accounts. That recovers 4.0 AI Visibility points.
Section 2 of 4 · By area
Where the site stands, by area
Both scores are a weighted mean of category values. Every weight, count and contribution is printed so the headline can be recomputed from these two pages alone.
| Category | Weight | Checks on this axis | Pass / warn / fail | Value | Contribution |
|---|---|---|---|---|---|
| Indexability & Crawl | 22 | 21 | 21 / 0 / 0 | 100.0 | 22.0 |
| Performance Foundations | 16 | 8 | 6 / 2 / 0 | 85.0 | 13.6 |
| On-Page & Meta | 12 | 8 | 7 / 1 / 0 | 95.2 | 11.4 |
| Structured Data | 12 | 4 | 3 / 1 / 0 | 91.7 | 11.0 |
| Rendering | 8 | 4 | 4 / 0 / 0 | 100.0 | 8.0 |
| Internal Linking & Semantics | 8 | 1 | 0 / 1 / 0 | 50.0 | 4.0 |
| E-E-A-T | 7 | 4 | 3 / 1 / 0 | 86.4 | 6.0 |
| Images / Media | 5 | 1 | 1 / 0 / 0 | 100.0 | 5.0 |
| Sitemaps & Discovery | 5 | 4 | 3 / 0 / 1 | 75.0 | 3.8 |
| Freshness | 3 | 1 | 1 / 0 / 0 | 100.0 | 3.0 |
| Social Cards | 2 | 2 | 2 / 0 / 0 | 100.0 | 2.0 |
| 11 active categories · 3 not applicable | 100 | 58 | 89.8 |
The two axes overlap. 14 of the 74 scored checks score on both axes, so this column and the AI column on the next page cannot be added together. Re-normalisation. 3 Search SEO categories are not applicable to this site (E-commerce, Local, International). Their weight leaves the denominator entirely rather than scoring zero, so the active weights re-normalise to 100 and the site is not penalised for lacking what it has no reason to have.
Three categories rest on a single test
Internal Linking & Semantics, Images / Media, Freshness carry the full category weight on one check each. Read those values as narrow, not as a verdict on the whole discipline the name suggests.
Performance Foundations is not Core Web Vitals
This run measured server response time, compression, cache headers, image weight, image dimensions and script loading. It did not measure LCP, INP or CLS, in the field or in a lab, so the category is named for what was measured. A field-data run would change this value in either direction.
Section 2 of 4 · By area (continued)
Where the site stands, by area
| Category | Weight | Checks on this axis | Pass / warn / fail | Value | Contribution |
|---|---|---|---|---|---|
| Answer Extractability | 20 | 4 | 4 / 0 / 0 | 100.0 | 20.0 |
| Structured Data | 16 | 4 | 3 / 1 / 0 | 91.7 | 14.7 |
| Fact Density / Original Data | 14 | 3 | 3 / 0 / 0 | 100.0 | 14.0 |
| AI Crawler Access | 12 | 3 | 3 / 0 / 0 | 100.0 | 12.0 |
| Rendering (non-JS) | 10 | 4 | 4 / 0 / 0 | 100.0 | 10.0 |
| Entity / Knowledge-Graph | 10 | 3 | 1 / 1 / 1 | 50.0 | 5.0 |
| E-E-A-T / Authority | 9 | 4 | 3 / 1 / 0 | 86.4 | 7.8 |
| Freshness | 6 | 1 | 1 / 0 / 0 | 100.0 | 6.0 |
| Images / Multimodal | 3 | 1 | 1 / 0 / 0 | 100.0 | 3.0 |
| llms.txt | 0 | 3 | 3 / 0 / 0 | 100.0 | 0.0 |
| 10 active categories | 100 | 30 | 92.4 |
llms.txt carries weight 0. Measured and reported, and contributing nothing to the score, because no answer engine has been shown to read it. It sits in the table so that its absence from the arithmetic is visible rather than silent.
Why two scores and never one
A site can rank well and be uncitable, or be beautifully structured for an assistant and invisible in search. Averaging the two hides exactly the finding an owner is paying to see, so the two numbers are published side by side and never blended. They share the modules that score on both axes, which is why one fix can move both columns at once in Section 3.
Where the AI score loses its points
Entity / Knowledge-Graph scores 50.0 and E-E-A-T / Authority scores 86.4; every other active category is above that. What the value measures is in Appendix B, check by check.
What a value of 100 means
Every scored check in that category passed — not that the category was examined exhaustively. The depth of each is in Appendix B.
Where a security check sits
The response-header checks — strict transport, content-type options, frame protection, referrer policy — are scored inside the crawl category. They are low severity and they are not crawl properties; they raise that row's pass count without describing crawling.
Section 3 of 4 · Findings
Findings and recommendations
Two failed checks and seven warnings, ordered by what each recovers against what it costs to fix. Each carries the check's own output as evidence, so the observation can be verified without us.
The business is not linked to its profiles elsewhere
FailSeverity 4Observed The homepage's Organization block declares the business but carries no sameAs array, so the site links itself to no register entry, no professional profile and no encyclopedia record.
What it means Your website does not link to your other profiles: a company register entry, a LinkedIn page, a Wikidata or Wikipedia record. Search engines and AI assistants cannot confirm it is the same business, so a similar name can be mistaken for yours.
Recommendation In the homepage's Organization or LocalBusiness JSON-LD block, add a sameAs array listing the profiles the business actually controls or appears in, starting with the ones that identify rather than merely present: the company register entry and LinkedIn before the social accounts.
Articles are not marked up as articles
WarningSeverity 2Observed The sampled content page declares itself as an application rather than as what it is. The type that applies is Article or BlogPosting, with a question-and-answer type kept only where a real question-and-answer block is on the page.
What it means The schema type on content pages does not match what those pages are, which is a weaker signal than no schema at all because it asserts something incorrect.
Recommendation Correct the @type on the content template to the type that genuinely applies.
SEO / AI trade-off Carries a trade-off Marking answers up for extraction can let an assistant answer the reader in full, so the reader never arrives. Publish it anyway: an unread page earns nothing either. Where the trade-off is real it is marked, as here.
Section 3 of 4 · Findings (continued)
Findings and recommendations
Some sitemap pages are not linked from the pages we read
WarningSeverity 3Observed 1 orphan(s) — https://hdbcalculator.com/blog/cpf-accrued-interest-hdb-2026.html
What it means Pages in the sitemap are not linked from the homepage or from the pages we sampled. A page that few other pages link to is discoverable in principle and easy to miss in practice, and it receives little of the site's weight.
Recommendation Link each listed page from a relevant parent page or navigation section. If a page should not be found, remove it from the sitemap rather than leaving the two in disagreement.
The sitemap does not say when pages last changed
FailSeverity 2Observed 1/27 missing lastmod
What it means Your sitemap, the list of pages you hand to search engines, does not say when each page last changed. They cannot tell which pages to revisit first, so newly changed pages wait behind unchanged ones.
Recommendation Emit a lastmod for every entry from the content's real modification date. An invented or build-time date is worse than none, because it trains crawlers to ignore the field.
Section 3 of 4 · Findings (continued)
Findings and recommendations
There is no real way to contact the business
WarningSeverity 3Observed The homepage offers one contact route inside the structured data, and no tappable telephone link, no email link and no marked-up postal address a reader or a machine can use directly.
What it means The homepage markup carries few or no direct ways to make contact — no linked email address, no linked telephone number, no address block. A reader on a phone cannot tap to call, and the business's contact details are not available as data to anything reading the page.
Recommendation Put the telephone number in a tel: link and the email address in a mailto: link, and mark the postal address up as a PostalAddress in the structured data. Where contact is deliberately routed through a form, say so and give at least one direct route beside it.
The business is named differently across the site
WarningSeverity 2Observed schema "HDB Calculator SG" vs title brand "HDB Calculator Singapore 2026: Affordability, Loan & Grants" — the page names the business two different ways, so the two declarations have to be reconciled before either can be trusted
What it means The name in the site's structured data does not agree with the name in its title or its social metadata. The site is describing itself two ways, and the discrepancy is the kind that has to be resolved by a person rather than by a rule.
Recommendation Choose the one form of the name the business uses publicly, and write that same form in all three places: the name in the structured data, the brand segment of the <title>, and og:site_name. Where a registered legal name differs from it, the legal name goes in the structured data's separate legalName field, so the three public names still read the same.
Section 3 of 4 · Findings (continued)
Findings and recommendations
Images are heavier than they need to be
WarningSeverity 3Observed 1 over 150KB — https://hdbcalculator.com/images/HDBCalculator.png (154KB)
What it means Oversized images are the most common cause of a slow page and the cheapest to fix. On mobile connections they dominate load time.
Recommendation Compress and resize to the dimensions actually displayed, serve modern formats with fallbacks, and lazy-load anything below the fold.
The search summary line is missing or the wrong length
WarningSeverity 2Observed 157 chars (>155)
What it means The meta description does not control ranking, but it is the sentence a searcher reads under the title. When it is missing or truncated, the engine composes its own from page text, and the result is frequently a fragment.
Recommendation Write a description of roughly 150-160 characters that states what the page offers and gives a reason to click.
Section 3 of 4 · Findings (continued)
Findings and recommendations
The server is slow to send the first byte
WarningSeverity 3Observed 2970ms (slow)
What it means The server takes a long time to return the first byte. Everything else on the page waits behind it, so no amount of front-end optimisation can compensate, and crawlers reduce their crawl rate against slow servers.
Recommendation Establish where the time is spent — origin processing, database, or network distance — before optimising. Caching at the edge is usually the largest single improvement for a site serving Hong Kong or Singapore from elsewhere.
Nothing else is open. The remaining 65 scored checks pass and are listed with their own output in Appendix B. 19 further checks are excluded from the score in one direction or the other, each with its reason, in Appendix C.
Section 4 of 4 · Risk
Risk and business impact
Four failure classes are open. Sized to this property, this page says which of them is real and which is close to noise.
| Failure class | Findings | Materiality here | What it costs this site, at this size |
|---|---|---|---|
| Indexing | T7, I3 | Material | What a machine is told the pages are decides how they are read and quoted. A template-level statement is asserted on every page that shares the template, so one wrong value is repeated across the site at once. |
| Performance | P6, HD7 | Moderate | A slow first byte is felt by every visitor on every page. The crawl-budget argument is borrowed from sites with hundreds of thousands of addresses; read this as a reader problem before an indexing one. |
| Identity | S4, EN2, EN3, EE4 | Material | Nothing outside this domain corroborates who runs it. That is the signal an assistant most needs before naming a source, and the one a competitor with a register entry and a professional profile already has. |
| Content | O2 | Moderate | What the pages say, and how plainly they say it, decides whether a passage can be lifted as an answer. These are the findings a reader of the page would notice too. |
The one that would keep me up. Identity. 4 of the 9 open findings sit in it — S4, EN2, EN3, EE4 — and together they recover 2.0 Search SEO points and 7.7 AI Visibility points. Nothing outside this domain corroborates who runs it. That is the signal an assistant most needs before naming a source, and the one a competitor with a register entry and a professional profile already has.
What would change this page
A field-performance run could move Performance to material or to negligible; today it is sized on server timing alone. A deeper crawl could add findings this run's sample did not see. Neither is guesswork we will print as a risk.
Appendix A
How the score is built
Everything needed to recompute both headline figures: the formula, the status factors, the band table, the severity scale, and the two rules that can move a letter without moving a number.
The formula
category_value = 100 × Σ(status_factor × severity) / Σ(severity)
score = Σ(category_value × weight) / Σ(active weight)
Status factors: pass 1.0 · warn 0.5 · fail 0.0. Only scored checks enter either sum. A not-applicable or unscored check leaves the numerator and the denominator, in both directions — it can neither pass nor penalise. Severity is the weight inside a category; the category weight is its weight inside the axis. Nothing else enters the arithmetic.
Bands
| Letter | Score is at least | This report |
|---|---|---|
| A | 90.0 | AI Visibility |
| B | 80.0 | Search SEO |
| C | 70.0 | |
| D | 60.0 | |
| F | 0.0 |
Published here because a letter no reader can check is decoration.
The two rules that can move a letter
Finding-count adjustment. The weighted mean is insensitive to how many findings are open, so the letter — never the number — drops one band at 8 open findings on an axis and two at 12. This report: 7 open on Search SEO, 4 on AI Visibility. No adjustment applied.
Severity gate (the cap). A severity-5 failure caps that axis at 40 and sets band F, whatever the mean says — a site nobody can index has no partial credit. This report: 0 severity-5 failures. Cap not triggered.
Severity, and where it is open
| Sev. | What it means | Tests | Open here |
|---|---|---|---|
| 5 | The site cannot be indexed or reached at all. Nothing else on the report matters while it holds, and it caps the axis at 40. | 3 | — |
| 4 | A primary signal is broken or absent. Directly costs indexing, ranking or citability. | 17 | EN2 |
| 3 | A real defect with measurable impact, but the page still works without it. | 25 | P6, I3, HD7, EE4 |
| 2 | Hygiene. Worth fixing, cheap to fix, rarely decisive on its own. | 24 | T7, S4, O2, EN3 |
| 1 | Minor. Reported for completeness; a site can be excellent without it. | 5 | — |
Appendix A (continued)
How the score is built
| Search SEO category | Weight | Value | AI Visibility category | Weight | Value |
|---|---|---|---|---|---|
| Indexability & Crawl | 22 | 100.0 | Answer Extractability | 20 | 100.0 |
| Performance Foundations | 16 | 85.0 | Structured Data | 16 | 91.7 |
| On-Page & Meta | 12 | 95.2 | Fact Density / Original Data | 14 | 100.0 |
| Structured Data | 12 | 91.7 | AI Crawler Access | 12 | 100.0 |
| Rendering | 8 | 100.0 | Rendering (non-JS) | 10 | 100.0 |
| Internal Linking & Semantics | 8 | 50.0 | Entity / Knowledge-Graph | 10 | 50.0 |
| E-E-A-T | 7 | 86.4 | E-E-A-T / Authority | 9 | 86.4 |
| Images / Media | 5 | 100.0 | Freshness | 6 | 100.0 |
| Sitemaps & Discovery | 5 | 75.0 | Images / Multimodal | 3 | 100.0 |
| Freshness | 3 | 100.0 | llms.txt | 0 | 100.0 |
| Social Cards | 2 | 100.0 | |||
| E-commerce n/a | 15 | — | |||
| Local n/a | 10 | — | |||
| International n/a | 8 | — | |||
| Active weight | 100 | 89.8 | Active weight | 100 | 92.4 |
Recovery, and why the figures do not add up
A finding's recovers alone figure is the score recomputed with that one check set to pass and everything else unchanged. Two findings in one category share a denominator, so their individual recoveries overlap and must never be summed. The joint figure is computed the same way, once, with all 9 set to pass: +10.2 Search SEO and +7.6 AI Visibility.
Effort
The toolkit's three-point scale, per finding, independent of its importance: 1 minutes — edit a tag, a file or a header · 2 hours — a template change, a redirect rule, a server setting · 3 days — structural, content or platform work.
Worked example
Entity / Knowledge-Graph holds 3 checks: EN1 (severity 4, pass), EN2 (severity 4, fail), EN3 (severity 2, warn). Category value = 100 × (1·4 + 0·4 + 0.5·2) / (4 + 4 + 2) = 50.0. That category carries weight 10 of 100, so setting EN2 to pass lifts the category and the axis by +4.0. Every figure in this report can be checked that way, from this page and Appendix B.
Where these numbers come from. Rubric 0.3.0 is our transcription of one published scoring document, not an industry standard, and the test map 0.2.0 binds each of the 74 scored checks to exactly one module. Both versions are on the cover so that two reports can be compared only when they were scored by the same rules. Another practitioner's weights would produce another number from the same facts — which is why the weights are printed rather than asserted.
Appendix B
Test results in full
All 74 scored checks, grouped by the category each one scores in, each printed with the output it actually returned. The 19 excluded checks are in Appendix C.
| Ref. | Check | What it returned | Sev. | Result |
|---|---|---|---|---|
| Indexability & Crawl — 21 checks · Search SEO | ||||
| T1 | HTTPS redirect | 301 -> https://hdbcalculator.com/ | 4 | Pass |
| T2 | www.hdbcalculator.com -> hdbcalculator.com 301 | 301->301->200 -> https://hdbcalculator.com/ | 4 | Pass |
| T3 | www.hdbcalculator.com not just canonical | 301 | 3 | Pass |
| T4 | /index.html -> / 301 | 301 -> https://hdbcalculator.com/ | 3 | Pass |
| T8 | robots.txt | 200, references sitemap | 3 | Pass |
| T10 | custom 404 | 404 with navigation | 2 | Pass |
| T11 | homepage canonical | https://hdbcalculator.com/ | 4 | Pass |
| T13 | robots.txt crawl access | crawlers may fetch the root | 5 | Pass |
| C1 | homepage canonical exact | https://hdbcalculator.com/ | 4 | Pass |
| C2 | /index.html 301s | 301 | 3 | Pass |
| C4 | internal index.html links | none | 2 | Pass |
| C5 | no www.hdbcalculator.com links | none | 2 | Pass |
| S5 | noindex check | no page is noindex | 5 | Pass |
| I2 | sitemap URLs 200 | all 27 OK | 4 | Pass |
| X3 | self-referential canonical | all 5 self-canonical | 4 | Pass |
| X4 | mixed content | no http:// assets | 4 | Pass |
| HD1 | HSTS header | max-age=31536000; includeSubDomains; preload | 2 | Pass |
| HD2 | X-Content-Type-Options | nosniff | 1 | Pass |
| HD3 | frame protection | set | 1 | Pass |
| HD4 | Referrer-Policy | strict-origin-when-cross-origin | 1 | Pass |
| HD8 | redirect chain | 1 hop(s) | 3 | Pass |
| Performance Foundations — 8 checks · Search SEO | ||||
Appendix B (continued)
Test results in full
| Ref. | Check | What it returned | Sev. | Result |
|---|---|---|---|---|
| Performance Foundations (continued) — 8 checks · Search SEO | ||||
| P2 | LCP fetchpriority | high | 2 | Pass |
| P3 | LCP preload | present | 2 | Pass |
| P4 | image dimensions | 6/6 have width+height | 3 | Pass |
| P5 | script defer/async | 4 head scripts ok | 2 | Pass |
| P6 | large images | 1 over 150KB | 3 | Warn |
| HD5 | compression | br | 3 | Pass |
| HD6 | Cache-Control | max-age=3600, public, must-revalidate | 2 | Pass |
| HD7 | TTFB | 2970ms (slow) | 3 | Warn |
| On-Page & Meta — 8 checks · Search SEO | ||||
| T12 | meta viewport | present | 3 | Pass |
| O1 | title tag | 59 chars | 4 | Pass |
| O2 | meta description | 157 chars (>155) | 2 | Warn |
| O3 | single H1 | 1 | 3 | Pass |
| O4 | html lang | en | 2 | Pass |
| O8 | article title lengths | all ≤65 | 2 | Pass |
| X1 | duplicate titles | all unique | 3 | Pass |
| X2 | duplicate meta descriptions | all unique | 2 | Pass |
| Structured Data — 4 checks · both axes | ||||
| S1 | JSON-LD on homepage | 3 block(s) | 4 | Pass |
| S2 | schema types (homepage) | Organization, WebApplication, FAQPage | 3 | Pass |
| S3 | JSON-LD on article | 3 block(s) | 3 | Pass |
| S4 | article schema type | WebApplication, FAQPage, BreadcrumbList | 2 | Warn |
| Rendering — 4 checks · both axes | ||||
| R1 | content without JS | 1406 words | 4 | Pass |
| R2 | headings without JS | 1 H1, 5 sub-heading(s) | 3 | Pass |
Appendix B (continued)
Test results in full
| Ref. | Check | What it returned | Sev. | Result |
|---|---|---|---|---|
| Rendering (continued) — 4 checks · both axes | ||||
| R3 | links without JS | 56 links | 4 | Pass |
| R4 | client-side app shell | no client-side mount point — content is in the HTML | 4 | Pass |
| Internal Linking & Semantics — 1 check · Search SEO | ||||
| I3 | orphan detection | 1 orphan(s) | 3 | Warn |
| E-E-A-T — 4 checks · both axes | ||||
| EE1 | content carries an author | 5/5 sampled page(s) name an author (author/byline class) | 3 | Pass |
| EE2 | business is identifiable | about and contact pages linked from the homepage | 3 | Pass |
| EE3 | published policies | privacy policy linked, also terms, cookie policy | 2 | Pass |
| EE4 | a real contact route | 1 route(s): ContactPoint schema | 3 | Warn |
| Images / Media — 1 check · both axes | ||||
| O9 | image alt coverage | 6/6 have alt | 3 | Pass |
| Sitemaps & Discovery — 4 checks · Search SEO | ||||
| T5 | sitemap.xml reachable | 200, 27 URLs | 3 | Pass |
| T6 | sitemap URL count | 27 URLs | 2 | Pass |
| T7 | sitemap <lastmod> | 1/27 missing lastmod | 2 | Fail |
| I1 | sitemap URL list | 27 URLs | 1 | Pass |
| Freshness — 1 check · both axes | ||||
| O7 | visible timestamp | present | 2 | Pass |
| Social Cards — 2 checks · Search SEO | ||||
| O5 | OG tags | all present | 2 | Pass |
| O6 | OG image reachable | 200 https://hdbcalculator.com/images/HDB_main_1200_675.png | 2 | Pass |
| Answer Extractability — 4 checks · AI Visibility | ||||
Appendix B (continued)
Test results in full
| Ref. | Check | What it returned | Sev. | Result |
|---|---|---|---|---|
| Answer Extractability (continued) — 4 checks · AI Visibility | ||||
| AB1 | question headings answered directly | 8/11 answered in 20-120 words | 4 | Pass |
| AB2 | extractable structures present | 5/6 page(s) carry a list, table or definition list (16 block(s)) | 3 | Pass |
| AB3 | content is segmented into passages | 0/6 page(s) over 600 words carry fewer than 2 sub-headings | 3 | Pass |
| AB4 | sections open self-contained | 0/43 section(s) open on a bare "this/it/they" | 2 | Pass |
| Fact Density / Original Data — 3 checks · AI Visibility | ||||
| FD1 | statistic density | 411 figure(s) in 7676 words — 5.4 per 100 words | 4 | Pass |
| FD2 | outbound citations to third-party sources | 8 external domain(s): cpf.gov.sg, cpfcalculatorsg.com, hdb.gov.sg, iras.gov.sg, mas.gov.sg +3 more | 3 | Pass |
| FD3 | claims supported by figures | 3 promotional claim(s), 411 figure(s) | 2 | Pass |
| AI Crawler Access — 3 checks · AI Visibility | ||||
| AI1 | AI answer engines can reach the site | all citation crawlers may fetch the root | 5 | Pass |
| AI2 | citation crawlers individually allowed | all 5 may fetch the root | 4 | Pass |
| AI3 | user-triggered fetchers allowed | all 3 may fetch the root | 3 | Pass |
| Entity / Knowledge-Graph — 3 checks · AI Visibility | ||||
| EN1 | primary entity declared | Organization "HDB Calculator SG" (typed node) | 4 | Pass |
| EN2 | identity links (sameAs) | no sameAs on the primary entity | 4 | Fail |
| EN3 | the entity is named consistently | schema "HDB Calculator SG" vs title brand "HDB Calculator Singapore 2026: Affordability, Loan & Grants" | 2 | Warn |
| llms.txt — 3 checks · AI Visibility | ||||
| L1 | /llms.txt present | 7447 bytes | 2 | Pass |
| L2 | llms.txt starts with H1 | # HDB Calculator SG | 1 | Pass |
| L3 | llms.txt links resolve | 10/10 OK | 2 | Pass |
Reading a row. “What it returned” is the check's own output string, unedited — this is the evidence, not a summary of it. Where a check sampled rather than read everything, the sample is in that string. Severity is the rubric's, fixed per check and not set per site. A check appears once, under the category it scores in; a check that scores on both axes does so from that single row.
Appendix C
Reported but not scored
Every check that was run and then left out of the arithmetic, with the reason. Exclusion runs in both directions: none of these could have earned a point, and none could have cost one.
| Ref. | Check | Why it does not apply |
|---|---|---|
| C3 | www.hdbcalculator.com canonical (if 200) | N/a — www.hdbcalculator.com redirects |
| HL1 | hreflang tags | Not applicable: the site declares no alternate-language versions, so there is nothing for this check to compare. |
| HL2 | hreflang values valid | Not applicable: the site declares no alternate-language versions, so there is nothing for this check to compare. |
| HL3 | self-referencing hreflang | Not applicable: the site declares no alternate-language versions, so there is nothing for this check to compare. |
| HL4 | hreflang x-default | Not applicable: the site declares no alternate-language versions, so there is nothing for this check to compare. |
| HL5 | hreflang reciprocity | Not applicable: the site declares no alternate-language versions, so there is nothing for this check to compare. |
| HL6 | hreflang targets 200 | Not applicable: the site declares no alternate-language versions, so there is nothing for this check to compare. |
| Ref. | Check | Why it is not scored |
|---|---|---|
| T9 | ads.txt | Only meaningful if the site sells ad inventory. Absence is not a defect. |
| H1 | .htaccess present | Reads a server configuration file that cannot be seen from outside the site, and duplicates the redirect and security-header checks, which can. |
| H2 | HTTPS redirect rule | Same: the outcome is already measured, from outside, by the HTTPS-redirect check (T1). |
| H3 | www -> non-www rule | Same: the outcome is already measured by the www-redirect check (T2). |
| H4 | /index.html -> / rule | Same: the outcome is already measured by the /index.html redirect check (T4). |
| H5 | security headers (HSTS) | Same: the outcome is already measured by the live HSTS header check (HD1). |
| P1 | GA4 tag | Analytics choice, not an SEO property. Plenty of good sites use something else or nothing. |
| I4 | cross-site links | Measures a linking convention of our own between properties we run. It describes us, not your site, so it would be meaningless as a score here. |
| A1 | AdSense snippet | Monetisation, not visibility. |
| A2 | AdSense pub-ID match | Monetisation, not visibility. |
| AI4 | training-crawler policy | Reports which model-training crawlers robots.txt refuses. Refusing them is a legitimate business choice that costs no citations, so this check returns information for the report to state rather than a verdict to score. |
| IN1 | IndexNow key file | Reflects our own publishing practice rather than a property of your site, and is only observable with server access. |
Why this appendix exists. A scoring system that silently drops the checks it cannot run flatters every site it touches. Each exclusion above would otherwise have been a free pass on one site and a free failure on another, so all of it is here instead, named, with the exclusion running in both directions: none of these could have earned a point, and none could have cost one.
Appendix D
Basis of preparation
What was measured, how, by whom, with what limits, and where the line falls between our responsibility and yours.
Scope
hdbcalculator.com, as served publicly on 9 September 2026. All 27 URLs declared in the sitemap were fetched for status and for the link graph. The tests that read a page in depth — structured data, headings, answer structure, authorship, fact density — read the homepage and a 5-page sample. No page behind a login, no staging host, no subdomain.
Method
Automated checks over the raw HTML, the response headers, robots.txt, the sitemap and llms.txt. Raw HTML only — no JavaScript was executed. That is the right view for AI citability, because most answer engines do not execute it either; it means this report cannot distinguish "missing for everyone" from "present only after JavaScript runs".
What was not used
No Search Console, no analytics, no backlink index, no keyword data, no field performance data, no competitor benchmark. Where a conclusion would have needed one of those, this report says the figure is not available instead of estimating it.
Crawlers named
Where a check reports "all 5" or "all 3", these are the agents tested. Citation and retrieval fetchers (5): OAI-SearchBot, Claude-SearchBot, PerplexityBot, Googlebot, Bingbot. User-triggered fetchers (3): ChatGPT-User, Claude-User, Perplexity-User. Training crawlers (7, reported not scored): GPTBot, ClaudeBot, Google-Extended, Applebot-Extended, CCBot, Bytespider, Meta-ExternalAgent. Blocking a training crawler costs no citations and is a legitimate choice.
Use of AI in preparing this report
No figure, score, status or count in this document was produced by a language model. Every number is a check's output or arithmetic on those outputs, reproducible from Appendix A and Appendix B.
Responsibilities
We are responsible for the accuracy of the measurements and the arithmetic. You remain responsible for the site, for deciding which recommendations to act on, and for the content's factual accuracy. We do not deploy changes as part of this assessment.
Limits — the five that matter most
1. Point in time. 9 September 2026. A site changes; this does not. 2. Sample. Deep checks read 6 pages of 27; a finding on an unsampled page is not here. 3. No field data. No vitals, no traffic, no rankings, so no claim about any of them. 4. No JavaScript. Content that exists only after rendering is invisible to this run. 5. Criteria, not consensus. Rubric 0.3.0 is our published transcription of one scoring document; another practitioner's weights would give another number from the same facts, which is why the weights are printed rather than asserted.
No ranking is promised. Nothing in this report predicts a position, a traffic level or a revenue outcome, and no recommendation in it is conditional on one. The recommendations concern hygiene, indexability and citability: what can be measured before and after, on your own site.
What happens next
Fix the nine, then re-measure — the same 74 checks, printed side by side.
A re-scan thirty days after the work is done reprints this document against the same criteria, so the change is observed rather than asserted. Every reference in it is stable between runs, which is what makes the two documents comparable row by row.