Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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-<version>-macos.zip`
from the [release page](https://github.com/BitmapAsset/probbit/releases), unzip it, move **probbit Monitor** to Applications,
Expand Down
2 changes: 1 addition & 1 deletion docs/adapters.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions docs/monitor-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)):
Expand Down
8 changes: 5 additions & 3 deletions docs/persona.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down Expand Up @@ -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
<a id="58-monitor-watch-an-individuals-inner-state"></a>

### 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
Expand Down Expand Up @@ -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):
Expand Down
Binary file modified docs/probbit-flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/probbit-flow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/probbit.1
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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
Expand Down
7 changes: 4 additions & 3 deletions docs/receipts.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 7 additions & 5 deletions llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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-<version>-macos.zip`
from the [release page](https://github.com/BitmapAsset/probbit/releases), unzip it, move **probbit Monitor** to Applications,
Expand Down Expand Up @@ -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).

Expand Down Expand Up @@ -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
<a id="58-monitor-watch-an-individuals-inner-state"></a>

### 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
Expand Down Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion plugins/openclaw/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading
Loading