Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
79773b3
build: pin Rust 1.97.1
seonghobae Aug 19, 2026
10ea759
ci: run the exact Rust 1.97.1 baseline
seonghobae Aug 19, 2026
96514e7
ci: track the pinned Rust toolchain
seonghobae Aug 19, 2026
53fe12b
test: enforce the reproducible Rust baseline
seonghobae Aug 19, 2026
01fd656
build(deps): add Dependabot cooldown for supply-chain safety
devin-ai-integration[bot] Aug 21, 2026
a13c086
Merge remote-tracking branch 'origin/main' into fix/pr77-rebase
seonghobae Aug 22, 2026
b87e3ec
Merge branch 'main' into agent/rust-toolchain-refresh-2026-08-19
seonghobae Aug 26, 2026
17cca73
test(toolchain): allow consistent multi-job CI pins
seonghobae Aug 26, 2026
a9642b9
Merge branch 'main' into agent/rust-toolchain-refresh-2026-08-19
opencode-agent[bot] Aug 30, 2026
1d0b8a5
fix(ci): derive the Rust pin from rust-toolchain.toml
codex Aug 30, 2026
947394f
Merge branch 'main' into agent/rust-toolchain-refresh-2026-08-19
seonghobae Aug 31, 2026
d44df5e
fix(ci): consume pinned Rust toolchain everywhere
codex Aug 31, 2026
d30de04
test(toolchain): require exact pinned Rust version
codex Aug 31, 2026
7cb6973
Merge d30de04d717204373c643a1dd209cdcccc707391 into cc15cc2c34daf8c10…
seonghobae Sep 1, 2026
86d7c42
build(rust): advance pinned stable toolchain to 1.98.0
seonghobae Sep 3, 2026
2f96565
docs(rust): record the Rust 1.98.0 stable pin
seonghobae Sep 3, 2026
43d2c87
test(deploy): reject first-match target deployment validation
seonghobae Sep 3, 2026
17a2a1e
fix(deploy): reject duplicate target Deployment documents
seonghobae Sep 3, 2026
46fef54
test(deploy): retain hostile runtime regression after repair
seonghobae Sep 3, 2026
d386d6f
merge(main): preserve pinned Rust on protected workflow controls
seonghobae Sep 4, 2026
2856bab
merge(main): adopt protected anti-bot boundary on pinned Rust foundation
seonghobae Sep 6, 2026
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
9 changes: 9 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
version: 2
updates:
- package-ecosystem: rust-toolchain
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 1
Comment thread
seonghobae marked this conversation as resolved.
Comment thread
seonghobae marked this conversation as resolved.
- package-ecosystem: cargo
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
13 changes: 10 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@ jobs:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
- name: Read pinned Rust toolchain
id: pinned-toolchain
run: |
version=$(sed -n 's/^channel = "\(.*\)"$/\1/p' rust-toolchain.toml)
test -n "$version"
echo "version=$version" >> "$GITHUB_OUTPUT"
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # pinned
with:
toolchain: stable
toolchain: ${{ steps.pinned-toolchain.outputs.version }}
Comment thread
seonghobae marked this conversation as resolved.
components: llvm-tools-preview, rustfmt, clippy
- name: Check formatting
run: cargo fmt --check
- name: Test
run: cargo test --locked --workspace
- name: Clippy
run: cargo clippy --locked --workspace --all-targets -- -D warnings
run: cargo clippy --locked --workspace --all-targets -- -D warnings
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ cargo +nightly fuzz run fuzz_score_request -- -max_total_time=60

## Toolchain

`rust-toolchain.toml` pins the `stable` channel with `llvm-tools-preview` (needed by `cargo llvm-cov`), `rustfmt`, and `clippy`. Both workspace crates use `edition = "2024"`. Fuzzing is the one exception that needs nightly.
`rust-toolchain.toml` pins Rust `1.98.0` with `llvm-tools-preview` (needed by `cargo llvm-cov`), `rustfmt`, and `clippy`. CI reads the compiler version from that file so automated toolchain bumps update one source of truth. Both workspace crates use `edition = "2024"`. Fuzzing is the one exception that needs nightly.

This pin is a supply-chain control, not just a convenience. Lamb and Zacchiroli (2021) describe reproducible builds as the path that lets independent builders verify that source and released binaries match, and Malka et al. (2026) show that Docker alone does not guarantee reproducibility because build instructions and environment details still matter. Wardnet therefore keeps the reviewed compiler version in `rust-toolchain.toml`, has CI derive the toolchain from that file, and avoids a second drifting Rust version source in the container build. Sources: Lamb, C., & Zacchiroli, S. (2021). *Reproducible Builds: Increasing the Integrity of Software Supply Chains* [Preprint]. arXiv. https://arxiv.org/abs/2104.06020 ; Malka, J., Zacchiroli, S., & Zimmermann, T. (2026). *Docker Does Not Guarantee Reproducibility* [Preprint]. arXiv. https://arxiv.org/abs/2601.12811. Local PDFs: `docs/papers/reproducible-builds-software-supply-chains-arxiv-2104.06020.pdf`, `docs/papers/docker-does-not-guarantee-reproducibility-arxiv-2601.12811.pdf`.

## Workspace Layout

Expand Down
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
FROM rust:1.88-bookworm@sha256:af306cfa71d987911a781c37b59d7d67d934f49684058f96cf72079c3626bfe0 AS build
FROM rust:bookworm@sha256:af306cfa71d987911a781c37b59d7d67d934f49684058f96cf72079c3626bfe0 AS build

WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY rust-toolchain.toml ./
Comment thread
seonghobae marked this conversation as resolved.
COPY src ./src
COPY crates ./crates
RUN cargo build --locked --release
Expand Down
Binary file not shown.
Binary file not shown.
3 changes: 2 additions & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
# harness fails with "failed to find llvm-tools-preview" before it can measure
# the workspace. Declaring it here lets rustup install it automatically in any
# environment that runs cargo from this workspace (org coverage harness + CI).
channel = "stable"
channel = "1.98.0"
profile = "minimal"
components = ["llvm-tools-preview", "rustfmt", "clippy"]
176 changes: 108 additions & 68 deletions tests/deployment_manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,80 +208,82 @@ fn named_list_item_block<'a>(
.collect()
}

/// Locate `ADMIN_TOKEN` on the `waf-ids-ai-soc` gateway container only.
/// Locate `ADMIN_TOKEN` on the one canonical `waf-ids-ai-soc` Deployment.
///
/// Duplicate entries, literal fallback values, and `secretKeyRef.optional: true`
/// are treated as absent (fail closed).
/// Duplicate target Deployments, duplicate token entries, literal fallback values,
/// and `secretKeyRef.optional: true` are treated as absent (fail closed).
fn external_admin_secret_ref(manifest: &str) -> Option<ExternalAdminSecretRef<'_>> {
manifest.split("\n---\n").find_map(|document| {
let mut target_documents = manifest.split("\n---\n").filter(|document| {
let lines = document.lines().collect::<Vec<_>>();
if !lines.iter().any(|line| line.trim() == "kind: Deployment") {
return None;
}

if mapping_value(&lines, "metadata:", 0, "name:") != Some("waf-ids-ai-soc") {
return None;
}
lines.iter().any(|line| line.trim() == "kind: Deployment")
&& mapping_value(&lines, "metadata:", 0, "name:") == Some("waf-ids-ai-soc")
&& mapping_value(&lines, "metadata:", 0, "namespace:") == Some("waf-ids-ai-soc")
});

let document = target_documents.next()?;
if target_documents.next().is_some() {
return None;
}

let namespace = mapping_value(&lines, "metadata:", 0, "namespace:")?;
let workload_spec = nested_block(&lines, "spec:", 0);
let pod_template = nested_block(&workload_spec, "template:", 2);
let pod_spec = nested_block(&pod_template, "spec:", 4);
let containers = nested_block(&pod_spec, "containers:", 6);
let gateway = named_list_item_block(&containers, "gateway", 8);
let env = nested_block(&gateway, "env:", 10);
let admin_token_entries = env
.iter()
.filter(|line| yaml_named_entry_matches(line, 12, "ADMIN_TOKEN"))
.count();
if admin_token_entries != 1 {
return None;
}
let lines = document.lines().collect::<Vec<_>>();
let namespace = mapping_value(&lines, "metadata:", 0, "namespace:")?;
let workload_spec = nested_block(&lines, "spec:", 0);
let pod_template = nested_block(&workload_spec, "template:", 2);
let pod_spec = nested_block(&pod_template, "spec:", 4);
let containers = nested_block(&pod_spec, "containers:", 6);
let gateway = named_list_item_block(&containers, "gateway", 8);
let env = nested_block(&gateway, "env:", 10);
let admin_token_entries = env
.iter()
.filter(|line| yaml_named_entry_matches(line, 12, "ADMIN_TOKEN"))
.count();
if admin_token_entries != 1 {
return None;
}

let env_block = named_list_item_block(&env, "ADMIN_TOKEN", 12);
if env_block
.iter()
.any(|line| line.trim().starts_with("value:"))
{
return None;
}
let secret_ref_index = env_block
.iter()
.position(|line| line.trim() == "secretKeyRef:")?;
let secret_ref_indent = leading_spaces(env_block[secret_ref_index]);
let secret_ref_block = env_block[secret_ref_index + 1..]
.iter()
.take_while(|line| line.trim().is_empty() || leading_spaces(line) > secret_ref_indent)
.copied()
.collect::<Vec<_>>();

let secret_name = secret_ref_block.iter().find_map(|line| {
line.trim()
.strip_prefix("name:")
.map(str::trim)
.filter(|value| !value.is_empty())
})?;
let secret_key = secret_ref_block.iter().find_map(|line| {
line.trim()
.strip_prefix("key:")
.map(str::trim)
.filter(|value| !value.is_empty())
})?;
match secret_ref_block.iter().find_map(|line| {
line.trim()
.strip_prefix("optional:")
.map(str::trim)
.filter(|value| !value.is_empty())
}) {
None | Some("false") => {}
Some(_) => return None,
}
let env_block = named_list_item_block(&env, "ADMIN_TOKEN", 12);
if env_block
.iter()
.any(|line| line.trim().starts_with("value:"))
{
return None;
}
let secret_ref_index = env_block
.iter()
.position(|line| line.trim() == "secretKeyRef:")?;
let secret_ref_indent = leading_spaces(env_block[secret_ref_index]);
let secret_ref_block = env_block[secret_ref_index + 1..]
.iter()
.take_while(|line| line.trim().is_empty() || leading_spaces(line) > secret_ref_indent)
.copied()
.collect::<Vec<_>>();

let secret_name = secret_ref_block.iter().find_map(|line| {
line.trim()
.strip_prefix("name:")
.map(str::trim)
.filter(|value| !value.is_empty())
})?;
let secret_key = secret_ref_block.iter().find_map(|line| {
line.trim()
.strip_prefix("key:")
.map(str::trim)
.filter(|value| !value.is_empty())
})?;
match secret_ref_block.iter().find_map(|line| {
line.trim()
.strip_prefix("optional:")
.map(str::trim)
.filter(|value| !value.is_empty())
}) {
None | Some("false") => {}
Some(_) => return None,
}

Some(ExternalAdminSecretRef {
namespace,
secret_name,
secret_key,
})
Some(ExternalAdminSecretRef {
namespace,
secret_name,
secret_key,
})
}

Expand Down Expand Up @@ -388,6 +390,44 @@ spec:
);
}

#[test]
fn duplicate_target_deployments_fail_closed_even_when_first_is_valid() {
let duplicate_target_manifest = r#"apiVersion: apps/v1
kind: Deployment
metadata:
name: waf-ids-ai-soc
namespace: waf-ids-ai-soc
spec:
template:
spec:
containers:
- name: gateway
env:
- name: ADMIN_TOKEN
valueFrom:
secretKeyRef:
name: waf-ids-ai-soc-admin
key: ADMIN_TOKEN
optional: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: waf-ids-ai-soc
namespace: waf-ids-ai-soc
spec:
template:
spec:
containers:
- name: gateway
env:
- name: ADMIN_TOKEN
value: repository-visible-fallback
"#;

assert_eq!(external_admin_secret_ref(duplicate_target_manifest), None);
}

#[test]
fn init_container_cannot_satisfy_the_gateway_secret_contract() {
let init_container_decoy = r#"apiVersion: apps/v1
Expand Down
67 changes: 67 additions & 0 deletions tests/rust_toolchain_contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! Repository contracts for the reviewed Rust compiler baseline.

const RUST_TOOLCHAIN: &str = include_str!("../rust-toolchain.toml");
const CI_WORKFLOW: &str = include_str!("../.github/workflows/ci.yml");
const DEPENDABOT: &str = include_str!("../.github/dependabot.yml");
const DOCKERFILE: &str = include_str!("../Dockerfile");

fn pinned_channel() -> String {
RUST_TOOLCHAIN
.lines()
.map(str::trim)
.find_map(|line| line.strip_prefix("channel = \""))
.and_then(|line| line.strip_suffix('"'))
.expect("rust-toolchain.toml must declare a channel")
.to_string()
}

#[test]
fn pinned_toolchain_is_consistent_in_local_and_ci_contracts() {
let pinned_channel = pinned_channel();
let parts: Vec<_> = pinned_channel.split('.').collect();
assert!(
parts.len() == 3
&& parts
.iter()
.all(|part| { !part.is_empty() && part.chars().all(|ch| ch.is_ascii_digit()) }),
"toolchain channel must be an exact numeric version"
);
assert_ne!(pinned_channel, "stable");
assert_ne!(pinned_channel, "nightly");
assert!(CI_WORKFLOW.contains("id: pinned-toolchain"));
assert!(CI_WORKFLOW.contains("sed -n 's/^channel = "));
assert!(CI_WORKFLOW.contains("toolchain: ${{ steps.pinned-toolchain.outputs.version }}"));
assert!(CI_WORKFLOW.contains("components: llvm-tools-preview, rustfmt, clippy"));
assert!(DOCKERFILE.contains("COPY rust-toolchain.toml ./"));
assert!(DOCKERFILE.contains("RUN cargo build --locked --release"));
assert!(!DOCKERFILE.contains("FROM rust:1."));
assert!(
DOCKERFILE.contains("FROM rust:bookworm@sha256:"),
"container build must consume rust-toolchain.toml instead of pinning a separate Rust version"
);
assert!(
DEPENDABOT.contains("- package-ecosystem: rust-toolchain"),
"toolchain bumps must remain automated from rust-toolchain.toml"
);
}

#[test]
fn stable_toolchain_updates_are_reviewable() {
let mut in_rust_toolchain_block = false;
let mut saw_weekly = false;

for line in DEPENDABOT.lines().map(str::trim) {
if line.starts_with("- package-ecosystem: ") {
in_rust_toolchain_block = line == "- package-ecosystem: rust-toolchain";
continue;
}
if in_rust_toolchain_block && line == "interval: weekly" {
saw_weekly = true;
}
}

assert!(
saw_weekly,
"rust-toolchain updater must stay on a weekly cadence"
);
}
Loading