Skip to content

Lonca v0.2.2

Choose a tag to compare

@github-actions github-actions released this 09 Nov 20:31
· 61 commits to main since this release
cb8a7b8

lonca doctor reads like flutter doctor

The text form was one flat, colourless line per check. It now groups the
checks under headings ([✓] Mode, [✗] Daemon, [!] Hooks, Tools,
Human, Repository <repo>), each marked with its worst check, says what
to do under each problem, and ends with how many categories have issues.
Colour only on a terminal, never with NO_COLOR or TERM=dumb. --json
is unchanged; in text mode the summary line replaces check(s) failed on
stderr, and the exit code is still 1 (#227).

session start into a full directory starts nothing

lonca session start --workspace DIR with a DIR that is not empty was
refused only after the daemon had started the session: the log had an
allow, and status listed an active session whose token nobody held
until its TTL ran out (#223). The directory is now checked first, and
anything that fails after the session started (making the workspace,
writing its token) ends that session again.

Symbol engine 16: a parse within a budget

A tree-sitter grammar can take far more work and memory than a file is
long: the fuzzer found a short Kotlin file that took gigabytes, so a
proposal holding one could take the daemon down. From engine 16 a parse
stops after a budget of work that grows with the file's length (256 steps
and one per 4 bytes, at most 8192), counted in parse actions and not in
time, so the auditor gets the same answer. A file past it goes by its lines,
as one over 2 MiB does: code people write stays far below it. Entries of
older engines are recomputed as they were written.

Fuzzing

The parsers and the merge are fuzzed (docs/fuzzing.md): stored log
entries, whole logs as the auditor reads them, daemon requests, hook
events, the symbol engine, the three-way merge, and repository
configuration and policy. Every saved input runs under cargo test. A git
id in a request or a log entry is now refused unless it is 40 lowercase
hex digits, as Lonca writes them. A C or C++ file with a broken scoped name
such as a:::b no longer makes the symbol engine panic: the request that
read it got no answer, and the connection was dropped. Such a name now has
one scope per ::, read from the left.

lonca policy check, and a guide to writing policies

lonca policy check --policy policy.cedar (or --config, or both) tries
a policy before lonca policy set: it decides every entry of the log again
with it and lists the decisions that would change, writing nothing. It also
warns when the new policy would deny an enrolled human a way back, such as
policy.update, unfreeze or approve. The new
Writing policies page lists what a Cedar rule sees
(principals, actions, every context key), what @escalate and
@approvals do, why an evaluation error denies, and examples.

A lost Mac comes back with the recovery key

When the Mac is lost, the daemon's key and your Secure Enclave key go with
it. A repository restored onto a new daemon then accepted only
daemon.recover, signed with an enrolled human's key, so the recovery key
alone could not bring it back. Now lonca human recover does it: on a
restored repository it sends a daemon.recover signed with the recovery
key, which moves the repository onto the new daemon and installs your new
key in one entry (log format 27). Every session ends; the recovery key is
used up. See Recovery.

Short change ids work

lonca pending and lonca log show the first 12 letters of a change id,
but lonca diff, lonca change and lonca advise refused them
("invalid change id"). They now take any 4 or more letters that name one
change; when several changes start with them the answer lists those. The
daemon has a new read method for it, change.resolve.

undo and revert read the whole log

The daemon answers log a page at a time (1000 entries), and lonca undo
and lonca revert read only the first page. On a longer log revert
planned nothing after entry 999 and said "nothing to revert", and
undo of a policy.update past entry 1000 put back the last policy of the
first page instead of the one before it. Both now read every page.

More of the guide

New pages: Concepts,
Reviewing agents' work,
Troubleshooting and
Recovery.

Live runs for this release

Claude Code 2.1 (haiku), as docs/release-checklist.md asks: a session
leased, proposed and integrated after approval, and lonca diff listed no
generated file; two sessions at once on one file, on different symbols, both
integrated; one that stopped without proposing was sent back by the stop
hook, proposed, and left no unproposed work. lonca-audit verify passed on
the log. Not run: Codex 0.167 and OpenCode 2.2. Their free models on
Ollama's cloud are retired and the local one was not used. No harness
profile has changed since 0.2.1; Codex last ran live before 0.2.0 (Codex
0.165), with Claude Code on one file, and both integrated.

Install

curl -fsSL https://selcukgural.github.io/lonca/install.sh | sh
brew tap selcukgural/lonca && brew install lonca
cargo install --locked lonca

Check an archive: gh attestation verify lonca-<target>.tar.gz --repo selcukgural/lonca.