Skip to content

v1.8.0

@HackPoint HackPoint tagged this 13 Oct 14:43
* docs: take a private project's file name out of the changelog, two test fixtures and a screenshot

CHANGELOG.md named a file from a private project twice, in the 1.4.0 and 1.6.0 entries. The
sentences now say "the heaviest file" and "the file that 1.4.0's entry gave as this repository's
heaviest"; every figure in them is unchanged.

The same name stood in the lumen-stats aggregates test and the Hotspots spec as sample data, and
in the Hotspots screenshot docs/assets/fault-report/fault-1-badge.png. The tests now use
large.rs, and the screenshot's label reads large.rs with every other pixel untouched.

Git history and the tags v1.4.0 through v1.7.0 still contain the old name.

* fix(release): a dispatch builds from the tag's commit, never from main

A manual run of the release workflow built main's head and attached the
result to the chosen tag's release, so a re-run could ship code that was
never in that version. It also pasted the tag input into a shell script's
text, where a crafted value ran as a command.

The first job now resolves the tag once to the commit it points at (an
annotated tag is peeled) and publishes that SHA as build_ref. Every job
that checks out the repository checks out that SHA, the Homebrew tap's
formula templates included, and none reads github.sha or the ref to decide
what to build. A tag that is malformed, missing or not a commit is refused
before anything is built, and the input reaches the script through env only.

When the tag's source does not build, a last job, which holds no token
permissions, fails the run with an annotation and a summary saying a patch
release is needed. Nothing falls back to main.

scripts/test-resolve-release.sh runs the workflow's own resolve step against
a throwaway repository whose main is past every tag, and runs in CI next to
test-release-notes.sh.

* feat(app): prompt an upgrader to run Setup until the identity hook is registered

1.8.0 turns repeat reads on by default, and the server can only tell which
conversation a call belongs to through one PreToolUse hook on smart_read,
recall_file and compress_logs. Setup registers it, but Setup runs by itself
only until ~/.claude/lumen/.setup_done exists, so an install set up under
1.7.0 or earlier is never sent back: the switch says on, every read is
answered in full, and nothing in the window says why.

The main window now says so. A prompt at the top of Home and of the
Optimizer tab shows while Setup is not pending, repeat reads are on and the
hook is not registered, with a Run Setup button that opens Setup. It clears
once the hook is registered: when the page opens (so on coming back from
Setup) and when the window gets focus. A check that fails shows nothing, and
the prompt is not on the Setup screen or in the tray panel.

Backend: lumen_identity_hook_status (async, off the main thread) answers
{registered, servedElsewhere}. "Registered" is one predicate shared with
validate_hooks_in, a Lumen command under PreToolUse on each of
lumen_core::identity::MATCHERS, so the validator and the prompt cannot
disagree. A plugin install registers its hooks from the plugin, so there the
newest fifty plan-bearing ledger rows decide, as lumen doctor does. A
settings.json that cannot be read, or is not an object, is an error and
shows nothing, since Setup refuses it too.

Tests: the predicate, the status and the validator over settings files of
every shape; Setup's installer run on a 1.7.0-shaped settings.json (not
registered and unhealthy before, registered and healthy after, foreign hooks
kept, nothing duplicated); the component and both pages; and that the
command the prompt asks is one the backend registers.

Not done: opening the window on launch for this, and a registered hook with
every call still unidentified, which running Setup would not fix.

* test(identity): drive live_identity with captured subagent payloads, add the /clear and /resume manual test

The identity tests built their PreToolUse payloads by hand, so they agreed with
what the hook's author assumed about subagent calls. They now start from
payloads captured from Claude Code 2.1.296: a main agent's smart_read, a
subagent's smart_read (the parent's session_id plus its own agent_id and
agent_type) and a subagent's Read. Ids, paths and the account name are replaced
by placeholders of the same shape; keys, nesting and order are as captured. One
test hands the captured bytes to the hook untouched and checks the record name
and the ledger's session and agent.

MANUAL_TEST gets TEST 6, the procedure behind the live numbers: a scratch
Claude Code config, ledger and home; one conversation (full outline, then the
30-token stub); /clear and /resume (full again, then the stub); a subagent
(full, the parent's stub unaffected); and a no-hook control that shows the
unidentified row. On a 313-line file: outline 282 tokens, full 5263, stub 30.

No production code changes.

* docs(bench): measure ab0151d against v1.7.0 on macOS, Ubuntu and Windows

The committed run measured an older commit. This one is the last code commit before the 1.8.0
bump: tokens and latency on macOS, latency on Ubuntu and Windows through the Benchmarks workflow
(run 38389263356, files copied unchanged).

Tokens are equal between the two builds. A blocked Read is slower than in 1.7.0 on all three
platforms (+0.4 to +2.6 ms): since #42 it looks the path up in the ledger, and a scratch build
without that lookup blocked a Read in 1.7.0's time on macOS, in two reviewers' runs. A hook now
runs before every Lumen call (about 0.1 to 2 ms above the process floor), and the server calls take
0.04 to 0.9 ms longer. The README says where each comes from and what it could not trace. It also
records a second workflow run (38390782413), which agrees in direction and not in size, and two
reviewers' re-runs on macOS, which agree in size.

* chore(release): 1.8.0

The version in the 14 files scripts/release.sh edits (the five crates, the app's
Cargo.toml, package.json and tauri.conf.json, the plugin manifest, the two hook
generator lines, the formula and the cask), and the workspace members' own lines in
Cargo.lock; no dependency moves.

CHANGELOG.md: the Unreleased block is now 1.8.0, dated 2026-10-13. It opens with
repeat reads on by default and with what an upgrader has to do (run Setup once, restart
Claude Code), and says what the benchmarks show about time. One sentence about the
previously committed benchmark results is removed, since those results were replaced.

---------

Co-authored-by: HackPoint <6758579+HackPoint@users.noreply.github.com>
Assets 2
Loading