Skip to content

Site audit — public findings register

This is the public rendering of an audit of gianlucamazza.it, carried out against the site's own stated positioning. It is generated from the finding sources; nothing here is written by hand.

The audit is published for the same reason its findings are guarded: 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: 40 of 40 findings are public — 37 closed · 3 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 (new)
F-032highclosedallLocale switching has no non-JavaScript path in the served HTML
F-070highclosedallUniversal soft-404: any URL serves HTTP 200 with the complete home document
F-071highclosedallThe proof surface is absent from every machine-curated retrieval surface
F-090highclosedallTitles/meta of the entry pages address the retired ICP as audience
F-091highclosedallHome message hierarchy leads with the retired ICP and explicitly subordinates the current one
F-092highclosedallHome FAQ declares 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 are 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 (new)
F-030mediumclosedallPolicy pages: skip link targets a nonexistent anchor; no `<main>` landmark
F-033mediumclosedallHeader controls are script-dependent buttons; mobile nav panel is served display:none
F-050mediumcloseden, itEN↔IT content parity matrix, claim by claim
F-051mediumcloseden, itBlog related-article rails diverge 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 names a mechanism that does not exist in the served HTML
F-072mediumclosedallEntity self-description diverges 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-101mediumdeferredallProof gap: no numbers, no third parties, stale cadence
F-104mediumclosedallServed HSTS carries `preload` without `includeSubDomains`
F-105mediumclosedenPublic audit register not served as a site route
F-007lowcloseditEN↔IT case-study register parity (promoted)
F-008lowdeferredallBrand-name query absence (deferred)
F-031lowclosedenRoot route `/`: skip link absent in raw HTML, present after hydration
F-054lowcloseditIT slug localization is a mixed convention: 7 Italian, 18 English
F-076lowclosedallFreshness signals are 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

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 renders 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 serves 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 (new)

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 does not resolve: DNS for the venerelabs.com zone returns 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 exists in the raw HTML of any of the 53 routes; the language switcher is served exclusively as <button type="button"> elements, which per the HTML specification have no default activation behavior.

F-070 — Universal soft-404: any URL serves 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 returns 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 is 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) contain 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 carry 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 declare 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 leads 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 receives is the retired ICP (hero paragraph: software "for Italian manufacturing SMBs" / "per PMI manifatturiere italiane"), the §1.1 ICP claim is demoted to a subordinate "Summary" block, and a footer section explicitly declares 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 declares 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 — answers 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 — leads with the retired ICP ("Independent software consultant for small and medium manufacturing businesses in Italy without an internal IT department") and expressly demotes 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 render more than one <h1>.

F-004 — FAQ proof-list parity EN↔IT (dropped: lists are 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 diverge 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 carry 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 are unconfirmed; og:locale:alternate is present but is not a substitute.

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

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, does not resolve: the venerelabs.com DNS delegation returns SERVFAIL.

F-030 — Policy pages: skip link targets 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 targets id "main-content", but no element with that id and no <main> landmark exists on those pages, in raw or hydrated HTML.

F-033 — Header controls are script-dependent buttons; mobile nav panel is 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 is 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 render differently across locales — including the audience definition on the services pair (IT adds "italiane", EN carries 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 diverge 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 serves no related rail while its IT counterpart serves 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 / is 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 serves in raw HTML — so the site's most externally linkable URL is its only IA orphan and its no-JS rendering diverges from the document it canonicalizes to.

F-053 — INV-4's language-switcher exception names a mechanism that does 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" — is 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 is unreachable from its counterpart, and the only cross-locale reference any document serves is the <link rel="alternate"> cluster in <head>, which is machine-readable but not user-traversable.

F-072 — Entity self-description diverges 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 differs 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 carries a stable @id (#emotional-memory), and it carries 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) are anonymous, so cross-page entity merging is possible only by string-matching names 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) is served in the JSON-LD of six routes whose visible text never names 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 does 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 carries 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 serves 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 carries 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 targets "PMI e aziende italiane" twice (intro and "Come lavoro"), and /en/services retains 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 declares a geographic audience on every crawled document: the ProfessionalService entity serves areaServed [Italy, European Union] on all 53 HTML documents, and each Service item on the services pages narrows 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 deferred · Locale all

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

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

F-104 — Served HSTS carries `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 cannot 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-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 (deferred)

Severity low · Status deferred · Locale all

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

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 / contains no skip link, while all 52 other routes serve one and the hydrated DOM of / itself contains one.

F-054 — IT slug localization is 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 carry 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 — carry 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 are 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 is 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 exist but cannot 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 exist 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 cannot be deleted because check-seo-static.mjs asserts the legacy 301 map through it — the assertions belong against nginx/default.conf, which actually serves 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).