diff --git a/CHANGELOG.md b/CHANGELOG.md index ce405aa..ef4f706 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ All notable changes to this project are documented here. The format follows Boolean flags; keyword mode remains local. The classifier timeout defaults to 300 ms in both modes. - The README distinguishes enforced stance habits from model obedience, limits replay claims to measured checks, and links to the changelog for release notes. Install and quickstart paths stay in place. +- `probbit monitor --help`, the man page and the docs call what the monitor draws "internal state" (was "inner state"); + no behaviour or output format changes. ### Fixed diff --git a/README.md b/README.md index 73cb75a..230e0b4 100644 --- a/README.md +++ b/README.md @@ -224,7 +224,7 @@ One line, no sudo, the archive's SHA-256 checked before anything is installed. T | npm (Node 18+) | `npm i -g probbit` | | by hand | archives for Linux x86_64 (glibc or static musl), Linux arm64 (static), macOS (Apple silicon and Intel) and Windows x86_64 on the [Releases page](https://github.com/BitmapAsset/probbit/releases), each with a `.sha256` beside it | -npm may print an `allow-scripts` warning: the package's only install script downloads the prebuilt binary for your platform +npm may print a warning about install scripts: the package's only install script downloads the prebuilt binary for your platform and checks its SHA-256. If npm blocks the script, the binary is fetched the first time you run `probbit` instead. The shell installer defaults to `~/.local/bin`, without replacing a system-wide installation. Set @@ -766,7 +766,7 @@ rail, and the header above the face says which agent, on which host, in which la labels in a sidecar next to each strand (`nova.labels.json`), outside the strand and its digests: `probbit live ... --strand nova.strand --label agent=Nova --label lane=support` writes them, the OpenClaw plugin writes them per lane, and `probbit monitor old.strand --label agent=Nova --open` labels a strand recorded before them without rewriting it. -See [the monitor guide](docs/persona.md#58-monitor-watch-an-individuals-inner-state) for the data and replay boundaries. +See [the monitor guide](docs/persona.md#58-monitor-watch-an-individuals-internal-state) for the data and replay boundaries. **The monitor as a Mac app.** On a Mac the same page opens in its own window: download `probbit-Monitor--macos.zip` from the [release page](https://github.com/BitmapAsset/probbit/releases), unzip it, move **probbit Monitor** to Applications, diff --git a/docs/adapters.md b/docs/adapters.md index 2cd15d3..ee9ecab 100644 --- a/docs/adapters.md +++ b/docs/adapters.md @@ -29,7 +29,7 @@ the receipt per decision and the bounded state the same mechanism drives. | LangChain / LangGraph | [examples/hosts/langchain/stance_callbacks.py](../examples/hosts/langchain/stance_callbacks.py) | `BaseCallbackHandler.on_tool_end` collects; a Runnable in front of the model prepends the stance `SystemMessage` (`stance_messages` for a LangGraph node) | `--offline` smoke; the LangChain path not run here | | any Node loop | [examples/node/stance-host.mjs](../examples/node/stance-host.mjs) | `await host.turn(toolTexts)`; `verify()` | `node --test examples/node/stance-host.test.mjs` against the release binary | | Vercel AI SDK | [examples/hosts/vercel-ai/stance.mjs](../examples/hosts/vercel-ai/stance.mjs) | `prepareStep` rebuilds the step's system message from `host.turn`; `onToolExecutionEnd` collects results | not run here (needs the `ai` package, a provider and a key) | -| MCP hosts (Claude Code, Codex CLI, Cursor, mcporter) | `probbit mcp` | tools `probbit_live_event`, `probbit_live_verify`, `probbit_persona_turn`, ... ([agents.md](agents.md)) | real calls from Claude Code and Codex CLI (agents.md) | +| MCP hosts (Claude Code, Codex CLI, Cursor, mcporter) | `probbit mcp` | tools `probbit_live_event`, `probbit_live_verify`, `probbit_persona_turn`, ... ([agents.md](agents.md)) | real calls from Claude Code; for Codex CLI the entry it writes, no model call (agents.md) | | OpenClaw | [plugins/openclaw](../plugins/openclaw/README.md) (`probbit-stance`, `openclaw plugins install npm:probbit-stance --accept-capabilities`) | `before_prompt_build`: one event per user message in the listed sessions, the block injected into the turn, the footer line in the chat; `before_tool_call`: shadow gate; `after_tool_call` (with `sensesMode` shadow or feed, since plugin 0.2.0): counts failed tool calls for the `tool_fail` reading | 165 tests against a mocked host built from the 2026.9.7 SDK types and the real binary; a build of this plugin runs live on the author's own agent since 2026-10-06 | "Not run here" means exactly that: the file is written to the framework's documented contract and compiles, but this diff --git a/docs/monitor-app.md b/docs/monitor-app.md index 95362f4..e768589 100644 --- a/docs/monitor-app.md +++ b/docs/monitor-app.md @@ -2,7 +2,7 @@ `probbit monitor STRAND --open` serves the monitor page on 127.0.0.1 and opens it in the browser. **probbit Monitor** is the same page in its own Mac window: an app you open from Finder, the Dock or Launchpad, with the probbit binary inside it. The -page itself is the one described in [persona.md §5.8](persona.md#58-monitor-watch-an-individuals-inner-state); what it looks +page itself is the one described in [persona.md §5.8](persona.md#58-monitor-watch-an-individuals-internal-state); what it looks like: [probbit-monitor.png](probbit-monitor.png). ## Get it @@ -42,7 +42,7 @@ either kind opens like any app. A copy you build yourself (below) has no quarant (`probbit monitor --demo week`), no strand needed. - **Several strands, a folder**: the app passes every file you open, and a folder as `--dir FOLDER`, to its probbit. The bundled probbit (0.13.0) serves them all on one page, with a rail on the left to switch between strands and each strand's - labels ([persona.md §5.8](persona.md#58-monitor-watch-an-individuals-inner-state)). A probbit that watches one strand at a + labels ([persona.md §5.8](persona.md#58-monitor-watch-an-individuals-internal-state)). A probbit that watches one strand at a time (0.12.1 and earlier, if you build the app around one) refuses that; the app then shows the first strand you chose (for a folder, its most recently changed `*.strand` file) and says so under the window title. - **Integrity** (engine 0.14.0+, a persona with the identity self keys, [persona.md §5.9](persona.md#59-integrity-the-drift-from-the-declared-self-rfc-0014)): diff --git a/docs/persona.md b/docs/persona.md index 36d1057..62280c2 100644 --- a/docs/persona.md +++ b/docs/persona.md @@ -21,7 +21,7 @@ This document is normative for the file format, the compilation, the stance docu CLI, `probbit mcp` (tools `probbit_persona_init`, `probbit_persona_turn`), the Python wrapper (`probbit.persona_init`, `persona_turn`, `persona_replay`) and the browser module (probbit-wasm ops 4 and 5). `probbit live` (section 5.7, live.rs) keeps an individual running on a clock, with learning (section 2.8) and a replayable log; `probbit monitor` (section 5.8, monitor.rs) -draws its inner state live from that log. The example personas and their goldens are in +draws its internal state live from that log. The example personas and their goldens are in [examples/persona/](../examples/persona/). An independent reference implementation of this format (Python) gives the same documents byte for byte on every example turn (section 5.3). @@ -1792,7 +1792,9 @@ a line that differs, 5 at a line with a field or line kind this engine does not a divergence), 2 for a bad flag or an unreadable file. `control` 0 when the line is appended, 2 for a bad field or an invalid move, 4 when the lock is held or the individual is retired. -### 5.8 Monitor: watch an individual's inner state + + +### 5.8 Monitor: watch an individual's internal state `probbit monitor STRAND` draws an individual's declared state as live terminal bars, or as a compact browser Activity Monitor. It replays the strand with the rules of `live verify` (the two share one replay), recomputing every stance document from the @@ -2074,7 +2076,7 @@ previous event, the restart included). `probbit_live_event` (MCP) and Python's ` | `probbit live PERSONA [--seed N \| --state FILE] [--strand FILE] [--events FILE [--watch]] [--clock real\|fixed]` | a resident individual: JSONL events in, one stance per event out, `elapsed_hours` stamped by the clock, the life logged to a strand (section 5.7); `--state` is rewritten after every event | | `probbit live PERSONA --demo week [--seed N] [--strand FILE] [--plain]` | one individual's scripted week on the fixed clock: learning to its cap, a quiet night, habits that hold (section 5.7) | | `probbit live verify STRAND [--from-checkpoint] [--chain] [--actions FILE]` | replay a strand from its header alone: ok, the earliest line that differs (exit 1), or the earliest line with a field or line kind this engine does not know (`unsupported`, exit 5: a newer engine's strand, not a divergence); with `--actions`, also the earliest turn whose host action differs from the level its stance released; with `--chain`, a segment and every previous segment file (exit 6: one is missing) (section 5.7) | -| `probbit monitor STRAND [--follow] [--once] [--plain] [--fps N] [--serve] [--open] [--port N]`, `probbit monitor --demo [...]` | watch an individual's inner state: the strand replayed as live bars in the terminal, or as a page on 127.0.0.1 (section 5.8) | +| `probbit monitor STRAND [--follow] [--once] [--plain] [--fps N] [--serve] [--open] [--port N]`, `probbit monitor --demo [...]` | watch an individual's internal state: the strand replayed as live bars in the terminal, or as a page on 127.0.0.1 (section 5.8) | A script is a JSON list of per-turn input objects (or `{"turns": [...]}`; a turn may be `{"inputs": {...}, ...}`). Exit codes (`live`'s are in section 5.7, `monitor`'s in section 5.8): diff --git a/docs/probbit-flow.png b/docs/probbit-flow.png index d08b50a..2d48409 100644 Binary files a/docs/probbit-flow.png and b/docs/probbit-flow.png differ diff --git a/docs/probbit-flow.svg b/docs/probbit-flow.svg index 121e5f7..748f8a9 100644 --- a/docs/probbit-flow.svg +++ b/docs/probbit-flow.svg @@ -20,7 +20,7 @@ - 2 · THE probbit PROCESSOR — one Rust binary, zero dependencies, built for macOS, Linux and Windows on x86_64 and arm64 + 2 · THE probbit PROCESSOR — one Rust binary, built for macOS, Linux and Windows on x86_64 and arm64 diff --git a/docs/probbit.1 b/docs/probbit.1 index 3829e1e..24aa2e8 100644 --- a/docs/probbit.1 +++ b/docs/probbit.1 @@ -455,7 +455,7 @@ probbit check agent.yaml \-\-props rules.yaml \-\-strand day1.strand \-\-strand .fi .RE .SS monitor -an individual's inner state, live: terminal bars or a page on 127.0.0.1 +an individual's internal state, live: terminal bars or a page on 127.0.0.1 .PP .nf \fBprobbit\fR monitor STRAND [\-\-follow] [\-\-once] [\-\-plain] [\-\-fps N] [\-\-serve] @@ -467,7 +467,7 @@ an individual's inner state, live: terminal bars or a page on 127.0.0.1 [\-\-open] [\-\-port N] .fi .PP -Watch an individual's inner state (docs/persona.md \[u00A7]5.8): replays the strand (`probbit live \-\-strand` writes it) with the rules of `probbit live verify`, recomputing every stance document from the strand alone, and draws the latest event as horizontal bars: the stance (each trait's levels with their reported odds, the level taken highlighted, the phrase it says), the moods with a sparkline of the last 50 events, the senses (the event's inputs, the history features), the habits in force and the ones that bound, the learned deltas, the drives when the documents carry them, and the stance line. +Watch an individual's internal state (docs/persona.md \[u00A7]5.8): replays the strand (`probbit live \-\-strand` writes it) with the rules of `probbit live verify`, recomputing every stance document from the strand alone, and draws the latest event as horizontal bars: the stance (each trait's levels with their reported odds, the level taken highlighted, the phrase it says), the moods with a sparkline of the last 50 events, the senses (the event's inputs, the history features), the habits in force and the ones that bound, the learned deltas, the drives when the documents carry them, and the stance line. .PP It changes no file (\-\-demo: its week goes through a temporary one, removed at once) and sends nothing anywhere. .PP diff --git a/docs/receipts.md b/docs/receipts.md index 464c712..faa1762 100644 --- a/docs/receipts.md +++ b/docs/receipts.md @@ -63,9 +63,10 @@ run, not pre-registered bars. The registered bars and their confidence intervals ## What the receipt proves, and what it does not -It proves **what the engine decided and from which inputs**, for every event, with a chain that detects any edit and a -replay anyone can run with the public binary. With the host's block log (`--blocks`, or `build_block` of the record for a -host that uses this module's block) it shows **what was put in front of the model**. With the host's action log +It proves **what the engine decided and from which inputs**, for every event, with a replay anyone can run with the public +binary: an edit to a line of the strand is found (the replay names the earliest line that differs); a log rewritten from its +first line is not, unless its head digest was kept somewhere else. With the host's block log (`--blocks`, or `build_block` +of the record for a host that uses this module's block) it shows **what was put in front of the model**. With the host's action log (`--actions`) it ties **what the agent then did** to the level its stance had released. It does not prove that the model obeyed the stance, and it says nothing about the words the model wrote. It records the diff --git a/llms-full.txt b/llms-full.txt index e6d7083..852b2ef 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -236,7 +236,7 @@ One line, no sudo, the archive's SHA-256 checked before anything is installed. T | npm (Node 18+) | `npm i -g probbit` | | by hand | archives for Linux x86_64 (glibc or static musl), Linux arm64 (static), macOS (Apple silicon and Intel) and Windows x86_64 on the [Releases page](https://github.com/BitmapAsset/probbit/releases), each with a `.sha256` beside it | -npm may print an `allow-scripts` warning: the package's only install script downloads the prebuilt binary for your platform +npm may print a warning about install scripts: the package's only install script downloads the prebuilt binary for your platform and checks its SHA-256. If npm blocks the script, the binary is fetched the first time you run `probbit` instead. The shell installer defaults to `~/.local/bin`, without replacing a system-wide installation. Set @@ -778,7 +778,7 @@ rail, and the header above the face says which agent, on which host, in which la labels in a sidecar next to each strand (`nova.labels.json`), outside the strand and its digests: `probbit live ... --strand nova.strand --label agent=Nova --label lane=support` writes them, the OpenClaw plugin writes them per lane, and `probbit monitor old.strand --label agent=Nova --open` labels a strand recorded before them without rewriting it. -See [the monitor guide](docs/persona.md#58-monitor-watch-an-individuals-inner-state) for the data and replay boundaries. +See [the monitor guide](docs/persona.md#58-monitor-watch-an-individuals-internal-state) for the data and replay boundaries. **The monitor as a Mac app.** On a Mac the same page opens in its own window: download `probbit-Monitor--macos.zip` from the [release page](https://github.com/BitmapAsset/probbit/releases), unzip it, move **probbit Monitor** to Applications, @@ -1053,7 +1053,7 @@ This document is normative for the file format, the compilation, the stance docu CLI, `probbit mcp` (tools `probbit_persona_init`, `probbit_persona_turn`), the Python wrapper (`probbit.persona_init`, `persona_turn`, `persona_replay`) and the browser module (probbit-wasm ops 4 and 5). `probbit live` (section 5.7, live.rs) keeps an individual running on a clock, with learning (section 2.8) and a replayable log; `probbit monitor` (section 5.8, monitor.rs) -draws its inner state live from that log. The example personas and their goldens are in +draws its internal state live from that log. The example personas and their goldens are in [examples/persona/](../examples/persona/). An independent reference implementation of this format (Python) gives the same documents byte for byte on every example turn (section 5.3). @@ -2824,7 +2824,9 @@ a line that differs, 5 at a line with a field or line kind this engine does not a divergence), 2 for a bad flag or an unreadable file. `control` 0 when the line is appended, 2 for a bad field or an invalid move, 4 when the lock is held or the individual is retired. -### 5.8 Monitor: watch an individual's inner state + + +### 5.8 Monitor: watch an individual's internal state `probbit monitor STRAND` draws an individual's declared state as live terminal bars, or as a compact browser Activity Monitor. It replays the strand with the rules of `live verify` (the two share one replay), recomputing every stance document from the @@ -3106,7 +3108,7 @@ previous event, the restart included). `probbit_live_event` (MCP) and Python's ` | `probbit live PERSONA [--seed N \| --state FILE] [--strand FILE] [--events FILE [--watch]] [--clock real\|fixed]` | a resident individual: JSONL events in, one stance per event out, `elapsed_hours` stamped by the clock, the life logged to a strand (section 5.7); `--state` is rewritten after every event | | `probbit live PERSONA --demo week [--seed N] [--strand FILE] [--plain]` | one individual's scripted week on the fixed clock: learning to its cap, a quiet night, habits that hold (section 5.7) | | `probbit live verify STRAND [--from-checkpoint] [--chain] [--actions FILE]` | replay a strand from its header alone: ok, the earliest line that differs (exit 1), or the earliest line with a field or line kind this engine does not know (`unsupported`, exit 5: a newer engine's strand, not a divergence); with `--actions`, also the earliest turn whose host action differs from the level its stance released; with `--chain`, a segment and every previous segment file (exit 6: one is missing) (section 5.7) | -| `probbit monitor STRAND [--follow] [--once] [--plain] [--fps N] [--serve] [--open] [--port N]`, `probbit monitor --demo [...]` | watch an individual's inner state: the strand replayed as live bars in the terminal, or as a page on 127.0.0.1 (section 5.8) | +| `probbit monitor STRAND [--follow] [--once] [--plain] [--fps N] [--serve] [--open] [--port N]`, `probbit monitor --demo [...]` | watch an individual's internal state: the strand replayed as live bars in the terminal, or as a page on 127.0.0.1 (section 5.8) | A script is a JSON list of per-turn input objects (or `{"turns": [...]}`; a turn may be `{"inputs": {...}, ...}`). Exit codes (`live`'s are in section 5.7, `monitor`'s in section 5.8): diff --git a/plugins/openclaw/README.md b/plugins/openclaw/README.md index 003da16..ad3f622 100644 --- a/plugins/openclaw/README.md +++ b/plugins/openclaw/README.md @@ -3,7 +3,7 @@ A [probbit](https://github.com/BitmapAsset/probbit) individual beside your OpenClaw agent. In the sessions you list, every user message becomes one engine event: the plugin reads the message into the persona's flags, runs `probbit live`, and puts the resulting stance block into the turn. The model writes every word; the stance says how. Every event is appended -to a strand that `probbit live verify` replays byte for byte, and `probbit monitor` shows the individual's inner state as +to a strand that `probbit live verify` replays byte for byte, and `probbit monitor` shows the individual's internal state as it changes. ![probbit monitor on a strand this plugin wrote](docs/monitor.png) diff --git a/probbit-cli/src/main.rs b/probbit-cli/src/main.rs index 0523736..075528c 100644 --- a/probbit-cli/src/main.rs +++ b/probbit-cli/src/main.rs @@ -357,11 +357,11 @@ pub(crate) static COMMANDS: &[Command] = &[ examples: &["probbit check examples/persona/dispatch-policy.yaml --props examples/persona/dispatch-props.json", "probbit check agent.yaml --props rules.yaml --strand day1.strand --strand day2.strand --json > check.json"], run: check_cmd }, - Command { name: "monitor", aliases: &[], group: "monitor", summary: "an individual's inner state, live: terminal bars or a page on 127.0.0.1", + Command { name: "monitor", aliases: &[], group: "monitor", summary: "an individual's internal state, live: terminal bars or a page on 127.0.0.1", usage: &["monitor STRAND [--follow] [--once] [--plain] [--fps N] [--serve] [--open] [--port N]", "monitor STRAND [--label KEY=VALUE]... [STRAND [--label KEY=VALUE]...]... [--dir DIR] [--serve] [--open] [--port N]", "monitor --demo [week|drives] [--once] [--plain] [--serve] [--open] [--port N]"], - about: "Watch an individual's inner state (docs/persona.md §5.8): replays the strand (`probbit live --strand` writes it) with the rules of `probbit live verify`, recomputing every stance document from the strand alone, and draws the latest event as horizontal bars: the stance (each trait's levels with their reported odds, the level taken highlighted, the phrase it says), the moods with a sparkline of the last 50 events, the senses (the event's inputs, the history features), the habits in force and the ones that bound, the learned deltas, the drives when the documents carry them, and the stance line.\nIt changes no file (--demo: its week goes through a temporary one, removed at once) and sends nothing anywhere.", + about: "Watch an individual's internal state (docs/persona.md §5.8): replays the strand (`probbit live --strand` writes it) with the rules of `probbit live verify`, recomputing every stance document from the strand alone, and draws the latest event as horizontal bars: the stance (each trait's levels with their reported odds, the level taken highlighted, the phrase it says), the moods with a sparkline of the last 50 events, the senses (the event's inputs, the history features), the habits in force and the ones that bound, the learned deltas, the drives when the documents carry them, and the stance line.\nIt changes no file (--demo: its week goes through a temporary one, removed at once) and sends nothing anywhere.", before: &[("modes", "one frame on stdout, then exit (--once; the default without --follow) · the terminal, redrawn as the strand grows (--follow) · a page in the browser (--serve; --open also opens it).")], flags: &[&[ Flag { name: "--follow", arg: "", help: "keep watching: lines appended to the strand are replayed and drawn within a second (a line counts once its newline is written); a truncated or rotated strand is replayed from the start, with a warning; Ctrl-C quits" }, diff --git a/probbit-cli/src/monitor.rs b/probbit-cli/src/monitor.rs index 2340a50..d5c8137 100644 --- a/probbit-cli/src/monitor.rs +++ b/probbit-cli/src/monitor.rs @@ -1,4 +1,4 @@ -//! `probbit monitor STRAND` (docs/persona.md §5.8): watch an individual's inner state as live horizontal bars. The monitor +//! `probbit monitor STRAND` (docs/persona.md §5.8): watch an individual's internal state as live horizontal bars. The monitor //! replays the strand with `live::Replay`, the rules `probbit live verify` uses, so it recomputes every stance document from //! the strand alone (no other log, any strand, any machine) and says whether the replay checks. It draws the latest event: the //! stance (each trait's levels as segments with their exact odds, the level taken highlighted, the phrase it says), the moods