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
54 changes: 54 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: CI

on:
push:
branches: [main]
pull_request:

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: "-Dwarnings"

permissions:
contents: read

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

jobs:
check-test:
name: Check & Test
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Format
run: cargo fmt -- --check
- name: Clippy
run: cargo clippy --locked --all-targets
- name: Test
run: |
git config --global user.email "ci@yolog.dev"
git config --global user.name "yoagent-state-ci"
cargo test --locked

# Enforce the DECLARED rust-version with a real compiler. Cargo never
# verifies rust-version against the code — 0.4.0/0.4.1 shipped a let-chain
# (needs 1.88) while declaring 1.85, breaking downstream MSRV builds
# (yologdev/yoagent#68). This job makes that class of lie impossible.
msrv:
name: MSRV (1.85)
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.85
- uses: Swatinem/rust-cache@v2
- name: Check
# --locked: uuid/getrandom sit at exactly rust-version 1.85 (zero
# headroom) — enforce the committed lock so a regeneration can't
# silently move the gate.
run: cargo check --locked --all-targets
19 changes: 9 additions & 10 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,17 @@ impl<S: EventStore> YoAgentState<S> {
let events = self.store.scan().await?;
let mut open: Option<(RunId, EventId)> = None;
for event in &events {
let run_id = event
.payload
.get("run_id")
.and_then(|v| v.as_str().map(RunId::from).or_else(|| {
serde_json::from_value::<RunId>(v.clone()).ok()
}));
let run_id = event.payload.get("run_id").and_then(|v| {
v.as_str()
.map(RunId::from)
.or_else(|| serde_json::from_value::<RunId>(v.clone()).ok())
});
match (event.kind.as_str(), run_id) {
("run.started", Some(id)) => open = Some((id, event.id.clone())),
("run.finished", Some(id)) => {
if open.as_ref().is_some_and(|(o, _)| *o == id) {
open = None;
}
// Guard fall-through hits the `_ => {}` arm — same no-op as
// the previous nested if.
("run.finished", Some(id)) if open.as_ref().is_some_and(|(o, _)| *o == id) => {
open = None;
}
_ => {}
}
Expand Down
11 changes: 9 additions & 2 deletions tests/failure_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,19 @@ async fn resume_open_run_recovers_the_marker_across_processes() {

// events in the resumed process chain + correlate to the original run
state2
.record_event(Event::new(actor(), "observation.created", json!({"id": "o1"})))
.record_event(Event::new(
actor(),
"observation.created",
json!({"id": "o1"}),
))
.await
.unwrap();
let events = state2.store().scan().await.unwrap();
let started = events.iter().find(|e| e.kind == "run.started").unwrap();
let obs = events.iter().find(|e| e.kind == "observation.created").unwrap();
let obs = events
.iter()
.find(|e| e.kind == "observation.created")
.unwrap();
assert_eq!(obs.causation_id.as_ref(), Some(&started.id));
assert_eq!(obs.correlation_id.as_deref(), Some("run_x"));

Expand Down
6 changes: 1 addition & 5 deletions tests/run_chaining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,7 @@ async fn events_inside_a_run_chain_to_run_started() {
.await
.unwrap();
let events = state.store().scan().await.unwrap();
let after = events
.iter()
.filter(|e| e.kind == "goal.created")
.last()
.unwrap();
let after = events.iter().rfind(|e| e.kind == "goal.created").unwrap();
assert_eq!(after.causation_id, None);
assert_eq!(after.correlation_id, None);
}
Expand Down
Loading