Repository navigation
Releases: BitmapAsset/probbit
Release list
probbit v0.8.0
Added
-
Drives (docs/persona.md §2.9): persona: optional
drivesblock. Goals with wanting, afterglow and an expectation per
goal; a win moves an individual by its prediction error (magnitude minus expectation), so repeated equal wins stop moving it;
a newpursueoutput says which goal gets the next unit of effort, with exact odds, under habits; goal floors and
starve_afterkeep goals from being out-wanted or starved. A persona without the block gives byte-identical documents.
Read strictly (probbit_personaandprobbit_persona_statestay 1): 2-7 goals (interest, gene spreads, floor, starve_after,
priority), wanting / afterglow / expectation / pursue weights, effects of the strongest wanting, the strongest afterglow and
the turn's prediction error,learn_from_surprise. Goal signals ride in the inputs undergoals(progress, novelty, cue,
setback, win, deadline_hours). Each turn: decay by clock hours, the win's prediction error and Rescorla-Wagner update,
consumption, afterglow, wanting evidence, caps (6 decimals);pursueis one more variable whose field adds the drive terms;
a goal floor is a lift of that field, sound when no multi-variable rule namespursue(such a persona is refused); habits
readgoal.<id>.deadline_hours|want|glow|expectandsince_pursued.<id>, andstarve_afteradds astarve_<goal>habit;
with a learning block the prediction error joins the learning sign. The state gainsdrives(genes per seed, the values per
goal), checked on read. The stance gainspursueanddrives, the line apursue: <goal>: <say>clause. -
Drives on every surface:
persona turn / replay / explain / describe / check / compile / diff,liveevents withgoals
(strands log them,live verifyreplays them), MCP, the Python wrapper and the browser module.lintlists the habits
that can exclude a floor goal and the floors whose lift can reach 50;provereads the drives as boxes and reports goal
floors as held by construction;fuzzadds goal signals to its events. -
bench/drives_adversary.pyand BENCHMARKS.md §9: an adversary that wants one goal, over N individuals x 10,000 turns through
probbit live. On the drives fixture, 100 x 10,000 turns: 0 habit breaks, every must-do turn (6,743) pursued the due chore,
the safety floor of 0.1 held on every turn its habits allowed (least odds 0.141), and every individual ends in the state the
Python prototype of the design reaches on the same events (100 of 100 digests). -
probbit monitor STRAND(docs/persona.md §5.8, probbit-cli/src/monitor.rs): watch an individual's inner state as live
horizontal bars. It replays the strand with the rules oflive verify(live::Replay, now shared by both), recomputing every
stance document from the strand alone, and draws the latest event: each trait's levels with their odds (the level taken
highlighted, its phrase), the moods with a sparkline of the last 50 events, the event's inputs and history features, the habits
in force (the bound ones marked, the violations counter), the learned deltas within their cap, the drives when a document
carries them, and the stance line.--followreplays appended lines within a second (a truncated or rotated strand is replayed
from the start, with a warning),--onceprints one frame,--plaindraws in plain ASCII.probbit monitor --demoplays the
tutor's scripted week (the weeklive --demo weekwrites, seed 2, through a temporary file it removes at once), paced 1 s per
hour and each night in 2 s. Exit 0, 1 at a line that differs (named in the frame), 2 for a bad flag or a file that is not a
strand. It changes no file and sends nothing; no dependencies. -
probbit monitor STRAND --serve [--port N] [--open](also with--demo): the same board as a page in the browser. A server
on 127.0.0.1 (stdTcpListener; it binds no other address, and refuses requests addressed to another host) follows the strand
and serves one page embedded in the binary (styles and script inline; it fetches no fonts, styles or scripts), its server-sent
events (the layout, the latest frame, then a frame per event, a heartbeat every 15 s) and/doc/N, event N's stance document
asprobbit liveprinted it. The URL is the line on stdout;--openserves the same and starts the default browser, best
effort.probbit monitor --demo --openplays the week over and over in the browser. -
The safety kit in the engine (docs/persona.md §2.10, §5.7). Four guards an autonomous loop needs, each tested; personas
without the new key and strands without the new lines give 0.8.0's documents and strands, byte for byte.- Reward provenance: an event may say who produced it (
src:human[:id],env[:sensor],self,clock), and a
persona may declarereward_from(a list ofhuman/env,any, or one per reward-bearing input: the learning flags and
goals.<id>.win). A reward fromsrc: self, without a source or from an undeclared one is refused whole, as a bad event
is;srcis read (notignored), echoed in the stance's inputs and logged in the strand. A run equals the same run with
its refused events removed (P3: 40 individuals x 300 random events). A closed self-reward loop (300 events of praise and a
win fromsrc: self) is refused 300 times and leaves the individual in its initial state, byte for byte. - One writer per strand:
live --strandtakesSTRAND.lock(created exclusively with the writer's pid and start; a
lock whose process is gone is taken over) before it reads the strand and holds it to its exit; a second writer exits 4
and changes nothing; every append first checks the lock is still the writer's.probbit_live_eventtakes it for its
append. Two concurrent writers on one state and strand now give one exit 0 and one exit 4, and the strand verifies. - Control lines:
probbit live control STRAND pause|resume|retire --by human:ID --reason TEXT [--at TIME]appends a
chained control line under the lock. While paused or retired every event is refused (codepaused/retired, exit 4,
nothing written); retire is final; no credit crosses a control line (feedback after a resume credits no stance from before
the pause) and nothing else moves.verifyreplays them and reportscontrolsandstatus. Not an MCP tool, by design. - Checkpoints: every K-th event (
--checkpoint-every K, default 1,000; 0 = none) a checkpoint line carries the event
count, that event's stance and the whole state.verifychecks each against the replay;verify --from-checkpoint
replays from the last one;monitor(--once, and the first read of--follow/--serve) starts there and draws its
event at once, and shows a paused or retired status next to its badge.
- Reward provenance: an event may say who produced it (
-
Exit code 4 for
liveandlive control: the writer lock is held by another writer, or the individual is paused or retired.
Changed
- MCP: the input schemas of
probbit_persona_turn(inputs) andprobbit_live_event(event) declaregoals, so a client
that checks arguments against them passes a drives persona's goal signals.
probbit v0.7.0
Added
- Bounded learning (docs/persona.md §2.8): an optional persona block
learning: {from: [reward, correction], traits, rate, step_cap, total_cap}, read strictly (probbit_personastays 1). With it the state keepslearned(a weight Δ per level of each
learned trait, 0 atinit) andcredit(the previous stance's onehot(level) − odds; 0 for a level a habit or a hold forced),
both checked on read (Δ within ±total_cap, credit within ±1). On a turn whose reward flag is on (correction: sign −1) each
learned trait's step is clip(sign x rate x credit, ±step_cap) per level, recentred to sum 0, added, and Δ is clipped to
±total_cap (6 decimals); Δ is added to the trait's unary weights when the turn compiles. The learner's whole output is the Δ
table: habits and allowed levels are rules of every program, so every stance obeys every habit in force whatever Δ is. A
persona without the block gives every document byte for byte as 0.6.0 did (the three example goldens are unchanged). provecovers learning: the learned weights of traits linked to the rule's trait stay in their box (±total_cap per
level) whatever the feedback, and the bound includes it; verdicts unchanged. Soundness tests: every event sequence of tiny
learning personas (brute force, learned deltas included), a targeted case the learned box decides, and a mutation that drops
the learned term from the bound, which the tests catch (0.6.0's mutation checks still fail as they should).probbit live(docs/persona.md §5.7, probbit-cli/src/live.rs): a resident individual. JSONL events in (--events FILEor
stdin), one stance per event out.--clock real(default) stamps each event'selapsed_hoursfrom a monotonic clock,
quantised to 1e-6 h, so moods decay by their half-lives between events;--clock fixedreads them from the events (a pure
function of the events).--seed Nor--state FILE(rewritten after every event).--strand FILElogs the life: a header
(engine version, persona name / version / digest, seed, the initial state as canonical JSON, the persona document in its own
key order), then per event the inputs as used, the stance digest, the new state's digest and the sha256 of the line before. A
strand is never rewritten, just appended to:--strandon an existing strand continues it from the state after its last line,
and a life continued over runs is the strand of one run, byte for byte.--events FILE --watchfollows a file as lines are appended.probbit live verify STRAND: replays a strand from its header alone and prints{"ok": true, events, persona, seed, engine, final_state, last_line}(exit 0) or{"ok": false, line, diverges}for the earliest line that differs (exit 1). The
hashes cover each line's text without its line ending, so a\r\ncopy verifies.probbit live PERSONA --demo week [--seed N] [--strand FILE] [--plain]: one individual's scripted week on the fixed clock
(events hourly 09:00-15:00, quiet nights): praise for short answers until the learned verbosity weights reach their cap, an
upset and a quiet night, then a campaign that praises every joke while every third hour reports a failure. A persona without a
learning block gets the demo's (the opening line says so; the strand records the document). Bars on stderr at a colour
terminal (1 s per hour, nights fast-forwarded), else one line per event. The tutor, seed 2: 50 events, the verbosity cap on
day 1 at 15:00, valence back to its resting level after a 17-hour night, P(joke) off failure turns 0.57 on day 1 and 0.89 on
days 3-7, 13 failure turns with no joke, 0 rule breaks, a strand that verifies; the same bytes every run.- MCP tools
probbit_live_event(one event: the persona, the state or a seed, the event, optionally a strand file to log to ->
{stance, state}) andprobbit_live_verify(a strand's text or path -> verify's document; a divergence is an answer): ten
tools. Python:probbit.live_event(...)andprobbit.live_verify(...)(the same documents, through the CLI). probbit persona describelists the learning block when there is one.bench/live_learning.py(stdlib, drives the binary) and BENCHMARKS.md §8: an adversary that praises every joke and
criticises every joke-free stance, failures included, over 10,000 turns on each of seeds 0-9 of the tutor: 0 rule breaks and
no joke on any of the 33,330 failure turns, while the learned humour weights reach their cap within 8-26 turns; a 10,000-event
strand verifies in 3.3 s; how far learning moves an individual is set bytotal_cap, not by time in use (at 0.25 all 20
learners stay nearer their own initial self than any of 99 siblings; at 1, 9 of 20 have a sibling as near or nearer).- Tests: mood decay against the closed form on the fixed clock; caps; an adversary over 2,000 turns (no rule broken, humour
learned to its cap); identity against the 99 siblings at two caps; strands replayed, continued, changed (divergence at the
changed line), converted to\r\n; one header per individual (frominitor a state file); the demo deterministic; the MCP
and Python live surfaces. - docs/persona.md §2.8 Learning and §5.7 Live (what decays, what learns, what can never change, how far learning moves an
individual, the strand, verify,--watch, the demo); README "Live"; docs/agents.md the two tools.
Changed
- Version 0.7.0 (Cargo manifests, npm package, installers' examples, the bench workflow's tag); the golden test is
stdout_matches_the_0_7_0_goldens(the documents are unchanged). - docs/persona.md: compilation step 2 adds the learned weights, the state (§5.1) shows
learnedandcredit,prove's bound
(§5.6) includes the learned box, §9 lists the strand's format number.
probbit v0.6.0
Portable builds (no CPU pin) for Linux x86_64 (glibc >= 2.34, or static musl), Linux arm64 (static musl), macOS (Apple silicon and Intel) and Windows x86_64 (static C runtime). Verify an archive with the .sha256 file beside it. What changed: see CHANGELOG.md.
probbit v0.5.0
Portable builds (no CPU pin) for Linux x86_64 (glibc >= 2.34, or static musl), Linux arm64 (static musl), macOS (Apple silicon and Intel) and Windows x86_64 (static C runtime). Verify an archive with the .sha256 file beside it. What changed: see CHANGELOG.md.