NEAPTIDE RELEASE CHECK 1.0.0 — LAB-RELEASE-2026-10-13
Python 3.9+ (standard library), Node.js 20.9+ and npm.
Tested versions are recorded in environment.json. Fixture: Next.js 15.5.22,
React/React DOM 19.2.6. Pinned npm package-lock.json is included.

REPRODUCE THE SYNTHETIC EXPERIMENT
Unzip and open a terminal in neaptide-release-check/fixture:
  npm ci --ignore-scripts
  npm run build
  npm run start
The fixture binds only 127.0.0.1:8792. Keep that terminal open.
In another terminal, from neaptide-release-check:
  python3 collect.py
  python3 analyze.py
This performs two rounds of the control and eight predefined defect cases.
Results: observations.json, analysis.json, evidence/r1-C00/report.json, etc.
The collector refuses to overwrite observations.json or an existing run folder.
Use a fresh extraction for another experiment. Stop the server with Ctrl-C.

RUN ONE EXPLICIT MANIFEST
From neaptide-release-check while the fixture is running:
  python3 check_release.py --origin http://127.0.0.1:8792 --manifest manifests/control.json --out control-check
Replace control.json with canonical.json to see an expected failing case.
Exit 0: no covered contract failure. Exit 1: findings. Exit 2: input/run error.
Do not turn exit 0 into a claim that a site is fully crawlable or indexed.
Reports contain passed checks, failed checks, response evidence and unchecked
areas. sample-report.json is a recorded canonical-defect report, not a template.

ADAPT TO YOUR OWN RELEASE
Make a small reviewed JSON manifest containing pages (path, expected canonical,
exact hreflang map) and one sitemap path. The token {origin} expands to the
--origin value. For preview deployments with production canonicals, write the
expected production canonical URLs literally. Do not auto-generate expectations
from the response being tested: that would preserve the same mistake twice.

The checker makes ordinary GETs only to the provided origin and never follows
redirects. Use public URLs you control or are authorized to test. There is no
login, credential, cookie or header configuration. It reads up to 100 explicit
pages and 30 same-origin URLs from one sitemap urlset, with a 2 MB response cap
and a 15-second connection timeout. It does not traverse links or sitemap indexes.
A sitemap limit, unsupported URL or network error is a failed/unsupported check,
not a successful full crawl. Adapt the sample and limits deliberately.

CONTRACTS AND LIMITS
One expected canonical, no generic noindex/none, one nonempty title, an H1 in
response HTML, exact declared hreflang values and HTTP-200 sitemap URLs are
contracts of this tool. A missing H1 is not asserted to be a universal indexing
blocker. The hreflang check compares values; it does not verify language quality
or fetch arbitrary alternate targets outside the manifest. Plain generic
X-Robots-Tag noindex/none and robots/googlebot meta tags are supported; complex
user-agent-specific X-Robots syntax is outside the validated scope.

No robots.txt parser, JavaScript execution, browser rendering, Googlebot
impersonation, URL Inspection, index check, selected-canonical check, structured
data validator, performance test or analytics integration is included. Review
these separately. A complete HTTP response can differ from the hydrated DOM.
Staging may intentionally use authentication/noindex; review environment-specific
expectations instead of removing protections to obtain a passing report.

The eight defects are artificial, selected by the same agent who wrote the
checker. Two runs test repeatability, not independent statistical reliability.
Six detected and two missed defects do not estimate real-world detection rates.
No ranking, traffic, lead or AI-citation effect was measured.

DEPENDENCY SNAPSHOT
The fresh installation audit reported 3 dependency advisories (2 high, 1 critical).
Versions are pinned to reproduce this dated experiment, not offered as a
production starter. Keep the fixture on loopback and do not deploy it publicly.
Review current dependency advisories before adapting any fixture code.
