ci: run fuzz smoke and scheduled deep fuzz

ober

2722d2176f4479a7b21af549f3c1fbd9057aa87a

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e8d4337..c6bed14 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,8 +5,9 @@ on:
     branches: [master]
   pull_request:
   schedule:
-    # Weekly advisory freshness check: `make audit` runs cargo-audit and jpkg audit.
-    - cron: '23 9 * * 1'
+    # Daily security maintenance: `make audit` refreshes advisories and the
+    # scheduled-only deep fuzz step exercises the checked-in corpora.
+    - cron: '23 9 * * *'
 
 env:
   IMAGE: jerboa21/jerboa
@@ -60,6 +61,25 @@ jobs:
             ${{ env.IMAGE }}:ci \
             make audit SCHEME=scheme
 
+      - name: Run fuzz smoke
+        timeout-minutes: 15
+        run: |
+          docker run --rm \
+            -v "${{ github.workspace }}:/workspace" -w /workspace \
+            -e JERBOA=/workspace/lib -e JERBOA_HOME=/workspace \
+            ${{ env.IMAGE }}:ci \
+            make fuzz-smoke SCHEME=scheme
+
+      - name: Run scheduled deep fuzz
+        if: github.event_name == 'schedule'
+        timeout-minutes: 60
+        run: |
+          docker run --rm \
+            -v "${{ github.workspace }}:/workspace" -w /workspace \
+            -e JERBOA=/workspace/lib -e JERBOA_HOME=/workspace \
+            ${{ env.IMAGE }}:ci \
+            make fuzz-deep SCHEME=scheme
+
       - name: Run feature tests (informational)
         continue-on-error: true
         timeout-minutes: 10
diff --git a/docs/kimi3-security-recommmendations.md b/docs/kimi3-security-recommmendations.md
index ea07f95..2bb815d 100644
--- a/docs/kimi3-security-recommmendations.md
+++ b/docs/kimi3-security-recommmendations.md
@@ -274,7 +274,7 @@ Keep this section to baseline facts only.
 | Actual native C ABI exports after cfg filtering | **190** | `make native-export-review-check` |
 | Rust unsafe sites in `jerboa-native-rs/src` | **390** | `make ffi-audit-report` |
 | Fuzz harnesses | 13 | `ls tests/fuzz/harness` |
-| Checked-in fuzz seed corpora | **0** | `tests/fuzz/` contains only `harness/` |
+| Checked-in fuzz seed/regression inputs | **15 / 11** | `find tests/fuzz/{corpus,regression} -mindepth 2 -type f` |
 | Security test files | 21 | Appendix A |
 | Vendored C amalgamation in tree | `vendor/jsqlite` | `ls vendor/` |
 
@@ -287,12 +287,13 @@ Keep this section to baseline facts only.
    breakage was reported for `lib/std/pipeline.ss`,
    `tests/test-pipeline.ss`, `tests/test-security2-parsers.ss` in the
    checklist appended to `security-reference.md` — re-verify all four.
-2. **The exec worker facade exists, but the native pre-exec confined backend
-   remains open** (see §2.3). The launcher composes argv exec, pure env,
-   deadline, output caps, and refused-axis reporting; rlimits, kernel
-   sandboxes, egress proxy wiring, and audit-log start/end still need to land.
-3. **No fuzz seed corpora and no crash-regression corpus** — fuzzing is
-   harness-only; nothing preserves found crashes as tests.
+2. **The exec worker facade exists and now has native confinement on the main
+   supported paths** (see §2.3). The remaining worker gaps are Seatbelt
+   path/exec parity plus arbitrary-command/proxy-aware Capsicum parity.
+3. **Fuzz seed corpora and crash/rejection regressions exist; CI needed
+   scheduled fuzzing** — the deterministic regression runner is wired into
+   `make fuzz-smoke`, and CI now runs smoke fuzzing normally plus deep fuzzing
+   on scheduled runs.
 4. **`docs/ai-threat.md` comparative table is stale**: it rates supply
    chain "Behind (cargo audit)" but jpkg now has TUF/signatures/transparency
    /OSV audit. Fixed 2026-07-27.
@@ -315,7 +316,7 @@ Keep this section to baseline facts only.
 |---|---|---|
 | G1 shrink target | Managed core is memory-safe; parsers budgeted; safe prelude exists; FFI audit inventory, per-site provisional verdicts, FFI hazard scanner rules, a gated `vendor/jsqlite` accepted-risk decision, native unsafe invariant comments, and a gated native export review exist | FFI remediation remains: Scheme per-binding safety review |
 | G2 cap blast radius | Capabilities, taint, kernel sandbox, egress policy objects, worker facade, memory rlimit pre-exec path, egress proxy env wiring, Linux pre-exec seccomp/Landlock setup, macOS Seatbelt no-write/no-network setup, standard FreeBSD worker-eval Capsicum entry, authenticated actor transport/envelopes, Ring HTTP source taint, and WebSocket/fiber WebSocket source taint all exist | Native Seatbelt path/exec parity and arbitrary-command/proxy-aware Capsicum worker parity remain open |
-| G3 find it first | 13 harnesses, scanner w/ rule DB, lint | No corpora, no crash regression, no scheduled fuzzing, no standing AI-red-team, no exploit-shaped regression suite |
+| G3 find it first | 13 harnesses, checked-in seed/regression corpora, scanner w/ rule DB, lint, exploit-shaped K3 suite | Standing AI-red-team and ongoing corpus growth remain open |
 | G4 fail closed | Raw-fork launchers retired correctly; `allow-degraded?` explicit | New controls must keep the invariant; degraded-mode warnings must be test-locked |
 | G5 recover fast | SBOM/repro/signing gates exist | TCB accounting manual; doc drift (stale tables, undocumented modules); independent-builder reproducibility not yet routine |
 
@@ -561,7 +562,8 @@ Harnesses without corpora find a bug once and forget it.
   frames, and REPL reader input. `tests/fuzz/regression/` contains checked-in
   known-bad inputs for the same surfaces, and `tests/test-fuzz-regression.ss`
   runs the deterministic corpus gate under normal `make test` and at the start
-  of `make fuzz-smoke`.
+  of `make fuzz-smoke`. On 2026-07-28, GitHub CI was updated to run
+  `make fuzz-smoke` on normal CI and `make fuzz-deep` on scheduled daily runs.
 - **Do:** (a) Add `tests/fuzz/corpus/<parser>/` seed corpora (start from
   valid samples mutated minimally; include every historical crash input).
   (b) Add `tests/fuzz/regression/` — every crash ever found becomes a
@@ -1170,7 +1172,7 @@ These become the permanent operating rhythm once the work items land.
 |---|---|---|
 | Balance + build health | every commit | `make audit` incl. all-file balance check (P0-01) |
 | Scanner with growing rule DB | every commit (changed lines), every night (full tree) | `jerboa_security_scan`, pre-commit template (P2-05) |
-| Fuzz smoke / deep | PR / nightly | `make fuzz-smoke` / `fuzz-deep` with corpora (P0-08) |
+| Fuzz smoke / deep | PR / nightly | GitHub CI runs `make fuzz-smoke`; scheduled CI runs `make fuzz-deep` with corpora (P0-08) |
 | Exploit-shaped regression suite | every `make test` | `tests/security/` (P0-07) |
 | Dependency advisories | weekly | `jpkg audit` + `cargo audit` (P2-02) |
 | AI red-team | quarterly + after P1 landings | protocol in P2-04 |
@@ -1223,8 +1225,8 @@ Track these in `docs/status.md` per release:
 | FFI bindings audited | scanner inventory and provisional verdicts in [ffi-audit.md](ffi-audit.md); native exports gated and justified | 100% with final verdicts |
 | Un-annotated Rust `unsafe` blocks | 0 unsafe review sites without nearby `SAFETY:` comments in [ffi-audit.md](ffi-audit.md) | 0 |
 | Blocking FFI missing `__collect_safe` | 0 source bindings in [ffi-audit.md](ffi-audit.md) | 0 |
-| Fuzz corpora / crash regressions | 0 / 0 | per-parser corpora + every crash a test |
-| Exploit-shaped regression tests | ~0 | ≥ 1 per historical finding |
+| Fuzz corpora / crash regressions | 15 / 11 checked-in inputs with smoke/deep CI wiring | per-parser corpora + every crash a test |
+| Exploit-shaped regression tests | K3 regression suite in `tests/security/` | ≥ 1 per historical finding |
 | Sandboxed-by-default app entry | no | yes (P0-06) |
 | Supply-chain gates in `make audit` | jpkg audit + cargo audit wired 2026-07-27; generated projects require signatures/provenance | signatures required for all release install checks |
 | Security-doc drift items | ≥ 5 (§4.4) | 0 |
diff --git a/docs/security-reference.md b/docs/security-reference.md
index 04159e3..d7f602a 100644
--- a/docs/security-reference.md
+++ b/docs/security-reference.md
@@ -795,7 +795,8 @@ under `make test-fuzz-regression` and before randomized `make fuzz-smoke`.
 Checked-in corpora cover reader/heredoc input, JSON, URI, YAML, safe-FASL
 envelopes, authenticated actor frames, archive path validation, MCP/LSP
 Content-Length frames, and REPL reader input; known-bad regressions live under
-`tests/fuzz/regression/`.
+`tests/fuzz/regression/`. GitHub CI runs `make fuzz-smoke` on normal CI and
+`make fuzz-deep` on scheduled daily runs.
 
 ---
 
diff --git a/docs/status.md b/docs/status.md
index 086062d..11bd87b 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -28,6 +28,7 @@ release artifacts are built as Jerboa multicall binaries with `jerboa`,
 | FFI audit phase 5 | [ffi-audit.md](ffi-audit.md) records the scanner output, provisional Scheme binding verdicts, and native Rust export inventory. `make native-export-review-check` gates native export decisions. The worker-launch native path in `aproc.rs`/`seccomp.rs`, crypto FFI buffer path in `crypto.rs`, secure-memory region lifecycle in `secure_mem.rs`, secure filesystem capability boundary in `secure_fs.rs`, TLS native ABI in `tls.rs`, Ed25519/X25519 key-agreement buffers, compression buffers, HTTP parse/writev boundary, embed-crypto ABI, integrity ABI, regex-native ABI, process-control ABI, pcap ABI, inotify ABI, epoll/eventfd ABI, antidebug ABI, SOCKS5 server ABI, PostgreSQL native ABI, Landlock native ABI, wasmi sandbox ABI, SpiderMonkey WASM ABI, DuckDB native ABI, X.509 native ABI, and SQLite native ABI now have nearby `SAFETY:` comments or equivalent checked FFI invariants. Generated counts are at 0 unannotated native unsafe sites and 0 Scheme blocking bindings missing `__collect_safe`. | Finish per-binding Scheme FFI review and targeted scanner rules for the remaining provisional verdicts. |
 | Native Rust exports | The native export review now has 190 exported functions: 183 tracked Scheme references and 7 retained standalone C/binary helpers. The previous 35 no-Scheme-reference removal candidates no longer have C ABI export markers. | Re-run `make native-export-review-check` whenever adding or removing native exports. |
 | Confined worker | `(std security worker)` provides the facade, audit lifecycle, output caps, deadlines, process-group kill, memory rlimit pre-exec setup, Linux syscall/ptrace seccomp pre-exec setup, Linux Landlock filesystem/TCP-connect setup for requested axes, macOS Seatbelt no-write/no-network setup for supported axes, standard worker-eval Capsicum entry on FreeBSD, explicit sandbox-axis refusal, and egress proxy env wiring. | Keep Linux/macOS/FreeBSD parity tests current; finish Seatbelt path/exec confinement and arbitrary-command/proxy-aware Capsicum worker paths. |
+| Fuzzing | `tests/fuzz/corpus/` has 15 checked-in seed inputs, `tests/fuzz/regression/` has 11 crash/rejection regressions, `make fuzz-smoke` runs the deterministic regression gate first, and GitHub CI runs smoke fuzzing normally plus deep fuzzing on scheduled daily runs. | Keep adding minimized corpus and regression inputs for every parser/security bug found. |
 | Safe surface | Direct scripts default to the safe prelude; raw access requires `--unsafe-prelude` or `(jerboa prelude unsafe)`. | Continue moving risky APIs behind explicit unsafe imports as new modules land. |
 
 ## Compatibility Notes
diff --git a/docs/testing-and-infrastructure.md b/docs/testing-and-infrastructure.md
index 89fccec..d5ea8d7 100644
--- a/docs/testing-and-infrastructure.md
+++ b/docs/testing-and-infrastructure.md
@@ -29,7 +29,8 @@ Use `make test-fuzz-regression` for checked-in fuzz corpus regressions. Seed
 corpora live under `tests/fuzz/corpus/<parser>/`; known-bad crash or rejection
 inputs live under `tests/fuzz/regression/<parser>/`. The regression runner is
 also part of `make test`, and `make fuzz-smoke` runs it before randomized fuzz
-harnesses.
+harnesses. GitHub CI runs `make fuzz-smoke` on normal CI and `make fuzz-deep`
+on scheduled daily runs.
 
 ---