Site audit — public findings register

I publish here the audit of gianlucamazza.it that I run against the site's own stated positioning. A script generates this page from the finding sources; I write none of it by hand.

I publish it for the same reason I attach a test to every closed finding: a claim about systems competence is worth what its evidence is worth. Every closed finding below names the executable test that keeps it closed, so a regression fails a build instead of waiting for the next manual pass.

Register: 57 of 57 findings are public — 55 closed · 2 deferred. Rendering status: publishable.

Publication gate: met. Every finding is closed or carries a dated deferral, and no high-severity finding is open. The remaining §2.1 condition — a green conformance suite — is asserted by CI on every commit and daily against production, not by this page.

Findings

IDSeverityStatusLocaleFinding
F-001highclosedallZenodo DOI enumeration (dropped: single identifier site-wide)
F-002highclosedit/it no-JS content language (dropped)
F-010highcloseden, itOpenFatture demo link target unresolvable
F-032highclosedallLocale switching has no non-JavaScript path in the served HTML
F-070highclosedallUniversal soft-404: any URL served HTTP 200 with the complete home document
F-071highclosedallThe proof surface was absent from every machine-curated retrieval surface
F-090highclosedallTitles/meta of the entry pages address the retired ICP as audience
F-091highclosedallHome message hierarchy led with the retired ICP and explicitly subordinates the current one
F-092highclosedallHome FAQ declared the retired ICP as the addressed audience, in prose and in FAQPage structured data
F-095highclosedenllms.txt / llms-full.txt serve the retired ICP as the primary positioning statement to retrieval agents
F-003mediumclosedall<h1> count per route (dropped)
F-004mediumcloseden, itFAQ proof-list parity EN↔IT (dropped: lists were identical)
F-005mediumclosedallVertical/geographic qualifiers in title tags and meta descriptions (promoted)
F-006mediumclosedallhreflang as served (dropped)
F-011mediumclosedallVenere Labs organization URL unresolvable in site-wide JSON-LD
F-030mediumclosedallPolicy pages: skip link targeted a nonexistent anchor; no `<main>` landmark
F-033mediumclosedallHeader controls are script-dependent buttons; mobile nav panel was served display:none
F-050mediumcloseden, itEN↔IT content parity matrix, claim by claim
F-051mediumcloseden, itBlog related-article rails diverged between locales on 7 of 9 pairs
F-052mediumclosedenRoot `/` is an IA orphan: a reduced EN home outside the locale system
F-053mediumclosedallINV-4's language-switcher exception named a mechanism that did not exist in the served HTML
F-072mediumclosedallEntity self-description diverged across machine surfaces
F-073mediumclosedall@id discipline: the entity graph is anchored for Person/Organization but anonymous for every artifact
F-074mediumclosedallStructured data asserts an entity on routes whose content never mentions it
F-075mediumclosedallProof-surface claims have no fragment anchors; only blog posts are citable below page level
F-093mediumclosedallServices body copy: geographic targeting in IT, retired SME framing in EN, and locale divergence
F-094mediumclosedallGeographic audience signals in site-wide JSON-LD (areaServed, Service items)
F-100mediumclosedallConversion funnel is a bare mailto with no next step
F-101mediumclosedallProof gap: no numbers, no third parties, stale cadence
F-104mediumclosedallServed HSTS carried `preload` without `includeSubDomains`
F-105mediumclosedenPublic audit register not served as a site route
F-107mediumclosedallPositioning claim was repeated instead of earned
F-108mediumclosedallCard-title heading idiom drifts across pages (two line-heights for one role)
F-110mediumclosedallCard grid internal rows misalign when titles wrap
F-112mediumclosedallService offer titles carried two unrelated typographic identities
F-116mediumclosedallCV page reachable only through the footer
F-119mediumdeferredallThe conversion relay is rejected upstream, and said so to no one
F-120mediumclosedallThe printed CV ran to six pages, without the name
F-121mediumcloseden, itEditorial directions and literal translations in public copy
F-122mediumcloseden, itHandover copy promises independence from all third parties
F-007lowcloseditEN↔IT case-study register parity (promoted)
F-008lowclosedallBrand-name query absence
F-031lowclosedenRoot route `/`: skip link absent in raw HTML, present after hydration
F-054lowcloseditIT slug localization was a mixed convention: 7 Italian, 18 English
F-076lowclosedallFreshness signals were inconsistent across machine surfaces and absent on pSEO routes
F-077lowclosedallThe benchmark claim is extractable; the benchmarks are not
F-078lowclosedallDiagram content is invisible to raw retrieval and English-only when hydrated on IT routes
F-102lowclosedallAnalytics consent posture and the Netlify redirects residue
F-103lowdeferredallUnnamed positioning asset: the Reasoning Kernel program
F-106lowclosedallF-106
F-109lowclosedallCard footer links float with copy length instead of bottom-aligning
F-111lowclosedallHome FAQ column jump and topic-hub first-heading offset
F-113lowclosedallArchitecture page: two scales for one bordered card-title shape
F-114lowclosedallTopic hub body row still drifts 7.25px after F-111
F-115lowclosedallCritical text fonts were discovered only via the blocking CSS
F-117lowclosedallClosing contact invitation present on 3 of 9 content pages
F-118lowclosedallArchitecture graph loop edge crosses the node row

Detail

F-001 — Zenodo DOI enumeration (dropped: single identifier site-wide)

Severity high · Status closed · Locale all

Observed at https://doi.org/10.5281/zenodo.19972258

Guarded by 40-conformance/f001-doi-uniqueness.test.mjs (INV-7)

The Zenodo DOI for emotional-memory rendered as two different identifiers across pages.

F-002 — /it no-JS content language (dropped)

Severity high · Status closed · Locale it

Observed at https://gianlucamazza.it/it

Guarded by 40-conformance/f002-it-locale.test.mjs (INV-7)

/it served a no-JS block whose <h1> and body are in English and whose navigation links target /en/* routes.

F-010 — OpenFatture demo link target unresolvable

Severity high · Status closed · Locale en, it

Observed at https://gianlucamazza.it/en/projects

Guarded by 40-conformance/f010-f011-external-resolvability.test.mjs (INV-7)

The OpenFatture case-study demo link https://openfatture.venerelabs.com/ on /en/projects and /it/progetti did not resolve: DNS for the venerelabs.com zone returned SERVFAIL.

F-032 — Locale switching has no non-JavaScript path in the served HTML

Severity high · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f032-f053-locale-switch.test.mjs (INV-7)

No anchor element targeting an alternate-locale URL existed in the raw HTML of any of the 53 routes; the language switcher was served exclusively as <button type="button"> elements, which per the HTML specification have no default activation behavior.

F-070 — Universal soft-404: any URL served HTTP 200 with the complete home document

Severity high · Status closed · Locale all

Observed at https://gianlucamazza.it/nonexistent-path-xyz

Guarded by 40-conformance/f070-soft404.test.mjs (INV-7)

Every unknown non-.md path on gianlucamazza.it returned HTTP 200 with the full home-page document (title, canonical https://gianlucamazza.it/en, complete Person/ProfessionalService/FAQPage JSON-LD including the DOI claim), so no retrieval agent can distinguish a real citation target from a fabricated one by status code or by content.

F-071 — The proof surface was absent from every machine-curated retrieval surface

Severity high · Status closed · Locale all

Observed at https://gianlucamazza.it/llms.txt

Guarded by 40-conformance/f071-f077-llms-proof.test.mjs (INV-7)

The machine-curated retrieval surfaces (llms.txt, llms-full.txt, and the .md mirrors) contained none of the §1.3 proof artifacts — no repository name, no Zenodo DOI, no package identifier — because they cover only the 18 blog articles, while the pages that carried the proof surface (/en/projects, /en/research, /en/systems, home FAQ) have no markdown mirror at all.

F-090 — Titles/meta of the entry pages address the retired ICP as audience

Severity high · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f090-meta-icp.test.mjs (INV-7)

The primary entry documents (/, /en, /it) and /it/servizi declared the retired ICP — a vertical (manufacturing) and a geography (Italy) — as the addressed audience in their title, meta description, og:*, twitter:* and webmanifest metadata, in direct violation of §1.2.

F-091 — Home message hierarchy led with the retired ICP and explicitly subordinates the current one

Severity high · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f091-f093-body-icp.test.mjs (INV-7)

On both home pages the first positioning claim a reader received is the retired ICP (hero paragraph: software "for Italian manufacturing SMBs" / "per PMI manifatturiere italiane"), the §1.1 ICP claim was demoted to a subordinate "Summary" block, and a footer section explicitly declared that "The landing page stays focused on the business problem" — an inversion of the §1 message hierarchy in the exact copy.

F-092 — Home FAQ declared the retired ICP as the addressed audience, in prose and in FAQPage structured data

Severity high · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f092-faq-audience.test.mjs (INV-7)

The home FAQ — rendered visibly and mirrored 1:1 into FAQPage JSON-LD in both locales — answered the literal question "Who do you build software for?" with the retired ICP ("Small and medium manufacturing businesses in Italy without an internal IT department" / "PMI manifatturiere in Italia senza un reparto IT interno"), the most explicit audience declaration on the site.

F-095 — llms.txt / llms-full.txt serve the retired ICP as the primary positioning statement to retrieval agents

Severity high · Status closed · Locale en

Observed at https://gianlucamazza.it/llms.txt

Guarded by 40-conformance/f095-llms-positioning.test.mjs (INV-7)

The blockquote positioning statement at the top of both llms.txt and llms-full.txt — the one sentence explicitly authored for retrieval agents — led with the retired ICP ("Independent software consultant for small and medium manufacturing businesses in Italy without an internal IT department") and expressly demoted the §1.1 audience to "Secondary credibility for technical buyers".

F-003 — <h1> count per route (dropped)

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/sitemap.xml

Guarded by 40-conformance/f003-single-h1.test.mjs (INV-7)

At least two routes rendered more than one <h1>.

F-004 — FAQ proof-list parity EN↔IT (dropped: lists were identical)

Severity medium · Status closed · Locale en, it

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f004-faq-parity.test.mjs (INV-7)

Proof lists diverged between locales — the EN FAQ and the IT FAQ name different projects as evidence for the same claim.

F-005 — Vertical/geographic qualifiers in title tags and meta descriptions (promoted)

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f090-meta-icp.test.mjs (INV-7)

Title tags and meta descriptions carried vertical and geographic qualifiers inconsistent with §1.

F-006 — hreflang as served (dropped)

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f006-hreflang.test.mjs (INV-7)

hreflang annotations were unconfirmed; og:locale:alternate is present but is not a substitute.

F-011 — Venere Labs organization URL unresolvable in site-wide JSON-LD

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f010-f011-external-resolvability.test.mjs (INV-7)

The JSON-LD ProfessionalService url https://venerelabs.com (Venere Labs, Person.worksFor target), served on every crawled document, did not resolve: the venerelabs.com DNS delegation returned SERVFAIL.

F-030 — Policy pages: skip link targeted a nonexistent anchor; no `<main>` landmark

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en/privacy-policy

Guarded by 40-conformance/f030-f031-skip-link.test.mjs (INV-7)

On /en/privacy-policy, /en/cookie-policy, /it/privacy-policy and /it/cookie-policy the served skip link targeted id "main-content", but no element with that id and no <main> landmark existed on those pages, in raw or hydrated HTML.

F-033 — Header controls are script-dependent buttons; mobile nav panel was served display:none

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f033-header-controls.test.mjs (INV-7)

The header's mobile navigation panel was served inside a container with class "hidden" (display:none in the served CSS) whose only toggle is a <button type="button">, so in the no-JS rendering on sub-lg viewports every header navigation link is inside a display:none subtree.

F-050 — EN↔IT content parity matrix, claim by claim

Severity medium · Status closed · Locale en, it

Observed at https://gianlucamazza.it/it/servizi

Guarded by 40-conformance/f050-claim-parity.test.mjs (INV-7)

On a claim-by-claim comparison of all 26 EN↔IT logical page pairs (~230 substantive claims), nine claims rendered differently across locales — including the audience definition on the services pair (IT added "italiane", EN carried no geographic qualifier), a service-scope promise widened in IT only, English diagram narration served untranslated on /it/sistemi, and two quantitative claims (a 2022 date and a sub-100ms latency threshold) present in EN prose but dropped or weakened in the IT rendering — in breach of INV-5.

F-051 — Blog related-article rails diverged between locales on 7 of 9 pairs

Severity medium · Status closed · Locale en, it

Observed at https://gianlucamazza.it/it/blog/agent-to-agent-communication

Guarded by 40-conformance/f051-related-rail-parity.test.mjs (INV-7)

On 7 of the 9 blog pairs the related-article rail links a different set of posts in EN than in IT (including /en/blog/slm-on-xbox, which served no related rail while its IT counterpart served one), so the same logical page routes readers to different content depending on locale, in breach of INV-4 full route parity as interpreted for in-content navigation and of INV-5.

F-052 — Root `/` is an IA orphan: a reduced EN home outside the locale system

Severity medium · Status closed · Locale en

Observed at https://gianlucamazza.it/

Guarded by 40-conformance/f052-root-parity.test.mjs (INV-7)

The root URL / was served as a structurally reduced third rendering of the EN home — HTTP 200 with no redirect, canonical to /en, absent from the sitemap, never the target of any hreflang or x-default annotation, and missing the skip link, the footer, and therefore every footer-only link (architecture, privacy policy, cookie policy) that its canonical target /en served in raw HTML — so the site's most externally linkable URL was its only IA orphan and its no-JS rendering diverged from the document it canonicalizes to.

F-053 — INV-4's language-switcher exception named a mechanism that did not exist in the served HTML

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f032-f053-locale-switch.test.mjs (INV-7)

INV-4's sole sanctioned cross-locale mechanism — "except via the language switcher" — was unsatisfiable in the served HTML: the switcher is a scriptless <button> with no href (F-032), so for a no-JS user every one of the 26 fully-paired locale routes was unreachable from its counterpart, and the only cross-locale reference any document served is the <link rel="alternate"> cluster in <head>, which is machine-readable but not user-traversable.

F-072 — Entity self-description diverged across machine surfaces

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/rss.xml

Guarded by 40-conformance/f072-entity-descriptor.test.mjs (INV-7)

The one-line self-description of the site's single Person entity differed on every machine-facing surface — "Independent software consultant" (llms.txt), "AI Systems Engineering" (rss.xml channel title), "Software Engineer & Fractional CTO" (JSON-LD jobTitle), "Custom software for manufacturing SMBs" (title tag), "Independent software engineer" (visible hero) — so the identity descriptor a retrieval agent extracts depends on which surface it happens to enter through.

F-073 — @id discipline: the entity graph is anchored for Person/Organization but anonymous for every artifact

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en/projects

Guarded by 40-conformance/f073-f074-jsonld-entities.test.mjs (INV-7)

Only one of the twelve software entities in the site's JSON-LD carried a stable @id (#emotional-memory), and it carried it only on routes other than /en/projects — the eleven SoftwareSourceCode nodes on the projects pages and every article node (TechArticle on the post page, BlogPosting in the /en/writing Blog node) were anonymous, so cross-page entity merging is possible only by string-matching named and URLs, not by identifier.

F-074 — Structured data asserts an entity on routes whose content never mentions it

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en/privacy-policy

Guarded by 40-conformance/f073-f074-jsonld-entities.test.mjs (INV-7)

The emotional-memory SoftwareSourceCode node (with DOI identifier) was served in the JSON-LD of six routes whose visible text never named the project — /en/privacy-policy, /it/privacy-policy, /en/cookie-policy, /it/cookie-policy, /en/research, /it/ricerca — so on those routes the structured data asserts an entity the page content did not carry.

F-075 — Proof-surface claims have no fragment anchors; only blog posts are citable below page level

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en/projects

Guarded by 40-conformance/f075-proof-anchors.test.mjs (INV-7)

No heading on any non-blog route carried an id attribute (0 of 22 headings on /en, 0 of 110+11 on /en/projects, 0 on services/systems/research/writing and the seven pSEO topic pages), while every blog post served kebab-case ids on all its h2/h3 — so no claim on the proof surface is addressable by fragment URL and none of its chunks carried an in-URL anchor.

F-093 — Services body copy: geographic targeting in IT, retired SME framing in EN, and locale divergence

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/it/servizi

Guarded by 40-conformance/f091-f093-body-icp.test.mjs (INV-7)

The services pages address the retired ICP in body copy: /it/servizi targeted "PMI e aziende italiane" twice (intro and "Come lavoro"), and /en/services retained the retired ICP's SME-sizing and no-IT-department framing ("small and medium businesses … without an internal IT department") while dropping vertical and country — two different residual audiences for the same page across locales.

F-094 — Geographic audience signals in site-wide JSON-LD (areaServed, Service items)

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en/services

Guarded by 40-conformance/f094-areaserved.test.mjs (INV-7)

Structured data declared a geographic audience on every crawled document: the ProfessionalService entity served areaServed [Italy, European Union] on all 53 HTML documents, and each Service item on the services pages narrowed it to areaServed Italy only — machine-readable geographic targeting that contradicts the "anywhere" of §1.1.

F-100 — Conversion funnel is a bare mailto with no next step

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en/contact

Guarded by 40-conformance/f100-conversion-path.test.mjs (INV-7)

The conversion funnel is a single unstructured mailto link: no reply-time commitment, no prefilled subject/body, and no contact call-to-action at the end of the highest-intent surfaces (article bodies, project case studies). A reader who finishes a 3000-word technical article gets no next step (2026-07-25 external audit, items C3/C6/C8 — human-surface counterpart of F-071/F-077, which cover the machine surfaces).

F-101 — Proof gap: no numbers, no third parties, stale cadence

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en/writing

Guarded by 40-conformance/f101-proof-depth.test.mjs (INV-7)

The proof layer stopped at self-reported claims: no case study carried baseline-to-result numbers (the STYLEGUIDE itself sets a "58% -> 79%" bar), no testimonials with named and roles existed on any surface, and the writing index showed a ~15-month publication gap that undercuts the "production systems, continuously" narrative (2026-07-25 external audit, items H2-H4).

F-104 — Served HSTS carried `preload` without `includeSubDomains`

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f104-hsts.test.mjs (INV-7)

The served Strict-Transport-Security header is `max-age=63072000; preload` with no `includeSubDomains` directive, so the domain could not be accepted into the HSTS preload list and no subdomain inherits HSTS — the `preload` token advertises a protection that is not in force. The repository asserted the opposite: nginx/security-headers.conf documented the edge as emitting `max-age=63072000; includeSubDomains; preload`.

F-105 — Public audit register not served as a site route

Severity medium · Status closed · Locale en

Observed at https://gianlucamazza.it/en/audit

Guarded by 40-conformance/f105-audit-public-route.test.mjs (INV-7)

The generated public audit register (docs/audit/99-public/) was not reachable at a stable site route: no prerendered /en/audit page, no sitemap entry, and no footer link, so the §2.1 publication gate's output never left the repository.

F-107 — Positioning claim was repeated instead of earned

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en/projects

Guarded by 40-conformance/f107-claim-density.test.mjs (INV-7)

The positioning sentence was repeated instead of being earned. The canonical pillar formulation ("durable state, deterministic recovery, reproducible evals, and cost under control" / its IT mirror) was served verbatim three times on the home and four times on the projects page, with 16-21 individual pillar mentions per page. On /en/projects every occurrence is a case study saying the project does *not* have these properties but could later — the claim displaces the description of the project instead of supporting it. brand.rules.json declared canonicalVocabulary.pillars, but scripts/lib/copy-lint.mjs never reads it: there is no adherence check and no density ceiling, so the IT surface has already drifted ('stato durevole' on /it/curriculum).

F-108 — Card-title heading idiom drifts across pages (two line-heights for one role)

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f108-card-title-idiom.test.mjs (INV-7)

The card/list-item title idiom existed in two divergent variants. The canonical form `text-lg leading-snug font-medium text-white` is used by ArticleCard, ProjectCard, ExperienceCard and the CV entries; seven other card titles with the same role drop `leading-snug` (HomePage offers and articles, ArchitecturePage principles, SystemCard, SystemsPage topics, TopicPage systems, AuditPage findings), so the same heading role rendered with two computed line-heights (24.75px vs 28px) depending on the page — on the home both variants sit in adjacent sections. No gate constrains the idiom, so the drift grew one copy-paste at a time.

F-110 — Card grid internal rows misalign when titles wrap

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f110-card-row-alignment.test.mjs (INV-7)

In the equal-height card grids each card laid out its internal rows in isolation: a title wrapping to two lines pushed its own body, meta, and tags down by one line-height (24.7px measured), so the same semantic row sat at different offsets across siblings of the same grid row. Affected: the home value grid (EN 1 of 3 cards drifted, IT 2 of 3), the writing article grid (every row, both locales), and latently the home proof grid (mt-auto aligns only the footer; PROBLEM/OUTCOME rows float with copy length). Nothing in the layout constrains cross-card row alignment.

F-112 — Service offer titles carried two unrelated typographic identities

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en/services

Guarded by 40-conformance/f112-card-title-identity.test.mjs (INV-7)

The same content item — `offer.name` from src/data/services.ts — rendered with two unrelated typographic identities: on the services page as a 14px monospace uppercase h2, on the home value grid as the canonical 18px card-title idiom (STYLEGUIDE §10.2, F-108: one idiom for the role). The services process-step h3 carried the same monospace treatment inside a Card. The card-title idiom declared in .agents/layout.rules.json (idioms.cardTitle) is violated by every card heading on the services page, so the identical offer has no stable typographic identity site-wide.

F-116 — CV page reachable only through the footer

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f116-cv-entry-point.test.mjs (INV-7)

The CV page was a first-tier content page (own route, breadcrumb trail, structured data) whose only site-wide entry point is a footer link — the same treatment the genuinely secondary Privacy/Cookie pages receive. Architecture shares the footer-only header treatment but is additionally reachable from the home deep-dive section; CV has no content-path entry at all. The footer list did not distinguish tiers while the header nav enforces one, so a primary content page is reachable only through the secondary tier.

F-119 — The conversion relay is rejected upstream, and said so to no one

Severity medium · Status deferred · Locale all

Observed at https://gianlucamazza.it/api/ads/conversion/health

Guarded by 40-conformance/f119-ads-relay.test.mjs

The server-side OpenAI Ads conversion relay has never worked. The runtime configuration was present on the host (`OPENAI_ADS_CONVERSIONS_API_KEY` and `OPENAI_ADS_PIXEL_ID`, both visible in the running container), but the credential lacks the `ads.third_party_events.write` scope, so every conversion was rejected upstream with HTTP 401 and the relay answered 502. Reproduced live 2026-09-06 in validate-only mode, which recorded nothing. Two properties kept this invisible. The relay discarded the upstream status and body, so the request log carried only `status: 502` and the cause was recoverable only by running a probe inside the production container. And the endpoint had received zero conversions in the preceding seven days, so a dead relay was indistinguishable from an idle one on a low-traffic site. `OPENAI_ADS_VALIDATE_ONLY=1` was also set on the host from the 2026-09-02 staging validation. It was not the defect — with that key nothing would have been recorded either way — but it would have needed removal when installing a corrected key, or the integration would still record nothing.

F-120 — The printed CV ran to six pages, without the name

Severity medium · Status closed · Locale all

Observed at https://gianlucamazza.it/it/curriculum

Guarded by 40-conformance/f120-cv-print.test.mjs (INV-7)

The browser-printed CV, the site's only PDF path since cvforge was retired, ran to six A4 pages with near-empty pages. It carried no name, prints the page-describing web intro, and expands every external link to its raw URL.

F-121 — Editorial directions and literal translations in public copy

Severity medium · Status closed · Locale en, it

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f121-f122-public-copy.test.mjs (INV-7)

The home served internal editorial directions to readers, and the Italian services page served literal translations of generic delivery language.

F-122 — Handover copy promises independence from all third parties

Severity medium · Status closed · Locale en, it

Observed at https://gianlucamazza.it/en/services

Guarded by 40-conformance/f121-f122-public-copy.test.mjs (INV-7)

The services ownership answer promises unconditional independence from third parties without describing external licenses or service dependencies.

F-007 — EN↔IT case-study register parity (promoted)

Severity low · Status closed · Locale it

Observed at https://gianlucamazza.it/it/progetti

Guarded by 40-conformance/f007-untranslated-it.test.mjs (INV-7)

Case study prose is more jargon-dense in IT than in EN — a parity defect regardless of which register is correct.

F-008 — Brand-name query absence

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/robots.txt

Guarded by 40-conformance/f008-brand-serp.test.mjs (INV-7)

A brand-name query did not surface the domain in results. Cause unestablished; may be an artifact of the search provider.

F-031 — Root route `/`: skip link absent in raw HTML, present after hydration

Severity low · Status closed · Locale en

Observed at https://gianlucamazza.it/

Guarded by 40-conformance/f030-f031-skip-link.test.mjs (INV-7)

The raw HTML served at / contained no skip link, while all 52 other routes serve one and the hydrated DOM of / itself contained one.

F-054 — IT slug localization was a mixed convention: 7 Italian, 18 English

Severity low · Status closed · Locale it

Observed at https://gianlucamazza.it/it/architettura

Guarded by 40-conformance/f054-slug-convention.test.mjs (INV-7)

Slug localization follows no single convention on the IT locale: 7 of 25 non-home IT routes carried Italian slugs (/it/servizi, /it/sistemi, /it/progetti, /it/ricerca, /it/scrittura, /it/architettura, /it/contatti) while the other 18 — all 7 topic pages, both policy pages, and all 9 blog posts under an English /blog/ segment — carried English slugs on lang="it" documents whose titles and H1s are fully Italian, and the articles listed on /it/scrittura live under /it/blog/, a section whose URL name matches neither its parent page's slug nor its documents' language.

F-076 — Freshness signals were inconsistent across machine surfaces and absent on pSEO routes

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/rss.xml

Guarded by 40-conformance/f076-freshness.test.mjs (INV-7)

Freshness signals disagree across surfaces for the same content: the HTML TechArticle asserts datePublished 2026-06-26 / dateModified 2026-07-10 for slm-on-xbox while the .md mirror, llms.txt and llms-full.txt state only "Published: 2026-06-26", rss.xml stamps the modified date into pubDate, the single RSS channel mixes EN and IT items under language en-us, and the 14 pSEO TechArticle routes serve no date fields at all.

F-077 — The benchmark claim is extractable; the benchmarks are not

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/en/projects

Guarded by 40-conformance/f071-f077-llms-proof.test.mjs (INV-7)

The emotional-memory benchmark claim was served only in qualitative form — "reproducible benchmarks against Mem0, LangMem, and Letta" — with no metric name, no result value, and no per-claim link adjacent to it on any of the 53 routes, so a retrieval agent can extract that benchmarks existed but could not quote a single result from the site.

F-078 — Diagram content is invisible to raw retrieval and English-only when hydrated on IT routes

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/assets/architectureDiagrams-C6OuOd1f.js

Guarded by 40-conformance/f078-diagram-fallback.test.mjs (INV-7)

The architecture-diagram content (node labels such as ingress, planner, executor, audit, capability gate) and its keyboard-help strings existed only inside lazily-loaded JS chunks, absent from the raw HTML of every route and shipped in English with zero Italian variants, so no-JS retrieval agents never see this content and JS-executing agents see English chunks embedded in Italian pages.

F-102 — Analytics consent posture and the Netlify redirects residue

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f102-consent-posture.test.mjs (INV-7)

Two residual-architecture items from the 2026-07-25 external audit: (1) GTM is loaded for every visitor under Google Consent Mode denied-by-default — a legitimate pattern, but a stricter posture (load GTM only after consent, or a first-party cookieless counter) would remove the pre-consent Google request entirely; (2) `public/_redirects` is a Netlify artifact with no runtime effect on the nginx host, but it could not be deleted because check-seo-static.mjs asserts the legacy 301 map through it — the assertions belong against nginx/default.conf, which actually served those redirects.

F-103 — Unnamed positioning asset: the Reasoning Kernel program

Severity low · Status deferred · Locale all

Observed at https://gianlucamazza.it/en/research

The 2026-07-25 external audit names an unexploited positioning asset: the research line (emotional-memory, DOI-published, benchmarked) plus the production-agent runtime work compose into a coherent "Reasoning Kernel" narrative that no competitor in the benchmarked set occupies, but the site never names or sequences it (audit Phase 11, item H1: essay -> project body -> Zenodo whitepaper -> cross-references). Adjacent content gaps from the same audit: an About page telling the banking -> agents story (M6), and the nice-to-have tier (newsletter, talks page, benchmarks page).

F-106

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f106-csp-posture.test.mjs (INV-7)

The served CSP posture — an enforced hardening subset plus the full policy in Report-Only with a Sentry report-uri — was the one security header with no conformance guard: HSTS drift produced F-104 precisely because an edge-emitted header was invisible to CI, and the CSP headers had the same blind spot. The in-file comment in nginx/security-headers.conf also contradicted the build: it claimed no report-uri was wired, while scripts/write-nginx-security-headers.mjs has appended the Sentry endpoint at image build time since #271.

F-109 — Card footer links float with copy length instead of bottom-aligning

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f109-card-footer-anchor.test.mjs (INV-7)

In the home "What I have built" grid the three cards are equal height (Card is h-full flex-col), but the "Open the project" footer link flows directly after the outcome text (mt-4) instead of anchoring to the card bottom, so its vertical position varies with copy length: the orka card's link sat 22.75px lower than its siblings and the shorter cards trap dead space under the link. ArticleCard already anchors its footer with mt-auto — the idiom existed and this grid did not use it. The research page cards duplicate the same defect and additionally hand-roll the card shell without flex-col, so no footer anchoring is possible there at all.

F-111 — Home FAQ column jump and topic-hub first-heading offset

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f111-column-alignment.test.mjs (INV-7)

Two systematic column misalignments, both measured and neither ever decided. (1) The home FAQ is the only section on the narrow centered 896px column, so the page's left edge jumps by 192px around it; every neighbouring section shares the 1280px edge. (2) On the topic hub the right-column card headings start 17px below the left-column section headings — the offset is the card's border+padding chrome, and the two headings are of comparable rank, so it reads as drift, not hierarchy. (The projects showcase showed a similar 52/28 offset, but there the delta is a real content element — the status eyebrow — over a symmetric p-7: intentional hierarchy, out of scope.)

F-113 — Architecture page: two scales for one bordered card-title shape

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/en/architecture

Guarded by 40-conformance/f113-architecture-card-title.test.mjs (INV-7)

On the architecture page two sibling sections render the same shape — a title inside a `border border-white/10 p-5` card — at two divergent scales: the Principles cards use the canonical card-title idiom (text-lg leading-snug, 18px/24.75px) while the Workflow cards use text-xl with no leading utility (20px/28px). One page, one card shape, two unrelated title scales, with no idiom reference for the second.

F-114 — Topic hub body row still drifts 7.25px after F-111

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/en/multi-agent-systems

Guarded by 40-conformance/f114-topic-body-row.test.mjs (INV-7)

F-111 aligned the two columns' first-heading tops on the topic hub, but the next row down still drifts: the left column pairs a 20px/28px heading with mt-3 body spacing while the right column pairs the 18px card-title idiom with mt-2, so the two columns' body paragraphs start 7.25px apart. The headings are of comparable rank (F-111), so the residual offset reads as drift, not hierarchy.

F-115 — Critical text fonts were discovered only via the blocking CSS

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/en

Guarded by 40-conformance/f115-font-preload.test.mjs (INV-7)

The self-hosted text fonts (@fontsource Inter, font-display swap) are referenced only from the render-blocking stylesheet: no `<link rel="preload" as="font">` existed in the served HTML, so the woff2 requests could not start until the CSS is downloaded and parsed. With font-display swap this widens the fallback-to-webfont swap window by one CSS round-trip on every cold load. Measured CLS is unaffected (0.0006-0.0011); the cost is the visible swap window only.

F-117 — Closing contact invitation present on 3 of 9 content pages

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/en/systems

Guarded by 40-conformance/f117-closing-cta.test.mjs (INV-7)

Pages sharing the same shape (Header - Breadcrumb - Sections - Footer) split inconsistently on how they end: Home, Services and Projects close with the owner-ratified contact invitation (F-100), while Systems, Architecture and the topic hubs — proof pages in the conversion path — end with no next step, leaving only the standing nav links. The CTA markup was also triplicated inline across the three pages that had it.

F-118 — Architecture graph loop edge crosses the node row

Severity low · Status closed · Locale all

Observed at https://gianlucamazza.it/en/architecture

Guarded by 40-conformance/f118-architecture-loop-routing.test.mjs (INV-7)

Loop edges in the architecture diagrams use the same horizontal corridor as the forward edge between the same nodes. The return edge therefore crosses the node row and appears to extend past the nodes, making the workflow graph ambiguous and visually incorrect.