Shipping Notes, 4 August 2026: The Fortnight We Fixed Measurement

169 commits across eight repositories in eight days. Most of it was not new features — it was discovering that several things we believed were working were not, and fixing them. Here is what shipped and what it cost.

Ganda Tech Services 8 min read
Shipping Notes, 4 August 2026: The Fortnight We Fixed Measurement

Every fortnight we publish what actually shipped across the group. This one is unusual: almost none of it was new features.

169 commits across eight repositories in eight days. The largest category was technical SEO, and the reason is that we spent the fortnight discovering that several things we had recorded as “done” were not working — then fixing them.

That is a less flattering story than a feature launch. It is also more useful.

The numbers

DivisionCommits
Content operations52
Cosmos Web Tech28
Potentialz16
Cloud Geeks12
Awesome Apps12
Ganda Tech Services9
Ash Ganda4

By category: web/SEO 64, content 50, AI agents 22, cybersecurity 10. Split roughly 63 content commits to 106 code commits.

What we found

Four of five sites returned “200 OK” for pages that do not exist

Type a made-up address on a website and you should get a 404. Four of our five sites returned a 200 OK with the homepage instead.

This is called a soft 404, and it tells search engines that every mistyped or dead URL is a real page worth indexing. Fixed on all four with genuine 404 handlers, verified by requesting nonsense URLs as Googlebot.

Every canonical URL was pointing at a redirect

One configuration line — trailingSlash: 'never' — set the sites to strip the trailing slash from URLs, while the hosting served the version with it.

The result: every canonical tag and every sitemap entry pointed at a URL that immediately redirected somewhere else. Google crawls, finds a redirect where the page should be, and declines to index. On one site that meant 419 published posts and one indexed page, with 136 sitting in “crawled — currently not indexed”.

Nothing looked broken. Every page loaded correctly for a human.

A deploy that succeeded, failed, and reported neither

The one worth reading carefully.

We committed a sitemap fix, pushed it, and the deployment dashboard showed a build against the correct commit. Git was clean. Everything looked shipped.

Production served a three-day-old build.

The build log had the answer: the commit added a dependency and updated the wrong lockfile — the repository builds with one package manager and the commit regenerated another one’s lockfile. CI runs a strict install that refuses to proceed when the lockfile and manifest disagree. The build exited with an error, and the platform did what it is designed to do: kept serving the last version that worked.

So the failure was invisible from every angle we habitually check. Clean git, pushed commit, a dashboard entry against the right SHA. Only the live site disagreed, and nothing was watching the live site.

Fixed by syncing the correct lockfile and removing the second one entirely, so the ambiguity cannot recur.

An analytics dashboard with three months of zero

Five sites were registered with our analytics provider in manual-installation mode, which requires a snippet in the page. The snippet was in none of the repositories.

The dashboard rows existed. They had recorded zero page views for three months. One site’s layout carried a comment reading “analytics — 100% traffic capture” with nothing underneath it.

A dashboard row is not data. We now verify that measurement produces a number, not that it was configured.

What we built

A gate that re-derives all of this in thirty seconds. Every finding above is now an executable check that runs against the live sites: canonical returns 200, sitemap URLs return 200, unknown URLs return 404, the analytics endpoint accepts a beacon, and the tracking ID in the documentation matches what the page actually fires.

The reasoning is in the script’s own header: a note asserts a fact at the moment it was written; a check asserts it now. Every defect above was already “documented” somewhere. The documentation was the thing that had rotted.

It has already earned its place — it caught the stale deploy above, and it is how we confirmed the fix rather than assuming it.

Thirteen local service pages. Six for Cloud Geeks, seven for Awesome Apps, covering Parramatta, Castle Hill, Bella Vista, Norwest, Rouse Hill and the wider Hills District. Hand-written rather than templated — near-identical location pages with the suburb swapped are a pattern search engines penalise, and they compete with each other.

First-party measurement on our own infrastructure, so we are not dependent on a third party’s snippet being present to know whether anyone visited.

What we got wrong

Two corrections worth publishing, since we published the originals.

We reported two of our sites as competing with each other for the same search terms. They were not. One was a subdomain of the other, and the search property we were reading includes every subdomain — so the smaller site’s data was inside the larger one’s numbers the whole time. We read containment as competition.

We wrote “18 clicks” and implied “18 visitors”. Search Console counts clicks from Google organic results only. It says nothing about direct, social, email or referral traffic. Different tools count different populations and disagree by design; we now name the instrument on every number.

The pattern across all of it

Every defect this fortnight shared a shape: a thing that looked correct from the place we habitually checked, and was wrong from where it mattered.

  • Pages loaded fine in a browser, and could not be indexed
  • Git was clean and pushed, and production was three days stale
  • The analytics dashboard had rows, and the rows had zeros
  • Two properties looked like competitors, and one contained the other

The common fix is not more documentation. It is checking the thing itself, from outside, on a schedule — which is what the gate now does.


Frequently Asked Questions

Why publish the mistakes?

Because the fixes are only useful with the diagnosis attached. “We added 404 pages” is not information. “Four of five sites returned 200 for dead URLs, here is how we found it” is something another team can act on.

What is a soft 404?

When a page that does not exist returns a success status instead of a 404. Search engines treat it as a real page and may index it, which fills the index with duplicates of your homepage.

How did a deploy fail without anyone noticing?

The hosting platform kept serving the previous working build, which is correct behaviour. The gap was that nothing was checking whether production matched what we had shipped. Git status and a dashboard entry both looked healthy.

What does the integrity gate check?

Five things per site: canonical resolves 200, sitemap URLs resolve 200, an unknown URL returns 404, the analytics endpoint accepts a beacon, and the live tracking ID matches the documented one. It runs against production, not the repository.

Can we run this on our sites?

Yes — the five checks are the same regardless of platform, and finding a soft 404 or a canonical redirect loop usually takes minutes.


Talk to us

We are at U608/8 Elizabeth Macarthur Drive, Bella Vista NSW 2153, on 0433 309 677.

Cosmos Web Tech handles web design and search, Cloud Geeks handles IT and cloud infrastructure, and Awesome Apps builds mobile applications — all from the same office in Bella Vista.

Tags

Shipping NotesTechnical SEOMeasurementEngineering Practice