secrets.sh --built reported ten credentials in dist/ and all ten were the same
false positive: the template's user:pass@host pattern reads the schema.org
JSON-LD on every prerendered page — //queuenorth.com"},"areaServed":{"@ — as a
host, a password and an @. One more finding for every page added, which is the
noise that turns a scanner into something people mute.
Quotes, braces, commas and angle brackets cannot occur in a real userinfo
component. Checked against a database URL with an inline password, one
percent-encoded, and a git remote carrying a token — all three still caught, all
ten false positives gone, and the historical Zoho leak from 033bdf6 still caught
when replayed.
The first version of that fix wrote its three test cases out literally in the
header, and --tracked then reported two credentials in the scanner itself. The
placeholders now use angle brackets, which are in the exclusion class the
comment is describing — so the examples cannot match the pattern they
illustrate. Same shape as the trap DOC_TRUST_MAP.md records about Exempt: lines.
doc-claims: 240 claimed paths, all present, up from 5 dangling. DOC_TRUST_MAP
was claiming banner.webp exists while saying it does not; GUARDS.md pointed at
prove-guard.sh, which this project declined. docs/history/ is excluded rather
than corrected — its entries name files that existed when they were written, and
editing an append-only log to satisfy a present-tense check is a category error.
TOOLS.md records the exclusion and why.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both are silent in the expensive direction, which is why they are written down
rather than remembered.
A webhook registered without the shared signing secret looks entirely healthy
in Forgejo — active:true, test deliveries accepted with 204 — and has every
delivery rejected by privacyllc.dev with 401 bad_signature. Forgejo exposes no
delivery history through its API, so nothing says so. This repository ran that
way for ten minutes today. Includes how to prove a delivery lands.
A check-in's projectId is the UUID, not the slug, unlike every other route in
that API. A slug returns a generic {"code":"unknown"} 500 that names no field
and is indistinguishable from a genuinely malformed request.
Also records that neither reconcile_all nor sync_projects forces a re-read of a
project inside its freshness window, and that the agent API has no per-project
force — so refreshed=0 means "not due", not "nothing to do".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Step 6 of docs/WORK_CYCLE.md. Records what the adoption proved rather than
what it did — the two facts that were not known this morning are that the lead
database is restorable, and that three defects were sitting in the tree that
the adopted tooling found on the way in.
Next action: start Batch 10 (accessibility), #189 first, and walk the pages
keyboard-only before fixing anything — all six were found by reading markup.
Blockers: none on this work. Six issues are blocked on the site owner, two of
which are unsubstantiated claims live on the site since May.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This checkout already had a pre-push in .git/hooks. Setting core.hooksPath
redirects every hook to .githooks/, so activating the template's hooks would
have silently stopped it running — which is the exact failure the versioned
hooks directory exists to prevent, applied to a hook.
Kept its two working-tree checks: a push that leaves edits behind is how docs
end up one commit adrift of the code they describe.
Dropped its third. It refused whenever the branch was ahead of its remote —
the precondition for pushing at all — so it fired on every real push and its
only advice was to re-run with --no-verify. A guard that can never pass teaches
people to bypass the two beside it that can. It did exactly that on the push of
the adoption commits.
Both remaining checks proven to refuse a dirty tree and pass a clean one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This repository is the one the template's README describes: 205 issues, zero
milestones, and severity labels spelled "P0 Critical" / "P1 High" / "P2 Medium",
which privacyllc.dev reports as NOT ADOPTED rather than as 87% complete.
Six markdown records described the same work and none pointed at the tracker.
Two of them said the project was in "Phase 5" while the code was at 0.9.3.
Migrated, then deleted in this commit:
FUTURE.md -> docs/history/BATCH_LEDGER.md (Archived). Its open
items were all already filed as issues, so nothing
needed migrating into the tracker
HISTORY.md -> docs/history/DEVELOPMENT_LOG.md, verbatim, 0 lines lost
DEVELOPMENT_LOG.md -> the same file, as a second labelled block. Not
interleaved: the changelog has three duplicated version
headings, so one date order would have implied more
than the record supports
PROJECT.md -> docs/planning/PROJECT_PLAN.md
STRUCTURE.md -> the agent pipeline into README.md; its versioning rules
retired
BUILD_SUMMARY.md -> BATCH_LEDGER.md. Its embedded SQL schema deliberately
NOT carried: it predated the UNIQUE constraint on
leads.email, and server/index.js owns the schema
SCRIPTS.md -> docs/TOOLS.md, corrected for the SSR + prerender build
Moved with history (git detects all four as renames):
OVERHAUL_PLAN.md, review.md, project-requirements.md, docs/zoho-setup.md
Kept because this project earned them: the five-agent pipeline, the design
system in OVERHAUL_PLAN.md (Status: Current, with a front-note saying which half
is history), the positioning argument in REDESIGN_REVIEW.md, and REQUIREMENTS.md
whole, including its change policy.
Deleted from the template because they do not apply, each said out loud in
DOC_TRUST_MAP.md: QA pass I (no money moves), the authorisation checklist group
and the session-token row (no accounts, no sessions), and one PRECAUTIONARY
paragraph in SECURITY.md about holding credentials on behalf of users — there
are none, and PROJECT_PLAN.md records accounts as out of scope. Pass H was kept
and rewritten: its authorisation half does not apply, its what-a-stranger-can-
reach half is the most exposed surface here.
Also removed: main.js, the old static site's hash router, referenced by nothing
and preserved in .drop/; and test-results/.last-run.json, a May Playwright
artifact reading {"status":"failed"} for a suite that does not exist.
The repository was made private on Forgejo before this commit. That is what let
the internal history be committed rather than exempted — null/fruit-fall is
already private and reports normally.
Two defects found on the way in and fixed here: zoho-setup.md told admins to
edit `server/zoho/`, a directory that has never existed in any commit (the
mapping is in server/index.js), and README.md's route list still advertised
/8x8, removed at 0.6.6, while omitting /privacy-policy.
Branding: icon.webp and logo.webp converted from this project's own marks in
assets/. banner.webp is absent and is filed as an issue rather than faked.
Verified: verify.sh 3/3, doc-claims 71 claimed paths all present, backup and a
first-ever restore of the live leads database (2 tables, 3 rows, under 1s).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ten scripts from ~/.openclaw/Projects/Template, taken one at a time and
configured against this deployment rather than copied wholesale.
Configured, not just copied:
- check-env.sh SPEC written from what server/index.js actually reads — 24
variables, each with the consequence of getting it wrong
- secrets.sh plus this project's own shapes: a bare 60+ hex run, which is
how the Zoho WebToLead tokens leaked into four commits, and a
reCAPTCHA key shape as NOTED rather than a failure, because the
site key and the secret key are indistinguishable by shape
- status.sh nebula / qn-website-dev
- healthcheck.sh /api/health, asserting 200 AND "status":"ok" AND "db":"ok".
The template probed /healthz, which does not exist here
- preflight.sh https://qn.isnull.dev, no --auth — there are no accounts
- verify.sh GUARD_DIR=scripts/verify.d, since this project has no test
runner and no typecheck for it to detect
- backup.sh ENGINE block replaced for SQLite: better-sqlite3's online
.backup() inside the container, verified with PRAGMA
integrity_check before anything is renamed into place
- restore-check.sh rewritten rather than configured — the template's is
pg_restore/psql end to end with no seam. Replays the dump from
SQL into a scratch database and times it
Three guards in scripts/verify.d, because verify.sh would otherwise detect
nothing and exit 2: the build, the tracked-tree secret scan, and a check that
every document carries a valid Status, Governs and Review trigger.
Every guard was proven to fail before being trusted, per GUARDS.md rule 1:
healthcheck against a 200 that is not this app, secrets against the real
historical leak replayed out of 033bdf6, doc-headers against both a missing
Review trigger and the Status word "Historical", restore-check against a
truncated dump, an empty database and a raised row floor.
pre-commit is ADAPTED, not the template's. That one runs `npx tsc --noEmit` and
`npx vitest run`; this project has neither, so unchanged it would refuse every
commit. It runs the secret scan and `npm run build`. Hooks are not activated by
this commit — `git config core.hooksPath .githooks` is a separate, per-clone act.
package.json: adds `verify`, and corrects the version to 0.9.3. It said 0.8.3
while the last four commits said batch 0.9.0 through 0.9.3 — the second drift of
the phase-versioning rule, which is retired in the following commit.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Client directive (Levi Halford, 2026-08-01) ahead of Google/Meta lead forms.
Privacy policy:
- Publish approved policy verbatim at /privacy-policy (src/data/privacyPolicy.js
is the single source of truth; 292/292 source lines verified present)
- Privacy Policy link in the footer of every page
- Effective/Last Updated 2026-07-31, privacy@queuenorth.com as mailto
Remove St. Petersburg street address from every surface named in the brief:
footer, contact page, schema markup, SEO metadata, Google Maps links. Collapse
ProfessionalService + Organization schema into a single Organization with
areaServed: United States; drop geo coordinates, priceRange, openingHours.
Add the approved US-coverage sentence to About. No replacement address.
Crawler visibility (the site previously served 0 bytes of body HTML without JS):
- Prerender all 19 routes at build time via src/entry-server.jsx + scripts/prerender.js
- Hoist title/meta/canonical/JSON-LD into <head>; renderToString does not do this
and react-helmet-async's context is empty under React 19
- Serve prerendered HTML; return a real 404 for unknown paths instead of 200
- Hydrate instead of discarding the prerendered markup
SEO/perf:
- Titles <=60 and descriptions <=160 chars across all pages
- Add BreadcrumbList to interior pages, WebSite to home
- Generate sitemap.xml from the route list with git-derived lastmod
- 301 duplicate URL forms (trailing slash, //, /index.html), preserving query
- Immutable caching for content-hashed assets; no-cache for HTML
- Split the 522 KB bundle into app/react-vendor/router/icons
- loading/decoding/fetchpriority + per-route hero preload; drop unused asset
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>