Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 58 additions & 43 deletions .github/workflows/gate-attestation.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
# WHY(#262 / kanon#2522): replaces the trailer-only passthrough
# (forkwright/.github/.github/workflows/gate-attestation.yml@57d32f7 — pure
# trailer verify, no ai-attribution, no doc-only exemption, no build at all)
# with the fleet hybrid gate. akroasis has never had a compiling/testing CI
# workflow (#262) -- full-gate-build below is the first one: a
# trailer-stamped PR takes the fast path; a trailer-less human PR falls
# through to a real fmt/check/clippy/nextest build; a docs-only PR is exempt
# from that build; ai-attribution runs unconditionally via the reusable
# workflow's own centralized job.
#
# NOTE (#262 residual gap, tracked -- not closed by this change): the
# reusable workflow's check-trailer job waives dependabot[bot] PRs from
# full-gate-build unconditionally (fleet-wide behavior, not overridable
# per-caller), and this workflow triggers on pull_request only (no
# push-to-main compile check). #262's "Done when" (a PR that fails
# `cargo check --workspace` cannot auto-merge; main compiles in CI on every
# push) is therefore only partially met: dependabot bumps still bypass the
# build, and there is no push-triggered compile check. Left as an explicit
# comment on #262 rather than silently claimed done.
#
# fmt/check/clippy/nextest command strings mirror .kanon-ci.toml's stage
# commands verbatim (the local `kanon gate --stamp` SSOT) so a Gate-Passed
# trailer and a green full-gate-build attest the identical stages, per the
# reusable workflow's own contract. --jobs 8 / --build-jobs 8 --test-threads 8
# match .kanon-ci.toml's concurrency cap (OOM guard on the local gate box;
# harmless headroom on the hosted runner).
#
# system_packages: libusb-1.0-0-dev (rusb -> libusb1-sys) + libudev-dev
# (-> libudev-sys), the only native -sys crates in Cargo.lock that need a
# pkg-config-discoverable Linux system library on the hosted runner
# (core-foundation-sys/io-kit-sys are macOS-only; js-sys/windows-sys/
# linux-raw-sys are pure-Rust bindings needing no apt package). No
# alsa/cpal/libasound anywhere in the Cargo.toml tree -- akroasis (ἀκρόασις,
# "attentive reception") is RF/mesh/comms, not a DSP/audio-synthesis
# pipeline. protobuf-compiler is a build tool, not a -sys library:
# prost-build shells out to protoc at compile time.
#
# rust_toolchain input intentionally omitted (stays default ""): akroasis
# carries its own rust-toolchain.toml (channel "stable"), auto-detected by
# actions-rust-lang/setup-rust-toolchain inside the reusable workflow.
#
# needs_fleet_repo_token false: the sole git dependency (sphragis) is a
# public forkwright repo with no observed anonymous-fetch rate-limit
# flakiness -- matches the reusable workflow's own conservative default.
name: Gate Attestation

on:
Expand All @@ -7,47 +51,18 @@ on:
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
gate-attestation:
name: gate-attestation
runs-on: ubuntu-latest
steps:
- name: Pass trusted automation PRs
if: ${{ github.actor == 'dependabot[bot]' || github.actor == 'release-please[bot]' }}
run: echo "Gate attestation waived for trusted automation actor."

- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6
if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'release-please[bot]' }}
with:
fetch-depth: 0
persist-credentials: false

- name: Verify Gate-Passed trailer
if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'release-please[bot]' }}
run: |
commits=$(git log --format="%H" "origin/${{ github.base_ref }}..HEAD")
if [ -z "$commits" ]; then
echo "ERROR: No commits found in PR"
exit 1
fi

found=false
for sha in $commits; do
body=$(git log -1 --format="%b" "$sha")
if echo "$body" | grep -q "^Gate-Passed:"; then
version=$(echo "$body" | grep "^Gate-Passed:" | head -1)
echo "Found gate attestation: $version"
found=true
break
fi
done

if [ "$found" = false ]; then
echo "ERROR: No Gate-Passed trailer found in any PR commit."
echo "Run the local gate and commit with the trailer."
exit 1
fi
gate:
uses: forkwright/.github/.github/workflows/hybrid-gate.yml@main
with:
fmt_cmd: "cargo fmt --all -- --check"
check_cmd: "cargo check --workspace --all-targets --jobs 8"
clippy_cmd: "cargo clippy --workspace --all-targets --jobs 8 -- -D warnings"
nextest_cmd: "cargo nextest run --workspace --build-jobs 8 --test-threads 8"
doctest_cmd: ""
system_packages: "libusb-1.0-0-dev libudev-dev protobuf-compiler"
needs_fleet_repo_token: false
rust_cache_key: "gate-attestation"
ai_attribution_check: true
docs_only_exemption: true
secrets: inherit
4 changes: 2 additions & 2 deletions crates/koinon/src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ macro_rules! define_id {
/// Generate a new ID backed by a fresh ULID.
#[must_use]
pub fn new() -> Self {
Self(Ulid::new())
Self(Ulid::generate())
}

/// Reconstruct an ID from an existing [`Ulid`].
Expand Down Expand Up @@ -69,7 +69,7 @@ mod tests {

#[test]
fn entity_id_from_ulid_round_trips() {
let ulid = Ulid::new();
let ulid = Ulid::generate();
let id = EntityId::from_ulid(ulid);
assert_eq!(id.as_ulid(), ulid);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/koinon/src/tamper_log_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,8 +610,8 @@ fn large_metadata_no_truncation() {

#[test]
fn id_types_usable_in_entry_kinds() {
let sid = SignalId::from_ulid(Ulid::new());
let eid = EntityId::from_ulid(Ulid::new());
let sid = SignalId::from_ulid(Ulid::generate());
let eid = EntityId::from_ulid(Ulid::generate());
let _ = LogEntryKind::SignalObserved {
signal_id: sid,
kind_tag: CompactString::from("t"),
Expand Down
4 changes: 2 additions & 2 deletions crates/semaino/src/alert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ impl AlertPipeline {
let summary = build_summary(&aggregated.signal.kind, &severity, convergence);

let alert = Alert {
id: Ulid::new(),
id: Ulid::generate(),
severity,
source_signals: vec![aggregated.signal.signal_id],
timestamp: Timestamp::now(),
Expand Down Expand Up @@ -476,7 +476,7 @@ mod tests {
fn tracing_sink_emit_does_not_panic() {
let sink = TracingSink;
let alert = Alert {
id: Ulid::new(),
id: Ulid::generate(),
severity: AlertSeverity::High,
source_signals: vec![],
timestamp: Timestamp::now(),
Expand Down