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
6 changes: 6 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ jobs:
- name: Run tests
run: bazel test //... --profile="$RUNNER_TEMP/bazel-test-profile.json"

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Rust decision cores
run: env CC=cc RUSTFLAGS='-C linker=/usr/bin/cc' cargo test -p decision_cores

- name: Build
run: bazel build //cmd/... --profile="$RUNNER_TEMP/bazel-build-profile.json"

Expand Down
1 change: 1 addition & 0 deletions crates/decision_cores/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ exports_files([
"src/lib.rs",
"src/gates.rs",
"tests/log_groups_dual.rs",
"tests/gates_dual.rs",
"Cargo.toml",
])
45 changes: 45 additions & 0 deletions crates/decision_cores/tests/gates_dual.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! Dual tables: thin `gates::*` wrappers ↔ generated decision modules.
//! Mirrors Go production gate tables (rate-limit, sync-bounds, tui-reload, …).

use decision_cores::gates;

#[test]
fn rate_limit_wait_needed_table() {
assert!(!gates::rate_limit_wait_needed(1, true, true));
assert!(!gates::rate_limit_wait_needed(0, false, true));
assert!(!gates::rate_limit_wait_needed(0, true, false));
assert!(gates::rate_limit_wait_needed(0, true, true));
}

#[test]
fn accept_jobs_attempt_table() {
assert!(gates::accept_jobs_attempt(2, 0)); // unknown attempt
assert!(gates::accept_jobs_attempt(2, 2));
assert!(!gates::accept_jobs_attempt(2, 1)); // stale
assert!(!gates::accept_jobs_attempt(3, 2));
}

#[test]
fn log_fetch_result_fresh_table() {
assert!(gates::log_fetch_result_fresh(1, 1, 0, 0));
assert!(!gates::log_fetch_result_fresh(0, 1, 0, 0)); // zero job
assert!(!gates::log_fetch_result_fresh(1, 2, 0, 0)); // wrong job
assert!(!gates::log_fetch_result_fresh(1, 1, 0, 1)); // stale gen
}

#[test]
fn drop_api_for_runner_twin_table() {
assert!(gates::drop_api_for_runner_twin(1, 1, false)); // drop API
assert!(!gates::drop_api_for_runner_twin(1, 1, true)); // keep runner
assert!(!gates::drop_api_for_runner_twin(1, 0, false));
assert!(!gates::drop_api_for_runner_twin(2, 1, false));
}

#[test]
fn clamp_span_to_parent_contains() {
// child end past parent → clamp end into parent
let (s, e) = gates::clamp_span_to_parent(2, 4, 1, 3);
assert!(s < e);
assert!(s >= 1);
assert!(e <= 3);
}
20 changes: 17 additions & 3 deletions scripts/decision-check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
#
# Fast path after gate/symbol edits:
# 1. Production wire symbols still exist
# 2. Bazel tests tagged decision (*spec duals + codegen up_to_date)
# 3. Optional: TLC for named cores (full + decision for that core)
# 2. Bazel tests tagged decision (*spec duals + Go/Rust up_to_date)
# 3. Rust decision_cores duals when cargo is on PATH
# 4. Optional: TLC for named cores (full + decision for that core)
#
# Full design TLC for everything: scripts/check-specs.sh
#
# Usage:
# scripts/decision-check.sh # wires + bazel decision tags
# scripts/decision-check.sh # wires + bazel decision tags + cargo
# scripts/decision-check.sh --with-tlc # also TLC every core with decision/
# scripts/decision-check.sh <core> ... # TLC only those cores (implies TLC)

Expand Down Expand Up @@ -48,6 +49,19 @@ if ! bazel test //... --test_tag_filters=decision --test_output=errors; then
fail=1
fi

echo
echo "=== cargo test -p decision_cores ==="
if command -v cargo >/dev/null 2>&1; then
# Force system linker: hermetic_cc/zig from Bazel env breaks rustc link.
# Always override RUSTFLAGS (do not inherit zig flags from the shell).
if ! env CC=cc RUSTFLAGS='-C linker=/usr/bin/cc' \
cargo test -p decision_cores --quiet; then
fail=1
fi
else
echo "skip: cargo not on PATH"
fi

if [ "$WITH_TLC" -eq 1 ]; then
echo
echo "=== TLC (decision cores) ==="
Expand Down
6 changes: 4 additions & 2 deletions specs/GATES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
**Race redesign:** full TLC in `specs/<core>/*.tla`.
**Regen:** `bazel run //tools/decision:update`
**Lean check:** `scripts/decision-check.sh`
(`--with-tlc` or `<core>` for TLC; full suite: `scripts/check-specs.sh`)
(wires + decision tags + `cargo test -p decision_cores` when cargo present)
**Full TLC:** `scripts/check-specs.sh` (`--with-tlc` / core names on decision-check)
**Cites:** production / decision / pure **symbols** only — never `file.go:line`
(lines rot; GATES + duals are the map).
(lines rot; GATES + duals are the map).
**Rust peer:** `crates/decision_cores` (same Decision.tla; `gates::*` wrappers).

| Core | GATES | Production package | Prod→gen SSOT |
|------|-------|--------------------|---------------|
Expand Down
Loading