commits on main
2026-10-02
2597195d Aly Raffauf docs(storage): explain online reports and offline cleanup
docs(storage): explain online reports and offline cleanup
Describe who owns the report and when local diagnosis applies. Reported paths never authorize local deletion.
b872b4b8 Aly Raffauf fix(e2e): inherit installed tools for loopback hosts
fix(e2e): inherit installed tools for loopback hosts
Use the actual environment PATH instead of fixed system directories. Keep the fixture Python first and quote the inherited path.
dcac456f Aly Raffauf test(storage): exercise report authority and offline safety
test(storage): exercise report authority and offline safety
Check real totals, discovery failures, and canceled diagnostics through the CLI. Online reports work without local storage or Python.
9542398d Aly Raffauf feat(cli): separate online reports from offline diagnosis
feat(cli): separate online reports from offline diagnosis
Ask the running daemon for storage usage and keep local SQL in the offline path. Private snapshots leave the installation untouched.
a6f9ab5c Aly Raffauf fix(storage): keep kernel state when SQLite disappears
fix(storage): keep kernel state when SQLite disappears
Repeat the database check after confirmation. A missing database now stops cleanup before any state file is removed.
91ebead9 Aly Raffauf feat(storage): serve typed usage reports from the daemon
feat(storage): serve typed usage reports from the daemon
Let the daemon count its own storage. Online clients can leave Python and SQLite at home.
d1bf2ecd dawn tui: after /cd, offer the /link add that links the folder the session left
tui: after /cd, offer the /link add that links the folder the session left
a notice with the folder as stored, ready to paste; a later move replaces it, and a move away from a missing folder offers nothing. Signed-off-by: dawn <90008@klbr.net>
483f7cfa dawn tui: no signoff for a turn a note opened that the agent never answered
tui: no signoff for a turn a note opened that the agent never answered
a /link or /work note commits just before your next message and opened a turn of its own, which your message then closed with an empty face and copy mark. Signed-off-by: dawn <90008@klbr.net>
8679812f dawn ssh: say when a probe is copying the kernel to a host, in the picker and the chat
ssh: say when a probe is copying the kernel to a host, in the picker and the chat
albedo_ssh.py probe announces a staging step on its own line before it copies the bundle; albedo_ssh.erl passes lines on as they arrive and keeps the last as the answer. /hosts/:host carries step while warming, and the session status's kernel carries it while a remote kernel boots, so both read "copying the kernel to chernobog…" instead of "connecting to". Signed-off-by: dawn <90008@klbr.net>
9e1bc29c dawn tui: animate a face while a host connects, in the picker and the chat status line
tui: animate a face while a host connects, in the picker and the chat status line
the picker ticks its own face while any host warms and stops once they settle; the chat animates while the session's kernel boots or reattaches on its host. both pick the face by the host's label, so a host connects with the same one in both places. Signed-off-by: dawn <90008@klbr.net>
2f43cb2d dawn links: link workspaces into one project, sharing memory and work items
links: link workspaces into one project, sharing memory and work items
/link adds or removes peers in a workspace_links group. each member keeps writing its own memory and work items; reads cover the group (memory snapshot, grep and search; every work ledger read and change), so a gone member loses nothing and unlinking undoes nothing. a member's folder is checked where it is: a remote one with one exists gather over the shared ControlMaster, every member at once. a host that doesn't answer reads as connecting, sign in or unreachable, never gone, and opening a session never waits on a host. a link or unlink queues a note in every open session of the workspaces it touches; a link note carries the new members' memory snapshot, so an open session sees it without rebuilding its prompt. memory moves daemon-side: the kernel's memory object calls the memory host route through a new blocking host_now, so a remote session's notes land in the daemon's ALBEDO_HOME instead of the host's. Signed-off-by: dawn <90008@klbr.net>
fbcd4e8c dawn kernel: a restarted daemon re-counts held heavy slots and ends a dead kernel's jobs
kernel: a restarted daemon re-counts held heavy slots and ends a dead kernel's jobs
#59: the hello reports jobs holding a granted slot, and the new pool claims them; kernel_links records the job groups a kernel owns, so an attach that finds the kernel gone still ends them. Darwin now gets a leader token (start time via sysctl), so a reused pid is never signalled. kernel.md spells out why replayed kernel frames are harmless after a crash restart. Signed-off-by: dawn <90008@klbr.net>
8b908ba7 dawn tui: browse hosts in the folder picker, warm them before committing, and show the kernel link on the header's host
tui: browse hosts in the folder picker, warm them before committing, and show the kernel link on the header's host
#58: host:/path and @ queries, host completion from GET /hosts, reachability and sign-in on rows, connecting/lost states on the header host, plus the ssh sign-in handoff for turns refused with host_needs_auth (#56). Signed-off-by: dawn <90008@klbr.net>
f8358641 dawn kernel: swap stale kernels at idle and run kernels on remote hosts over ssh
kernel: swap stale kernels at idle and run kernels on remote hosts over ssh
#55: a kernel on an older bundle, protocol or module set is swapped at the next idle moment (snapshot, boot the new one beside it, restore, stop the old), with a note naming what carried; live jobs hold the swap until /kernel upgrade forces it. #56: sessions at host:/path boot their kernel there through the same bridge over ssh, on the ControlMasters remote.connect() uses; reaping runs on the host, heavy slots are per host, an unreachable host is a reattach rather than a lost kernel, and login profiles that print cannot corrupt the frames. #57: /fs routes, AGENTS.md and project skills read remote workspaces in one ssh round trip, interpreted by the local code path; GET /hosts lists recent and ssh-config hosts. Signed-off-by: dawn <90008@klbr.net>
c3dc8ec1 dawn kernel: run the python kernel detached behind a bridge, with a durable seq/ack session layer so it survives dropped connections and daemon restarts
kernel: run the python kernel detached behind a bridge, with a durable seq/ack session layer so it survives dropped connections and daemon restarts
Signed-off-by: dawn <90008@klbr.net>
e6ecc048 dawn workspaces: remote locations ([user@]host:/abs/path) with host labels, refusals until kernels can run there, and the host in the tui header
workspaces: remote locations ([user@]host:/abs/path) with host labels, refusals until kernels can run there, and the host in the tui header
Signed-off-by: dawn <90008@klbr.net>
4c9c2242 Aly Raffauf docs(client): explain adapter ownership and recovery
docs(client): explain adapter ownership and recovery
Show where new operations belong and how callers handle their results.
be17beac Aly Raffauf test(daemon): exercise typed workflows against a separate daemon
test(daemon): exercise typed workflows against a separate daemon
Cover context, trees, catalogs, MCP secrets, and webhook changes. Recover rejected creation receipts without allocating a session.
626ac74f Aly Raffauf refactor(daemon): give the client adapter protocol ownership
refactor(daemon): give the client adapter protocol ownership
Keep routes, typed decoding, and recovery in domain files. Migrate callers and preserve confirmed results when a follow-up fails.
bc34a398 Aly Raffauf refactor(cli): move session rendering out of the adapter
refactor(cli): move session rendering out of the adapter
Keep display helpers with their screens and shared presentation code.
e0678ba4 Callie Peden fix(codex): exclude virtual ultra reasoning effort
fix(codex): exclude virtual ultra reasoning effort
9c41da62 Aly Raffauf docs(daemon): explain attachment and local startup
docs(daemon): explain attachment and local startup
Describe the restart choice, daemon-owned defaults, and the connection contract for future clients.
370f0ab7 Aly Raffauf test(daemon): cover lifecycle races and recovery
test(daemon): cover lifecycle races and recovery
Exercise real startup, cancellation, restart approval, and active-work recovery. Wait for the tool before testing a crash.
354f06cd Aly Raffauf refactor(cli): separate attach, launch, and upgrade
refactor(cli): separate attach, launch, and upgrade
Keep restart approval in the CLI and make local discovery failures actionable. Cancellation leaves shared daemons running.
a6d8ebe3 Aly Raffauf feat(daemon): own startup defaults and readiness
feat(daemon): own startup defaults and readiness
Give standalone and local launches the same defaults, protected discovery record, and honest health status.
b7914ad5 Aly Raffauf fix(cli): match Python trace limits with O(n) text checks
fix(cli): match Python trace limits with O(n) text checks
Count Unicode characters so valid Python traces stay visible. Decoding stays O(n), with character checks adding 1-3% in the same microbenchmarks.
59aa6f71 Aly Raffauf fix(cli): keep chats readable with O(n) trace decoding
fix(cli): keep chats readable with O(n) trace decoding
Skip broken display details so saved chats still open. Trace decoding benchmarks take 48-61% less time and use 68 allocations instead of 73.
cec01ea7 Aly Raffauf perf(stream): skip missing provider-error diagnostics
perf(stream): skip missing provider-error diagnostics
OTP 28 medians cut text decoding from 5.01 to 4.75 us (about 5% faster) versus the preceding commit. Preserve error precedence and malformed-envelope fallthrough; full test.sh passed.
3815558a Aly Raffauf perf(stream): validate delta maps without rebuilding them
perf(stream): validate delta maps without rebuilding them
OTP 28 medians used 2.4% fewer reductions for text and 4.9% fewer with reasoning; plain-text timing was unchanged. Keep string-key validation; all 212 Gleam tests passed.
9137b328 Aly Raffauf perf(stream): make unknown-field emptiness checks O(1)
perf(stream): make unknown-field emptiness checks O(1)
OTP 28 medians: rejecting 10,000-key objects fell from 4.36 to 1.68 ms (2.6x faster), with ordinary text unchanged. Preserve empty-value semantics; all 203 Gleam tests passed.
34b54dc1 nekomimi.pet test: make the gate usable on macOS
test: make the gate usable on macOS
- ty: pin python-platform to linux. The tests call os.pidfd_open behind a skip, and ty on macOS reported it unresolved, which failed the gate and the pre-commit hook before any suite ran. - e2e harness: resolve the scratch root. The daemon reports realpaths, so on macOS (/tmp -> /private/tmp) two catalog and extensions tests compared unresolved paths against resolved ones and failed on a clean checkout. - snapshot-daemon.sh: start from an empty output directory. Reusing one kept the previous beams (cp -R nested into the old ebin) and let `ln -s` follow the old priv link into the checkout as priv/priv.
d056d320 nekomimi.pet feat(mcp): skip servers that are offline and add them when they return
feat(mcp): skip servers that are offline and add them when they return
A server that could not start used to fail the whole mcp extension for the session, taking every other server's tools with it. It is now left out with a warning, and the rest load. A missing server is probed when the session shows activity, never on a timer, with doubling backoff from the new `retryMs` setting (default 30s). One found up asks the session to refresh at the end of a turn, which leaves the usual "capabilities changed" turn and pins the old prompt until compaction. `extension.Session` gains `refresh(reason)` for this. Saving or enabling a server through settings stays strict, so a mistyped command is still refused where it is typed.
0405d908 Aly Raffauf perf(daemon): reduce commit collection from O(n^2) to O(n)
perf(daemon): reduce commit collection from O(n^2) to O(n)
OTP 28 microbenchmarks, seven-sample medians: 32 commits took 2.54 to 1.38 us (1.8x faster), and 4,096 took 12.28 to 0.21 ms (58x faster). Order and positions stay intact; full test.sh passed.
c970a11a Aly Raffauf docs(stream): explain bounded delivery
docs(stream): explain bounded delivery
Document queue limits, overflow recovery, and coalesced session wakes.
dabb0e70 Aly Raffauf fix(tui): refresh agents after stream overflow
fix(tui): refresh agents after stream overflow
Subscribe before loading the tree and discard stale refresh replies. Recovery clears unfinished previews while keeping drafts and pending action results.
646a2023 Aly Raffauf fix(stream): bound subscriber delivery
fix(stream): bound subscriber delivery
Cap agents queues before mailboxes and coalesce session wakes. Slow readers overflow cleanly while model work keeps moving.
9edfece6 Aly Raffauf docs(stream): explain generation-bound replay
docs(stream): explain generation-bound replay
Two cursor values, one checkpoint. Document resets and reconnects for client authors.
9c2c62ac Aly Raffauf test(stream): cover replay across restarts
test(stream): cover replay across restarts
Make old cursors meet new actors. Check durable resets, keepalives, failed reads, and older-history navigation.
0b52054a Aly Raffauf fix(stream): bind replay to actor generations
fix(stream): bind replay to actor generations
New actors get fresh replay tickets. Keep generation and sequence together through resets and reconnects.
5e4df35c Aly Raffauf docs(sessions): explain when streams take a break
docs(sessions): explain when streams take a break
Describe cursor consumption, reconnect delays, and the one-reset recovery limit.
71ebb978 Aly Raffauf fix(tui): give broken streams a graceful stop
fix(tui): give broken streams a graceful stop
Retry temporary disconnects and allow one durable reset for protocol failures. Show terminal failures, stop polling, and keep drafts and pending work intact.
2370e605 Aly Raffauf fix(cli): keep stream batches honest
fix(cli): keep stream batches honest
Validate known events before delivery and save cursors only after consumption. Keep unknown kinds quiet and classify stream failures.
67f241f4 Aly Raffauf docs(operations): explain receipts and recovery
docs(operations): explain receipts and recovery
Document the queue, storage, and retry contracts. Spell out what an unresolved action means.
a9354a36 Aly Raffauf feat(tui): keep unresolved turns in sight
feat(tui): keep unresolved turns in sight
Retain uncertain turns and creation handles across navigation. Expired receipts leave a visible note and stop the polling loop.
4b54992d Aly Raffauf feat(cli): give retries one identity
feat(cli): give retries one identity
Carry operation handles through lost acknowledgements and stop recovery when receipts expire. Keep prompt cancellation scoped to its own submission.
a8fec8b9 Aly Raffauf feat(daemon): give submissions a durable receipt
feat(daemon): give submissions a durable receipt
Keep each accepted input in line across retries and restarts. Bound the queue and keep image payloads out of display metadata.
5dbb5daa Aly Raffauf fix(tui): keep replies and paste in their lane
fix(tui): keep replies and paste in their lane
Reject stale screen replies, finish chat loads under modals, and feed paste to the focused input.
072198d3 Aly Raffauf fix(prompt): cancel yours and follow the right turn
fix(prompt): cancel yours and follow the right turn
Track submission membership through completion and report timeout cleanup honestly.
53b1925b Aly Raffauf refactor(daemon): give stream events proper types
refactor(daemon): give stream events proper types
Validate known events before delivery and leave the cursor untouched on malformed batches.
6cd888d5 Aly Raffauf perf(cli): read history without the shuffle
perf(cli): read history without the shuffle
Count turns per page and assemble the requested history once.