lib.rsannotatedlib.rssource601 lines · 22.8 KB · raw

The archive: every request lmjtfy has had answered, and the questions people asked. These are the messages the Worker and the archive's Durable Object exchange. No I/O and no clock.

The rule (the user, 2026-10-02): the same request is never sent to the same model twice. A request is the exact body, and it is kept with its response under the model it went to. Asking again returns that response. The archive is also what makes the call, so two visitors asking the same new thing at once share one request.

10#![forbid(unsafe_code)]
12use ask::{Sent, Wanted};
13use serde::{Deserialize, Serialize};
14
15pub mod event;
16pub use event::{Event, Origin, Seen as Report};

What the Worker asks the archive.

19#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
20pub enum Ask {

Jev's answer to wanted about input. request is the body the Worker prepared and shows on the page; the archive prepares it again from wanted, and refuses if the two differ.

24    Jev { input: String, wanted: Wanted, request: String, #[serde(default)] pick: Pick },

The LLM's reply to request, from model.

26    Llm { model: String, request: String, #[serde(default)] pick: Pick },

input was asked and got answers, one per question Jev answered. llm is whether an LLM had to be asked; listed is whether the question may be shown on the public feed. who is the asking browser for this question only (Asker): a browser that asked it before is not counted again. None when the browser sent no id. browser is that browser's id itself, kept beside who so the owner can see whose row it is.

34    Asked {
35        input: String,
36        answers: Vec<Answer>,
37        llm: bool,
38        listed: bool,
39        #[serde(default)]
40        who: Option<Asker>,
41        #[serde(default)]
42        browser: String,
43    },

Someone cloned or pulled repo (lmjtfy.git) through the site. Counted, and told to every open page.

46    Fetched { repo: String, fetch: Fetch },

who thinks Jev's answer to input right (Up) or wrong (Down). The vote is for the answer as it is kept now; the same vote again takes it back. Answered with the Rating after it.

50    Rate {
51        input: String,
52        who: Asker,
53        vote: Vote,
54        #[serde(default)]
55        browser: String,
56    },

The votes on Jev's answer to input as it is kept now, and who's.

58    Rating { input: String, who: Option<Asker> },

What the home page shows from the archive.

60    Home,

The next FEED listed questions asked before after, newest first: the feed scrolled to its end.

63    Older { after: Cursor },

What Jev said to input, if it was ever asked and answered. Nothing is sent to find out.

66    Answer { input: String },

Something happened, to be kept whole (event.rs).

68    Event(Box<Event>),
69}

The archive object's name: there is one, for the whole site. A Worker that binds the archive (the site's, the admin's) reaches it by this.

73pub const OBJECT: &str = "everything";

The path of the archive's door for the owner's admin backend. The site's own Worker never sends a request there; the admin's Worker, which binds the same object from the owner's account, does.

78pub const ADMIN: &str = "/admin";

What the admin backend asks the archive.

81#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
82pub enum Admin {

Rows of the archive's tables: one statement that only reads (reads_only), with a value for each ?.

85    Select {
86        sql: String,
87        #[serde(default)]
88        values: Vec<serde_json::Value>,
89    },

The owner's say on whether input may be shown on the feed: yes, no, or None to leave it to the rules again. Jev's own verdict (asked.listed) is kept beside it, untouched.

93    Moderate { input: String, listed: Option<bool> },
94}

What the archive answers the admin backend.

97#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
98pub enum Answered {
99    Rows { columns: Vec<String>, rows: Vec<Vec<serde_json::Value>> },
100    Done,
101    Refused(String),
102}

Whether sql is one statement that can only read. The admin's door changes the archive through Admin's own messages, never through SQL: the schema changes only by a migration, and a response that was kept is never edited. Text in quotes is not looked at, so a question that says "delete" can still be searched for; pass such text as a value.

109pub fn reads_only(sql: &str) -> bool {
110    let mut bare = String::new();
111    let mut quoted = None;
112    for c in sql.chars() {
113        match quoted {
114            Some(quote) if c == quote => quoted = None,
115            Some(_) => {}
116            None if c == '\'' || c == '"' => quoted = Some(c),
117            None => bare.push(c.to_ascii_lowercase()),
118        }
119    }
120    let bare = bare.trim().trim_end_matches(';').trim_end();
121    let words: Vec<&str> = bare.split(|c: char| !c.is_ascii_alphanumeric() && c != '_').filter(|word| !word.is_empty()).collect();
122    const WRITES: [&str; 13] = ["insert", "update", "delete", "replace", "drop", "alter", "create", "attach", "detach", "pragma", "vacuum", "reindex", "analyze"];
123    quoted.is_none() && !bare.contains(';') && matches!(words.first(), Some(&"select") | Some(&"with")) && !words.iter().any(|word| WRITES.contains(word))
124}

Which of a request's kept responses an ask wants. A request is sent again only when a visitor asks for that (Fresh, the page's ↻); every response it ever got is kept, numbered from 1, newest last.

129#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
130pub enum Pick {

The newest kept, or sent if there is none.

132    #[default]
133    Latest,

Sent now, whatever is kept, and kept as the newest.

135    Fresh,

That one, if kept; the newest kept otherwise.

137    Version(u32),

The newest kept, and never sent: Called::NotKept if there is none. What a page that is stepping through old versions uses for the calls after the one it stepped, so looking costs nothing.

141    KeptOnly,
142}

Which version of each call a page wants, by call_id: the page's $pins signal, id:3;id:fresh, later entries winning. A call it does not name gets the newest kept.

147#[derive(Clone, Debug, Default, PartialEq, Eq)]
148pub struct Pins(pub Vec<(String, Pick)>);
150impl Pins {
151    pub fn parse(text: &str) -> Pins {
152        let mut pins: Vec<(String, Pick)> = Vec::new();
153        for entry in text.split(';') {
154            let Some((id, what)) = entry.trim().split_once(':') else { continue };
155            if id.len() != 12 || !id.bytes().all(|b| b.is_ascii_hexdigit()) {
156                continue;
157            }
158            let pick = match what {
159                "fresh" => Pick::Fresh,
160                number => match number.parse::<u32>() {
161                    Ok(version) if version > 0 => Pick::Version(version),
162                    _ => continue,
163                },
164            };
165            pins.retain(|(seen, _)| seen != id);
166            pins.push((id.to_owned(), pick));
167        }
168        Pins(pins)
169    }

Stepping through old versions, and asking nothing new: a version is pinned and nothing is to be sent again. Then a call that is not pinned is only read, never sent, so looking costs nothing.

174    pub fn browsing(&self) -> bool {
175        self.0.iter().any(|(_, pick)| matches!(pick, Pick::Version(_))) && !self.0.iter().any(|(_, pick)| *pick == Pick::Fresh)
176    }

What to ask the archive for, for the call id.

179    pub fn pick(&self, id: &str) -> Pick {
180        match self.0.iter().find(|(seen, _)| seen == id) {
181            Some((_, pick)) => *pick,
182            None if self.browsing() => Pick::KeptOnly,
183            None => Pick::Latest,
184        }
185    }
186}

A call, as the page names it for ↻ and ◀ ▶: the first 12 hex digits of the SHA-256 of where it went and what was sent.

190pub fn call_id(sent_to: &str, request: &str) -> String {
191    use sha2::{Digest, Sha256};
192    let digest = Sha256::new().chain_update(sent_to.as_bytes()).chain_update([0]).chain_update(request.as_bytes()).finalize();
193    digest.iter().take(6).map(|byte| format!("{byte:02x}")).collect()
194}

A response the archive holds, and the call that got it.

197#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
198pub struct Record {

The response body exactly as it arrived.

200    pub response: String,
201    pub request_id: Option<String>,
202    pub attempts: u32,

The round trip of the call that was sent, in milliseconds.

204    pub took_ms: f64,

When that call was answered, in Unix milliseconds.

206    pub answered_ms: f64,

Whether this ask is the one that sent it.

208    pub sent_now: bool,

Which of the request's kept responses this is, from 1, and how many there are.

211    #[serde(default = "first")]
212    pub version: u32,
213    #[serde(default = "first")]
214    pub versions: u32,
215}
217fn first() -> u32 {
218    1
219}
220
221impl Record {
222    pub fn sent(&self) -> Sent {
223        if self.sent_now { Sent::Now } else { Sent::Before { at_ms: self.answered_ms } }
224    }

The same record, as someone who did not send it sees it.

227    pub fn kept(mut self) -> Self {
228        self.sent_now = false;
229        self
230    }
231}

A browser, for one question: the hex SHA-256 of the browser's random id and the question. It says whether this browser asked this question before, and nothing else: two questions from one browser give unrelated values, and the id cannot be had back from one.

237#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
238pub struct Asker(pub String);

A browser's view of Jev's answer.

241#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
242pub enum Vote {
243    Up,
244    Down,
245}

The votes on one answer, and the asking browser's own, if it voted.

248#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
249pub struct Rating {
250    pub up: u32,
251    pub down: u32,
252    pub mine: Option<Vote>,
253}

Which shared budget refused a call.

256#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
257pub enum Pot {
258    Jev,
259    Llm,
260}

What became of a call.

263#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
264pub enum Called {
265    Answered(Record),

Sent, or not sendable, and there is no response. Nothing is kept, so the same request may be sent again.

268    Failed { error: String, request_id: Option<String>, took_ms: f64 },

Not sent: today's budget for it is used up.

270    Spent(Pot),

Not sent, because the ask was Pick::KeptOnly and nothing is kept.

272    NotKept,
273}

What Jev said to one question, as it is kept for the feed and for link previews: the answer in a few words, and the numbers behind it.

277#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
278pub struct Answer {

What the page prints large: "No?", "Pepperoni.", "28%.".

280    pub headline: String,
281    pub detail: Detail,
282}

The numbers behind an answer, by the type of question it answered.

285#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
286pub enum Detail {

Kept before details were. Only the headline is known.

288    Unknown,

A yes-or-no: the probability of yes.

290    Noul { p_yes: f64 },

A how-likely, which Jev answers as a Noul about the thing itself: the probability that it is so.

293    Chance { p: f64 },

A pick: every option with its probability, most likely first.

295    Choice { confidence: f64, options: Vec<(String, f64)> },

A how-much: every level with its probability, lowest first.

297    Score { score: f64, confidence: f64, levels: Vec<(String, f64)> },
298}
300impl Answer {

The type and the numbers in one line, as the page prints them under an answer. None when only the headline was kept.

303    pub fn note(&self) -> Option<String> {
304        Some(match &self.detail {
305            Detail::Unknown => return None,
306            Detail::Noul { p_yes } => format!("Noul · p(yes) = {p_yes:.2}"),
307            Detail::Chance { p } => format!("Noul · p = {p:.2} · Jev thinks that's {}", ask::likelihood(*p)),
308            Detail::Choice { confidence, .. } => format!("Choice · confidence {confidence:.2}"),
309            Detail::Score { score, confidence, levels } => {
310                format!("Score · {score:.1} of {} · confidence {confidence:.2}", levels.len().saturating_sub(1))
311            }
312        })
313    }

The most likeliest options or levels, likeliest first, for a line of text. Empty for a Noul, whose one number is in the note.

317    pub fn spread(&self, most: usize) -> Vec<(&str, f64)> {
318        let mut spread: Vec<(&str, f64)> = match &self.detail {
319            Detail::Choice { options, .. } => options.iter().map(|(label, p)| (label.as_str(), *p)).collect(),
320            Detail::Score { levels, .. } => levels.iter().map(|(label, p)| (label.as_str(), *p)).collect(),
321            _ => Vec::new(),
322        };
323        spread.sort_by(|a, b| b.1.total_cmp(&a.1));
324        spread.truncate(most);
325        spread
326    }

Everything in one line: the headline, the note and the spread.

329    pub fn line(&self) -> String {
330        let mut parts = vec![self.headline.clone()];
331        parts.extend(self.note());
332        let spread: Vec<String> = self.spread(3).iter().map(|(label, p)| format!("{label} {:.0}%", p * 100.0)).collect();
333        if !spread.is_empty() {
334            parts.push(spread.join(", "));
335        }
336        parts.join(" · ")
337    }
338}

A kept answer as it is stored: with its numbers, or, from before they were kept, as the headline alone.

342#[derive(Deserialize)]
343#[serde(untagged)]
344enum Stored {
345    Whole(Answer),
346    Headline(String),
347}

Reads the answers a question was stored with, old form or new.

350pub fn stored(text: &str) -> Vec<Answer> {
351    let stored: Vec<Stored> = serde_json::from_str(text).unwrap_or_default();
352    stored
353        .into_iter()
354        .map(|stored| match stored {
355            Stored::Whole(answer) => answer,
356            Stored::Headline(headline) => Answer { headline, detail: Detail::Unknown },
357        })
358        .collect()
359}

A question somebody asked, and what Jev said. Nothing about who asked.

362#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
363pub struct Entry {
364    pub input: String,
365    pub answers: Vec<Answer>,

When it was last asked.

367    pub asked_ms: f64,

How many times it has been asked and answered.

369    pub times: u32,
370}
372impl Entry {

The answers in a few words each, as the feed prints them.

374    pub fn headlines(&self) -> String {
375        let headlines: Vec<&str> = self.answers.iter().map(|answer| answer.headline.as_str()).collect();
376        headlines.join(" ")
377    }
378}

How many questions the feed shows as asked lately, and as most asked.

381pub const FEED: u32 = 50;
382pub const MOST: u32 = 5;

The archive in numbers.

385#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
386pub struct Stats {

Different questions answered.

388    pub questions: u32,

Times a question was asked and answered, repeats included.

390    pub asks: u32,

Of the different questions, those Jev answered with no LLM.

392    pub no_llm: u32,

Requests that went out and were answered.

394    pub sent: u32,

Requests that did not go out, because their response was kept.

396    pub kept: u32,

Clones and pulls of the code through the site.

398    #[serde(default)]
399    pub clones: u32,
400    #[serde(default)]
401    pub pulls: u32,
402}
404impl Stats {

The share of questions answered with no LLM, as a whole percentage.

406    pub fn no_llm_percent(&self) -> Option<u32> {
407        (self.questions > 0).then(|| (f64::from(self.no_llm) * 100.0 / f64::from(self.questions)).round() as u32)
408    }
409}

What the home page shows from the archive. The lists hold only questions that may be shown publicly; the numbers count every question.

413#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
414pub struct Home {

Newest first.

416    pub lately: Vec<Entry>,

Asked more than once, most asked first.

418    pub most: Vec<Entry>,
419    pub stats: Stats,
420}

Where the feed was scrolled to: the last question shown. Questions are listed newest first, ties broken by the question itself, so the next page starts strictly after this one and none is shown twice or skipped.

425#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
426pub struct Cursor {
427    pub asked_ms: f64,
428    pub input: String,
429}
431impl Entry {

Where the feed is once this entry is the last shown.

433    pub fn cursor(&self) -> Cursor {
434        Cursor { asked_ms: self.asked_ms, input: self.input.clone() }
435    }
436}

What a fetch through the clone proxy was. Git's upload-pack request names the commits wanted; a pull also names the ones it has.

440#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
441pub enum Fetch {
442    Clone,
443    Pull,
444}
446impl Fetch {

Its name in the archive's counts, for one repository.

448    pub fn counted(self, repo: &str) -> String {
449        match self {
450            Fetch::Clone => format!("clone:{repo}"),
451            Fetch::Pull => format!("pull:{repo}"),
452        }
453    }
454}

What the archive pushes to every open page over its socket, as JSON: {"online": 3} or {"toast": "<html>"}.

458#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
459#[serde(rename_all = "lowercase")]
460pub enum Live {

Pages open now.

462    Online(u32),

Something happened, as markup to show for a moment.

464    Toast(String),

The build the site is now (LMJTFY_BUILD), told to each page as it connects. A page built from another offers a reload: a deploy restarts the object, every page reconnects, and each hears this.

468    Build(String),

Elements that changed, each with an id: a page that has an element with that id replaces it. An element with data-prepend="<id>" instead puts its children at the top of that element, each removing any element with its id first: a question asked again moves to the top of the feed, and what a page has scrolled in below stays. The activity feeds stay current this way, with no refresh.

475    Patch(String),
476}

Where an open page connected from, as Cloudflare placed the request: a country code and a city, either unknown. It is kept on the page's socket while it is open, for the online list.

481#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
482pub struct Place {
483    pub country: Option<String>,
484    pub city: Option<String>,
485}
487impl Place {

From what the Worker passed on, kept only if it looks like a place: a country is two letters, a city a short line of text.

490    pub fn new(country: Option<&str>, city: Option<&str>) -> Place {
491        let country = country
492            .map(str::trim)
493            .filter(|code| code.len() == 2 && code.bytes().all(|b| b.is_ascii_alphabetic()))
494            .map(str::to_ascii_uppercase)
495            // Cloudflare's own codes for Tor and for unknown are not places.
496            .filter(|code| code != "T1" && code != "XX");
497        let city = city
498            .map(str::trim)
499            .filter(|city| !city.is_empty() && city.chars().count() <= 64 && !city.chars().any(char::is_control))
500            .map(str::to_owned);
501        Place { country, city }
502    }

The country's flag: its two letters as regional indicator symbols.

505    pub fn flag(&self) -> Option<String> {
506        let code = self.country.as_deref()?;
507        code.chars().map(|letter| char::from_u32(0x1F1E6 + (letter as u32 - 'A' as u32))).collect()
508    }

Austin, US, US, or somewhere.

511    pub fn label(&self) -> String {
512        match (&self.city, &self.country) {
513            (Some(city), Some(country)) => format!("{city}, {country}"),
514            (Some(city), None) => city.clone(),
515            (None, Some(country)) => country.clone(),
516            (None, None) => "somewhere".to_owned(),
517        }
518    }
519}

A header value as the Worker percent-encoded it (+ for a space), back to text. None if it is not UTF-8 or a % is not followed by two hex digits.

524pub fn percent_decoded(text: &str) -> Option<String> {
525    let mut bytes = Vec::with_capacity(text.len());
526    let mut rest = text.bytes();
527    while let Some(byte) = rest.next() {
528        match byte {
529            b'+' => bytes.push(b' '),
530            b'%' => {
531                let hex = [rest.next()?, rest.next()?];
532                bytes.push(u8::from_str_radix(std::str::from_utf8(&hex).ok()?, 16).ok()?);
533            }
534            byte => bytes.push(byte),
535        }
536    }
537    String::from_utf8(bytes).ok()
538}

What the archive keeps on an open page's socket: where it is, and whether a Worker that passes places on sent it. A page that reconnects while a deploy is still reaching Cloudflare's edge can come through the Worker from before, which passes no place; passed is false for it, and the archive asks it to reconnect once the deploy has settled.

545#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
546pub struct Seen {
547    pub place: Place,
548    pub passed: bool,

When it connected, in Unix milliseconds.

550    pub at_ms: f64,

The row of events that says it connected, which the row that says it left copies who it was from.

553    #[serde(default)]
554    pub event: Option<f64>,
555}

How long after connecting an unplaced page is asked to reconnect: long enough for a deploy to reach the whole edge.

559pub const REPLACE_AFTER_MS: f64 = 10_000.0;
561impl Seen {

Whether this page should reconnect to be placed: it came through a Worker that passes no place, long enough ago. A socket with nothing kept on it (None) was accepted by code from before places.

565    pub fn stale(seen: Option<&Seen>, now_ms: f64) -> bool {
566        seen.is_none_or(|seen| !seen.passed && now_ms - seen.at_ms >= REPLACE_AFTER_MS)
567    }
568}

How many open pages are in each place, most first, then by name.

571pub fn places(open: impl IntoIterator<Item = Place>) -> Vec<(Place, u32)> {
572    let mut counted: std::collections::BTreeMap<Place, u32> = std::collections::BTreeMap::new();
573    for place in open {
574        *counted.entry(place).or_default() += 1;
575    }
576    let mut counted: Vec<(Place, u32)> = counted.into_iter().collect();
577    counted.sort_by(|(a, n), (b, m)| m.cmp(n).then_with(|| a.label().cmp(&b.label())));
578    counted
579}

What the archive says back.

582#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
583pub enum Told {
584    Called(Called),
585    Noted,
586    Home(Home),
587    Answer(Option<Entry>),
588    Older(Vec<Entry>),

None if the question was never answered, so there is nothing to vote on.

591    Rating(Option<Rating>),
592}

A moment as YYYY-MM-DD HH:MM UTC.

595pub fn when(unix_ms: f64) -> String {
596    let minutes = (unix_ms / 60_000.0).floor().max(0.0) as u64;
597    format!("{} {:02}:{:02} UTC", budget::date(budget::day(unix_ms)), minutes / 60 % 24, minutes % 60)
598}
600#[cfg(test)]
601mod tests;