ci: gate guest crates with fmt, clippy and rustdoc (#276) #287

Merged
buildagent merged 1 commit from fix-276-guest-crate-ci-gates into master 2026-09-20 19:05:29 +02:00
Member

Closes #276.

cargo fmt --all, cargo clippy --workspace --all-targets and cargo doc --workspace are ci.yml's entire format/lint/doc gate, and all three are workspace-scoped. The four crates under crates/guest/*/ declare their own [workspace] table, so none of those commands reads one file under any of them — and three of the four are the SOURCE of the extractor.wasm inside de.h-dv.ruby, de.h-dv.timeline and de.h-dv.svelte: signed with the first-party key, pinned by digest, and executed inside the sandbox on an operator's own files.

What this adds

  • .forgejo/scripts/guest_gates.sh — discovers the guest crates and runs the three commands over each. --list prints the discovered set and nothing else, so the test executes the same discovery CI runs (require_free_disk.sh's "one implementation, two doors").
  • a guest-gates job in ci.yml that installs the wasm target, carries the #161 disk pre-flight, and invokes the script.
  • crates/indexer/tests/ci_guest_gates.rs — 6 tests proving the discovered population is the real one. Both sides derive independently and are compared BY NAME, so a fifth guest is graded on the day it is added.

The population is NOT derived from exclude, and that is measured

#276's table says all four guests appear in the root Cargo.toml's exclude list, and offers deriving from it as the first option. Only example and ruby are there. timeline and svelte are outside the workspace purely by virtue of their own [workspace] table.

Run as a mutation, the exclude-derived form grades two of the four crates and silently drops the newest guest — the one a new gate exists to catch. Discovery therefore keys on the [workspace] table itself, and guest_gates_population_is_not_derivable_from_the_exclude_list pins the difference.

Two real defects, found by the doc gate on its first run

#276 states all three commands are clean today. True of fmt and clippy on all four; rustdoc was RED on two, both classes CLAUDE.md governs, both demoted to citations rather than #[allow]ed:

  • crates/guest/ruby/src/lib.rs — [`extract`] is ambiguous, naming both mod extract and pub extern "C" fn extract.
  • crates/guest/timeline/src/lib.rs — [`OUT_LEN`] is a private item linked from the public docs of SRC_OFFSET, resolving only under --document-private-items.

No --all-targets for clippy, and that is measured too

These crates are no_std with their own #[panic_handler]. The lib-test target links std's and fails with error[E0152]: found duplicate lang item panic_impl before any lint runs. All four fail with it; all four are clean without it. The lib is the shipped artifact, so the lib is what this grades.

Mutations

All 8 documented mutations were run, each RED on exactly the named test, every restore md5-verified. Mutation 1 is recorded as grading the script's own floor rather than the set comparison — which is why mutation 2 exists: a mutation caught by a different gate proves nothing about the test under it.

Verification

Local: fmt, clippy, cargo test --workspace (3970 passed / 0 failed / 368 suites), daemon E2E leg (826/0), precision_gate 7/7 phantoms=0, corpus_ratchet (7 repos, 14 controls, baseline.json unmoved), workspace rustdoc.

CI: run #5372 on 7a5fd70 — success, 14/14 jobs, 1h33m02s. The new job took ~2.5 min and did not extend the lane.

The runner log confirms the job is not vacuous — it graded all four crates, each getting clippy (Finished release) and rustdoc (Documenting … → Generated …/target/doc/<crate>/index.html):

guest crates graded by this run:
  crates/guest/example
  crates/guest/ruby
  crates/guest/svelte
  crates/guest/timeline

🤖 Generated with Claude Code

https://claude.ai/code/session_0126PDDLB4wNHxKXvWM1VNmu

Closes #276. `cargo fmt --all`, `cargo clippy --workspace --all-targets` and `cargo doc --workspace` are `ci.yml`'s entire format/lint/doc gate, and all three are workspace-scoped. The four crates under `crates/guest/*/` declare their own `[workspace]` table, so none of those commands reads one file under any of them — and three of the four are the SOURCE of the `extractor.wasm` inside `de.h-dv.ruby`, `de.h-dv.timeline` and `de.h-dv.svelte`: signed with the first-party key, pinned by digest, and executed inside the sandbox on an operator's own files. ## What this adds - `.forgejo/scripts/guest_gates.sh` — discovers the guest crates and runs the three commands over each. `--list` prints the discovered set and nothing else, so the test executes the *same* discovery CI runs (`require_free_disk.sh`'s "one implementation, two doors"). - a `guest-gates` job in `ci.yml` that installs the wasm target, carries the #161 disk pre-flight, and invokes the script. - `crates/indexer/tests/ci_guest_gates.rs` — 6 tests proving the discovered population is the real one. Both sides derive independently and are compared BY NAME, so a fifth guest is graded on the day it is added. ## The population is NOT derived from `exclude`, and that is measured #276's table says all four guests appear in the root `Cargo.toml`'s `exclude` list, and offers deriving from it as the first option. **Only `example` and `ruby` are there.** `timeline` and `svelte` are outside the workspace purely by virtue of their own `[workspace]` table. Run as a mutation, the `exclude`-derived form grades **two of the four** crates and silently drops the newest guest — the one a new gate exists to catch. Discovery therefore keys on the `[workspace]` table itself, and `guest_gates_population_is_not_derivable_from_the_exclude_list` pins the difference. ## Two real defects, found by the doc gate on its first run #276 states all three commands are clean today. True of fmt and clippy on all four; rustdoc was **RED on two**, both classes `CLAUDE.md` governs, both demoted to citations rather than `#[allow]`ed: - `crates/guest/ruby/src/lib.rs` — ``[`extract`]`` is ambiguous, naming both `mod extract` and `pub extern "C" fn extract`. - `crates/guest/timeline/src/lib.rs` — ``[`OUT_LEN`]`` is a private item linked from the public docs of `SRC_OFFSET`, resolving only under `--document-private-items`. ## No `--all-targets` for clippy, and that is measured too These crates are `no_std` with their own `#[panic_handler]`. The lib-test target links std's and fails with `error[E0152]: found duplicate lang item panic_impl` before any lint runs. All four fail with it; all four are clean without it. The lib is the shipped artifact, so the lib is what this grades. ## Mutations All 8 documented mutations were run, each RED on exactly the named test, every restore md5-verified. Mutation 1 is recorded as grading the script's own floor rather than the set comparison — which is why mutation 2 exists: a mutation caught by a different gate proves nothing about the test under it. ## Verification Local: fmt, clippy, `cargo test --workspace` (3970 passed / 0 failed / 368 suites), daemon E2E leg (826/0), `precision_gate` 7/7 phantoms=0, `corpus_ratchet` (7 repos, 14 controls, `baseline.json` unmoved), workspace rustdoc. CI: run [#5372](https://git.h-dv.de/h-dv/code-index/actions/runs/851) on `7a5fd70` — **success, 14/14 jobs, 1h33m02s**. The new job took ~2.5 min and did not extend the lane. The runner log confirms the job is not vacuous — it graded all four crates, each getting clippy (`Finished release`) and rustdoc (`Documenting …` → `Generated …/target/doc/<crate>/index.html`): ``` guest crates graded by this run: crates/guest/example crates/guest/ruby crates/guest/svelte crates/guest/timeline ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0126PDDLB4wNHxKXvWM1VNmu
ci: gate guest crates with fmt, clippy and rustdoc (#276)
All checks were successful
CI / cargo fmt (pull_request) Successful in 49s
CI / OSS corpus tier-3 scale (nightly) (pull_request) Has been skipped
CI / Grammar rebuild from source (nightly) (pull_request) Has been skipped
CI / guest crates (fmt, clippy, doc) (pull_request) Successful in 1m3s
CI / cargo doc (intra-doc links) (pull_request) Successful in 10m21s
CI / cargo deny (pull_request) Successful in 11m11s
CI / cargo check (MSRV 1.98) (pull_request) Successful in 11m24s
CI / cargo test (abi, 32-bit + wasm32) (pull_request) Successful in 11m37s
CI / cargo clippy (pull_request) Successful in 12m31s
CI / cargo check (windows-gnu) (pull_request) Successful in 13m7s
CI / OSS corpus (tier 1) (pull_request) Successful in 39m49s
CI / cargo test (pull_request) Successful in 34m32s
CI / cargo test (daemon transport) (pull_request) Successful in 9m45s
CI / Plugin path cost + pool throughput (nightly) (pull_request) Has been skipped
CI (Windows) / fmt + clippy + build + test (windows) (pull_request) Successful in 58m5s
7a5fd70303
`cargo fmt --all`, `cargo clippy --workspace --all-targets` and
`cargo doc --workspace` are ci.yml's entire format/lint/doc gate, and
all three are workspace-scoped. The four crates under `crates/guest/*/`
declare their own `[workspace]` table, so none of those commands reads
one file under any of them — and three of the four are the SOURCE of
the `extractor.wasm` inside `de.h-dv.ruby`, `de.h-dv.timeline` and
`de.h-dv.svelte`: signed with the first-party key, pinned by digest,
and executed inside the sandbox on an operator's own files.

Adds `.forgejo/scripts/guest_gates.sh` (discovers the guests, runs the
three commands over each), a `guest-gates` job that invokes it, and
`crates/indexer/tests/ci_guest_gates.rs` to prove the discovered
population is the real one.

THE POPULATION IS NOT DERIVED FROM `exclude`, AND THAT IS MEASURED.

The issue's table says all four guests appear in the root Cargo.toml's
`exclude` list, and offers deriving from it as the first option. Only
`example` and `ruby` are there; `timeline` and `svelte` are outside the
workspace purely by their own `[workspace]` table. Running that form as
a mutation grades TWO of the four crates and silently drops the newest
guest, which is the one a new gate exists to catch. Discovery therefore
keys on the `[workspace]` table itself, and a test pins the difference.

TWO REAL DEFECTS, FOUND BY THE DOC GATE ON ITS FIRST RUN.

The issue states all three commands are clean today. True of fmt and
clippy on all four; rustdoc was RED on two, both classes CLAUDE.md
governs, both demoted to citations rather than allowed:

  * guest/ruby     [`extract`] is ambiguous (mod and extern fn)
  * guest/timeline [`OUT_LEN`] is a private item linked from the
                   public docs of `SRC_OFFSET`

NO `--all-targets` FOR CLIPPY, AND THAT IS MEASURED TOO. These crates
are no_std with their own `#[panic_handler]`; the lib-test target links
std's and fails with `error[E0152]: found duplicate lang item
panic_impl` before any lint runs. All four fail with it and all four
are clean without it. The lib is the shipped artifact, so the lib is
what this grades.

MUTATIONS (ALL RUN, each RED on exactly the named test, every restore
md5-verified) are listed in the test's header. Mutation 1 is recorded
as grading the script's own floor rather than the set comparison, which
is why mutation 2 exists: a mutation caught by a different gate proves
nothing about the test under it.

Gates: fmt, clippy, cargo test --workspace (3970 passed, 0 failed, 368
suites), daemon E2E leg (826/0), precision_gate 7/7 phantoms=0,
corpus_ratchet (7 repos, 14 controls, baseline.json unmoved), workspace
rustdoc, and guest_gates.sh green over all four crates.

NOT VERIFIED HERE: that the job runs on a runner. These are
source-shape assertions plus an execution of the discovery; a CI job is
verified by dispatching it and by nothing else.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126PDDLB4wNHxKXvWM1VNmu
buildagent deleted branch fix-276-guest-crate-ci-gates 2026-09-20 19:05:30 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
h-dv/code-index!287
No description provided.