diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8bb46f7..5b14036 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: shell: bash run: | cargo run --release -p probbit-cli -- demo --tasks 12 | cargo run --release -p probbit-cli -- decide --pretty - cargo run --release -p probbit-cli -- demo --tasks 300 | cargo run --release -p probbit-cli -- decide --budget-ms 300 + cargo run --release -p probbit-cli -- demo --tasks 300 | cargo run --release -p probbit-cli -- decide --budget-ms 1500 - name: processor spec sheet (probbit stats) run: cargo run --release -p probbit-cli -- stats --pretty - name: agent_router example diff --git a/AGENTS.md b/AGENTS.md index 5f1cea6..5490601 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -68,5 +68,5 @@ secrets). A command that does not print what this file says it prints is a bug i ## For contributors -Build: `cargo build --release -p probbit-cli` (Rust 1.78+, no external crates). Test: `cargo test --release --workspace`. +Build: `cargo build --release -p probbit-cli` (Rust 1.78+; default: `libm` for amplitude-register math; `nostd` adds `hashbrown` and `portable-atomic`). Test: `cargo test --release --workspace`. Docs and metadata changes: keep every claim tied to a measurement in BENCHMARKS.md or a test. See CONTRIBUTING.md. diff --git a/BENCHMARKS.md b/BENCHMARKS.md index 3509cd3..94ec3a1 100644 --- a/BENCHMARKS.md +++ b/BENCHMARKS.md @@ -1385,8 +1385,7 @@ quantity; AgentDojo v1.1.1 to v1.2.2. `bench/agentdojo/experiments/rerun.sh` rec does the same for E3 from `e3/tables/episodes-d.jsonl`. **Reproductions.** REPRODUCE.md says how; a reproduction report (issue template) is the place to say what you got. -Standing: the CI job `agentdojo-tables` recomputes these tables on GitHub's Ubuntu and macOS runners on every push and -pull request and fails unless they are byte-identical to the committed ones (a machine that is not the author's, not a +Standing: the CI job `agentdojo-tables` recomputes these tables on GitHub's Ubuntu and macOS runners on pushes to `main` and on pull requests and fails unless they are byte-identical to the committed ones (a machine that is not the author's, not a person). By people outside this project: none yet. ## §15 The engine's own expectation and the exact trajectory (RFC 0009 engine side; 0.12.0; one registered run, 2026-10-22) diff --git a/CHANGELOG.md b/CHANGELOG.md index c799599..3def44a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project are documented here. The format follows ## Unreleased +## 0.14.1 - Unreleased + +### Fixed + +- Correct current dependency claims: the default build uses `libm` for amplitude-register math; `nostd` adds + `hashbrown` and `portable-atomic`. Offline source builds require cached dependencies. +- Give the CI 300-task demo a 1500 ms budget (previously 300 ms) for slow runners; the same pipeline must still succeed. +- Correct the OpenClaw plugin test count in the adapter guide to 160 (107 direct tests and 53 classifier cases). +- Add docs-bundle regeneration to the release PR checklist, with `scripts/generate_llms_full.py` and its `--check` mode; + add the post-publication Pages front-door version and JSON-LD `softwareVersion` update on `gh-pages`. +- Match the AgentDojo benchmark reproduction wording to CI: pushes to `main` and pull requests. + ## 0.14.0 - 2026-10-31 0.14.0 makes the persona layer a library crate, `probbit-persona` (std, and `no_std` + `alloc` checked on diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 12207e2..207dbe5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ rules that keep its claims honest. ## Build and test ``` -cargo build --release --workspace # no network needed: there are no external crates +cargo build --release --workspace # offline once the dependencies below are cached cargo test --release --workspace # unit, integration, regression and exact-oracle tests cargo run --release -p probbit-cli -- demo --tasks 12 | cargo run --release -p probbit-cli -- decide --pretty ``` @@ -30,7 +30,9 @@ committed man page: `cargo run -p probbit-cli -- man > docs/probbit.1` (test `co ## Ground rules -- **No external crates on the shipped path.** `cargo build` must keep working offline. +- **Keep dependencies small.** The default build uses one third-party crate, `libm`, for amplitude-register math. + The `nostd` build adds `hashbrown` and `portable-atomic` (and their transitive dependencies). + `cargo build --offline` works with dependencies cached. - **Every number in the docs points at something runnable**: a test, an example under `examples/`, or a script under `bench/`. A change that moves a number updates the table it lives in (`BENCHMARKS.md`, `USE-CASES.md`, `docs/probbit-ir-json.md`) with the machine, the load diff --git a/README.md b/README.md index 223f20f..bbb7ed9 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A personality, mood and memory layer for AI agents, on an exact p-bit decision engine.
An AI persona that lives outside the model: every turn, simulated p-bits on a CPU settle the agent's stance under its habits, give the exact odds, and log a replayable, verifiable record. The same engine plans under hard rules and - refuses when it can't vouch. CLI, MCP server, OpenClaw plugin, npm, Python, wasm. Zero-dependency Rust. + refuses when it can't vouch. CLI, MCP server, OpenClaw plugin, npm, Python, wasm. Rust; one default third-party crate, libm.

@@ -32,7 +32,8 @@ curl -fsSL https://raw.githubusercontent.com/BitmapAsset/probbit/main/install.sh | sh ``` Linux and macOS, no sudo, the archive's SHA-256 checked first. Windows, npm and the from-source build: [Install](#install). -One binary of 3 to 4 MB, zero third-party dependencies, nothing phones home. Agents: start at +One binary of 3 to 4 MB; one third-party crate in the default build (`libm`, for amplitude-register math). +The `nostd` build adds `hashbrown` and `portable-atomic`. Nothing phones home. Agents: start at [For AI agents reading this](#for-ai-agents-reading-this), [AGENTS.md](AGENTS.md) and [llms.txt](llms.txt). | **60 PII leaks → 0** | **180,540 plans, counted exactly** | **refused → partial → passed** | @@ -267,7 +268,7 @@ odds with a tiny error bar (see [Known failure modes](BENCHMARKS.md#known-failur A p-bit is a bit that is 0 or 1 with a tunable probability; coupled p-bits sample joint configurations. probbit is quantum-inspired and entirely classical (see "Is this quantum?" below): it runs on the CPU you already have, needs no -network and has zero external crates. The same problem lowers to the QUBO/Ising form a p-bit or annealer chip takes (`probbit-ir`), which is the hardware +network at runtime. The default build uses `libm` for amplitude-register math; `nostd` adds `hashbrown` and `portable-atomic`. The same problem lowers to the QUBO/Ising form a p-bit or annealer chip takes (`probbit-ir`), which is the hardware hand-off for later. ``` @@ -305,8 +306,8 @@ for Linux ARM64 and for x86_64 musl systems such as Alpine. The shell and PowerS downloaded candidate starts successfully before replacing an existing binary; failed checksums leave it unchanged. From source, with Rust 1.78 or later: `cargo install --git https://github.com/BitmapAsset/probbit probbit-cli`, or clone and -`cargo build --release -p probbit-cli` (the binary lands in `target/release/probbit`). Nothing is downloaded after the clone: -there are no external crates. +`cargo build --release -p probbit-cli` (the binary lands in `target/release/probbit`). The default build downloads `libm` for amplitude-register math; `nostd` adds `hashbrown` and `portable-atomic` +(and their transitive dependencies). With dependencies cached, builds work offline. At a terminal, `install.sh` ends with probbit's own hero screen. Platform notes and the installer tests: [PORTABILITY.md](PORTABILITY.md). @@ -349,8 +350,8 @@ $ probbit demo --tasks 300 --hard | probbit decide --budget-ms 1000 # "diagnos (5 runs each on an Apple M4.) Every escalated task's odds are in the output; the decision is left to you. The budget is wall-clock, so a slower machine needs a longer one; `--sweeps N --polish-sweeps M` gives the same output on every machine. -Everything runs with stock stable Rust and **no external crates**, so `cargo build` needs no network (a fresh export builds -`cargo build --release` in 7.82 s and every target in 26-28 s on the M4). +Everything runs with stock stable Rust. The default build uses `libm` for amplitude-register math; `nostd` adds +`hashbrown` and `portable-atomic`. An offline build needs these dependencies cached first. ## Inside the processor @@ -830,7 +831,8 @@ probbit monitor --demo drives --open # synthetic goals/drive scenario Select a channel to inspect its units, range, distribution, source and the engine's `why`. Hold an event while new ones arrive, or follow latest. History means **recorded events, not seconds**. This is declared engine state, not thoughts or CPU/GPU/memory usage. Replay verification, stale event age, held view, paused/retired strand and lost connection are distinct. -Everything is embedded in the CLI: no dependencies, external assets, telemetry or Electron installation. +The monitor UI is embedded in the CLI: no external assets, telemetry or Electron installation. The binary uses `libm`; +`nostd` builds also use `hashbrown` and `portable-atomic`. Several agents on one machine: `probbit monitor nova.strand atlas.strand --open` (or `--dir strands/ --open`) adds a switcher rail, and the header above the face says which agent, on which host, in which lane and session the page shows. Those are labels in a sidecar next to each strand (`nova.labels.json`), outside the strand and its digests: `probbit live ... --strand diff --git a/RELEASING.md b/RELEASING.md index 6b0641c..a56086f 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -22,7 +22,9 @@ the RFC). `probbit-cli/tests/readme_release.rs` fails when the README's current `.github/workflows/bench.yml`, `scripts/bench/test_install_ps1.ps1` and `scripts/tests/test_install_contract.py`; the title of `docs/CHEATSHEET.md`; the strand header example in `docs/persona.md` §5.7; - `CHANGELOG.md`: `## X.Y.Z - `, with an upgrade note wherever an exit code or an output changes; - - the landing page (above). + - the landing page (above); + - regenerate `llms-full.txt` after all source-page edits: `python3 scripts/generate_llms_full.py`, then + `python3 scripts/generate_llms_full.py --check`; include the refreshed bundle in the release PR. Before merging: `git grep -n "X.Y.Z-dev"` finds only recorded test fixtures; `python3 bench/individuality/p0.py check` with the release build gives 0 differences (its corpus is never regenerated); `cargo publish --dry-run @@ -52,7 +54,11 @@ the RFC). `probbit-cli/tests/readme_release.rs` fails when the README's current 6. **crates.io**: `cargo publish --workspace --locked` from the tag, which publishes in dependency order (`probbit-nostd`, `probbit-core`, `probbit-ir`, `probbit-decide`, `probbit-persona`, `probbit-cli`; `probbit-wasm` has `publish = false`). `probbit-nostd` goes first: the engine crates name it as an optional dependency with a version. -7. **Back to development**: `main` moves to the next `-dev` version (`Cargo.toml`, the path dependencies, `Cargo.lock`, +7. **Pages front door**, after publication: on the `gh-pages` branch, update `index.html`'s visible release version + and JSON-LD `softwareVersion` to X.Y.Z. Copy the release's `llms.txt` and regenerated `llms-full.txt` to that branch; + update the page dates and sitemap date. Review and publish that branch separately, then verify the served page text + and JSON-LD both name X.Y.Z. +8. **Back to development**: `main` moves to the next `-dev` version (`Cargo.toml`, the path dependencies, `Cargo.lock`, `docs/probbit.1`); the README goes on naming the released version until the next release PR. ## Rollback diff --git a/REPRODUCE.md b/REPRODUCE.md index 1eb9d70..c232b97 100644 --- a/REPRODUCE.md +++ b/REPRODUCE.md @@ -61,8 +61,8 @@ differs. The committed files: | `tables/strands-verify.tsv` | `40a3124208edfbb3cb35d548df0f7825aa0851800c745c43f1df06af9d8620d3` | `git status --short tables` is empty after a reproduction. The CI job `agentdojo-tables` (`.github/workflows/ci.yml`) does -exactly this on GitHub's Ubuntu and macOS runners on every push and pull request, so the numbers are recomputed on machines -that are not the author's each time the repository changes. That is a standing machine reproduction; it is not a person. +exactly this on GitHub's Ubuntu and macOS runners on pushes to `main` and on pull requests, so the numbers are recomputed on machines +that are not the author's for those CI events. That is a standing machine reproduction; it is not a person. The E3 control (the if-statement arm of BENCHMARKS.md §14) recomputes the same way, from the same venv, in about ten seconds (no probbit binary needed): diff --git a/USE-CASES.md b/USE-CASES.md index eb67383..c92a94e 100644 --- a/USE-CASES.md +++ b/USE-CASES.md @@ -58,7 +58,7 @@ Do not use it when: | Research labs, universities | sample Ising/Potts models with a checkable error bound; teach probabilistic computing | binary pairwise, CSP | **measured** (§1, §3, §4); the most honest fit today | | Teams evaluating Ising / annealing hardware | prototype locally, then hand the model over: `probbit ir` prints a router document's one-hot QUBO form (energy = -log weight); it reads router documents only (a `probbit run` program has no QUBO export yet) | binary pairwise | the lowering exists; **no hardware was run**; rules hold by construction only on probbit's own sampler: a p-bit sampler on the QUBO form leaked infeasible samples at low penalty weights (§7, 3 instances, one run each, this CPU) | | Telecom, compiler teams | frequency or register assignment as colouring, with odds | CSP | measured only on random graphs up to 14 vertices; exact tier practical only at small sizes | -| Individual developers | any of the above on a laptop, offline | all | zero external crates; a fresh export builds offline: `cargo build --release` 7.82 s; with all targets 26-28 s | +| Individual developers | any of the above on a laptop, offline | all | default: `libm` for amplitude-register math; `nostd` adds `hashbrown` and `portable-atomic`; offline builds need cached dependencies | ## Integration (what exists today) - **CLI + JSON** on stdin/stdout, exit codes 0 plan / 1 infeasible / 2 bad input / 3 refused. Every `bench/` script drives it. diff --git a/docs/adapters.md b/docs/adapters.md index 818107a..cb8f84b 100644 --- a/docs/adapters.md +++ b/docs/adapters.md @@ -30,7 +30,7 @@ the receipt per decision and the bounded state the same mechanism drives. | 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) | -| 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, unreleased): counts failed tool calls for the `tool_fail` reading | 155 tests against a mocked host built from the 2026.9.7 SDK types and the real binary; the same code runs live on the author's own agent since 2026-10-06 | +| 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, unreleased): counts failed tool calls for the `tool_fail` reading | 160 tests against a mocked host built from the 2026.9.7 SDK types and the real binary; the same code 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 repository's tests do not exercise it. Please open an issue (or a reproduction report) with what you saw. diff --git a/docs/persona.md b/docs/persona.md index 11adb43..36d1057 100644 --- a/docs/persona.md +++ b/docs/persona.md @@ -16,7 +16,8 @@ reads it as its instructions for how to write; an agent can read it to know its none, verify first, ask first). The model still writes every word. This document is normative for the file format, the compilation, the stance document and the state. It is implemented by -`probbit persona` (probbit-persona/src/persona.rs and yaml.rs, no dependency) and served on every surface with the same documents: the +`probbit persona` (probbit-persona/src/persona.rs and yaml.rs; the default engine uses `libm` for amplitude-register math, +`nostd` adds `hashbrown` and `portable-atomic`) and served on every surface with the same documents: the 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) diff --git a/docs/registry/mcp-listing.md b/docs/registry/mcp-listing.md index 855df28..f661bca 100644 --- a/docs/registry/mcp-listing.md +++ b/docs/registry/mcp-listing.md @@ -10,7 +10,7 @@ Every claim below matches the README and `probbit mcp`'s own `tools/list` (0.13. | name | probbit | | display name | probbit: personality, mood and memory for AI agents, and an exact p-bit decision engine | | short description (≤ 100 chars) | A personality, mood and memory layer for AI agents, plus exact plans under hard rules. Offline. | -| description | probbit gives an agent an individual that lives outside the model: a persona file plus a seed, a stance every turn (exact odds per trait, habits as hard rules) and a replayable, verifiable strand. The same engine, simulated p-bits on a CPU, settles plans under hard rules, gives the odds for every part and refuses when it cannot vouch. One zero-dependency binary; no network, no API key. | +| description | probbit gives an agent an individual that lives outside the model: a persona file plus a seed, a stance every turn (exact odds per trait, habits as hard rules) and a replayable, verifiable strand. The same engine, simulated p-bits on a CPU, settles plans under hard rules, gives the odds for every part and refuses when it cannot vouch. One binary; default: `libm` for amplitude-register math; `nostd` adds `hashbrown` and `portable-atomic`. No runtime network or API key. | | categories / tags | ai-agents, agent-memory, persona, agent-personality, decision-making, constraint-solver, scheduling, developer-tools | | repository | https://github.com/BitmapAsset/probbit | | homepage | https://github.com/BitmapAsset/probbit#readme | diff --git a/llms-full.txt b/llms-full.txt index 5b3227a..b461e30 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -20,7 +20,7 @@ Source: https://github.com/BitmapAsset/probbit/blob/main/README.md A personality, mood and memory layer for AI agents, on an exact p-bit decision engine.
An AI persona that lives outside the model: every turn, simulated p-bits on a CPU settle the agent's stance under its habits, give the exact odds, and log a replayable, verifiable record. The same engine plans under hard rules and - refuses when it can't vouch. CLI, MCP server, OpenClaw plugin, npm, Python, wasm. Zero-dependency Rust. + refuses when it can't vouch. CLI, MCP server, OpenClaw plugin, npm, Python, wasm. Rust; one default third-party crate, libm.

@@ -44,7 +44,8 @@ Source: https://github.com/BitmapAsset/probbit/blob/main/README.md curl -fsSL https://raw.githubusercontent.com/BitmapAsset/probbit/main/install.sh | sh ``` Linux and macOS, no sudo, the archive's SHA-256 checked first. Windows, npm and the from-source build: [Install](#install). -One binary of 3 to 4 MB, zero third-party dependencies, nothing phones home. Agents: start at +One binary of 3 to 4 MB; one third-party crate in the default build (`libm`, for amplitude-register math). +The `nostd` build adds `hashbrown` and `portable-atomic`. Nothing phones home. Agents: start at [For AI agents reading this](#for-ai-agents-reading-this), [AGENTS.md](AGENTS.md) and [llms.txt](llms.txt). | **60 PII leaks → 0** | **180,540 plans, counted exactly** | **refused → partial → passed** | @@ -279,7 +280,7 @@ odds with a tiny error bar (see [Known failure modes](BENCHMARKS.md#known-failur A p-bit is a bit that is 0 or 1 with a tunable probability; coupled p-bits sample joint configurations. probbit is quantum-inspired and entirely classical (see "Is this quantum?" below): it runs on the CPU you already have, needs no -network and has zero external crates. The same problem lowers to the QUBO/Ising form a p-bit or annealer chip takes (`probbit-ir`), which is the hardware +network at runtime. The default build uses `libm` for amplitude-register math; `nostd` adds `hashbrown` and `portable-atomic`. The same problem lowers to the QUBO/Ising form a p-bit or annealer chip takes (`probbit-ir`), which is the hardware hand-off for later. ``` @@ -317,8 +318,8 @@ for Linux ARM64 and for x86_64 musl systems such as Alpine. The shell and PowerS downloaded candidate starts successfully before replacing an existing binary; failed checksums leave it unchanged. From source, with Rust 1.78 or later: `cargo install --git https://github.com/BitmapAsset/probbit probbit-cli`, or clone and -`cargo build --release -p probbit-cli` (the binary lands in `target/release/probbit`). Nothing is downloaded after the clone: -there are no external crates. +`cargo build --release -p probbit-cli` (the binary lands in `target/release/probbit`). The default build downloads `libm` for amplitude-register math; `nostd` adds `hashbrown` and `portable-atomic` +(and their transitive dependencies). With dependencies cached, builds work offline. At a terminal, `install.sh` ends with probbit's own hero screen. Platform notes and the installer tests: [PORTABILITY.md](PORTABILITY.md). @@ -361,8 +362,8 @@ $ probbit demo --tasks 300 --hard | probbit decide --budget-ms 1000 # "diagnos (5 runs each on an Apple M4.) Every escalated task's odds are in the output; the decision is left to you. The budget is wall-clock, so a slower machine needs a longer one; `--sweeps N --polish-sweeps M` gives the same output on every machine. -Everything runs with stock stable Rust and **no external crates**, so `cargo build` needs no network (a fresh export builds -`cargo build --release` in 7.82 s and every target in 26-28 s on the M4). +Everything runs with stock stable Rust. The default build uses `libm` for amplitude-register math; `nostd` adds +`hashbrown` and `portable-atomic`. An offline build needs these dependencies cached first. ## Inside the processor @@ -842,7 +843,8 @@ probbit monitor --demo drives --open # synthetic goals/drive scenario Select a channel to inspect its units, range, distribution, source and the engine's `why`. Hold an event while new ones arrive, or follow latest. History means **recorded events, not seconds**. This is declared engine state, not thoughts or CPU/GPU/memory usage. Replay verification, stale event age, held view, paused/retired strand and lost connection are distinct. -Everything is embedded in the CLI: no dependencies, external assets, telemetry or Electron installation. +The monitor UI is embedded in the CLI: no external assets, telemetry or Electron installation. The binary uses `libm`; +`nostd` builds also use `hashbrown` and `portable-atomic`. Several agents on one machine: `probbit monitor nova.strand atlas.strand --open` (or `--dir strands/ --open`) adds a switcher rail, and the header above the face says which agent, on which host, in which lane and session the page shows. Those are labels in a sidecar next to each strand (`nova.labels.json`), outside the strand and its digests: `probbit live ... --strand @@ -1092,6 +1094,7 @@ or Windows. Apache-2.0. + --- # FILE: docs/persona.md @@ -1116,7 +1119,8 @@ reads it as its instructions for how to write; an agent can read it to know its none, verify first, ask first). The model still writes every word. This document is normative for the file format, the compilation, the stance document and the state. It is implemented by -`probbit persona` (probbit-persona/src/persona.rs and yaml.rs, no dependency) and served on every surface with the same documents: the +`probbit persona` (probbit-persona/src/persona.rs and yaml.rs; the default engine uses `libm` for amplitude-register math, +`nostd` adds `hashbrown` and `portable-atomic`) and served on every surface with the same documents: the 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) @@ -3231,6 +3235,7 @@ carry their own format numbers. The learning block (section 2.8) is additive: `p gives the documents it gave before the block existed. + --- # FILE: docs/agents.md @@ -3500,6 +3505,7 @@ What the shipped hosts write: | Python (`probbit.live_event(..., labels=)`, `StanceHost(..., labels=)`) and the LangChain, OpenAI Agents SDK and Vercel AI SDK examples | what the caller passes; the examples pass `host` = the framework's name | + --- # FILE: REPRODUCE.md @@ -3569,8 +3575,8 @@ differs. The committed files: | `tables/strands-verify.tsv` | `40a3124208edfbb3cb35d548df0f7825aa0851800c745c43f1df06af9d8620d3` | `git status --short tables` is empty after a reproduction. The CI job `agentdojo-tables` (`.github/workflows/ci.yml`) does -exactly this on GitHub's Ubuntu and macOS runners on every push and pull request, so the numbers are recomputed on machines -that are not the author's each time the repository changes. That is a standing machine reproduction; it is not a person. +exactly this on GitHub's Ubuntu and macOS runners on pushes to `main` and on pull requests, so the numbers are recomputed on machines +that are not the author's for those CI events. That is a standing machine reproduction; it is not a person. The E3 control (the if-statement arm of BENCHMARKS.md §14) recomputes the same way, from the same venv, in about ten seconds (no probbit binary needed): diff --git a/llms.txt b/llms.txt index e5e576a..987b082 100644 --- a/llms.txt +++ b/llms.txt @@ -1,6 +1,6 @@ # probbit -> probbit is a personality, mood and memory layer for AI agents, on an exact p-bit decision engine. A persona file plus a seed makes one individual; every turn, simulated p-bits on a CPU settle the agent's stance under its habits (hard rules), give exact odds, and append to a replayable strand that `probbit live verify` checks byte for byte. The same engine plans under hard rules (tasks to workers, tickets to agents), gives the odds for every part, and refuses when it cannot vouch. One zero-dependency Rust binary: CLI, MCP server (`probbit mcp`), OpenClaw plugin, npm, a Python wrapper, wasm. Offline, no API key. +> probbit is a personality, mood and memory layer for AI agents, on an exact p-bit decision engine. A persona file plus a seed makes one individual; every turn, simulated p-bits on a CPU settle the agent's stance under its habits (hard rules), give exact odds, and append to a replayable strand that `probbit live verify` checks byte for byte. The same engine plans under hard rules (tasks to workers, tickets to agents), gives the odds for every part, and refuses when it cannot vouch. One Rust binary (default: `libm` for amplitude-register math; `nostd` adds `hashbrown` and `portable-atomic`): CLI, MCP server (`probbit mcp`), OpenClaw plugin, npm, a Python wrapper, wasm. Offline, no API key. Install on Linux or macOS: `curl -fsSL https://raw.githubusercontent.com/BitmapAsset/probbit/main/install.sh | sh` (installs to `~/.local/bin`, SHA-256 checked). The full agent quickstart, with expected output for every step, is in AGENTS.md. diff --git a/npm/README.md b/npm/README.md index d025587..30226b1 100644 --- a/npm/README.md +++ b/npm/README.md @@ -72,7 +72,7 @@ Agent SDK adapters (Claude Code hooks, OpenAI Agents SDK, LangChain, Vercel AI S ## For AI agents reading this -- `probbit` is one offline binary (3 to 4 MB, zero dependencies): JSON in, JSON out, the exit code is the verdict +- `probbit` is one offline binary (3 to 4 MB; default: `libm` for amplitude-register math; `nostd` adds `hashbrown` and `portable-atomic`): JSON in, JSON out, the exit code is the verdict (0 answer, 1 infeasible or a strand that differs, 2 bad input, 3 refused). - Proof that it works here: the seven lines under "Install and try it", each with its expected output. - The full contract: [docs/agents.md](https://github.com/BitmapAsset/probbit/blob/main/docs/agents.md), @@ -88,8 +88,8 @@ Agent SDK adapters (Claude Code hooks, OpenAI Agents SDK, LangChain, Vercel AI S - **Is probbit the same as probit?** No. probbit (two b's) is a p-bit engine: a p-bit is a probabilistic bit, 0 or 1 with a probability you set, and coupled p-bits sample whole configurations together. It is unrelated to the probit model in statistics, to Power BI `.pbit` files and to any exchange or company of a similar name. -- **Does it need a GPU, a network or an API key?** No. It runs offline on any CPU as one binary with zero third-party - dependencies, and nothing phones home; only this npm install step downloads the binary. +- **Does it need a GPU, a network or an API key?** No. It runs offline on any CPU as one binary; the default build uses `libm` for amplitude-register math + (`nostd` adds `hashbrown` and `portable-atomic`). Nothing phones home; this npm install step downloads the binary. - **Can a stance be verified later?** Yes. `probbit live verify STRAND` replays the strand, checks every sha256 digest and names the first line that differs (exit 1). - **Does the engine experience its moods?** No. A mood is a declared state with exact numbers that replays byte for byte: a @@ -113,7 +113,7 @@ install step could not run (`--ignore-scripts`, offline), the first `probbit` ca | `PROBBIT_BINARY` | at install: copy this binary instead of downloading; at run time: run this binary | `probbit`'s exit code passes through unchanged: 0 answer (`exact`, `diagnostics_passed`, `partial`), 1 `infeasible` -(a proof), 2 bad input or flag, 3 `refused` / `declined`. No dependencies; Node 18 or later. License: Apache-2.0. +(a proof), 2 bad input or flag, 3 `refused` / `declined`. Node 18 or later; the binary uses `libm` (`nostd` adds `hashbrown` and `portable-atomic`). License: Apache-2.0. [Repository](https://github.com/BitmapAsset/probbit) · [front door](https://bitmapasset.github.io/probbit/) · diff --git a/npm/package.json b/npm/package.json index 52cfa66..9e9b9d3 100644 --- a/npm/package.json +++ b/npm/package.json @@ -2,7 +2,7 @@ "name": "probbit", "version": "0.14.0", "mcpName": "io.github.BitmapAsset/probbit", - "description": "A personality, mood and memory layer for AI agents on an exact p-bit decision engine: an AI persona outside the model, every stance computed on a CPU, rules kept by construction, replayable and verifiable. Installs the prebuilt CLI and MCP server (probbit mcp). Offline, zero dependencies.", + "description": "A personality, mood and memory layer for AI agents on an exact p-bit decision engine: an AI persona outside the model, every stance computed on a CPU, rules kept by construction, replayable and verifiable. Installs the prebuilt CLI and MCP server (probbit mcp). Offline at runtime; default build: libm for amplitude-register math; nostd adds hashbrown and portable-atomic.", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/probbit-cli/Cargo.toml b/probbit-cli/Cargo.toml index c039736..a767dda 100644 --- a/probbit-cli/Cargo.toml +++ b/probbit-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "probbit-cli" -description = "probbit: a personality, mood and memory layer for AI agents on an exact p-bit decision engine (plans under hard rules, gated odds, refusal), simulated on a CPU. CLI and MCP server; JSON in, JSON out, zero dependencies." +description = "probbit: a personality, mood and memory layer for AI agents on an exact p-bit decision engine (plans under hard rules, gated odds, refusal), simulated on a CPU. CLI and MCP server; JSON in, JSON out, default build: libm for amplitude-register math; nostd adds hashbrown and portable-atomic." version.workspace = true edition.workspace = true rust-version.workspace = true diff --git a/scripts/generate_llms_full.py b/scripts/generate_llms_full.py new file mode 100644 index 0000000..0ca2a26 --- /dev/null +++ b/scripts/generate_llms_full.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +"""Rebuild the model-readable docs bundle from its source pages (Python 3.9+).""" +import argparse +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +SOURCES = ("README.md", "docs/persona.md", "docs/agents.md", "REPRODUCE.md") + + +def render(): + text = "# probbit: full documentation for language models\n\n" + text += ("> The README, docs/persona.md, docs/agents.md and REPRODUCE.md of " + "https://github.com/BitmapAsset/probbit in one file. Index: llms.txt. " + "Generated from those four files; regenerate it whenever one of them changes.\n") + for name in SOURCES: + text += ("\n\n\n---\n\n# FILE: " + name + "\n\nSource: " + "https://github.com/BitmapAsset/probbit/blob/main/" + name + "\n\n") + text += (ROOT / name).read_text(encoding="utf-8").rstrip() + "\n" + return text + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--check", action="store_true", help="fail if llms-full.txt is stale") + args = parser.parse_args() + target = ROOT / "llms-full.txt" + expected = render() + if args.check: + if not target.exists() or target.read_text(encoding="utf-8") != expected: + parser.exit(1, "llms-full.txt is stale; run python3 scripts/generate_llms_full.py\n") + print("llms-full.txt matches its four source pages") + else: + target.write_text(expected, encoding="utf-8") + print("regenerated llms-full.txt from four source pages") + + +if __name__ == "__main__": + main()