shippers.studio 2.3
5 october 17:00 to 17 october 2026, read from git on origin/main

the week, resolved.

one hundred and eighty commits in twelve days, and nothing at all on sunday or monday. strydeos took 116 of them. wednesday the fourteenth, the second tallest day, is mostly the voice agent and the simulated callers that grade it, working through a safety rule until it held. injury time arrived late, sixteen pull requests in under three days, and the studio site moved only by its bot. the acts further down are six pieces of that work with a mechanism worth keeping, each pinned to its own marks on the tape. the close opens on what the last edition got wrong.

point at a mark, or focus the tape and use the arrow keys, to read the commit under it
one commit, stacked by the hour it landedthe studio botnothing landed all week
strydeos, the voice receptionist's red-flag rulesmon 5, then wed 14 to thu 15 october, commits lit

the ban that kept the words in.

on 5 october the receptionist learned that a caller describing cauda equina in their own words gets "call 999 or get to a&e now". six everyday phrasings joined the emergency list. nine days later the rule was reversed: weak or tingly legs are often ordinary back pain, and the decision belongs to a clinician. the case got a tier of its own, a clinician rings back and nothing is booked. then ten runs per scenario showed her adding "if it gets worse, call 111 or a&e" anyway. a sentence forbidding that did not stop it. what the ledger credits is writing the exact line she should say at that moment, and taking the banned words out of the rule entirely.

81e4377c
six regexes added to the 999 list, with a test for each phrasing. the changelog still carries this line as policy
7bbe7208
those patterns move to a callback tier with its own message, graph node and alert. a description that also matches chest pain still goes to 999
fbc9787d
one prompt sentence: add no safety-net advice of your own. the message records 4 of 10 and 7 of 10 runs still adding it
7c4cd2f0
the sentence becomes a script for the close, and a test asserts the rule contains neither "a&e" nor "111"

read in code on origin/main. "ten in a row" after the script is claimed only: no run count is recorded in the repo. the model moved to a larger one a minute after the script landed (295d3735), so the repo cannot say which of the two made it hold.

after the ban, runs that still said a&e scenario a, 4 of 10 scenario b, 7 of 10 after the script no count in the repo the line she says now, once she has a number: "a clinician will ring you back as soon as possible."
filled gold is a run that added a&e or 111 advice, hollow is a run that did not, dashed is a run nobody recorded.
strydeos, the war room gatetue 6, wed 14 and fri 16 october, commits lit

94.57 is not 95.

the war room puts the receptionist in front of hundreds of simulated callers and blocks a release on any failed top-severity scenario, or a pass rate under 95. on 6 october it was comparing a rounded figure: 854 of 903 is 94.57 percent, printed as 95, and that cleared the rate check. the same run failed on something else, so nothing got through, but the hole was real and the check is now in whole numbers. ten days later the gate moved the other way. full runs kept failing a different one or two scenarios that then passed alone, so a failed scenario is re-run twice and blocks only if it fails again.

2ad8bae5
passes times 100 against gate times runs, in integers. a test pins 854 of 903 as a fail and 855 of 900 as a pass
a66140cd
the retest: two more calls per failed scenario, cleared only if every one passes. the pass rate still counts the first failure
f02fa178
a new top-severity failure: telling the caller they are booked before the booking tool has run
6cb8ccdb
the harness refuses to start if it cannot supply a value the live tools read, and a one-scenario run no longer paints the board green

read in code on origin/main. the clearing path of the retest has only ever run in a unit test, by its own commit message. the odds in the drawing are worked from the code, not measured.

the rate check before 6 october gate 95 94 96 94.57 rounded to 95 a scenario that fails 3 calls in 10 chance it clears the gate anyway before the retest 49% after 74%
two main calls plus two retests, the defaults in ci. that covers safety scenarios too, which cuts against the act above: judge a safety prompt by ten runs.
strydeos, the owner dashboard and the booking pathtue 13 to sat 17 october, commits lit

fields that nothing wrote.

the follow-up card on the owner dashboard counted events stamped as actioned by the follow-up engine. over the summer that stamp was narrowed, correctly, until one path wrote it: an owner approving a gap-fill. automatic sends never stamp it, so the card read zero beside a send ledger that was full. it now reads that ledger. the same fortnight turned up two more of the kind. a "follow-up booked" flag was written by five places, every one hard-coded to false, so a discharge rule that checked it always passed. and the marker that locks a call's outcome as booked never ran on a live call, because no tool sent the conversation id it waits for.

68c2eb3c
the card drops the stamp query for the send ledger. unconfirmed after 48 hours is not counted as sent, and money shows only on high-confidence attribution
7ce76648
the follow-up flag is deleted along with its five writers, each of which set it to false
d37f2980
every booking tool now posts the conversation id. its own comment: the id "was undefined on every live call"
f57e6180
switched on, the marker failed on every call with no clinician preference: one undefined value and the database refuses the whole write. the test double now refuses it too

read in code on origin/main. the live counts in the commit messages were not re-measured. one write further down the same booking path still sends the same undefined value, and its failure only reaches the console.

readswaiting onwritten by follow-up cardthe actioned stamp one manual path until 14 october discharge rulefollow-up booked 5, all false until 17 october booking markerconversation id no tool until 13 october
dashed is a reader joined to something nothing live was writing. each was right in its own file.
strydeos, the patient-state contractfri 16 and sat 17 october, commits lit

six rulers, then one.

until 17 october the code had no single answer to whether a patient had drifted. the lifecycle measured each patient against their own rhythm, the dropout insight used 35 to 49 days, deep metrics a flat 30, and a classifier written three days earlier had its own order. whether someone counted as churned turned on whether the clinic had texted them in the last 60 days, so our own messaging decided their state. someone who reached six appointments and then cancelled was filed as discharged. there is now one function with eight states, first match wins, read by the board, the messaging, the metrics and the voice agent. the subject says every module. one insight still keeps its own window.

a1cf2e25
a cancellation after the last visit stops an inferred discharge. the message counts 22 of 55 inferred discharges that had one
7ce76648
one classifier, 72 files. the commit says four definitions; the diff removes six places that had their own
449b29ae
the first churn row counted every starter under six visits as lost and read 93% for one month. 70 minutes later, lost means seen once or cancelled away

read in code on origin/main. the clinic counts are the commit messages' own. the revenue insight that still says "due a rebook" from its own 35 to 49 day window is still there, and a quiet three-visit course reads churned on the board but finished in the owner summary.

before: each module's own line 30, flat 35 to 49 60 since our last text own 090 days180 now: one rule, for someone seen weekly betweenoverduestopped, shown as churnedpast 14, then 45, then 180 days, from patient-state.ts on main
the bands stretch with a person's own gap between visits; the floors are the ones drawn.
outreach, the unsubscribe link and the send pathtue 6 october, commits lit

the scanner pressed unsubscribe.

the unsubscribe link acted on a plain fetch, so anything that fetched it could press it, and mail scanners fetch every link in a message. two opt-outs landed 3 and 8 seconds after an open, and the click counter had scored them as clicks. the fix splits the verb: a fetch checks the signed token and shows a button, and only pressing it opts out and stamps the time. the same evening the opt-out question moved inside the one function every prospect email passes through, so a draft written before someone unsubscribed, or a duplicate row on the same address, can no longer slip past a caller that forgot to ask.

b2c1232
the fetch handler is read-only, with a comment saying so. the write moved to a post on the same address, which also suits a one-click unsubscribe
4eee0e2
the confirm page used to say "will no longer receive emails" before anything had happened
1429a10
five checks inside the send function, before the provider is called. a failed lookup means not this time, never send anyway
72c9592
a hold on first emails, flipped in the database. while it is on, a held first email's later steps wait too

read in code on origin/main. not exercised here: pressing a live unsubscribe is a state change. the click counter itself is untouched since july and still counts every visit to the confirm page.

before: seconds after an open open +3s +8s opted out, logged as clicks now fetch: show a button a person press: opt out, stamp a scanner can do the first step only
gold is an opt-out. the timings are the ledger's own record, not re-read from events.
injury time, the matchday opposition cardwed 14 to sat 17 october, commits lit

a coin flip, worked out.

the opposition card is a small, standard football model rather than a feeling. attack and defence come from goals per game against the league average, pulled toward average by three phantom games so a short season is not over-read. home advantage is measured from the league's own home and away points, square-rooted and clamped. two poisson scorelines give the win, draw and loss chances and the likeliest scores. a language model then writes the brief from those numbers, and that is where one figure drifts: the live brief pairs the raw conceded rate with the shrunk percentage, so it says 32 percent fewer where the raw rate is 38.

04693b9
a pure model file: three prior games, home edge clamped to 1 to 1.4, a ten by ten score grid renormalised
04693b9
its test runs on the real table but pins only bounds and orderings, so a wrong coefficient that keeps the order would pass
7b9ca1f
the same days moved health data rules into the database. its own build record says those migrations are applied only on a local stack

seen in production. injury-time.vercel.app/team, fetched 17 october, prints the odds drawn here; 1.53 each way reproduces from the committed table. nothing checks the brief's arithmetic against the numbers it was handed.

the card as served win 38%draw 24%lose 38% goals we should score1.53 goals they should score1.53 the brief: concedes 1.2 a game, "32% fewer than the league average" raw: 38%
filled is a win, hollow a draw, gold a loss. symmetric looks like a bug and is not: it reproduces from the data.

still wrong.

13commits the last edition missed, found by recounting the same window on fresh clones

2.2 printed 252. counted again on clones fetched from each remote, the same window gives 265. nine of the thirteen sat in a lane that read a local copy with no remote, so nothing pushed elsewhere ever reached it. the other four carry 4 october dates and may have landed after that run. the fix is in how this edition counts: every lane now reads a bare clone fetched for the run, and shas the previous edition counted are dropped by prefix.

the drift comparison tested through a stubcarried forward. a new test covers the message written after the comparison, not the comparisonuntested
the seat price the refusal quotedno longer true. fixed in f803a5c2, 22 minutes into this window. one stripe product description still says 49fixed
commits by a person, on origin's default branch, merges left out180
of those, in strydeos116
the busiest day, tuesday 6 october48
days with nothing from a personsunday 11 and monday 12 october2
repositories that moved9 of 15
pull requests merged by squash50
commits by the studio bot, left out of the 180each one refreshes the client portal's access registry, two lines at a time23

every figure came out of git log across fifteen repositories, 5 october 17:00 to 17 october 02:52, counted on origin's default branch in clones fetched for this edition, so an evicted icloud checkout cannot hang the count or hide a merge. merges are left out, and anything the last edition already counted is dropped. the evidence and strydelens lanes now read their own remotes. third-party repositories on the machine are left out. the monday 12 october run left no edition, so this one covers twelve days. the acts were read from the diffs and from the code as it stands on main, and each says whether it was seen in production. read from production on 17 october: injury time's public team page. this public cut leaves out findings still open in a live clinical system and the subjects of a personal planner lane; every count is unchanged. no test suite was re-run, no phone call was placed and no login-gated page was opened.
shippers studio 2.3, ldn to worldwide