Extract the event model into its own crate, shared with client-core

RUST.md's recommendation item 1 starts here: Event, QuestionOption,
SessionStatus, ImageRef, AttachmentRef, SeqEvent, context_tokens and
context_after move to a new event-model crate so a future Rust client
shares one definition with server/ instead of Events.kt's hand-kept
mirror. session/driver.rs and session/transcript.rs re-export
everything they used to define, so nothing downstream of either
module changed.

cargo test (127 passed), clippy --all-targets and fmt clean in both
server/ and event-model/.

Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
This commit is contained in:
irisandClaude Sonnet committed 2026-09-04 22:40:15 -04:00
1 parent 1fcaa2d72d
commit bc3db183e3
140 files changed
+863 -365

No files matched your search

+107
View File
@@ -0,0 +1,107 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "event-model"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "memchr"
version = "2.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
[[package]]
name = "proc-macro2"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "3.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "zmij"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
+20
View File
@@ -0,0 +1,20 @@
[package]
name = "event-model"
version = "0.1.0"
edition = "2024"
# The common event model, extracted from `server/session/driver.rs` and
# `session/transcript.rs` so a Rust client (`client-core`) can share one
# definition with the server instead of hand-mirroring it the way
# `app/.../Events.kt` used to. Nothing here talks to a process, a file, or a
# socket -- it is exactly the wire shape in PLAN.md's "common event model",
# plus the transcript envelope and the context-token rule three different
# readers (the pump, the transcript, and a phone folding the same events)
# have to agree on.
[dependencies]
serde = { version = "1", features = ["derive"] }
# `Event::ToolStart.input` is a tool's raw call arguments, whatever shape the
# dialect gave them -- typing it further would mean this crate knowing every
# driver's tool schema.
serde_json = { version = "1", features = ["float_roundtrip"] }
+377
View File
@@ -0,0 +1,377 @@
//! The common event model: what a driver's process turns into before it
//! touches the transcript or the phone (see `PLAN.md`'s "The common event
//! model"). Extracted from `server/src/session/driver.rs` and
//! `session/transcript.rs` on 2026-09-04 so `client-core` shares this
//! definition instead of hand-mirroring it, which is what
//! `app/.../Events.kt` used to do. `server/`'s `session::driver` module
//! re-exports everything here, so nothing downstream of it had to change.
//!
//! What stayed behind in `server/`: the `Driver` trait, `SessionCommand`,
//! `Unqueued` and `EventSink`. Those are how *this* server runs a session,
//! not part of what a client reads off the wire.
use serde::{Deserialize, Serialize};
/// The name a session's image is stored and served under -- minted for an
/// upload or for one a tool produced, and fetched back from
/// `/sessions/{id}/files/{ref}`. One id both directions, so the transcript
/// renders them identically.
pub type ImageRef = String;
/// The name an upload is stored and served under: an image is
/// `<hex>.<extension>` and is an [`ImageRef`] like any other; any other file
/// keeps its own name after the hex, `<hex>-<name>`, because the name is what
/// the reader attached and what the session is told. Told apart by
/// `crate::media::media_type_for`.
pub type AttachmentRef = String;
/// One choice offered in answer to a [`Event::Question`]. More than a label
/// because the reader is deciding rather than confirming: what an option
/// means, and what picking it would produce, are what decide it.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct QuestionOption {
pub label: String,
/// A sentence about what this option means.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
/// A block to show as written -- a mockup, a diff, a config file.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub preview: Option<String>,
}
impl QuestionOption {
pub fn plain(label: impl Into<String>) -> Self {
Self {
label: label.into(),
description: None,
preview: None,
}
}
}
/// Everything a session can tell the outside world. Every event is appended
/// to the transcript with a sequence number, then fanned out to SSE
/// subscribers, so reconnecting is just "events after seq N" -- no separate
/// history path to drift from the live one.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
// `rename_all` renames the variants; `rename_all_fields` renames what is
// inside them. Both are needed and only the first is obvious: every field
// here was one lowercase word until `pre_tokens` arrived, so a multi-word
// field went out as snake_case, the app looked for camelCase and found
// nothing, and the event still rendered -- as the "no counts reported" case,
// which is a state it is allowed to be in.
#[serde(
tag = "type",
rename_all = "camelCase",
rename_all_fields = "camelCase"
)]
pub enum Event {
/// What the user sent, written into the transcript by the manager (not by
/// drivers) so every device renders the conversation from one stream.
/// Recorded when the session reads it, which is what `MessageTaken` reports.
UserMessage {
/// The [`Event::MessageQueued`] this resolves, when it waited. The
/// phone has a bubble on screen for the waiting message and needs to
/// know *which* one this is, rather than matching on the text and
/// clearing the wrong one when the same thing was sent twice.
#[serde(default, skip_serializing_if = "Option::is_none")]
id: Option<String>,
text: String,
/// What was attached, by the ref the files route serves. On the
/// message rather than beside it: these used to be their own `Image`
/// events just before, which left the phone deciding from adjacency
/// which message an image belonged to. `images` on disk until
/// 2026-09-03, when files joined them; the alias reads the older rows.
#[serde(default, alias = "images", skip_serializing_if = "Vec::is_empty")]
attachments: Vec<AttachmentRef>,
},
/// A message accepted from the phone that the session cannot read yet.
///
/// Recorded, unlike the message itself, and that difference is the point:
/// the message belongs in the transcript where the session read it, but
/// something has to say it is waiting, and it has to be the server. The
/// phone used to remember its own outgoing messages, so leaving the
/// screen showed nothing pending when something was.
///
/// Carries no row of its own; resolved by the `UserMessage` bearing the
/// same id, as `CommandQueued` is resolved by `CommandSent`.
MessageQueued {
id: String,
text: String,
/// Carried for the same reason [`Event::UserMessage`] carries it,
/// and it matters more here: a waiting message is on screen for as
/// long as the turn runs, so its attachment has nowhere else to be.
#[serde(default, alias = "images", skip_serializing_if = "Vec::is_empty")]
attachments: Vec<AttachmentRef>,
},
/// A message taken out of the queue before the session read it.
///
/// Recorded for the same reason `MessageQueued` is: the queue is the
/// server's, so what is waiting has to be answerable from the transcript
/// alone. Without it a phone that reconnects replays the `MessageQueued`
/// and puts back a bubble nothing will ever resolve -- the `UserMessage`
/// that normally does is exactly what is not coming.
///
/// Only ever sent for a message that had not been handed over; see
/// [`Unqueued::AlreadySent`].
MessageDropped {
id: String,
},
/// A driver has taken one of the user's messages and started reading it.
/// The manager turns this into the `UserMessage` above, so it never
/// reaches a phone itself.
///
/// It exists because sending and being read are not the same moment. A
/// message sent into a running turn waits, and recording it among things
/// already read puts it in the transcript above output that predates it.
MessageTaken {
/// The `MessageQueued` this answers, or `None` when it never waited.
/// Carried through onto the `UserMessage`.
id: Option<String>,
text: String,
#[serde(default, alias = "images", skip_serializing_if = "Vec::is_empty")]
attachments: Vec<AttachmentRef>,
},
/// Streaming assistant text; the phone renders the concatenation as
/// markdown.
AssistantText {
delta: String,
},
ToolStart {
id: String,
tool: String,
input: serde_json::Value,
},
ToolUpdate {
id: String,
output: String,
},
ToolEnd {
id: String,
output: String,
},
/// An image the session produced or was sent, saved under the session
/// dir and referenced by id; the phone fetches it by URL.
Image {
#[serde(rename = "ref")]
image: ImageRef,
/// The tool call whose result carried it, when one did. A screenshot
/// belongs under the call that took it, not floating beside it -- the
/// reader has to pair them by position otherwise, and position is
/// exactly what a page boundary breaks.
#[serde(default, skip_serializing_if = "Option::is_none")]
about: Option<String>,
},
/// Anything the session needs a human for: AskUserQuestion, and
/// permission requests, are the same shape with different options.
Question {
id: String,
prompt: String,
/// A few words naming what the question is about, when the asker
/// offered one. `None` for a permission, which is about the call
/// above it.
header: Option<String>,
options: Vec<QuestionOption>,
/// Whether several options may be chosen at once. Here rather than
/// left for a phone to work out from the dialect underneath: how many
/// answers a question takes is a fact about the question, and the
/// alternative was Claude Code's tool-input schema written out a
/// second time in Kotlin, where no other dialect could reach it.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
multi_select: bool,
/// The tool call this is permission for, when it is one, so a phone
/// can draw the ask on the tool's own row rather than as a second
/// card repeating its input. `None` for anything not about a tool.
#[serde(default, skip_serializing_if = "Option::is_none")]
about: Option<String>,
},
/// A message another agent sent this session.
///
/// Its own kind rather than a `UserMessage`, because it is not something
/// the reader said and a transcript that renders it in their voice is
/// claiming they did. It also explains what would otherwise be
/// inexplicable: a session working on something nobody here asked for.
PeerMessage {
/// The sending session's own name, which is what the reader
/// recognises it by -- the socket path it came from is not.
from: String,
text: String,
/// The seq of the `Status::Running` that opened the turn this message
/// started, so a reader can draw it above that turn.
///
/// The CLI says nothing about a peer message until the turn's
/// `result`, so the event is appended after everything it caused, and
/// an append-only transcript cannot go back and insert it. Carrying
/// the position instead keeps one order on the wire and one on screen.
///
/// Filled in by the pump, the only place that knows a seq, and only
/// where a turn was open: `None` for a message replayed by `import`,
/// which already has it in the right place.
#[serde(default, skip_serializing_if = "Option::is_none")]
turn_start: Option<u64>,
},
/// The manager's record of a question being answered, so a rendered
/// question card resolves on every device rather than only the one that
/// answered.
///
/// A list because a question can take several answers, and one that took
/// one is the list of length one rather than a different shape.
Answered {
id: String,
answers: Vec<String>,
},
Status {
state: SessionStatus,
},
/// What the session is set to, as the session itself reports it.
///
/// Asking for a change and having one are different things, and only this
/// is a measurement: a model name the dialect does not know, a mode it
/// refuses, or a driver whose model is fixed at startup all leave a
/// request that was sent and nothing that changed. Reporting from the
/// request put the answer on the phone before the question was answered.
///
/// Either field alone, because the two are confirmed separately.
Settings {
#[serde(default, skip_serializing_if = "Option::is_none")]
model: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
permission_mode: Option<String>,
},
/// Per-turn token counts, where the dialect reports them.
UsageDelta {
/// What this turn cost: the tokens it was charged for.
tokens: u64,
/// What the model was holding when the turn ended -- see
/// [`context_tokens`].
///
/// Carried rather than summed by whoever is reading, because it is
/// not a sum: context goes *down* at a compaction and a clear, so
/// adding turns up would report a figure the session stopped being
/// true of long ago.
///
/// `None` where the dialect did not say, which every reader has to be
/// able to draw.
#[serde(default, skip_serializing_if = "Option::is_none")]
context: Option<u64>,
},
/// A compaction that finished, and how much context it recovered.
///
/// The counts are the point, and a spinner is not. They are optional
/// because the record has shipped without them, and "the compaction
/// happened, we don't know by how much" is a state this has to be able to
/// say -- a plausible number would be indistinguishable from a counted one.
Compacted {
#[serde(default, skip_serializing_if = "Option::is_none")]
pre_tokens: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
post_tokens: Option<u64>,
/// What asked for it, in the dialect's own word -- `auto` when the
/// session compacted on its own. Carried rather than reduced to a bool
/// so an unrecognised trigger stays unrecognised: an automatic
/// compaction is the one worth naming, because it explains a wait
/// nobody asked for.
#[serde(default, skip_serializing_if = "Option::is_none")]
trigger: Option<String>,
},
/// A command the session was asked to run on itself, held because it
/// cannot run yet. These are not messages: `/compact` and `/rename` are
/// instructions about the session, and a session mid-turn reads a line
/// written to it as something the model should see. So they wait, and
/// this is what a phone draws while they do.
CommandQueued {
id: String,
text: String,
},
/// The same command, now handed to the session. Its [`CommandQueued`]
/// stops being pending when this arrives, matched by `id`; a command
/// that ran immediately has only this.
CommandSent {
id: String,
text: String,
},
/// The conversation was cleared: everything above this is still in the
/// record but is no longer in the session's context.
///
/// Nothing is deleted. A transcript is the thing a person scrolls back
/// through, so this is a divider, not a truncation.
///
/// **Load-bearing, not decorative.** For any driver that rebuilds its
/// conversation from the transcript, this marker decides what the model
/// is given -- dropping it, or treating it as something only the phone
/// draws, silently puts a cleared conversation back in front of the model
/// at full cost. Today `llama::conversation` is the only fold that reads
/// it, which is why this is written down rather than left to be inferred
/// from a second example that does not exist.
Cleared,
Error {
message: String,
},
}
/// How much the model was holding, from the three figures a turn reports:
/// the input side only, prompt plus both cache figures. A cached token is
/// cheaper but it is still one the model was given; output is what the turn
/// produced rather than what continuing has to carry.
///
/// One function so the definition cannot drift, because it is extracted two
/// quite different ways -- the live translators have the usage object parsed,
/// and `import::context_tokens` scans it out of a raw line without parsing.
pub fn context_tokens(input: u64, cache_creation: u64, cache_read: u64) -> u64 {
input + cache_creation + cache_read
}
/// The context after `event`, given what it was before.
///
/// The whole rule in one place, because three readers need the same answer:
/// the pump keeping a live session's figure, the transcript seeding it at
/// startup, and the phone folding the same events into what it draws.
///
/// The two that *lower* it are the point. A clear takes the conversation away
/// and a compaction replaces it with a summary, so a figure measured before
/// either stopped being true at that moment -- and carrying it forward is how
/// a session that had just been cleared went on reporting the context it no
/// longer had.
///
/// `None` is "we don't know", which each of them can reach.
pub fn context_after(current: Option<u64>, event: &Event) -> Option<u64> {
match event {
// `or`, so a turn the dialect reported no usage for leaves the last
// measurement standing: stale by a turn, which every context figure
// is, rather than wrong.
Event::UsageDelta { context, .. } => context.or(current),
Event::Compacted { post_tokens, .. } => *post_tokens,
Event::Cleared => None,
_ => current,
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum SessionStatus {
Idle,
Running,
AwaitingInput,
Compacting,
Exited,
/// There is a process recorded for this session and the machine will not
/// say whether it is still running.
///
/// Its own state rather than the nearest of the others, because both
/// neighbours are lies with consequences: `Exited` invites starting a
/// second process against a conversation that may already have one, and
/// `Idle` claims a session is waiting for you when nobody has checked.
Unknown,
}
/// One transcript line: an [`Event`] plus its position and time. The event
/// is flattened so the wire shape stays one flat object.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SeqEvent {
pub seq: u64,
/// Epoch seconds.
pub ts: f64,
#[serde(flatten)]
pub event: Event,
}
+1
View File
@@ -0,0 +1 @@
{"rustc_fingerprint":16968256872041900714,"outputs":{"8688260251109005551":{"success":true,"status":"","code":0,"stdout":"rustc 1.98.0 (88d9e12ae 2026-08-18)\nbinary: rustc\ncommit-hash: 88d9e12ae178fab0fb5cc050a94da85685d449ea\ncommit-date: 2026-08-18\nhost: x86_64-unknown-linux-gnu\nrelease: 1.98.0\nLLVM version: 22.1.8\n","stderr":""},"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/bob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_primitive_alignment=\"16\"\ntarget_has_atomic_primitive_alignment=\"32\"\ntarget_has_atomic_primitive_alignment=\"64\"\ntarget_has_atomic_primitive_alignment=\"8\"\ntarget_has_atomic_primitive_alignment=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}
+3
View File
@@ -0,0 +1,3 @@
Signature: 8a477f597d28d172789f06886806bc55
# This file is a cache directory tag created by cargo.
# For information about cache directory tags see https://bford.info/cachedir/
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
0a35a2159733b34f
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[]","declared_features":"[]","target":7600547062124258715,"profile":8731458305071235362,"path":10763286916239946207,"deps":[[5330460842384404171,"serde_json",false,3521654318384187666],[6557439603276904804,"serde",false,9115200261241786175]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/event-model-22939ccd17cf0d53/dep-lib-event_model","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
28d1a47e1679c2ee
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[]","declared_features":"[\"no-panic\"]","target":18426369533666673425,"profile":15657897354478470176,"path":14942821222029544552,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/itoa-e940bf7c9c083c64/dep-lib-itoa","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
e07eefd3ad107c74
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"alloc\", \"std\"]","declared_features":"[\"alloc\", \"core\", \"default\", \"libc\", \"logging\", \"rustc-dep-of-std\", \"std\", \"use_std\"]","target":11745930252914242013,"profile":15657897354478470176,"path":17502693890317708870,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/memchr-55c8f9bd116d57f0/dep-lib-memchr","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
908122be755d3bde
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"proc-macro\"]","declared_features":"[\"default\", \"nightly\", \"proc-macro\", \"span-locations\"]","target":369203346396300798,"profile":2225463790103693989,"path":9326605962526047067,"deps":[[8901712065508858692,"unicode_ident",false,9002592617963285065],[16346726298725429545,"build_script_build",false,10309388049098035721]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/proc-macro2-6e7a54961830b09e/dep-lib-proc_macro2","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"proc-macro\"]","declared_features":"[\"default\", \"nightly\", \"proc-macro\", \"span-locations\"]","target":5408242616063297496,"profile":2225463790103693989,"path":9923770499906903100,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/proc-macro2-ced09248f21b5d01/dep-build-script-build-script-build","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"","declared_features":"","target":0,"profile":0,"path":0,"deps":[[16346726298725429545,"build_script_build",false,8844359754317230827]],"local":[{"RerunIfChanged":{"output":"debug/build/proc-macro2-e91ee3baef79ebaa/output","paths":["src/probe/proc_macro_span.rs","src/probe/proc_macro_span_location.rs","src/probe/proc_macro_span_file.rs"]}},{"RerunIfEnvChanged":{"var":"RUSTC_BOOTSTRAP","val":null}}],"rustflags":[],"config":0,"compile_kind":0}
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"proc-macro\"]","declared_features":"[\"default\", \"proc-macro\"]","target":5408242616063297496,"profile":2225463790103693989,"path":15204616833879173795,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/quote-096835ab63739f47/dep-build-script-build-script-build","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"","declared_features":"","target":0,"profile":0,"path":0,"deps":[[8949245912927223590,"build_script_build",false,13168906214976151189]],"local":[{"RerunIfChanged":{"output":"debug/build/quote-a65b75d92ce755e8/output","paths":["build.rs"]}}],"rustflags":[],"config":0,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
ec92212b256d4034
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"proc-macro\"]","declared_features":"[\"default\", \"proc-macro\"]","target":8313845041260779044,"profile":2225463790103693989,"path":10909413009652471663,"deps":[[8949245912927223590,"build_script_build",false,1299253780567681050],[16346726298725429545,"proc_macro2",false,16013495660328419728]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/quote-f95d225106368b84/dep-lib-quote","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"","declared_features":"","target":0,"profile":0,"path":0,"deps":[[6557439603276904804,"build_script_build",false,7538447504461486726]],"local":[{"RerunIfChanged":{"output":"debug/build/serde-2b6dc38641ca5f93/output","paths":["build.rs"]}}],"rustflags":[],"config":0,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
3f4fdddb57b27f7e
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"default\", \"derive\", \"serde_derive\", \"std\"]","declared_features":"[\"alloc\", \"default\", \"derive\", \"rc\", \"serde_derive\", \"std\", \"unstable\"]","target":11327258112168116673,"profile":15657897354478470176,"path":259703313627472752,"deps":[[6557439603276904804,"build_script_build",false,12069747732468100742],[11029742160753049355,"serde_core",false,10682519779281431540],[13312204359551525516,"serde_derive",false,12133960540131049856]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/serde-4f0323fc6c5c4c08/dep-lib-serde","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"default\", \"derive\", \"serde_derive\", \"std\"]","declared_features":"[\"alloc\", \"default\", \"derive\", \"rc\", \"serde_derive\", \"std\", \"unstable\"]","target":5408242616063297496,"profile":2225463790103693989,"path":12674769013409038814,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/serde-f06f4da0f75e7ba8/dep-build-script-build-script-build","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"result\", \"std\"]","declared_features":"[\"alloc\", \"default\", \"rc\", \"result\", \"std\", \"unstable\"]","target":5408242616063297496,"profile":2225463790103693989,"path":3109787618151281189,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/serde_core-0a31bdcb556041d4/dep-build-script-build-script-build","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
f46b270e24ef3f94
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"result\", \"std\"]","declared_features":"[\"alloc\", \"default\", \"rc\", \"result\", \"std\", \"unstable\"]","target":6810695588070812737,"profile":15657897354478470176,"path":17604523466576488115,"deps":[[11029742160753049355,"build_script_build",false,11881783826505965304]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/serde_core-50472241cf64cf59/dep-lib-serde_core","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"","declared_features":"","target":0,"profile":0,"path":0,"deps":[[11029742160753049355,"build_script_build",false,9868700438545241361]],"local":[{"RerunIfChanged":{"output":"debug/build/serde_core-c51701b0944e4e50/output","paths":["build.rs"]}}],"rustflags":[],"config":0,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
80411ea1d27c64a8
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"default\"]","declared_features":"[\"default\", \"deserialize_in_place\"]","target":13076129734743110817,"profile":2225463790103693989,"path":1622169132691883934,"deps":[[4481353994425695856,"syn",false,3884405872263008629],[8949245912927223590,"quote",false,3765129294886572780],[16346726298725429545,"proc_macro2",false,16013495660328419728]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/serde_derive-ac77baf888970ea2/dep-lib-serde_derive","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
128902adf16ddf30
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"default\", \"float_roundtrip\", \"std\"]","declared_features":"[\"alloc\", \"arbitrary_precision\", \"default\", \"float_roundtrip\", \"indexmap\", \"preserve_order\", \"raw_value\", \"std\", \"unbounded_depth\"]","target":9592559880233824070,"profile":15657897354478470176,"path":18434498419618500693,"deps":[[5330460842384404171,"build_script_build",false,7131227597519702231],[5532778797167691009,"itoa",false,17204446664029688104],[11029742160753049355,"serde_core",false,10682519779281431540],[12613788554453945248,"memchr",false,8393602144282836704],[16226529040278277557,"zmij",false,11886773985880792019]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/serde_json-86f92794bab1b2e3/dep-lib-serde_json","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"default\", \"float_roundtrip\", \"std\"]","declared_features":"[\"alloc\", \"arbitrary_precision\", \"default\", \"float_roundtrip\", \"indexmap\", \"preserve_order\", \"raw_value\", \"std\", \"unbounded_depth\"]","target":5408242616063297496,"profile":2225463790103693989,"path":6089029597847711871,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/serde_json-9eba6b6192117dbe/dep-build-script-build-script-build","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"","declared_features":"","target":0,"profile":0,"path":0,"deps":[[5330460842384404171,"build_script_build",false,14385980320883741292]],"local":[{"RerunIfChanged":{"output":"debug/build/serde_json-b93d1fe6f70f6d93/output","paths":["build.rs"]}}],"rustflags":[],"config":0,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
7591ad738f2ee835
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[\"clone-impls\", \"derive\", \"parsing\", \"printing\", \"proc-macro\"]","declared_features":"[\"clone-impls\", \"default\", \"derive\", \"extra-traits\", \"fold\", \"full\", \"parsing\", \"printing\", \"proc-macro\", \"test\", \"visit\", \"visit-mut\"]","target":9442126953582868550,"profile":2225463790103693989,"path":4661929566105643723,"deps":[[8901712065508858692,"unicode_ident",false,9002592617963285065],[8949245912927223590,"quote",false,3765129294886572780],[16346726298725429545,"proc_macro2",false,16013495660328419728]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/syn-ba824d1fb7fccb81/dep-lib-syn","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
496a41cb49a2ef7c
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[]","declared_features":"[]","target":14045917370260632744,"profile":2225463790103693989,"path":10448178182353594507,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/unicode-ident-30c770f20c543060/dep-lib-unicode_ident","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"","declared_features":"","target":0,"profile":0,"path":0,"deps":[[16226529040278277557,"build_script_build",false,3183603099212200132]],"local":[{"RerunIfChanged":{"output":"debug/build/zmij-24daae732fd830da/output","paths":["build.rs"]}}],"rustflags":[],"config":0,"compile_kind":0}
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[]","declared_features":"[\"no-panic\"]","target":5408242616063297496,"profile":2225463790103693989,"path":2094852904543046020,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/zmij-b8e41156ec2eb9b9/dep-build-script-build-script-build","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
This file has an mtime of when this was started.
@@ -0,0 +1 @@
d35bc719f64df6a4
@@ -0,0 +1 @@
{"rustc":2467252760697041086,"features":"[]","declared_features":"[\"no-panic\"]","target":16603507647234574737,"profile":15657897354478470176,"path":5968495413377776620,"deps":[[16226529040278277557,"build_script_build",false,10979419188323205865]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/zmij-dac683281b28ed51/dep-lib-zmij","checksum":false}}],"rustflags":[],"config":9396254390672932401,"compile_kind":0}
@@ -0,0 +1,7 @@
/home/bob/repos/ai-app-2/.claude/worktrees/agent-a30feda38122e4492/event-model/target/debug/deps/event_model-22939ccd17cf0d53.d: src/lib.rs
/home/bob/repos/ai-app-2/.claude/worktrees/agent-a30feda38122e4492/event-model/target/debug/deps/libevent_model-22939ccd17cf0d53.rlib: src/lib.rs
/home/bob/repos/ai-app-2/.claude/worktrees/agent-a30feda38122e4492/event-model/target/debug/deps/libevent_model-22939ccd17cf0d53.rmeta: src/lib.rs
src/lib.rs:
@@ -0,0 +1,8 @@
/home/bob/repos/ai-app-2/.claude/worktrees/agent-a30feda38122e4492/event-model/target/debug/deps/itoa-e940bf7c9c083c64.d: /home/bob/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.18/src/lib.rs /home/bob/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.18/src/u128_ext.rs
/home/bob/repos/ai-app-2/.claude/worktrees/agent-a30feda38122e4492/event-model/target/debug/deps/libitoa-e940bf7c9c083c64.rlib: /home/bob/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.18/src/lib.rs /home/bob/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.18/src/u128_ext.rs
/home/bob/repos/ai-app-2/.claude/worktrees/agent-a30feda38122e4492/event-model/target/debug/deps/libitoa-e940bf7c9c083c64.rmeta: /home/bob/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.18/src/lib.rs /home/bob/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.18/src/u128_ext.rs
/home/bob/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.18/src/lib.rs:
/home/bob/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.18/src/u128_ext.rs:
Loaded 100 of 140 files, more files were not shown because too many files have changed in this diff. Show more