]> git.giacomolli.uk - onechat/log
onechat
5 hours agoSubmit root events through the local socket
Anderson A. Giacomolli [Wed, 11 Nov 2026 17:48:09 +0000 (14:48 -0300)]
Submit root events through the local socket

One local notify command accepts a source, event ID, and text, then
prints a private accepted or duplicate receipt. It rejects unsupported
targets and fields instead of redirecting input. The receipt does not
claim that an agent has processed the event.

Caller cancellation and a submission deadline stop pending socket I/O.
The command help states the root-only test scope, input bounds, and
fixed receipt capacity. Isolated socket checks cover intake, retries,
output failures, cancellation, and receipt privacy.

Issue: 44d8703

5 hours agoQueue external data for the next root turn
Anderson A. Giacomolli [Wed, 11 Nov 2026 17:30:02 +0000 (14:30 -0300)]
Queue external data for the next root turn

Root events stay in the durable agent queue until a turn boundary, so
accepted data cannot enter an active tool chain or its memory view.
Source and event IDs bind retries to the accepted text across restart
and completion. A fixed receipt cap rejects new keys without discarding
pending work or retry protection.

External data carries its receipt time and an explicit trust boundary.
Quoted bodies cannot create image attachments, and raw events do not
produce task-worker completion notices in Telegram. Delivery recovery
can repeat model calls and tool effects, not delivery log entries.

Issue: 44d8703

6 hours agoSync agent queue replacements before success
Anderson A. Giacomolli [Wed, 11 Nov 2026 17:16:53 +0000 (14:16 -0300)]
Sync agent queue replacements before success

Agent queue writes sync the replacement file and its directory before
returning success. This gives local event acceptance a durable storage
boundary and stops queue writes when a replacement has an uncertain
outcome.

Issue: 44d8703

8 hours agoReturn known failures without redundant checks
Anderson A. Giacomolli [Wed, 11 Nov 2026 15:35:21 +0000 (12:35 -0300)]
Return known failures without redundant checks

Telegram update failures and worker state-save failures return their
wrapped errors directly inside existing failure branches. A compaction
without a line also returns its known failure directly. Unreachable nil
returns and repeated conditions are removed without changing error
causes or successful paths.

Issue: 3cdc678

8 hours agoProve direct cancellation during a pending sync
Anderson A. Giacomolli [Wed, 11 Nov 2026 15:07:59 +0000 (12:07 -0300)]
Prove direct cancellation during a pending sync

A cancelled flush returns the direct context error while the durable
write is still pending. Releasing the sync then lets final cleanup
finish normally. This protects cancellation identity and shutdown
ordering while local failure context is added elsewhere.

Issue: 3cdc678

8 hours agoCheck forced-disconnect test setup failures
Anderson A. Giacomolli [Wed, 11 Nov 2026 15:04:03 +0000 (12:04 -0300)]
Check forced-disconnect test setup failures

The HTTP failure fixture checks whether it can take over the test
connection before closing it. A setup failure cannot silently become a
different network failure. Only the deliberate disconnect close remains
a justified nonfatal discard.

Issue: 3cdc678

8 hours agoComplete context on forwarded local errors
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:57:25 +0000 (11:57 -0300)]
Complete context on forwarded local errors

Forwarded failures from local setup, scans, persistence, and command
execution identify their operation without losing the original cause.
Successful results remain unchanged, and privacy-safe Telegram
diagnostics keep their existing contract. Tests cover nil results for
missing nodes and cause identity after read or sync failures.

Issue: 3cdc678

8 hours agoAdd local context to chat operation failures
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:49:23 +0000 (11:49 -0300)]
Add local context to chat operation failures

Daemon, chat, schedule, and worker failures identify their local
operation while wrapping the original cause. Successful results keep a
nil error. Privacy-safe causes and direct context errors retain their
existing handling, and shutdown and retry decisions do not change.

Issue: 3cdc678

8 hours agoAdd local context to memory operation failures
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:43:13 +0000 (11:43 -0300)]
Add local context to memory operation failures

Memory, tree, view, log, and chain failures name their local operation
while retaining the original error through wrapping. Combined result
checks keep their successful nil error instead of wrapping it. Error
classification, cancellation causes, and successful values stay intact.

Issue: 3cdc678

9 hours agoCorrect the remaining review style findings
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:38:34 +0000 (11:38 -0300)]
Correct the remaining review style findings

Multiline callbacks and literals keep their required separators even
when the next operation has its own error assertion. The hook test
comment uses the repository reflow tool without changing fixtures. View
layout comments explain the current prompt-cache contract instead of
retaining historical measurements.

Issue: 3cdc678

9 hours agoMake intentional error discards explicit
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:34:57 +0000 (11:34 -0300)]
Make intentional error discards explicit

Cancellation, removed-client cleanup, typing hints, and cancelled HTTP
fake replies keep their nonfatal behavior with justified lint
directives. Ordinary test response writes and final pipe cleanup check
their errors. No blank assignment hides an unchecked error, and
application shutdown and retry paths stay unchanged.

Issue: 3cdc678

9 hours agoKeep recovery advice out of log events
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:22:47 +0000 (11:22 -0300)]
Keep recovery advice out of log events

The WhatsApp logout log records the event without a command for the
user. The existing user-facing notice still explains how to pair again,
so recovery advice reaches the user without becoming part of the event
name.

Issue: 3cdc678

9 hours agoCheck the complete message before committing
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:19:30 +0000 (11:19 -0300)]
Check the complete message before committing

The commit procedure checks the final message file with every trailer
before signing it. The commit uses that same file without later trailer
edits. Commit prose fills 72-column lines; the source-comment reflow
tool has an 80-column limit and is not the commit formatter.

Issue: 3cdc678

9 hours agoTest the commit message wrapping boundaries
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:15:48 +0000 (11:15 -0300)]
Test the commit message wrapping boundaries

Hook regression tests distinguish a next word that does not fit within
72 columns from a genuinely underfilled paragraph. The checks include
trailers and formatted blocks, so the complete message is tested without
applying source-comment formatting to commit prose.

Issue: 3cdc678

9 hours agoName private helpers for their owning feature
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:11:27 +0000 (11:11 -0300)]
Name private helpers for their owning feature

Daemon log formatting and single-consumer test helpers identify their
owning feature. Memory replay helpers identify the memory test owner.
WhatsApp tests reuse the shared discard logger instead of a duplicate
logger factory. The renamed functions keep their behavior.

Issue: 947bddb

9 hours agoOrder functions by their first use
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:07:43 +0000 (11:07 -0300)]
Order functions by their first use

Constructors, each receiver group, and standalone helpers follow the
order in which their callers use them. Type-aware references keep
unrelated methods with the same name distinct. Functions without an in-
file caller retain a stable relative order. Function text and behavior
stay unchanged.

Issue: 947bddb

9 hours agoName subtests for the behavior they prove
Anderson A. Giacomolli [Wed, 11 Nov 2026 14:03:34 +0000 (11:03 -0300)]
Name subtests for the behavior they prove

Table cases describe their accepted, rejected, routed, or displayed
behavior instead of naming only the input. Assertions, inputs, and
production behavior stay unchanged; test reports identify the contract
of each case.

Issue: 3cdc678

9 hours agoReflow comments and expand event literals
Anderson A. Giacomolli [Wed, 11 Nov 2026 13:59:17 +0000 (10:59 -0300)]
Reflow comments and expand event literals

Comment paragraphs use the repository reflow tool, and event literals
put each field on its own line. The Telegram request comment
distinguishes method-bearing setup errors from safe network causes. Code
behavior and error values stay unchanged.

Issue: 3cdc678

9 hours agoSeparate multiline Go statements
Anderson A. Giacomolli [Wed, 11 Nov 2026 13:55:28 +0000 (10:55 -0300)]
Separate multiline Go statements

Multiline literals and calls have a blank separator before the next
logical block, except for their immediate error check. This includes
test case literals before loops. Event fields and empty callbacks use
multiline bodies. Whitespace and literal layout do not change behavior.

Issue: 3cdc678

9 hours agoOrder model and chat declarations
Anderson A. Giacomolli [Wed, 11 Nov 2026 13:51:58 +0000 (10:51 -0300)]
Order model and chat declarations

Model, memory, chat, tool, and view files put constants and variables
before types, then constructors, grouped methods, and helpers. Shared
test helpers use the same order, and ordinary tests keep tests first.
Declaration text and function bodies stay unchanged.

Issue: 947bddb

9 hours agoOrder daemon and storage declarations
Anderson A. Giacomolli [Wed, 11 Nov 2026 13:48:26 +0000 (10:48 -0300)]
Order daemon and storage declarations

Daemon, storage, configuration, and build files put types before
constructors and grouped methods. Shared test helpers use that order,
and ordinary tests keep their tests-first order. Constants and variables
precede types so every declaration category is easy to find.

The declaration text and function bodies stay unchanged.

Issue: 947bddb

9 hours agoKeep scenario tests with their implementation
Anderson A. Giacomolli [Wed, 11 Nov 2026 13:44:30 +0000 (10:44 -0300)]
Keep scenario tests with their implementation

Memory tests hold replay and queued append scenarios, and daemon queue
tests hold routed WhatsApp scenarios. Their source filenames identify
the implementation they exercise without empty production files.

Helpers with one consumer stay with that consumer. All function bodies
and test behavior stay unchanged.

Issue: 947bddb

10 hours agoSeparate commands from the entry point
Anderson A. Giacomolli [Wed, 11 Nov 2026 13:33:16 +0000 (10:33 -0300)]
Separate commands from the entry point

Command parsing and dispatch have their own source file beside their
tests. Help text, build version, output, and returned errors stay the
same. The entry point keeps run, which creates and cancels the signal
context before it calls the command parser.

Issue: 947bddb

10 hours agoDefine the required code and commit rules
Anderson A. Giacomolli [Wed, 11 Nov 2026 13:11:35 +0000 (10:11 -0300)]
Define the required code and commit rules

The skills set declaration order, owning test filenames, multiline
separators, and explicit handling of ignored errors. Review covers the
rules that the current checks do not enforce, so a tool pass does not
stand for full style compliance.

Every commit uses the configured signing key and needs cryptographic
verification. Code and issue pushes need permission, as does a rewrite
of published history, so routine steps do not imply that consent.

Issue: 3cdc678

13 hours agoInclude the small model in the Nix package
Anderson A. Giacomolli [Wed, 11 Nov 2026 03:45:39 +0000 (00:45 -0300)]
Include the small model in the Nix package

The Nix package supplies pinned small-model and Whisper executable paths
for local voice transcription. The user instructions describe the local
model and executable overrides for other builds. Chat media comments
cover voice-note input, and voice test cases keep their fields explicit.

13 hours agoReceive voice notes from both chat services
Anderson A. Giacomolli [Wed, 11 Nov 2026 03:30:30 +0000 (00:30 -0300)]
Receive voice notes from both chat services

Owner voice notes from Telegram and accepted WhatsApp voice notes enter
shared audio storage and reach the agent as text. Downloads and local
transcription complete before durable message acknowledgement. Failure
markers keep later messages moving, and routed transcripts use the same
child queue and restart recovery as text. Other senders, view-once
messages, and music attachments do not become voice input.

20 hours agoTranscribe stored voice notes locally
Anderson A. Giacomolli [Wed, 11 Nov 2026 03:22:32 +0000 (00:22 -0300)]
Transcribe stored voice notes locally

Private content-addressed audio storage keeps voice notes before a local
Whisper process decodes them. Configured executable and model paths
override the Nix defaults. Missing tools and failed or cancelled
transcriptions produce safe markers instead of stopping message intake.
Plain text output keeps internal timestamps and disables carried text
context. Temporary transcript files stay out of backups.

21 hours agoBenchmark local voice transcription
Anderson A. Giacomolli [Wed, 11 Nov 2026 02:07:16 +0000 (23:07 -0300)]
Benchmark local voice transcription

A separate Nix package compares two pinned Whisper models on public
English and Portuguese Ogg Opus excerpts. It prints each transcript,
wall time, and peak memory so the local voice model can be selected
without an external service or private audio. A decode probe selects 16
kHz mono WAV conversion when direct Opus input is not supported.

26 hours agoCheck the width of comment lines
Anderson A. Giacomolli [Tue, 10 Nov 2026 20:48:48 +0000 (17:48 -0300)]
Check the width of comment lines

bin/check fails on a Go comment line over 80 columns, counted as
bin/reflow counts them, with tabs as 8 columns. gofumpt does not wrap
comments, and the line length linter would also count code lines, which
the go-code skill keeps on one line, so ten long comment lines had
passed every check.

26 hours agoReflow comments over the reflow width
Anderson A. Giacomolli [Tue, 10 Nov 2026 20:47:30 +0000 (17:47 -0300)]
Reflow comments over the reflow width

bin/reflow wraps each changed paragraph again, so that no comment line
passes 80 columns with tabs as 8 columns, as the docs skill asks. Ten
lines were over, from edits that skipped the reflow. Only comments
change.

27 hours agoLog image and message sends
Anderson A. Giacomolli [Tue, 10 Nov 2026 19:45:36 +0000 (16:45 -0300)]
Log image and message sends

Each WhatsApp send logs one line, message sent at info or message send
failed at warning with its safe cause, and an image shown in Telegram
logs image sent. A chat shows as a short hash, the same for received
images and sends, so the log tells chats apart with no phone number,
text, or caption. Before, a successful send left no trace in the
journal.

Issue: 441b3c7

28 hours agoKeep test daemon sockets under the path limit
Anderson A. Giacomolli [Tue, 10 Nov 2026 19:27:23 +0000 (16:27 -0300)]
Keep test daemon sockets under the path limit

The test daemon keeps its data, and so its socket, in a short directory
under /tmp. t.TempDir holds the test name and the long TMPDIR of the
development shell, so a test with a long name failed to listen on a
socket path over 107 bytes, and bin/check failed in the shell unless
TMPDIR was set short by hand.

28 hours agoSend stored images to WhatsApp chats
Anderson A. Giacomolli [Tue, 10 Nov 2026 19:11:27 +0000 (16:11 -0300)]
Send stored images to WhatsApp chats

WhatsApp sends accept a stored image and use the text as its caption.
The send record includes the image name and precedes the upload, so a
repeated ID cannot upload or send again. Media errors keep safe causes
without URLs or keys.

The root asks for consent as for text sends, and image markers in tell
give children the shared pixels. The user can also ask to see a received
Telegram photo without a separate import.

28 hours agoShow stored images to the user
Anderson A. Giacomolli [Tue, 10 Nov 2026 18:59:13 +0000 (15:59 -0300)]
Show stored images to the user

The root can show a stored image as a Telegram photo and return its name
and path to terminal clients. A refused photo goes as a document, while
an uncertain send does not cause a second send. Children and subagents
have no image output tool.

29 hours agoName timeouts for the operations they limit
Anderson A. Giacomolli [Tue, 10 Nov 2026 18:09:23 +0000 (15:09 -0300)]
Name timeouts for the operations they limit

Each operation limit ends in Timeout and names its operation. Telegram
file lookup, image download, and typing have separate names from message
sends. All wait values stay the same, including the server wait for
updates and the memory build wait.

29 hours agoKeep time limits with their operations
Anderson A. Giacomolli [Tue, 10 Nov 2026 18:01:07 +0000 (15:01 -0300)]
Keep time limits with their operations

Operation files own their duration constants without struct fields that
only supply shorter test waits. Fake time checks the full send, lookup,
batch, catch-up, notice, and schedule waits. Retry delays and batch
policy values stay the same.

29 hours agoPass caller contexts through WhatsApp callbacks
Anderson A. Giacomolli [Tue, 10 Nov 2026 17:43:29 +0000 (14:43 -0300)]
Pass caller contexts through WhatsApp callbacks

Library callbacks use the context of WhatsApp.Run, so daemon
cancellation ends name lookups and image downloads. Each image keeps its
own deadline without the shorter name lookup deadline. Tests use their
caller context.

30 hours agoDerive contexts from the caller and name timeouts
Anderson A. Giacomolli [Tue, 10 Nov 2026 17:37:54 +0000 (14:37 -0300)]
Derive contexts from the caller and name timeouts

The go-code skill asks for contexts derived from the caller, with
context.WithoutCancel for work that must finish after a cancel and
context.Background only where no caller context exists. It also names
each operation limit after its operation with the Timeout suffix, in the
file that applies it. Handlers with a background context could not be
stopped by the daemon, and limits named only Time did not say what they
limit.

30 hours agoReceive images in WhatsApp batches
Anderson A. Giacomolli [Tue, 10 Nov 2026 17:14:06 +0000 (14:14 -0300)]
Receive images in WhatsApp batches

WhatsApp stores supported images before it acknowledges their messages,
so a stop cannot lose them. A download has its own limit of two minutes,
apart from the ten seconds of the name lookups. Batch text keeps the
image markers and captions on their own lines, so the agent and a routed
child can read the pixels. Failed images and other visual media keep
short text markers instead of stopping the batch. View-once messages
stay unread.

A failed download logs only a short chat hash and a safe cause, such as
an HTTP status, because the library error text can hold signed media
URLs. Tests use made-up images and a fake download client to check
storage, the limits, the markers, routed delivery, and restarts.

Issue: 441b3c7

32 hours agoSend terminal images by local path
Anderson A. Giacomolli [Tue, 10 Nov 2026 15:03:38 +0000 (12:03 -0300)]
Send terminal images by local path

Accept /image PATH with an optional caption and quoted paths with
spaces. Resolve relative paths in the client and let the daemon store
the image before it submits the marker and caption. The socket carries
only the path, so image bytes never enter its events or the chat log.

32 hours agoAccept owner photos and image files in Telegram
Anderson A. Giacomolli [Tue, 10 Nov 2026 14:57:46 +0000 (11:57 -0300)]
Accept owner photos and image files in Telegram

Download the largest supplied photo up to 1568 pixels, or an image file,
into the shared store and submit its marker and exact caption. Refuse
unsupported or large images with a short notice. Retry network failures
without moving the offset, and stop on storage failures so images are
not lost. Keep tokens and pixels out of daemon logs.

32 hours agoCarry new images through model request chains
Anderson A. Giacomolli [Tue, 10 Nov 2026 14:42:27 +0000 (11:42 -0300)]
Carry new images through model request chains

Attach stored pixels to new user messages for the whole turn chain.
Later turns keep text markers and descriptions, which keeps the request
prefix stable. Leaf compaction sees pixels once per build and preserves
visible details. Single-message zoom returns text and image parts while
the durable log keeps only text.

32 hours agoStore shared private images by content hash
Anderson A. Giacomolli [Tue, 10 Nov 2026 14:35:12 +0000 (11:35 -0300)]
Store shared private images by content hash

Keep one immutable JPEG, PNG, or WebP file per image in the shared data
store. Validate size and format before atomic publication, and preserve
image files and modes in backups. The WebP config decoder needs x/image
because the standard library has no WebP decoder.

32 hours agoRewrite the README as a user guide
Anderson A. Giacomolli [Tue, 10 Nov 2026 14:41:53 +0000 (11:41 -0300)]
Rewrite the README as a user guide

The README is a guide for the user: setup of the data directory, login,
Telegram, WhatsApp, the user service, and backups, then the client
commands, what the agent does, the log, and development. It drops the
internal files, formats, locks, queues, recovery details, and limits
that each feature had added, which the doc comments of their code hold.
It shrinks from 703 to 240 lines.

33 hours agoKeep the README for the user
Anderson A. Giacomolli [Tue, 10 Nov 2026 14:39:58 +0000 (11:39 -0300)]
Keep the README for the user

The docs skill says that the README is for the user and that a feature
adds at most a few lines to it, with internal files, locks, queues,
recovery, and limits in Go doc comments. Short alone was not enough:
each worker documented its feature in full, and the README grew to 700
lines.

36 hours agoImport WhatsApp history into a child
Anderson A. Giacomolli [Tue, 10 Nov 2026 10:48:50 +0000 (07:48 -0300)]
Import WhatsApp history into a child

The import command selects an existing direct child with --agent NAME
and uses its log, prompt, tools, cache key, and usage records. The root
stays the default target and supplies live cutoff history for a child.
Plans name the target without model calls or changes to its files.

Child rebuilds keep their staging directories and timestamped backups
outside children. Only complete child configs appear in that directory,
so a backup or interrupted rebuild cannot stop daemon startup.

36 hours agoUse both logs for WhatsApp import cutoffs
Anderson A. Giacomolli [Tue, 10 Nov 2026 10:43:34 +0000 (07:43 -0300)]
Use both logs for WhatsApp import cutoffs

Import plans use the first live message of each chat across the target
and root logs. An unrelated chat does not cut off an export, and only
imported days in the target count as held. This lets a child take its
history without copying newer live messages or skipping root-only days.

40 hours agoDeliver routed WhatsApp batches to children
Anderson A. Giacomolli [Tue, 10 Nov 2026 07:21:17 +0000 (04:21 -0300)]
Deliver routed WhatsApp batches to children

A routed batch enters the durable agent message queue as work and wakes
only its child. Saved log IDs prevent a second entry on restart, and a
receipt remains until inbox removal even if the child finishes first.
Receipts use batch numbers rather than a watermark because chats can
close out of number order.

Unrouted batches keep the root path. A missing child sends new inputs
and its queued external batches to the root. Routed events keep their
WhatsApp source without a subagent completion status, and daemon logs
name the destination without message text or chat IDs.

40 hours agoManage source routes with root tools
Anderson A. Giacomolli [Tue, 10 Nov 2026 07:06:03 +0000 (04:06 -0300)]
Manage source routes with root tools

The root keeps a private source-to-child map and manages it through
route, unroute, and routes. Only direct children can receive a route,
and only WhatsApp chat sources are supported. The prompt requires user
agreement, and WhatsApp status lists the configured routes. Route logs
omit source IDs because they can contain phone numbers.

40 hours agoGive the root tools to start and message children
Anderson A. Giacomolli [Tue, 10 Nov 2026 06:46:17 +0000 (03:46 -0300)]
Give the root tools to start and message children

The root creates permanent children with its model and effort, sends
them durable messages with tell, and reads their views with zoom. A
child has a short capitalized name for its area, such as House, which no
child, subagent, or the root uses. spawn keeps its short tasks. Children
have no creation or WhatsApp tools.

The root sees each child name and area in its turn state, while its
shared prompt stays stable. The prompt directs mixed-chat area messages
to the right child with their sender, date, and words, and requires user
agreement before the root sends a child draft to WhatsApp.

A new child is prepared outside the children directory and published in
one step, so a stop never leaves a half-made child that blocks the next
start, and a failed creation frees its name. Runtime children join the
daemon lifetime and backup locks before they receive tasks.

Issue: 63b101c

41 hours agoKeep each schedule with its owning agent
Anderson A. Giacomolli [Tue, 10 Nov 2026 05:50:59 +0000 (02:50 -0300)]
Keep each schedule with its owning agent

Schedules record the agent that sets them and wake only its loop. Saved
schedules without an owner take the name of their agent, so root tasks
keep their behavior across a restart. A different stored owner stops
startup instead of sending the task to the wrong agent.

42 hours agoDeliver messages between parent and child agents
Anderson A. Giacomolli [Tue, 10 Nov 2026 05:19:49 +0000 (02:19 -0300)]
Deliver messages between parent and child agents

A parent can queue a user message for its own child through the daemon.
The child's final reply queues a work message for the parent with the
child's name in brackets. Each delivery wakes its recipient, including
one that is busy, and an empty final reply sends nothing.

The durable queue keeps inputs until their turn completes and saves a
child report with its input acknowledgments. Saved log positions prevent
repeat entries after restart. Interrupted turns can repeat model calls
and tools. Queue failures stop the loops, and backups lock the queue
before the agent files. Turn logs name their agent. Tools and prompts
stay unchanged.

42 hours agoResume queued appends at their saved log ID
Anderson A. Giacomolli [Tue, 10 Nov 2026 05:06:24 +0000 (02:06 -0300)]
Resume queued appends at their saved log ID

Memory saves a queued message's position before it appends under the
write lock. Recovery reads that position or completes its append, so a
stop between the queue save and the log write cannot repeat the message.
The queue owns the saved position and stops delivery after a failure.

42 hours agoDescribe child agent directories and limits
Anderson A. Giacomolli [Tue, 10 Nov 2026 04:42:20 +0000 (01:42 -0300)]
Describe child agent directories and limits

The agent guide in the README describes manual child configuration,
separate state and calls, startup checks, and backup coverage. It makes
clear that clients still address the root and that children have no
WhatsApp tools or parent message transport.

42 hours agoRun each child with its own files and loop
Anderson A. Giacomolli [Tue, 10 Nov 2026 04:38:37 +0000 (01:38 -0300)]
Run each child with its own files and loop

The daemon opens the root and each direct child with separate memory,
compaction, usage records, schedules, and subagents. Invalid child
configuration stops startup, and the ready event names the children.
Each child uses its own cache key and has no WhatsApp tools. Its turn
and compaction calls share the same prompt and tools.

Backups flush and lock every agent and its subagent logs during the
copy, so the archive holds the full state of the children as well as the
root. Clients still address only the root.

42 hours agoDefine child agent areas and reporting rules
Anderson A. Giacomolli [Tue, 10 Nov 2026 04:27:07 +0000 (01:27 -0300)]
Define child agent areas and reporting rules

Child configuration names its parent and responsibility together. Its
prompt limits work to that area, reports only what needs attention,
allows an empty report, and requires drafts instead of WhatsApp sends.
Each child reads its own instructions file at each call.

42 hours agoWait for the send back line in the retry test
Anderson A. Giacomolli [Tue, 10 Nov 2026 04:49:06 +0000 (01:49 -0300)]
Wait for the send back line in the retry test

The bot writes the end of a send outage to the log after the send
returns, so the fake server can hold the message before the line exists.
The test now waits for the line instead of reading the log once, which
made it fail now and then, also inside nix build.

43 hours agoDocument private backups and a daily user timer
Anderson A. Giacomolli [Tue, 10 Nov 2026 03:56:17 +0000 (00:56 -0300)]
Document private backups and a daily user timer

The README explains backup consistency, secret archive contents, safe
restore, and the empty destination requirement. A user timer example
makes one local archive each day and keeps the last 14 after a
successful backup.

43 hours agoBack up the daemon and restore its data
Anderson A. Giacomolli [Tue, 10 Nov 2026 03:51:26 +0000 (00:51 -0300)]
Back up the daemon and restore its data

The backup command asks the running daemon for an archive. A flushed
memory snapshot holds the write locks during the agent copy, and SQLite
VACUUM INTO saves the WhatsApp session without raw database files.
Compression runs after the write locks are released.

Restore validates the archive in a staging directory before it installs
the files. The token lock excludes a running daemon, and a nonempty
destination fails without replacement of its data.

44 hours agoWrite private data archives with safe extraction
Anderson A. Giacomolli [Tue, 10 Nov 2026 03:36:42 +0000 (00:36 -0300)]
Write private data archives with safe extraction

The archive writer installs a complete mode 0600 tar.gz file through a
temporary file and a rename. Extraction preserves regular file and
directory modes and rejects unsafe paths, links, and special files.

44 hours agoFormat only the Go files of the repository
Anderson A. Giacomolli [Tue, 10 Nov 2026 03:24:20 +0000 (00:24 -0300)]
Format only the Go files of the repository

bin/format and bin/check give gofumpt only the Go files that Git tracks
or would add, as they do for the other formatters. gofumpt walked into
the ignored .devenv directory, so a format in the main checkout changed
the files of a worktree there, and a check failed on its unfinished
files.

44 hours agoRevert compaction view block messages
Anderson A. Giacomolli [Tue, 10 Nov 2026 03:23:14 +0000 (00:23 -0300)]
Revert compaction view block messages

This reverts 0a98ccb. A compaction sends the view, its closing tag, a
newline, and the task as one user message with the same joined bytes.
Each retry adds its note as one separate user message. The prompt path,
names, style, and summary-failure log stay unchanged.

After the split, compactions read 32.8% of input from the cache across
493 calls, against 31.9% across 183 calls before it. Imports read 30.7%.
The split adds code and messages for no measured gain.

44 hours agoLog the version when the daemon is ready
Anderson A. Giacomolli [Tue, 10 Nov 2026 02:59:40 +0000 (23:59 -0300)]
Log the version when the daemon is ready

The ready line starts with the build version, so the journal shows which
build runs after each start.

Issue: 6d865d5

44 hours agoShow an input prompt while the agent is idle
Anderson A. Giacomolli [Tue, 10 Nov 2026 02:46:12 +0000 (23:46 -0300)]
Show an input prompt while the agent is idle

The terminal client ends shown events with a prompt while no turn runs.
Busy and idle events track the turn, and the next shown event clears the
prompt before it prints. Pipes and files keep the same output. The small
prompt does not keep a typed line separate from incoming events.

44 hours agoShow styled replies only on terminal output
Anderson A. Giacomolli [Tue, 10 Nov 2026 02:38:19 +0000 (23:38 -0300)]
Show styled replies only on terminal output

Replies and work reports use the terminal width for Markdown rendering.
Other event kinds and output to files or pipes keep their text. Each
event reads the width again, with 80 columns when a terminal reports
zero. Tests use isolated terminal descriptors and fake events, including
single-column and very narrow table headers.

44 hours agoRender Markdown with plain terminal styles
Anderson A. Giacomolli [Tue, 10 Nov 2026 02:30:51 +0000 (23:30 -0300)]
Render Markdown with plain terminal styles

The terminal renderer wraps styled text and table cells to the display
width. It uses bold, dim, italic, and reverse without colors, and keeps
unclosed marks as text through the shared parser. Wide characters take
two columns. The existing text module supplies width data, so vendoring
includes that package without a new dependency.

45 hours agoShare the Markdown marks and block parser
Anderson A. Giacomolli [Tue, 10 Nov 2026 02:26:46 +0000 (23:26 -0300)]
Share the Markdown marks and block parser

The inline and block parser supplies the same closed marks to each
renderer. Telegram keeps its existing text and entities while terminal
rendering can use the same rules for unclosed marks and code fences.

45 hours agoWrite the log rules in the Go skill
Anderson A. Giacomolli [Tue, 10 Nov 2026 01:47:01 +0000 (22:47 -0300)]
Write the log rules in the Go skill

The go-code skill gets the rules for log lines: a short event as the
message, names, IDs and durations as attributes, the cause in err, a
level for each kind of event, and no secrets or personal data. The rules
were only in issue comments, so workers missed them, and every Go task
reads this skill.

45 hours agoExplain daemon log levels and journal filtering
Anderson A. Giacomolli [Tue, 10 Nov 2026 01:35:24 +0000 (22:35 -0300)]
Explain daemon log levels and journal filtering

The README gives the short log form and the meaning of each level. The
journal example selects warnings and errors without the normal events,
so a user can find the failures that need attention.

45 hours agoLog daemon events at their slog levels
Anderson A. Giacomolli [Tue, 10 Nov 2026 01:33:22 +0000 (22:33 -0300)]
Log daemon events at their slog levels

Each daemon part gives its event, level, and raw attributes to the
shared handler. Normal events use info, recoverable failures use
warning, and lost data or stopped work uses error. Outages still log
only their start and end, and probe and rebuild runs discard their
summary log output.

46 hours agoFormat short daemon events with slog
Anderson A. Giacomolli [Tue, 10 Nov 2026 01:26:01 +0000 (22:26 -0300)]
Format short daemon events with slog

A shared handler writes the event and ordered attributes, with the error
cause last. Journal lines carry a syslog priority and terminal lines
carry the time and level, so each output keeps short, readable events.

46 hours agoVersion the package and command from the commit
Anderson A. Giacomolli [Tue, 10 Nov 2026 00:54:15 +0000 (21:54 -0300)]
Version the package and command from the commit

The Nix package and the version command use the commit date and short
revision, with a dirty suffix for a changed tree. Direct Go builds keep
the dev version. The install check compares the binary version with the
package version so a missing linker value fails the build.

2 days agoGive the rebuild its own call limit
Anderson A. Giacomolli [Mon, 9 Nov 2026 21:56:19 +0000 (18:56 -0300)]
Give the rebuild its own call limit

A rebuild summarizes the whole merged log, so it can need more calls
than a probe sample. The import of two chats estimates 647 calls, close
to the 660 calls of the probe, and a stop at the limit swaps nothing and
wastes the calls. The rebuild now stops after 1,500 calls, and the quota
stop still guards the account. The probe keeps its own limit of 660
calls.

Issue: b0b8bf9

2 days agoName the tools that check the Go rules
Anderson A. Giacomolli [Mon, 9 Nov 2026 21:17:23 +0000 (18:17 -0300)]
Name the tools that check the Go rules

The skills identify the linters that enforce error, assertion, name, and
spacing rules. They keep manual review for logical groups, local error
paths, and the config exceptions because passing lint does not prove
those rules.

2 days agoCheck spacing between Go statement blocks
Anderson A. Giacomolli [Mon, 9 Nov 2026 21:14:59 +0000 (18:14 -0300)]
Check spacing between Go statement blocks

Wsl v5 checks empty lines around blocks and multiline declarations and
calls. Spacing keeps immediate error checks and short declarations with
their uses. Checks that split those groups are off because they conflict
with the Go rule. The cleanup changes only spacing and groups of
variable declarations.

2 days agoSeparate returns from longer statement blocks
Anderson A. Giacomolli [Mon, 9 Nov 2026 21:03:33 +0000 (18:03 -0300)]
Separate returns from longer statement blocks

Nlreturn checks spacing before returns and branch statements. Its short-
block allowance keeps a declaration with its immediate use, as the Go
rules require. Longer blocks have an empty line before they return or
continue.

2 days agoCheck operation context on returned errors
Anderson A. Giacomolli [Mon, 9 Nov 2026 21:00:39 +0000 (18:00 -0300)]
Check operation context on returned errors

Wrapcheck requires operation context on errors from package and
interface calls. Returned errors keep their causes for errors.Is and
errors.As. Context cancellation and the listed functions with one error
path keep their direct returns, as the Go rules allow.

2 days agoCheck Go names and declarations with revive
Anderson A. Giacomolli [Mon, 9 Nov 2026 20:54:59 +0000 (17:54 -0300)]
Check Go names and declarations with revive

The lint check applies revive to Go declarations and common style rules.
Unused callback and interface parameters have blank names, and the
command has a package comment for its entry points.

2 days agoCheck test assertions with testifylint
Anderson A. Giacomolli [Mon, 9 Nov 2026 20:52:43 +0000 (17:52 -0300)]
Check test assertions with testifylint

Test assertions use the specific require helpers for errors, lengths,
JSON, and numeric values. Test setup completes before its server starts
so that a failed assertion stops the test goroutine, not a worker.

2 days agoCheck error handling and common Go mistakes
Anderson A. Giacomolli [Mon, 9 Nov 2026 20:49:59 +0000 (17:49 -0300)]
Check error handling and common Go mistakes

The lint config keeps the standard linters and adds errorlint and
gocritic. Error checks accept wrapped errors, and common Go mistakes
fail the same check command as the existing code checks.

2 days agoName the test group in English
Anderson A. Giacomolli [Mon, 9 Nov 2026 20:39:45 +0000 (17:39 -0300)]
Name the test group in English

The find test names its group "Souza Family", so all test data is in
English. The contact with an accent in its name still checks that a
search ignores accents.

2 days agoImport WhatsApp exports before live messages
Anderson A. Giacomolli [Mon, 9 Nov 2026 20:29:48 +0000 (17:29 -0300)]
Import WhatsApp exports before live messages

"onechat import [-n] ZIP..." reads the chat exports of the phone, makes
one marked WhatsApp batch for each chat and day, and rebuilds the memory
with them in date order. It takes only messages from before the first
live batch, maps the owner's profile name to "You", and skips the chat
days that an earlier import added. With -n it prints the plan and the
estimated calls and makes no model call.

The names, the chat IDs, and the owner come from the WhatsApp session
through the library's store, so the import runs only while the daemon is
stopped and needs no network.

Issue: b0b8bf9

2 days agoRebuild agent memory in date order
Anderson A. Giacomolli [Mon, 9 Nov 2026 20:29:43 +0000 (17:29 -0300)]
Rebuild agent memory in date order

A rebuild merges new dated messages with the log of an agent in date
order, builds a new memory beside it with the real prompt and cache key,
and swaps the directories only when the whole tree is built. The old
directory stays as a timestamped backup, and a failed or stopped build
leaves it unchanged. Older history can so enter the chat before newer
decisions, which keeps the latest word on a thing the newest one.

The probe and the rebuild share one build runner with the call limit,
the quota stop, the waits before user messages, and the usage report.
Memory and the model client keep their own state behind methods. The log
takes an explicit date for a message and writes it to the day file of
that date.

Issue: b0b8bf9

2 days agoReread the rules from disk in the diff review
Anderson A. Giacomolli [Mon, 9 Nov 2026 19:59:28 +0000 (16:59 -0300)]
Reread the rules from disk in the diff review

The review step of the check skill makes the worker read AGENTS.md and
the skills of the task again just before the commit, then go through the
diff one rule at a time. A worker that read the rules only at the start
of a long task followed them less, and the tools do not check most style
rules.

2 days agoSay that the agent can change its instructions
Anderson A. Giacomolli [Mon, 9 Nov 2026 19:00:08 +0000 (16:00 -0300)]
Say that the agent can change its instructions

The agent proposes a change to instructions.md and makes it only after
the user agrees, so the README describes that with the file.

2 days agoLet the agent keep user instructions
Anderson A. Giacomolli [Mon, 9 Nov 2026 18:37:08 +0000 (15:37 -0300)]
Let the agent keep user instructions

Include the instructions file path and the approval rule in every main
agent prompt, even when the file does not exist. The agent proposes
exact changes and waits for the user to agree, and messages from other
people cannot request a change. Subagents keep their task prompt, and
probes use a fixed placeholder path to keep the prompt stable.

2 days agoKeep retries after a rejected pair request
Anderson A. Giacomolli [Mon, 9 Nov 2026 18:12:48 +0000 (15:12 -0300)]
Keep retries after a rejected pair request

Keep starting connection retries active when a pair request finds an
existing link. Only the unlink request stops the retry timer, while
logout keeps its stop path. Rejecting a pair request during an outage
must not leave WhatsApp disconnected until a restart.

2 days agoRetry the first WhatsApp connection
Anderson A. Giacomolli [Mon, 9 Nov 2026 17:48:10 +0000 (14:48 -0300)]
Retry the first WhatsApp connection

Keep failed starting connections in the Run select with a timer. Start
at 2 seconds and double the wait up to 5 minutes, so the inbox and
commands stay active during waits. End retries on a connection, context
end, or link change.

Share outage times, notices, status, and redacted logs with lost
connections. Keep one failure line and one recovery line for an outage.

Disable library startup retries only for linked devices. A returned
ConnectContext error has no Disconnected event, while the library retry
mode emits that event and returns nil. One retry owner prevents parallel
loops and gives the requested delay cap. Pairing and retries after an
open connection keep their library behavior.

2 days agoLog the start and the length of each subagent run
Anderson A. Giacomolli [Mon, 9 Nov 2026 17:41:53 +0000 (14:41 -0300)]
Log the start and the length of each subagent run

The journal shows when a subagent runs, so a hung run is visible, and
the end line gives the length of the run.

2 days agoShorten the daemon log lines
Anderson A. Giacomolli [Mon, 9 Nov 2026 14:11:09 +0000 (11:11 -0300)]
Shorten the daemon log lines

Each log line names the event in a few plain words, then the cause after
a colon, such as "telegram: receive failed: 502 Bad Gateway (retry in
2s)" or "whatsapp: connected again after 1m25s". The lines no longer
explain what the event means for the user: they stay short enough to
read in the journal at a glance. A Telegram error gives the HTTP status
and its text without a prefix, because the telegram: prefix names the
service. The behavior of the logs does not change.

Issue: e4acfcb

2 days agoLog failed summary builds
Anderson A. Giacomolli [Mon, 9 Nov 2026 13:35:37 +0000 (10:35 -0300)]
Log failed summary builds

A build of a summary node that fails logs one line with the node and the
cause, and tells that the build is tried again at the next message. A
build that a stop of the daemon ends logs nothing. The error of the
compactor holds no node, because the line names it once.

The tests give each memory a logger, and a shared helper gives the ones
that the tests do not read.

Issue: e4acfcb

2 days agoLog each schedule run by its ID
Anderson A. Giacomolli [Mon, 9 Nov 2026 13:31:00 +0000 (10:31 -0300)]
Log each schedule run by its ID

Each run of a schedule logs one line with the ID of the schedule, after
its message is durable in the chat. A late run after a stop of the
daemon tells how late it is. The line holds no text of the schedule, so
the log shows that a task ran but not what it asks.

Issue: e4acfcb

2 days agoLog failed turns and the ends of subagents
Anderson A. Giacomolli [Mon, 9 Nov 2026 13:28:15 +0000 (10:28 -0300)]
Log failed turns and the ends of subagents

A turn that ends with an error logs one line with the error that the
clients get, such as a needed login or HTTP 429, so that it is not lost
when no client is connected. An interrupt of the user or a stop of the
daemon logs nothing.

The end of each subagent run logs one line with the name of the
subagent: done, failed with the cause, or stopped by the user. A cut
subagent that cannot go on after a restart logs its cause too.

Issue: e4acfcb

2 days agoLog each change of the WhatsApp connection
Anderson A. Giacomolli [Mon, 9 Nov 2026 13:23:55 +0000 (10:23 -0300)]
Log each change of the WhatsApp connection

The WhatsApp log gets one line for each change of the connection of the
linked device: connected, a failed first connection, a lost connection,
connected again with the length of the outage, a connection that does
not come back by itself, a link, an unlink, and a logout from the phone.
The retries of the library between them log nothing, and the logger of
the library stays off.

Each line says first what happens to the WhatsApp messages, and then the
cause. An unlink clears the time of the last disconnection, so the first
connection of a new link does not count as the end of an outage.

Issue: e4acfcb

2 days agoStamp daemon log lines only outside the journal
Anderson A. Giacomolli [Mon, 9 Nov 2026 13:19:42 +0000 (10:19 -0300)]
Stamp daemon log lines only outside the journal

The daemon makes the logger of each part in one place. Under the
journal, which sets JOURNAL_STREAM and adds its own time, the lines have
no time stamp. Otherwise every line has the standard time stamp, the
onechat lines too, so that no line has two time stamps and none has
none.

The start line names each value: the socket, the model and its effort,
the directory where the commands run, whether WhatsApp is linked, and
the number of active schedules.

Issue: e4acfcb

2 days agoLog Telegram outages once in plain words
Anderson A. Giacomolli [Mon, 9 Nov 2026 13:16:50 +0000 (10:16 -0300)]
Log Telegram outages once in plain words

A Telegram outage logs one line at its start and one at its end, with
its length, and the retries between them log nothing. Each line says
first what the user loses or gets, such as "cannot get messages from
Telegram" or "replies go to Telegram again, after 1m25s", and then the
cause in plain words, such as "no answer in 1m10s" or "Telegram answered
502 Bad Gateway".

The errors of the Bot API client hold no method name and no Go deadline
text, so that the log line can say what the call was for. A refused
format, a dropped reply, and an ignored message use the same plain
words.

Issue: e4acfcb

2 days agoOpen the chat when no command is given
Anderson A. Giacomolli [Mon, 9 Nov 2026 13:13:51 +0000 (10:13 -0300)]
Open the chat when no command is given

onechat with no command opens the terminal chat, as onechat chat does,
because the chat is the command of daily use once the daemon runs as a
service. A start of the daemon stays explicit, so a second daemon does
not start by accident. onechat help, --help, and -h print the commands,
and an unknown command prints the error and the same help. The install
check runs onechat help in place of the bare command.

2 days agoSend the compaction view in block messages
Anderson A. Giacomolli [Mon, 9 Nov 2026 13:02:40 +0000 (10:02 -0300)]
Send the compaction view in block messages

A compaction sends each whole block of four view lines as its own user
message, the first one with the opening tag, and one last user message
with the rest of the lines, the closing tag, and the task. The note of a
retry is one more user message after them. The blocks count from the
first line of the view, so two compactions whose views begin with the
same lines send the same block messages. Joined, the messages are the
same bytes as the one message before.

The backend reads a cache entry only at a message end of a request. With
the view in one message, a compaction read only the shared prompt and
tools, about 1,920 of 10,000 tokens. The first request of a turn sends
its view as messages that only grow and reads 74% to 85% from the cache,
so the compactions get the same kind of split.

Issue: 72c95ad

2 days agoShorten user service updates
Anderson A. Giacomolli [Mon, 9 Nov 2026 02:03:01 +0000 (23:03 -0300)]
Shorten user service updates

The user unit links through result-service, so each build replaces its
package without another unit link. The update command builds with that
out-link, reloads the user manager, and uses try-restart to restart only
an active service. A stopped service stays stopped.

The README gives the first link and the two update commands. The checks
include shell lint for the update script.

Issue: 99a5e07

2 days agoDocument user service updates
Anderson A. Giacomolli [Mon, 9 Nov 2026 01:59:06 +0000 (22:59 -0300)]
Document user service updates

The README gives the update commands after a git pull. The same result
link keeps the new package available, and linking the unit again makes
the user manager load the unit from that package before the service
restarts.

Issue: 99a5e07