Skip to content

koto 1.7.1

Choose a tag to compare

@jpzk jpzk released this 25 Oct 10:04
Immutable release. Only release title and notes can be modified.

koto 1.7.1

TUI: Nerd Font icons for session rows (#58)

  • Session rows in the tree show a Nerd Font icon instead of the hollow ◦: a git-branch icon (nf-oct-git_branch, U+F418) for regular sessions and a bullseye (nf-fa-bullseye, U+F140) for goal runs (goal-<name>, including -judge).
  • The icon stays gray. Unread rows still show the pink ●. Both icons are one cell wide, like ◦, so row width and padding do not change.
  • Opt-out: set KOTO_TUI_NERDFONT=0 (or false/no/off) to get ◦ back on terminals without a Nerd Font. It is read once, at startup.
  • In black-and-white mode the icons fold to - and O, one cell each.

TUI: ctrl+x on a session row destroys that session, not the group (#59)

  • On a session row, ctrl+x opens its own confirm dialog: "destroy session <s> of <g>? its conversation and transcript are deleted". y calls the daemon's existing Clear RPC for that one session.
  • On a group row, ctrl+x is unchanged: it destroys the group after the existing confirm dialog.
  • Goal rows (including -judge) and main are refused with a status line. Job rows still target their group.
  • The TUI refuses to send an empty, -, default, goal or main session name, because Clear with an empty session wipes the whole group.
  • After a confirmed destroy the session leaves the tree. If it was the active session, the view falls back to the group's default session. Nothing changes locally until the daemon answers.
  • The help cheatsheet and palette now say "destroy group / session". TUI-only change; no daemon or protocol changes.

Goals: remember the origin session (#60)

  • A goal started from a named session records that session (origin_session in goals.json; it survives a daemon restart).
  • The goal-finished and goal-terminated handoff turns go back to that session while it is still registered. Otherwise they go to the group's default session.
  • In the TUI tree the goal's worker row, its -judge row and their jobs nest under the origin session's row. Goals started from the default session stay at group level.
  • Jobs whose session no longer has a row (finished goal, cleared session) no longer vanish. They show under the group's default row, tagged @<session>.
  • How to pass the session: the gRPC GoalSet takes session; ctl goal_set takes an optional "session" (only when a group targets itself; main→peer ignores main's session); koto ctl goal set -session <name>; and the TUI's /goals set and goal dialogs pass the active session. Default aliases and malformed, reserved (goal-*) or unregistered names fold to the default session. That is logged, not an error.
  • Unchanged: job_done callbacks that name a goal-* session still go to the default session (audit M42).
  • Needs both sides on 1.7.1. The origin session is carried by new protocol fields (GoalSetReq.session, GoalItem.origin_session, GroupInfo.session_origins). With a 1.7.0 daemon or a 1.7.0 TUI, goals behave as in 1.7.0: they hand off to the default session and show at group level. Upgrade the daemon (koto install) and koto-tui together.

Assets

  • koto: rebuilt (#60 daemon changes). Same pinned go1.26.10 build image as 1.7.0.
  • koto-tui: rebuilt (#58, #59, #60). Same pinned go1.26.10 build image.
  • rootfs.img (fedora44), vmlinux 6.1.188, firecracker 1.17.0: the 1.7.0 assets, reused byte-for-byte. Nothing under fcguest/ has changed since 1.7.0. They were downloaded from release 1.7.0 and checked against its signed SHA256SUMS before they were added here.
  • No dependency changes since 1.7.0: go.mod, go.sum, go.work and package*.json are identical to tag 1.7.0.

Tests

  • On release/1.7.1 @cff6300 (#58, #59, #60 merged) with the go1.26.10 image: gofmt is clean on every .go file changed since 1.7.0, and build and vet pass for all 4 modules. go test for tui, protocol and daemon passes (daemon 121.7s). The first full run hit two flaky tests whose files are unchanged since 1.7.0 (TestStateHashChangeDetection, TestStopDisarmsTheReportWindow). Both passed 20/20 in a focused rerun, and the full rerun passed.
  • The final release candidate (release/1.7.1 @d513c3d: koto 438fc4b8, koto-tui 61b433db, plus the 1.7.0 rootfs e389ba0c, vmlinux and firecracker) was installed and passed the claude-wan, claude-none and minimax end-to-end cases, each on the first try (EXIT=0). In claude-wan the guest reached the internet; in claude-none it had no egress, as expected; minimax answered PONG. koto-tui started and drew its screen.

Known issues

  • The goal-finished notification banner is not session-scoped. The handoff turn goes to the origin session (#60), but the operator banner is still raised against the group as a whole (goalNotify passes no session, daemon/goals.go:1665).
  • TestOtelUnreachableReceiverNeverBlocks is slow (about 2 minutes of the daemon test run). It measures wall-clock p99 latency, so it can flake on a heavily loaded host.
  • Guest boot has a fixed 30s limit. On a heavily loaded host a guest can miss it and the send fails with a boot timeout. Retrying once the load drops works.
  • GO-2026-5932 (golang.org/x/crypto/openpgp) still shows up in dependency scans. govulncheck finds the vulnerable code is not reachable, and there is no fixed version upstream.
  • Carried over from 1.6.0: koto ctl history can return a partially written reply if it is polled while the reply is still being written. Accept a reply only once it is stable across two polls.

🤖 Generated with Claude Code