[ci-bootstrap] CI smoke-test — close without merging#2
Conversation
|
Closing without merging — registration purpose succeeded. The The check itself ran red because These errors predate Pass 2 and are deferred to a Phase A.0 cleanup commit at the start of Pass 2 Phase A (where we naturally re-touch the affected files). Phase 0.3 sub-steps 4 and 5 ( Full deferral context tracked in the Pass 2 backlog entry on the deferred sub-steps. The |
Two new sections between "Implementation phasing" and "Skills": - "Gate-based handoff pattern" — four rules on how to sequence work with Claude: plan-first for multi-decision tasks, pause at named gates, report diagnostics before editing, surface uncertainty as open questions rather than silent guesses. The discipline Pass 1 shipped on. - "Process rules from Pass 1" — three specific technical lessons extracted from bugs we caught during G1b / G4 / post-deploy: token-conversion verification scope (diff both preset and companion CSS), wrangler env-inheritance gotcha (observability / vars / routes don't inherit into env.* blocks), and primary- source verification for version-dependent API behavior. Closes items #2, #3 of the Pass 2 backlog (which also had them scheduled for a CLAUDE.md touch at Pass 2 start; landing them now keeps the rules in the file when the next session picks up). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diagnostic at G B.1.3a smoke #2: rate-limit fix unblocked the path to email-send, which then failed with MIMETEXT_INVALID_HEADER_VALUE: The value for the header "Reply-To" is invalid. mimetext's setHeader signature accepts string | Mailbox | Mailbox[]; the bare email string fails its internal validation. Constructed the Mailbox explicitly via `new Mailbox({ addr: email })`. Visitor display name is intentionally omitted from the header to avoid header-injection risk on user-supplied input; the name is rendered in the body for context. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diagnostic at G B.1.3a smoke #2: rate-limit fix unblocked the path to email-send, which then failed with MIMETEXT_INVALID_HEADER_VALUE: The value for the header "Reply-To" is invalid. mimetext's setHeader signature accepts string | Mailbox | Mailbox[]; the bare email string fails its internal validation. Constructed the Mailbox explicitly via `new Mailbox({ addr: email })`. Visitor display name is intentionally omitted from the header to avoid header-injection risk on user-supplied input; the name is rendered in the body for context. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…failures" design
Adds verify-cloudflare-facts.yml weekly cron workflow + scripts/checks/dpf.mjs
+ scripts/checks/cwa-retention.mjs + 6 fixtures + scripts/run-verifier.mjs
orchestrator. Extends scripts/check-cloudflare-facts-freshness.mjs to read
_meta.last_check_attempt with 30-day threshold (down from 90).
Migrates src/data/cloudflare-facts.json to verifier-era schema (schema_version
1; per-fact status + value fields; _meta block; structured cwa_retention with
integer month values; raw_events_retention_months explicitly null per
Cloudflare's documented absence). Updates src/lib/cloudflare-facts.ts type +
adds getEffectiveVerifiedDate helper (worst-case freshness signal: older of
the two per-fact verified_at). Privacy pages (datenschutz.astro, en/privacy.astro)
read via the helper.
Verifier shape per plans/active/pass-2/g-d-2/spec.md: 1/5/15-min retry budget
(21 min total, fits 30-min workflow timeout); status-return error handling
(no throws cross check boundaries); explicit registry per spec §9.6;
hand-written validator per §9.7; status-enum rename ('ok' CheckResult →
'active' JSON) per §6.2; v1-coverage smoke step inside verifier workflow only,
mode #8 deploy-triggered limitation acknowledged per §3.8.
All synthetic failure modes (#2, #4, #5, #6) verified via MOCK_SCENARIO=
fixture routing. Mode #1 (freshness gate) verified via stale last_check_attempt.
Modes #3, #7, #8, #9 deferred to controller-side post-commit per prompt's
"may defer" guidance. Outcome record at
plans/active/pass-2/g-d-7/verifier-test-matrix.md (workspace, gitignored).
Closes backlog #8.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…y workflows
Master plan §4 D.1 required wiring PRODUCT_REPOS_PAT into all 4 build
workflows (deploy-staging, deploy-production, rebuild-on-dispatch,
rebuild-nightly). G D.4 wired only the two NEW workflows (G D.5 +
G D.6); the two existing Pass-1-era files (deploy-staging.yml,
deploy-production.yml) were missed.
Symptom: G D.9's populated-state UI shipped to dev correctly per local
build, but the staging deploy rendered no release content because the
loader's first guard (no PAT → return []) silently fired on the runner.
Fix: add PRODUCT_REPOS_PAT to the Build step's env block in both
existing deploy workflows. Matches the master plan's intent and the
pattern already in rebuild-on-dispatch.yml + rebuild-nightly.yml.
Per master plan §4 D.1: "Wire into deploy workflows ... via env:
PRODUCT_REPOS_PAT: ${{ secrets.PRODUCT_REPOS_PAT }} on each build step.
Staging also gets it — the loader's behaviour must match across envs
so no 'works in prod, fails in staging' drift."
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… footer overflow Resolves three visual issues Lars surfaced via mobile + desktop screenshots: 1. Two horizontal lines on product detail pages (between description and 'Release history' heading). Root cause: empty .product-detail__body wrapper from Phase C's stub template renders an empty bordered block stacked on top of G D.9's .release-history border. Fix: render the wrapper conditionally on hasBodyContent (entry.body with HTML comments stripped + trimmed). v1 products keep an empty body; future products with body markdown still get the wrapper rendered. 2 & 3. Mobile footer overflows iPhone 16 Pro viewport AND entire design appears to have right-side padding. Single root cause: .site-footer__nav ul lacked flex-wrap on mobile, so the 6 nav items couldn't fit in one row at 393px viewport, triggering horizontal body scroll which visually shifted the rest of the design left. Fix: add flex-wrap: wrap and a denser gap (0.75rem row, 1.25rem column) to the mobile media query. Pre-existing footer responsive bug surfaced during Phase D verification; fixing real broken behavior, not retrofitting working code (no-mid-flight- retrofit rule allows bug fixes). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e updates The VERIFIER_LAST_OK_AT variable-update step in verify-cloudflare-facts.yml failed with HTTP 403 against the default GITHUB_TOKEN, even with `actions: write` declared in the permissions block. The workflow- permissions YAML does not actually expose a `variables` scope; updating Actions Variables requires either a classic PAT with `repo` scope or a fine-grained PAT with Variables: read/write. Resolution: switch the variable-update step's GH_TOKEN to a new VERIFIER_VARIABLE_TOKEN repo secret (fine-grained PAT scoped to this repo only, Variables: read/write + Metadata: read). Drop the unused `actions: write` from the workflow's permissions block; replace with an explanatory comment so future maintainers don't re-add it. The PR and Issue steps continue to use GITHUB_TOKEN — they only need pull-requests: write and issues: write, which the default token carries. Surfaced when the first live workflow_dispatch on dev's new YAML failed at step 6. The mock-scenario drift tests passed because their channel steps gate on dry_run=false and were correctly skipped end-to-end. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI smoke-test PR for the new
.github/workflows/ci-pr.yml. Purpose: register thebuild-prcheck name with GitHub so it becomes selectable in theprotect-mainruleset — GitHub only exposes a check name after it has run at least once. Diff is a single new file; no other Pass 2 work piggybacks. Will be closed without merging oncebuild-prhas succeeded; the actualci-pr.ymllands onmainthrough the Pass 2dev → mainmerge.