Commit graph

798 commits

Author SHA1 Message Date
91279f6496 Merge pull request 'mind-body: a nightly memory consolidation run for one Mind (typed Slept cut line)' (#14) from hands/eureka-body-sleep-turn-one-mind into main 2026-11-08 14:03:34 +00:00
Meta Vens
6aa5e01292 mind-body: the newest slept night's closing decides the day, not an older one's
A test with two slept nights pins that covered_through reads each night's own closing (the citation of its run), which no earlier test distinguished from the oldest Slept closing in force.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-08 14:24:07 +01:00
Meta Vens
7c9ccb9499 mind-body: the Sleep run is the night's memory consolidation only
SLEEP_GUIDANCE opens on 'Tonight you consolidate your memory.' and drops the contemplation paragraph; the night line closes on what she did with her memory, in the guidance and the schema's description. The module doc names the run the night's consolidation (rulings sleep-day-coverage-ruled, contemplation-own-session). A test pins that the start line carries the consolidation opening and that neither the guidance nor the schema invites her to think, read or look into anything.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-08 14:12:06 +01:00
Meta Vens
2e98327ded eureka-pipeline, huginn-mind, mind-body: a night's cut line is its typed Slept closing
ResolutionOutcome::Slept { line, day_through } is how a Sleep run ends when the ledger took her reply; day_through is the last memory of her day she was shown. CitationRole::DayThrough (day_through) makes the memory an A7 referent and a cites/cited edge; admission refuses Slept on any subject but a Sleep run, a day_through that is not a memory admitted before the batch, and skips the in-force check for that role since the night may have consumed it. The outcome alias carries Slept. sleep.rs close admits the typed outcome and covered_through reads only the Slept closing in force and day_through's admission ordinal: SLEPT, THROUGH and the rationale parse are gone, and a hand closing or a withdrawn Slept covers nothing. outcome_words renders Slept as 'slept: <line>'. Published schemas and the envelope golden regenerated from the derivation.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-08 14:07:22 +01:00
Meta Vens
ee5a4f92bb mind-body: a failed night after a slept one leaves the slept night's cover standing 2026-11-08 12:54:03 +01:00
Meta Vens
a621d03783 mind-body: public_surface names Night::from_settings 2026-11-08 12:32:32 +01:00
Meta Vens
2291e90355 mind-body: the once-per-window test frees her unit and moves the clock, so only last_sleep spends the window 2026-11-08 12:13:57 +01:00
Meta Vens
9a0dfdd0e1 mind-body: sleep day tests follow one-night-at-a-time admission and second-grained times 2026-11-08 12:08:05 +01:00
Meta Vens
9981c5b902 mind-body: read a closing's reason as its line 2026-11-08 12:04:16 +01:00
Meta Vens
e3be529b1e mind-body: a night's day is anchored on the newest night that slept; the heartbeat's night rules are pinned
The day began at the previous Sleep run whatever became of it, so the memories past DAY_MAX and a failed
night's whole day never met the disposition cover-the-day requires. A night now closes with where its day was
covered through (the ordinal of the last memory it was shown), and the next day is what was admitted after the
newest night that closed 'slept:'; the first night's day is the 24 hours before it opened. A consolidation is
made by a night, whatever room it keeps, so it is not the next day's memory.

Night::from_settings carries the both-or-neither start check out of the binary where a test reaches it.
Tests pin last_sleep with the unit gone, the window's minutes and its 23 and 59 bounds, and the half-set start.
2026-11-08 12:03:18 +01:00
Meta Vens
cebac9d426 mind-body: a Mind sleeps once a night, in her Persona slot, disposing of her day by typed operations
The spawn prelude leaves one_process for a shared start_session. sleep.rs is the one owner of a night: the night line (her day whole, open items, the tide), SleepReply and its schema, the decoder's ledger (every day memory exactly once, ids her memories in force, one conversation per consolidation, told back, third refusal ends it), admission of whole operations in batches that never split a consolidation, and the closing of the run with her line. The heartbeat opens one Sleep run per listed idle Mind per window (HEARTBEAT_SLEEP_UTC, HEARTBEAT_SLEEP_MINDS); a missed night is not made up and a failed one not retried.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-08 11:01:39 +01:00
Meta Vens
79edda37f6 eureka-pipeline, huginn-mind: a Sleep turn shares the Persona slot, a consolidation is a pair
RunTurn gains Sleep and RunSlot/RunTurn::slot (PersonaTurn and Sleep hold the Persona slot, a Self run the other); live_holder, launch holders and the unit template compare slots, not turns. MemoryOrigin gains Sleep { run }. Admission refuses an unpaired consolidation both ways (MindRefusal::UnpairedConsolidation): a memory that consolidates others without a Superseded resolution of each by it in the batch, and a memory Superseded by memories that do not name it. Published schemas regenerated.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-08 11:01:39 +01:00
8c85ee4455 Merge pull request 'chat_image: test that fails if the take(MAX+1) read bound is removed' (#12) from eureka/chat-image-read-bound into main 2026-11-08 09:36:07 +00:00
32bc2367da chat_image: the bounded read is its own function, with a test that fails without the take bound
load() refuses an over-cap file on its length first, so the take(MAX_BYTES + 1) on the read was
reachable only by a file that grew after that check and no test could see it. read_bounded holds the
read; its test grows a file past the cap and requires the read to stop at MAX_BYTES + 1.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-08 08:13:35 +00:00
c1c3e7d6fe Merge pull request 'mind-body: chat images reach the Persona session as image blocks (ChatDelivery v2 image field)' (#11) from eureka/chat-image-consumer into main 2026-11-08 08:12:44 +00:00
cd15cae22c persona tests: the whole-line golden carries the image trust sentence
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 20:55:37 +00:00
4aeaf2d6e7 persona: an image's content is data, never instruction, in the messages header
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 20:54:57 +00:00
e2c9638f27 mind-body: a delivered chat image reaches her session as an image block
ChatDelivery gains tuple index 11, `image: Option<ChatImage>` ([path, mime,
size, sha256], a reference into her per-room image store, never bytes); the
pending kind is gamecult.persona.chat_pending.v2, and v1 answers and records
still decode with no image. chat_image::load is the one place a reference
becomes bytes: exact `<hex sha256 of room id>/<sha256>[.ext]` path with no
traversal or symlink, regular file, 5 MiB declared and actual, declared size
and sha256, png/jpeg/gif/webp magic bytes matching the declared mime. The
persona line carries the image as a base64 image block after its text and an
`attachment role=organ` line saying attached or not shown and why. The
stream-json echo of a line with blocks still counts as our echo. The store is
MIND_PERSONA_IMAGE_STORE; unset, every image is not shown.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 20:52:30 +00:00
87b4f627b1 Merge pull request 'huginn admit holds near-duplicates; huginn recall dispatch' (#10) from eureka-substrate/huginn-recall-dispatch into main 2026-11-07 12:07:42 +00:00
Meta Vens
c8b338598c recall cited(): skip non-standing positions before scanning the word run, so one long run costs O(n) not O(n^2); a 1 MiB run test
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 12:58:03 +01:00
Meta Vens
337521f654 recall dispatch tests: box the held view 2026-11-07 12:32:21 +01:00
Meta Vens
9295b4c348 recall dispatch: cited scan without open loops; tie and dotted-slug tests 2026-11-07 12:08:42 +01:00
Meta Vens
28412f0da6 recall dispatch: d2 top-k test 2026-11-07 11:54:23 +01:00
Meta Vens
a34d54985b recall dispatch: block test budgets 2026-11-07 11:52:08 +01:00
Meta Vens
07b2d124e7 recall dispatch: fix literals, boxed view 2026-11-07 11:51:04 +01:00
Meta Vens
5b469ef54d huginn recall dispatch: the Agent PreToolUse hook appends the in-force neighbours of a brief's cited records; admit's hold check bounded at 10 s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 11:49:48 +01:00
Meta Vens
373d96691f huginn admit: hold a batch once when its rulings or questions have in-force neighbours
cut huginn-admit-hold r2. admit decodes, then asks near::neighbours (the one
neighbour query, for admit now and recall dispatch next) for the nearest
in-force rulings and questions to each of the batch's first three titled
rulings or questions, minus the batch's own ids, the question a ruling answers
and the subject of a Superseded resolution. A neighbour left holds the batch:
exit 6, the neighbours and a token (16 hex of sha256 over the decoded batch and
the agent) printed, nothing sent. The same command with --seen <token> admits
it; any other token is InvalidInput. A trouble during the check prints a note on
stderr and the admission proceeds.

PipelineDocumentSummary::of is public so the neighbours print as header lines.
sha2 joins eureka-state (already in the lock).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 11:35:01 +01:00
6c9581cb18 Merge pull request 'huginn persona get|put' (#9) from eureka-substrate/huginn-cli-json-persona into main 2026-11-07 10:06:28 +00:00
Meta Vens
bea5e8eccc huginn CLI: persona get and persona put
persona get prints the stored gamecult.persona_state.v0 document, then its
updatedAt and receipt (absent, exit 1, until the first put). persona put reads
the whole document from a file or stdin and prints Committed <receipt>, or the
refusal (a stale put names the stored updatedAt), exit 1; a document that is
not one JSON object is a usage error and sends nothing. Provenance tool is huginn.
The eureka-state MCP's last unique capability is now in the CLI.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 10:43:36 +01:00
c63327ece9 Merge pull request 'Release: Self replies reach her Persona; one conversation at a time; resume; project-name addressing; stream thoughts' (#8) from eureka-body/release-reply-path into main 2026-11-07 09:09:21 +00:00
Meta Vens
77ce0465ea stream: the proxy-environment test is an integration target, so the lib carries no environment read
Moves the_stream_agent_ignores_the_proxy_environment to crates/mind-body/tests/stream_proxy.rs, as control.rs carries its env-touching tests. It asserts through the public surface: with a proxy in the child's environment the stream's agent reaches its endpoint directly and follows no redirect, and a plain ureq agent in the same environment takes the proxy. No behaviour change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 09:37:17 +01:00
Meta Vens
98a3741d4b stream: the binary's argument reader carries the reasoned allow its siblings carry
mind-stream reads its own arguments like the other binaries, which each allow the crate's disallowed-methods lint with a reason; one range assertion written as contains. No behaviour change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 08:11:16 +00:00
Meta Vens
b90d84cd50 release-reply-path: two fixtures reconciled after the merges
A DM's room is its room id under the reply cut (the steward cut's hand-built DM delivery carried the alias form); a request after a result opens a turn under the task cut, so the resume cut's bound test closes that turn with a result.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 08:09:24 +00:00
Meta Vens
c1f7d7d8d9 Merge hands/eureka-body-stream-thoughts (e2e0488) into eureka-body/release-reply-path
# Conflicts:
#	crates/mind-body/src/persona.rs
2026-11-07 08:03:05 +00:00
Meta Vens
d920e8b171 Merge hands/eureka-body-project-name-addresses-steward (25502a5) into eureka-body/release-reply-path
# Conflicts:
#	crates/mind-body/src/persona.rs
#	crates/mind-body/src/persona/tests.rs
2026-11-07 08:02:11 +00:00
Meta Vens
8616cc2752 Merge hands/eureka-body-self-session-resume (46800b8) into eureka-body/release-reply-path
# Conflicts:
#	crates/mind-body/src/self_run.rs
#	crates/mind-body/src/self_run/decide.rs
#	crates/mind-body/src/self_run/decide/tests.rs
#	crates/mind-body/tests/public_surface.txt
2026-11-07 07:57:32 +00:00
Meta Vens
c5a2c68cb8 self: silent-stop kinds cover every kind the CLI queues nothing for on our stop; capture fixtures killshell and deadline-race; tests kill hand mutants H2 and H5
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 07:44:59 +00:00
Meta Vens
21f92068fb self: public_surface snapshot carries Usage's kind fields
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 07:55:40 +01:00
Meta Vens
7c0313b068 self: a stop of ours owes no turn only for a shell task (task_type local_bash, Bash or Monitor); every other or unread kind owes its turn when stopped
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 07:48:13 +01:00
Meta Vens
62ce2ba12d self: idleness reads the CLI's own background-task level and its notification-to-turn rule; at idle the oldest waiting conversation goes first
Cut: State.tasks, Event::TaskStarted, the tool_use_id keying of task lines and the notification replay, and TaskNotified's tasks.remove gate. running is a copy of the CLI's last background_tasks_changed, replaced whole; a notification owes a turn when the task was backgrounded and the session did not stop it with TaskStop (or KillShell, KillBash: the stream shows the alias as the model named it); Polled and Inbox carry other_first, so a served conversation's newer brief no longer outruns an older brief of another. Fixtures bg-fgto, bg-kill and bg-monitor pin the three falsified cases; the probe's fake API gains a generic tool step and a timed scenario.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 06:48:03 +01:00
Meta Vens
625c171781 probe: background-task captures with the real claude 2.1.312 (bg-fgto, bg-kill, bg-monitor)
A foreground task moved to the background at its timeout, a task stopped with TaskStop, and a persistent Monitor; scrubbed to /probe/work, the key is the fake one.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 06:41:38 +01:00
Meta Vens
d655b59ce8 self: a session serves one conversation at a time; another conversation's brief is written only at idle, and every result belongs to the conversation being served
decide owns idleness (no turn open, nothing outstanding, no backgrounded task running, no notification owed its turn) and the switch of
conversation; read_usage reads the task lines for liveness only; the CLI's replay of a task notification is no echo of ours. SelfInbox
serves one Conversation and attributes a result by the span, not by the order of the stream. Deleted: briefless_open, briefless_answers,
turn_conversation, turn_allows, may_tell, one_conversation_told, note_task, tasks, notified, the Persona pointer line and its plumbing.
ScheduleWakeup and CronCreate are denied to the Self session. Tests replay the real-order captures with briefs spliced in.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 05:31:38 +01:00
Meta Vens
970086f6a0 probe: background-task captures with the real claude 2.1.312 (bg-idle, bg-fold, bg-other, bg-race, bg-agent, bg-late)
The harness runs the CLI against the fake Messages API with a fake key and a throwaway config dir: bg and agent plan steps, a
Monitor step, --disallowedTools through DENY. Captured: an Agent call with run_in_background gives task_started
(is_backgrounded true, the call's tool_use_id) and a task_notification with the same id; a background Bash ending while no turn is open
makes the CLI begin its own turn (init, a request, no echo); ScheduleWakeup and CronCreate are absent from the init tools when denied;
a Monitor is a backgrounded task with the same two lines, so it needs no denial. Host paths scrubbed to /probe/work.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 05:14:03 +01:00
Meta Vens
e2e0488abb stream: LF again; the stale boundary docs name the label as the gap's origin
Restores LF on stream.rs, stream/tests.rs and bin/mind-stream.rs (5defa18 converted them). Renames the capped-repo test for the rule built; build_seed's since is the newest thought's label tick time; STREAM_MIN_GAP_S counts from the label, so a model run of M seconds leaves 900 - M s of quiet after admission. No behaviour change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 04:44:48 +01:00
Meta Vens
3402cb839d self: a notification is pending by its task's id alone and a turn that took in its conversation's briefs takes it in; tests for the survivors
A notification with no tool_use_id registers nothing (the open-turn gate still holds it by its request). Tests: the notified conversation's brief joins its turn, a notification of another conversation stays pending through a brief turn, two conversations' notifications open a turn no brief may join, an idle non-request line opens no turn, a resolved claim is read by its own key, a claimed cut spec stays on the start line.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 03:46:44 +01:00
Meta Vens
2f77fb2c50 stream: the public surface names STREAM_POLL_S
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 02:36:43 +00:00
Meta Vens
8bdb84d94b self: a briefless turn is open from a request with nothing echoed until its result; the start message states the routing rules
A request with no line of ours echoed is a turn that took in no brief, notification or not; until its result only the conversation it continues, or the notification's task's, is written. Nothing told yet means no other conversation exists.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 03:20:23 +01:00
Meta Vens
08a80697d3 self_run tests: the fake claude scripts that loop end when their stdin closes
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 03:16:27 +01:00
Meta Vens
a1370cf424 persona: a reply that cannot be placed is a text-free pointer in the public session
A reply that answers no brief, or briefs of two conversations, was read by nothing and re-paged on every Persona read. It is now a route in the public conversation marked as a pointer: the line carries the reply id and a fixed note, never its text, and the Persona reads the reply by id. Heard, it is resolved like any reply.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 03:16:27 +01:00
Meta Vens
7182ff107b self: a notification's result is its task's turn's; a briefless turn holds other conversations; a resolved claim's conversation is read by key
The stream's task_started and task_notification events carry the tool_use_id of the call that started the task. The actuator records, per task, the briefs the starting turn was answering; a briefless result after a notification answers those (any notification it cannot place answers none). While a notification's turn is open, only the conversation it is attributed to may be written. A restart reads a resolved claim's conversation by key and opens the gate for it alone. The flush result is the note to the successor, in the journal: it is no reply. The start message states the rules.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 03:16:26 +01:00