Skip to content

feat(hybrid-gate): let a repo with no Cargo manifest use the fleet gate - #57

Open
forkwright wants to merge 1 commit into
mainfrom
feat/hybrid-gate-non-rust
Open

feat(hybrid-gate): let a repo with no Cargo manifest use the fleet gate#57
forkwright wants to merge 1 commit into
mainfrom
feat/hybrid-gate-non-rust

Conversation

@forkwright

Copy link
Copy Markdown
Owner

Finding

dioptron and mneme are design-phase repos with no Cargo.toml anywhere. Their gate is a
bare Gate-Passed trailer check, and that trailer is emitted only by kanon gate --tier full,
which needs a build box the fleet does not currently declare. No PR in either repo can pass.
They are not strict; they are unsatisfiable.

Evidence — and a correction to a prior decision

An earlier attempt to point them here (dioptron#42, mneme#3) was closed unmerged with:

the trailer-only passthrough (stamped locally via the nobuild gate tier) remains the correct
gate class for no-code repos

That premise is false.kanon gate --help, verbatim:

nobuild runs only the stages that don't invoke the compiler (fmt + lint) — zero rustc
invocations, parallel-safe, never emits the trailer.

Only full "emits the Gate-Passed trailer on success". The nobuild tier cannot mint what those
gates require, so the passthrough was never satisfiable either. Those PRs also failed at
cargo metadata — which is the concrete thing this change fixes.

Desired correction

No new inputs. Every non-Rust behaviour comes from widening two mechanisms that already exist.
A caller-declared rust_project: false was rejected deliberately: it would be a second fact about
the repo, and it drifts from reality the moment a Cargo.toml lands.

  • The existing Cargo-manifest detection moves ahead of toolchain setup so its output can gate more
    than the build cache. Toolchain install, cargo-nextest install and the Rust cache now all skip
    when there is no manifest — the same condition the cache step already used.
  • fmt, clippy and nextest skip on an empty command, mirroring doctest_cmd's existing
    skip-on-empty exactly.

check stays unconditional on purpose. It is the one step a non-Rust caller must wire
something into, so a full-gate-build can never be configured to verify nothing.

Done when: dioptron and mneme can call this reusable and get a check that actually runs.

Non-regression — verified structurally, not asserted

PropertyResult
workflow_call input keys, defaults, types, required flagsbyte-identical
Job ids and job namesbyte-identical — no check-run context renamed, no branch protection stranded
full-gate-build step-name setunchanged; reordered only, zero added, zero removed

All 11 confirmed callers (gnomon, koinon, epistole, sphragis, heurema, harmonia, hamma, akroasis,
thumos, theatron, zetesis) have a root Cargo.toml and non-empty fmt_cmd/clippy_cmd/
nextest_cmd, so every new condition evaluates true for them and every gated step still always
runs.

WARNING for a docs-phase caller

docs_only_exemption defaults true and its patterns (**.md, docs/**, llms.txt) match
essentially all of such a repo's content — leaving it at the default would exempt nearly every PR
forever. A required check that samples rather than proves is worse than none, because it is
trusted. Such a caller must set it false and wire a real command into check_cmd. This is now
stated on the input itself.

What this deliberately does NOT do

It does not install the kanon binary. kanon ships no release asset and the repo is private, so
the only precedent (epistole's kanon-lint) needs two private checkouts, FLEET_REPO_TOKEN and a
~10-minute cargo install — and is non-required for exactly that cost. That does not belong on the
one required check. A repo wanting kanon-lint coverage adds a separate non-required job beside its
gate call, as epistole does.

Known gap, not papered over

mneme's .kanon-ci.toml is onlykanon lint . and kanon lint --writing README.md — both
need the kanon binary, so unlike dioptron (which has 3 kanon-free Python stages) mneme has nothing
to put in a required check_cmd today. That needs a kanon-free check authored before mneme adopts
this; it is not fixed here.

CI note

GitHub Actions is in a major outage (incident opened 2026-08-26T15:11:58Z, database failover in
progress). Checks on this PR may queue, startup_failure, or never be created. Nothing red here
before that incident closes is evidence about the change.

dioptron and mneme are design-phase repos with no Cargo.toml anywhere. Their
gate is a bare Gate-Passed trailer check, and the trailer is emitted only by
`kanon gate --tier full`, which needs a build box the fleet does not declare.
No PR in either repo can pass. They are not strict; they are unsatisfiable.
An earlier attempt to point them here (dioptron#42, mneme#3) was closed with
the reasoning that "the trailer-only passthrough (stamped locally via the
nobuild gate tier) remains the correct gate class for no-code repos". That
premise is false: `kanon gate --tier nobuild` runs only non-compiling stages
and its own help says it "never emits the trailer". The nobuild tier cannot
mint what those gates require, so the passthrough was never satisfiable
either. Those PRs also failed at `cargo metadata` -- which is the concrete
thing this change fixes.
No new inputs. Every non-Rust behaviour comes from widening two mechanisms
that already exist, because a caller-declared `rust_project: false` would be
a second fact about the repo that drifts from reality the moment a Cargo.toml
lands:
- The existing Cargo-manifest detection moves ahead of toolchain setup so its
output can gate more than the build cache. Toolchain install, cargo-nextest
install and the Rust cache now all skip when there is no manifest -- the
same condition the cache step already used.
- fmt, clippy and nextest skip on an empty command, mirroring doctest_cmd's
existing skip-on-empty exactly.
`check` stays unconditional on purpose. It is the one step a non-Rust caller
must wire something into, so a full-gate-build can never be configured to
verify nothing.
Non-regression, verified structurally rather than asserted: workflow_call
input keys, defaults, types and required flags are byte-identical; job ids and
job NAMES are byte-identical, so no check-run context is renamed and no
repo's branch protection is stranded; the full-gate-build step-name set is
unchanged and only reordered. All 11 confirmed callers have a root Cargo.toml
and non-empty fmt/clippy/nextest commands, so every new condition evaluates
true for them and every gated step still always runs.
WARNING for a docs-phase caller: docs_only_exemption defaults true and its
patterns match essentially all of such a repo's content, so leaving it at the
default would exempt nearly every PR forever. A required check that samples
rather than proves is worse than none, because it is trusted. Such a caller
must set it false and wire a real command into check_cmd.
This deliberately does NOT install the kanon binary. kanon ships no release
asset and the repo is private, so the only precedent (epistole's kanon-lint)
needs two private checkouts, FLEET_REPO_TOKEN and a ~10-minute cargo install,
and is non-required for exactly that cost. That cost does not belong on the
one required check; a repo wanting kanon-lint coverage adds a separate
non-required job beside its gate call.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@forkwright