Skip to content

Commit 66fb176

Browse files
Wave 1 follow-up: CORS + npm-policy CI fixes, docs/reality alignment, 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>
1 parent d907270 commit 66fb176

18 files changed

Lines changed: 182 additions & 4228 deletions

File tree

.envrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ if has nix && [ -f flake.nix ]; then
1818
fi
1919

2020
# Project environment variables
21-
export PROJECT_NAME="{{PROJECT_NAME}}"
21+
export PROJECT_NAME="gv-clade-index"
2222
export RSR_TIER="infrastructure"
2323
# export DATABASE_URL="..."
2424
# export API_KEY="..."

.github/workflows/boj-build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77
jobs:
88
trigger-boj:
99
runs-on: ubuntu-latest
10+
timeout-minutes: 5
1011
steps:
1112
- name: Checkout
1213
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

.github/workflows/worker-ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
build-test:
2727
name: Lint, format, test, bundle
2828
runs-on: ubuntu-latest
29+
timeout-minutes: 15
2930
steps:
3031
- name: Checkout repository
3132
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -34,11 +35,10 @@ jobs:
3435
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
3536
with:
3637
node-version: '22'
37-
cache: npm
38-
cache-dependency-path: worker/package-lock.json
3938

39+
# No tracked package-lock.json (npm-avoidant policy) → npm install, not npm ci.
4040
- name: Install dependencies
41-
run: npm ci
41+
run: npm install --no-audit --no-fund
4242

4343
- name: Lint (eslint)
4444
run: npm run lint

.github/workflows/worker-deploy.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ jobs:
3434
deploy:
3535
name: Deploy
3636
runs-on: ubuntu-latest
37+
timeout-minutes: 15
3738
# Manual dispatch picks the env (production requires approval if the
3839
# "production" GitHub Environment has protection rules); push → staging.
3940
environment: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || 'staging' }}
@@ -45,11 +46,10 @@ jobs:
4546
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
4647
with:
4748
node-version: '22'
48-
cache: npm
49-
cache-dependency-path: worker/package-lock.json
5049

50+
# No tracked package-lock.json (npm-avoidant policy) → npm install, not npm ci.
5151
- name: Install dependencies
52-
run: npm ci
52+
run: npm install --no-audit --no-fund
5353

5454
- name: Test before deploy
5555
run: npm test

.well-known/security.txt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
# RFC 9116 - security.txt
33
# https://securitytxt.org/
44

5-
Contact: mailto:{{SECURITY_EMAIL}}
6-
Expires: {{CURRENT_YEAR}}-12-31T23:59:59.000Z
7-
Encryption: {{PGP_KEY_URL}}
5+
Contact: mailto:j.d.a.jewell@open.ac.uk
6+
Expires: 2026-12-31T23:59:59.000Z
87
Preferred-Languages: en
9-
Canonical: https://{{FORGE}}/{{OWNER}}/{{REPO}}/.well-known/security.txt
10-
Policy: https://{{FORGE}}/{{OWNER}}/{{REPO}}/blob/main/SECURITY.md
11-
Hiring: https://{{WEBSITE}}/careers
8+
Canonical: https://github.com/hyperpolymath/gv-clade-index/.well-known/security.txt
9+
Policy: https://github.com/hyperpolymath/gv-clade-index/blob/main/SECURITY.md

README.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ This repo includes a `clade-hygiene.a2ml` contractile:
122122
| 0 | Clade taxonomy, repo seed, VCL schema | *Complete*
123123
| 1 | Deploy CLADE.a2ml to all 200 repos | Pending
124124
| 2 | VeriSimDB instance on VPS | Pending
125-
| 3 | Cloudflare Worker API | Pending
126-
| 4 | AffineScript/typed-WASM portal | Pending
125+
| 3 | Cloudflare Worker API (hardened, tested, CI-gated) | In progress (~60%)
126+
| 4 | ReScript/typed-WASM portal | Pending
127127
| 5 | LLM query endpoint | Pending
128128
| 6 | Bot write endpoints | Pending
129129
| 7 | Contributor OAuth | Pending

ROADMAP.adoc

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,45 @@
11
// SPDX-License-Identifier: MPL-2.0
2-
= Gv Clade Index Roadmap
2+
= gv-clade-index Roadmap
33

4-
== Current Status
4+
Mirrors the canonical phase plan in `.machine_readable/6a2/STATE.a2ml`. The registry
5+
is the *map* of the hyperpolymath ecosystem; "production" means a hardened, observable,
6+
CI-deployed Cloudflare Worker API backed by a live VeriSimDB.
57

6-
Initial development phase.
8+
== Current status
79

8-
== Milestones
10+
* Maturity: *alpha*. Phase 0 complete; Phase 3 (Worker API) in progress.
11+
* The Cloudflare Worker is import-fixed, hardened, tested (Vitest) and CI-gated.
12+
Automated deploy and live VeriSimDB backing are the remaining external steps.
913

10-
=== v0.1.0 - Foundation
11-
* [ ] Core functionality
12-
* [ ] Basic documentation
13-
* [ ] CI/CD pipeline
14+
== Phases
1415

15-
=== v1.0.0 - Stable Release
16-
* [ ] Full feature set
17-
* [ ] Comprehensive tests
18-
* [ ] Production ready
16+
[cols="1,4,2"]
17+
|===
18+
| Phase | Deliverable | Status
1919

20-
== Future Directions
20+
| 0 | Clade taxonomy, repo seed, VCL schema, named queries | *Complete*
21+
| 1 | Deploy CLADE.a2ml to all ~200 repos | Pending
22+
| 2 | VeriSimDB instance on VPS + ingest | Pending (external infra)
23+
| 3 | Cloudflare Worker API (hardened, tested, deployed) | In progress (~60%)
24+
| 4 | ReScript/typed-WASM portal on github.io | Pending
25+
| 5 | LLM query endpoint (API-key tier) | Pending
26+
| 6 | Bot write endpoints (signed JWT) + TODO octads | Pending
27+
| 7 | Contributor OAuth + scoped access | Pending
28+
| 8 | Repo lockdown (visibility management) | Pending
29+
|===
2130

22-
_To be determined based on community feedback._
31+
== Cross-cutting workstreams
32+
33+
* *Engineering hygiene* — toolchain, tests, linting, docs/reality alignment.
34+
* *Worker hardening* — input validation, security headers, rate limiting, structured logs, readiness.
35+
* *Observability & ops* — logging, metrics, backups, drift detection, runbook.
36+
* *Security* — tiered auth (public / LLM key / bot JWT / contributor OAuth), secrets, supply chain.
37+
* *CI/CD* — test-gated CI + automated Cloudflare deploy (staging → production).
38+
39+
== External prerequisites (owner-provided)
40+
41+
* `CLOUDFLARE_API_TOKEN` secret — enables automated Worker deploys (Phase 3).
42+
* VeriSimDB instance on a VPS — the declared source of truth (Phase 2).
43+
* GitHub OAuth app + JWT signing key — Phases 6–7.
44+
45+
See `.machine_readable/6a2/STATE.a2ml` for live status and blockers.

TEST-NEEDS.md

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
# TEST-NEEDS.md — gv-clade-index
22

3-
## CRG Grade: C — ACHIEVED 2026-04-04
3+
## Current test state
44

5-
## Current Test State
5+
The deliverable is the Cloudflare Worker registry API (`worker/`). Tests run on
6+
Vitest (Node) and are gated in CI by `.github/workflows/worker-ci.yml`.
67

7-
| Category | Count | Notes |
8-
|----------|-------|-------|
9-
| Test files | 1 | Current state |
8+
| Suite | Location | Count | Covers |
9+
|-------|----------|-------|--------|
10+
| Worker integration | `worker/test/worker.test.js` | 30 | Routing, input validation, security headers, CORS, pagination, search/LLM, 405/404/429/500/503 paths, KV-fallback queries, fuzz (no uncontrolled 5xx) |
11+
| Data contract | `worker/test/data.test.js` | 3 | 12-clade invariant + snapshot count/membership consistency |
1012

11-
## What's Covered
13+
Run:
1214

13-
- [x] 1 existing test file(s)
14-
- [x] Zig FFI integration tests
15+
```bash
16+
cd worker && npm install && npm test
17+
```
1518

16-
## Still Missing (for CRG B+)
19+
## Covered
1720

18-
- [ ] CI/CD test automation
19-
- [ ] Property-based tests
20-
- [ ] Edge case coverage
21+
- [x] Unit + integration tests for all 9 API endpoints
22+
- [x] Input validation and error-path tests (400/404/405/429/500/503)
23+
- [x] Fuzz sweep (random paths/params → no uncontrolled 5xx)
24+
- [x] Data contract test (clade invariant, count consistency)
25+
- [x] CI automation (lint + format + test + bundle dry-run on every PR)
2126

22-
## Run Tests
27+
## Still missing
2328

24-
```bash
25-
cd src/interface/ffi/test && cargo test
26-
```
29+
- [ ] Integration tests against a live VeriSimDB (blocked on Phase 2)
30+
- [ ] End-to-end smoke tests against a deployed staging Worker
31+
- [ ] Tests for the future auth tiers (LLM key, bot JWT, contributor OAuth)
32+
33+
## Notes
34+
35+
This project has **no native/FFI surface**. The former Zig FFI template stubs
36+
under `src/interface/ffi/` were removed — they were non-compiling `{{project}}`
37+
template placeholders, not real tests.

src/interface/ffi/README.adoc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,14 @@
1-
= ffi Logic
1+
// SPDX-License-Identifier: MPL-2.0
2+
= FFI surface
3+
4+
gv-clade-index has *no native/FFI surface*. It is a data + edge project: the runtime
5+
artifact is a Cloudflare Worker (JavaScript, see `worker/`) backed by VeriSimDB; there
6+
is no compiled library exposing a C ABI.
7+
8+
The `src/interface/{abi,ffi,generated}` directories are retained only to satisfy the RSR
9+
repository structure (`just validate-rsr`). Their previous contents were non-compiling
10+
`{{project}}` Zig/Idris template stubs and have been removed to avoid implying a
11+
verification or FFI surface that does not exist (cf. `PROOF-NEEDS.md`).
12+
13+
If a native surface is ever introduced, restore `build.zig`, `src/main.zig` and
14+
`test/integration_test.zig` from the RSR template and wire them into CI.

src/interface/ffi/build.zig

Lines changed: 0 additions & 94 deletions
This file was deleted.

0 commit comments

Comments
 (0)