Wave 1: harden, test & CI-gate the Cloudflare Worker (production-grade roadmap) - #19
Merged
Merged
Conversation
… API Wave 1 of the production-grade roadmap: make the only running software (the Cloudflare Worker) actually load, and surround it with hardening, tests and CI. Worker (CC-A / CC-B): - Fix dead import: index.js imported ./verisimdb.js but the file is verisim.js, so the Worker never loaded. Now imports ./verisim.js. - Add top-level try/catch (controlled 500), input validation (clade whitelist, NaN/oversized pagination clamps, safe URI decode, bounded query length), security headers (CSP/nosniff/HSTS/frame-deny), structured JSON logging with request ids, optional native rate limiting (fails open), and a /v1/ready readiness probe (reports "degraded" on KV fallback). - Add scheduled() cron handler + refreshFromSource() to re-seed from the canonical snapshot. - Split helpers into http/log/validate/ratelimit modules. Toolchain + tests (CC-A / CC-F): - Add worker/package.json with Vitest, ESLint (flat) and Prettier; configs and package-lock for reproducible `npm ci`. - 30 tests: routing, validation, headers, pagination, search, 405/404/503/500 paths, KV-fallback queries, a fuzz sweep (no uncontrolled 5xx), and a contract test enforcing the 12-clade invariant + snapshot count consistency. Data fix (Phase 0 reconcile): - Regenerate worker/data/index.json: it claimed total_repos=202 while carrying 203 repos, and game-server-admin (ix) was missing from clade membership. Now internally consistent (203 / 203 / member-sum 203). CI/CD (CC-E): - Add worker-ci.yml (lint, format, test, wrangler dry-run) and worker-deploy.yml (staging on main; production via dispatch; skips cleanly until CLOUDFLARE_API_TOKEN is set). - Fix malformed JSON quoting in boj-build.yml curl trigger. Hygiene: - Fix /var$REPOS_DIR path bug in sync/deploy-clade-a2ml.sh and parse-repos.sh (now derive paths from script location; REPOS_DIR overridable). - Add .well-known/groove/manifest.json (service discovery). - wrangler.toml: VERISIMDB_URL/DATA_SOURCE_URL vars, observability, hourly cron, rate-limiter binding, staging environment. - Stop tracking local .wrangler/ dev state. - STATE.a2ml: honest status (Phase 3 → 60%, external blockers recorded). Verified locally: eslint clean, prettier clean, 30/30 tests pass, and both the top-level and staging configs pass `wrangler deploy --dry-run`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UCnxjXkN6uDj9YSANuGEgR
| @@ -0,0 +1,69 @@ | |||
| // SPDX-License-Identifier: MPL-2.0 | |||
🔍 Hypatia Security ScanFindings: 73 issues detected
View findings[
{
"reason": "Issue in boj-build.yml",
"type": "missing_timeout_minutes",
"file": "boj-build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in codeql.yml",
"type": "missing_timeout_minutes",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dependabot-automerge.yml",
"type": "missing_timeout_minutes",
"file": "dependabot-automerge.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
marked this pull request as ready for review
June 20, 2026 18:27
hyperpolymath
pushed a commit
that referenced
this pull request
Jun 20, 2026
…idant policy Follow-up fixes for CI findings on PR #19: - Security (CWE-942 / Hypatia js_wildcard_cors, critical): replace the hardcoded wildcard Access-Control-Allow-Origin with an env-configurable allowlist (CORS_ALLOW_ORIGIN), defaulting to the portal origin. CORS headers are now applied centrally in fetch(); request Origin is echoed only when allowlisted. Added 3 CORS tests (default origin, echo-allowed, never-wildcard). - Governance (npm-avoidant policy / standards JS-RUNTIME-POLICY): stop tracking worker/package-lock.json (now gitignored) and pin devDependencies to exact versions for reproducibility; CI uses `npm install` instead of `npm ci`. - Workflows: add timeout-minutes to worker-ci, worker-deploy and boj-build (Hypatia workflow_audit). Verified: 33/33 tests pass, eslint + prettier clean, wrangler dry-run OK, no tracked package-lock.json. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UCnxjXkN6uDj9YSANuGEgR
hyperpolymath
added a commit
that referenced
this pull request
Jun 20, 2026
… FFI cleanup (#20) * fix(worker): restrict CORS to configured origins; comply with npm-avoidant policy Follow-up fixes for CI findings on PR #19: - Security (CWE-942 / Hypatia js_wildcard_cors, critical): replace the hardcoded wildcard Access-Control-Allow-Origin with an env-configurable allowlist (CORS_ALLOW_ORIGIN), defaulting to the portal origin. CORS headers are now applied centrally in fetch(); request Origin is echoed only when allowlisted. Added 3 CORS tests (default origin, echo-allowed, never-wildcard). - Governance (npm-avoidant policy / standards JS-RUNTIME-POLICY): stop tracking worker/package-lock.json (now gitignored) and pin devDependencies to exact versions for reproducibility; CI uses `npm install` instead of `npm ci`. - Workflows: add timeout-minutes to worker-ci, worker-deploy and boj-build (Hypatia workflow_audit). Verified: 33/33 tests pass, eslint + prettier clean, wrangler dry-run OK, no tracked package-lock.json. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UCnxjXkN6uDj9YSANuGEgR * docs+chore: align docs with reality, fill placeholders, drop vestigial FFI stubs In-repo Wave 1 hygiene (no external credentials needed): - ROADMAP.adoc: replace the generic template with the real 8-phase plan (mirrors .machine_readable/6a2/STATE.a2ml). - TEST-NEEDS.md: correct false claims ("Zig FFI integration tests", `cargo test`, "CRG C achieved"); document the actual Vitest suite (33 tests) + CI gating. - README.adoc: Phase 3 -> "In progress (~60%)"; Phase 4 label -> ReScript/typed-WASM (aligns with ADR-004 and the overview). - .envrc, .well-known/security.txt: fill load-bearing template placeholders. - src/interface/ffi: remove non-compiling {{project}} Zig template stubs (main.zig, build.zig, integration_test.zig) — this project has no FFI surface; keep the RSR dirs with an explanatory README (cf. PROOF-NEEDS.md). No functional Worker changes; 33/33 tests still pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UCnxjXkN6uDj9YSANuGEgR --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
First wave of the agreed 8-phase production-grade roadmap. This wave is the in-repo, no-external-dependency work that turns the only running software — the Cloudflare Worker registry API — from broken and untested into hardened, tested, and CI-gated.
Changes
Worker — fix & harden (
worker/src/*)try/catch→ controlled500(no isolate crashes).NaN/oversized pagination clamps, safe URI decode, bounded query length.default-src 'none',nosniff, HSTS,X-Frame-Options: DENY)./v1/readyreadiness probe (reportsdegradedon KV fallback) and ascheduled()cron handler to refresh the snapshot.http/log/validate/ratelimitmodules.Toolchain + tests (
worker/package.json,test/)npm ci.405/404/503/500paths, KV-fallback queries, a fuzz sweep (no uncontrolled 5xx), and a contract test enforcing the 12-clade invariant + snapshot count consistency.Data fix — Phase 0 reconcile (
worker/data/index.json)total_repos: 202while carrying 203 repos, andgame-server-admin(ix) was missing from clade membership. Regenerated → internally consistent (203 / 203 / member-sum 203). The new contract test prevents this drift from recurring.CI/CD (
.github/workflows/)worker-ci.yml— lint, format, test,wrangler deploy --dry-runon every PR/push (the gate that actually tests the deliverable).worker-deploy.yml— staging on merge tomain, production via manual dispatch; skips cleanly (stays green) untilCLOUDFLARE_API_TOKENis set.boj-build.yml.Hygiene
/var$REPOS_DIRpath bug insync/deploy-clade-a2ml.sh+parse-repos.sh(now derive paths from script location;REPOS_DIRoverridable). Verified:parse-repos.shemits 203 rows..well-known/groove/manifest.json(service discovery).wrangler.toml:VERISIMDB_URL/DATA_SOURCE_URL, observability, hourly cron, rate-limiter binding, staging environment..wrangler/dev state.STATE.a2ml: honest status (Phase 3 → 60%; external blockers recorded).Verified locally
eslintclean ·prettier --checkclean · 30/30 tests pass ·wrangler deploy --dry-runpasses for both top-level and--env staging.Constraints respected
Worker stays plain JavaScript (no TypeScript — per
AGENTIC.a2ml); MPL-2.0 headers; canonical file locations.Next steps (need you)
CLOUDFLARE_API_TOKENrepo secret → unlocks auto-deploy to staging./v1/ready→ready).Deferred to follow-ups (tracked in the plan)
Placeholder sweep via
just init; fullROADMAP.adoc/README.adoc/TEST-NEEDS.mdrewrite;src/interface/ffi/cleanup; Phases 1–8 proper.🤖 Generated with Claude Code
https://claude.ai/code/session_01UCnxjXkN6uDj9YSANuGEgR
Generated by Claude Code