Repository navigation
probbit monitor: watch an individual's inner state live - #21
Merged
Merged
Conversation
…he terminal live::Replay checks a strand's header and replays it line by line with the rules `live verify` used (prev, n, the stance and state digests, the bytes); verify is now a loop over it, so the monitor and verify read a strand one way. `probbit monitor STRAND [--follow] [--once] [--plain] [--fps N]` replays the strand, recomputing every stance document, and draws the latest event as horizontal bars: the stance (each trait's levels as segments with their odds, the level taken highlighted, its phrase), the moods with a sparkline of the last 50 events, the senses, the habits (bound ones marked, violations), the learned deltas within their cap, drives when a document carries them, and the stance line. A line that differs is named in the header and the frame shows the event before it (exit 1). --follow polls the file and replays appended lines; a truncated or rotated strand is replayed from the start with a warning. --plain is ASCII only.
tests/monitor.rs: help; one --once --plain frame pinned byte for byte (the tutor's demo week, the last event and a failure turn with a bound habit); exit 0 / 1 (a changed input: the frame names the line verify names and shows the event before it) / 2; --follow draws an appended line within a second, replays a truncated strand from the start, waits out a removed one and follows a rotated one. A frame at a terminal keeps the rows that fit. Prose kept to the repo's word list.
…(unset in CI) The replay-equals-verify check as a helper: every document's sha256 is its line's stance digest and the replay ends where verify does. The three example personas run it always; strands named in the environment (paths joined as in PATH) run it on demand.
`probbit monitor --demo [--once] [--plain]` plays the week `live --demo week` writes (the tutor, seed 2): live::week writes it to a temporary strand, read back and removed, and the monitor replays it, at a terminal paced 1 s per hour and each night in 2 s; piped, or with --once, its last frame. The last frame equals the pinned frame of the fixture week but for the footer (tested); the embedded tutor is examples/persona/tutor.yaml (tested). Follow mode and the demo share one in-place redraw that keeps the rows a terminal fits.
…stream, /doc/N A std TcpListener bound to 127.0.0.1 (no other address; requests addressed to another host are refused) serves one page embedded in the binary (monitor.html, 21 KB, styles and script inline), its server-sent events (the layout, the latest frame, a frame per event, a heartbeat every 15 s) and /doc/N, event N's stance document as probbit live printed it. The strand is followed with the replay --follow uses; --demo --serve plays the week over and over. --open starts the default browser, best effort. Tests: the page, the documents byte for byte, the stream (a line appended is pushed), the host guard, a port in use, the flag errors.
… 127.0.0.1, the demo What the board shows, --once / --follow / --plain, --serve's routes (/, /events and its frame fields, /doc/N), the loopback bind and the host guard, the demo week, the exit codes; the command table and the intro point to it.
A failed assert in the --serve test left its server running (the child outlived the test process). The children of the --follow and --serve tests are now killed on drop, passing or not.
…d, a still of the page README: a section after Live: probbit monitor in three lines, the demo command and docs/probbit-monitor.gif (the tutor's week in the browser, 1280x720, 14.9 s, 2.5 MB), and the documentation map. CHEATSHEET: the monitor rows and exit codes. agents.md: a person can watch the individual behind a strand_path. docs/probbit-monitor.png: the page at event 21, a failure turn (no_jokes_on_loss bound).
… week starts over without an empty board The note (a quiet night, a truncated or rotated strand) sat on its own line under the header and pushed the board down while it showed; it is now part of the header row (on a narrow page it wraps there). When the demo week started over, the page drew the empty board for a moment before event 1; the week now goes from its last event straight to event 1. docs/probbit-monitor.gif captured again (1280x720, 14.9 s, 1.9 MB).
…y file removed at once) The help, the module notes, the CHANGELOG and docs/persona.md §5.8 said the monitor writes nothing; with --demo the week goes through a temporary strand (written by live::week, read back, removed). They now say it changes no file and name the temporary one. The CHANGELOG lines are wrapped again.
A strand read from its header is replayed before the board shows its last event: 10,000 events take about 3.5 s, and the page said 'waiting for the strand' meanwhile (the terminal stayed blank). The replay now draws the board every 250 ms on the way, with the note 'replaying the strand from its header: the board catches up': --serve publishes those frames (and the documents so far), --follow redraws at a terminal. Unit test: a replay published at every event (6 frames for 5 events, the last without the note) and at none on the way (1 frame). Checked by hand on a 10,000-event strand: 14 frames with the note over the page's event stream, then event 10000; 16 redraws at a pty. docs/persona.md §5.8: one sentence.
… in the browser - `--open` alone serves the page as `--serve --open` does: `probbit monitor --demo --open` plays the tutor's week in the browser (it exited 2 with "--open goes with --serve"). Help, usage line, README command, cheat sheet, docs/persona.md §5.8 and the CHANGELOG say so; a CLI test serves the demo with --open. - /events heartbeat tested: a 100 ms beat in a unit test (15 s when served), before the strand has replayed and after a frame. - Each example persona's scripted week (seed 2) replays to its digests (unit test). - §5.8: events that land within one 100 ms poll, or while a page falls behind, come as the latest frame.
CHANGELOG: one 0.8.0 section, drives first, then the monitor. README: Live, Drives, Watch it live. The monitor's learned rows take the levels of `pursue` from the drives block's goals (describe hides that trait), in the terminal and on the page; a unit test replays a real drives strand to its digests and checks the drives and learned rows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
probbit monitor: watch an individual's inner state live, inside the probbit binary, with no dependencies: as bars in theterminal, or as a page in the browser served from 127.0.0.1.
It replays a strand (the header holds the persona, the initial state and the engine version; one line per event holds the
inputs) with the rules of
probbit live verify, recomputing every stance document from the strand alone, so it works for anystrand on any machine and needs no extra log. It says "replay verified" when the chain checks, and names the line when one
differs. It changes no file (the demo's week goes through a temporary one, removed at once) and sends nothing anywhere.
Done against the done-when list below, CI green on ubuntu, macOS, Windows and wasm at the head; a draft until it is reviewed.
probbit monitor STRAND [--follow] [--once] [--plain] [--fps N] [--serve] [--open] [--port N]andprobbit monitor --demo [--once] [--plain] [--serve] [--open] [--port N](--openserves the page as--servedoes andstarts the browser), with help in the style of the other subcommands
and exit codes 0 (every line replays), 1 (a line differs: named in the frame, which shows the event before it), 2 (a bad
flag, a port that cannot be had, an unreadable file, a file that is not a strand). Terminal view: one row per trait (its
levels as segments with their odds, the level taken highlighted, its phrase), moods with a sparkline of the last 50 events,
senses (flags, levels, numbers, the clock, history features), habits (bound ones marked, the violations counter), learned
deltas as centred bars within the cap, drives rows when a document carries
pursue/drives(feature-detected), the stanceline and why.
--plainis plain ASCII; colour follows the existing theme rules (NO_COLOR,PROBBIT_THEME=plain,TERM=dumb).live::Replay(open the header, step one line, summary);verifyis aloop over it, and the existing
livetests pass unchanged. Unit tests replay strands of the three example personas (eachone's scripted
--demo week, seed 2, and a strand that lights every input in turn) and check each monitor document's sha256against the line's
stancedigest, on every line, and that the replay ends whereverifydoes.--followdraws anappended line within a second (tested), replays a truncated strand from the start with a warning, waits out a removed one
and follows a rotated one (tested).
--servebinds 127.0.0.1 with stdTcpListenerand no other address (there is no host flag;--host/
--bindexit 2 saying so), port 0 by default (a free one) or--port N; the URL is the line on stdout. It answers GETrequests addressed to
127.0.0.1:PORTorlocalhost:PORT(others get 403, so a page of another site that resolves its nameto 127.0.0.1 cannot read the documents):
/the page (one file embedded in the binary, 21 KB, styles and script inline,a Content-Security-Policy that lets it connect to nothing but its own server),
/eventsserver-sent events (the layout,the latest frame, then a frame per event; a heartbeat comment after 15 quiet seconds; events that land within one 100 ms
poll, or while a page falls behind, come as the latest frame),
/doc/Nevent N's stance document asprobbit liveprinted it (the latest 10,000 kept). The strand is followed with the same replay as--follow; while along strand replays from its header (10,000 events: about 3.5 s), the page and the terminal draw the board every 250 ms
with a note.
--openstarts the default browser (BROWSER, elseopen/cmd /c start/xdg-open), best effort: abrowser that does not start fails nothing. A thread per connection, at most 64 at once. Nothing beyond std, so the same code
on macOS, Linux and Windows; the server tests run in the existing CI matrix.
--demoin the terminal (paced at a terminal;--demo --plain --oncedeterministic and tested) andprobbit monitor --demo --open(or--servewithout the browser), the week paced 1 s per hour and each night in 2 s,over and over, for the page (a week that starts over goes from its last event straight to event 1; the night's note sits
in the header row, so the board holds still).
tests/monitor.rs: help; a--once --plainframe pinned byte for byte on the tutor's demo week (the lastevent and a failure turn); exit codes;
--followpickup, truncation, removal, rotation; and the server: GET / (the page,under 40 KB, no URL in it but the SVG namespace),
/doc/1..3equal toprobbit live's stdout lines byte for byte, 404s,the host guard (403),
/events(the layout, then the latest frame with that document; a line appended to the strand ispushed as the next frame and
/doc/4serves it), a port in use (exit 2),--openwith a browser that does not start(the server runs on),
--demo --openserving the demo's page and stream, and the flag errors (7 tests). Unit tests (9):replay equals verify on the three personas' scripted weeks and on strands that light every input, plus any strands named
in
PROBBIT_MONITOR_STRANDS(a copy of a real 14-event strand passes); a hand-written document withdrives/pursuedraws its rows, and passes through to the page's frames as it is (the page draws it too, checked in headless Chrome: no
script error); a long replay is published on the way; the event stream's heartbeat (a 100 ms beat in the test); the page's
layout follows the persona's order; the embedded tutor equals the example; cell rounding.
--serveroutes and frame fields, the host guard, the demo, exit codes) and its row in the command table; README "Watch itlive" right after "Live" (three lines,
probbit monitor --demo --open, the GIF) and the documentation map; the cheatsheet's monitor rows and exit codes; docs/agents.md (a person can watch the individual behind a
strand_path).docs/probbit-monitor.gif: the tutor's week in the browser, 1280x720, 14.9 s, 1,895,852 bytes (headless Chrome screenshots
of
--demo --serveevery 400 ms, assembled with ffmpeg at 10 frames/s, a 128-colour palette); docs/probbit-monitor.png:the page at event 21, a failure turn (
no_jokes_on_lossbound, humour none 1.00).cargo test --release --workspacegreen locally (macOS arm64, 54a1794: every suite, probbit-decide'sacceptance 19/19; that crate is unchanged, and its wall-clock asserts need its
CIthreshold on a machine at load 50+);clippy: 0 new warnings; no new dependencies (Cargo.lock unchanged); release binary 2,317,328 bytes vs 2,190,320 on main,
+127,008 bytes (macOS arm64). CI at 54a1794: green on every job (tests on ubuntu, macOS and Windows, wasm, the four
release targets).
main.rschanges are one module, one match arm and one usage line.