Skip to content

1.0.1 - 2026-08-24

Choose a tag to compare

@github-actions github-actions released this 23 Aug 16:37
b1c6848

Release Notes

Added

  • A page about which shape to deploy in. docs/deployment-topologies.md
    answers three questions the reference pages each answer a piece of: whether to
    let a client spawn groove or to leave one running, what residency actually
    buys, and where the same-host boundary comes from.

    It began as an internal note measured against v0.26.0 and was re-measured
    against v1.0.0 before publishing, because the two releases in between changed
    exactly what it was about. /api/search — which its benchmark named and its
    fourth open question argued about — no longer exists. Origin validation, which
    it listed as unresolved, ships on by default. All four of its open questions
    were settled before 1.0.0, so they appear as outcomes with the ADR that
    records each one, rather than as questions.

    The measurements are new: a resident daemon answers a search in about 200 ms
    where the CLI takes about 3.1 seconds. The page splits that three seconds into
    three terms and says which two were measured — process and database setup at
    about 35 ms, the search itself at about 200 ms — leaving the model load, about
    2.9 seconds, as the one derived by subtraction. It also says the thing the
    internal note did not: residency is not the same as speed. A first query after hours
    idle took 4.6 seconds, and a CLI search running alongside the daemon dragged it
    from 200 ms to 2 seconds, which is the page's own "one process, one model"
    warning arriving as latency.

    Nothing in it cites a line number. The version it replaced cited eleven, and
    all eleven were wrong within five days.

Fixed

  • The reranker's documented latency was wrong by two orders of magnitude.
    --help and docs/usage.md said rerank adds "300–700 ms per
    query on CPU with bge-v2-m3 over 50 candidates". Measured against 1.0.0 on
    one Windows machine, the same query takes 3.1–3.6 s without it and 74–87 s
    with it through groove search, and 0.1 s against 74–79 s through a resident
    daemon. Residency does not help: the daemon builds the reranker at startup, so
    its second and later reranked queries have no model left to load and still take
    74–79 s. The cost is the cross-encoder pass over the candidate pool.

    The number, the --help line, and the recommendation table built on the
    number are replaced by the measurement and the conditions it was taken under.
    Nothing about reranking changed — only what the tool says it costs, and
    therefore the advice about when to switch it on.

  • docs/mcp-tools.md dated the rebuild_index bound to a version that never
    existed.
    It said the one-at-a-time refusal arrived in v0.28.0; 0.27.0 was
    followed by 1.0.0, so there is no such release. The bound shipped in 1.0.0 and
    the page now says so.

Internal

  • A Markdown link that no longer resolves now fails the test suite.
    grooveseek/tests/docs_links_resolve.rs walks every .md file in the
    repository and checks two things about each relative destination: that the file
    is there, and that an #anchor matches a heading GitHub would generate in it.
    It found one, in docs/stability.ja.md, which had
    carried the English page's #stable since it was translated — a link that
    opened the right page at the wrong place for anyone who followed it. The
    Japanese anchor is #コマンドライン.

    A throwaway script checked this once by hand during the README split and then
    lived in a scratch directory. This is that check in the tree: 70 pages, 489
    relative destinations, 35 of them anchored, 17 of those with Japanese
    fragments.

    The anchor half follows github-slugger, the implementation the remark and
    MDX toolchains use to reproduce GitHub's anchors: downcase, delete everything
    outside [\p{Word}\- ], then turn spaces into hyphens. The order is what
    implementations get wrong — 信頼する置き場所 / しない置き場所 loses the slash
    first and keeps two spaces, so its anchor carries two hyphens, and a slugger
    that mapped spaces before stripping punctuation would reject a link this
    repository contains. Counted twice, with a second implementation built on a
    different principle (Unicode general categories and a line matcher, against
    this one's char::is_alphanumeric and a parser): identical on all 792 anchors.

    Repeats retry their suffix until it is free, so # Foo, # Foo, # Foo-1
    ends foo, foo-1, foo-1-1 rather than handing foo-1 out twice. Which of
    the two GitHub itself does is not documented and cannot be measured (POST /markdown renders headings without ids); the retry is the side that can only
    ever accept a missing anchor, where the counter can reject a working link and
    stop CI.

    Pages are parsed rather than matched line by line, which is what makes a #
    inside a fenced TOML block not a heading and a reference-style link still a
    link, and destinations are read as the URLs they are before they are read as
    paths: the query and the fragment are cut off first (docs/usage.md?plain=1
    is a link GitHub's own interface hands out), percent escapes are decoded the
    way GitHub decodes them, and a rooted path — /x, \x, or the %2F that
    decodes into one — is answered as the site-root path it is rather than by
    asking a filesystem that differs between CI and a laptop. A fragment is read
    in the language of the file it lands on: on a page a heading slug or an anchor
    the page names outright with <a name="…">, on anything GitHub renders as
    source a line range (#L10 is checked against the file's length), and on a
    directory the README GitHub shows underneath its file list. Destinations are
    resolved lexically, counting depth from the
    repository root, so a .. that would climb above it is out of bounds wherever
    the checkout happens to sit — exists() cannot ask that, and neither can
    folding the path absolutely, which merely walks up one directory and back down
    into whatever sits beside the checkout. On Actions that is the checkout
    itself, since the path is work/<repo>/<repo>. External
    URLs are skipped entirely, on the URI grammar rather than a list of the
    schemes seen so far, so tel: and MAILTO: are not looked for on disk — a
    guard that can fail because
    someone else's server is down stops being read — and what it cannot catch is
    written down in the test: a link that resolves while the sentence around it
    lies, which is the failure the same README split shipped seven of.

  • A doc comment that names something this tree no longer has now fails CI.
    cargo doc --no-deps --workspace --all-features --document-private-items runs
    as the last step of the test job, and [workspace.lints.rustdoc] in the root
    Cargo.toml denies every warn-by-default rustdoc lint except one. Until now CI
    ran fmt, clippy, check and test, none of which read a doc comment:
    transport/http.rs named admin_host_check for two days after
    ADR-0009 deleted it, and
    PR #219 converted references like it into links that nothing was yet checking.

    Twenty-four references were already broken when the check was switched on, and
    the interesting ones were not typos. binary_size_exceeded was the old name of
    size_cap_exceeded, cited twice. Refusal::message had become
    Refusal::response. Six more — GraphNode, inspect, is_multiply_linked
    twice, read_checked twice, recover_db — sat in module //! headers, where
    a bare name does not resolve even to an item defined in the same file; they
    are absolute paths now. The rest were prose that rustdoc was reading as a link:
    a TOML section [eval], an interval [30,100], an array<string> that parsed
    as an unclosed HTML tag.

    private_intra_doc_links is the one lint left at allow. It fires when a
    public item's documentation links to a private one and that link resolves
    the item is there, it is simply not in the published set. This crate's Rust API
    is Unstable by docs/stability.md and its rustdoc is
    published nowhere, so pointing at the private helper that answers the question
    is the useful thing to write. A name that no longer exists is a different lint,
    and that one is denied: renaming size_cap_exceeded while leaving its four
    doc references alone fails the build with four errors.

    --all-features is there for the reason clippy runs twice: test-helpers is
    default-off and gates documented items, and rustdoc removes a gated item's doc
    comment along with the item. Unlike clippy this needs only one run, because the
    workspace's only #[cfg(not(feature = ...))] is in benches/, which cargo doc does not document either way.

    It is a step in an existing job rather than a fourth job. cargo doc --no-deps
    wants exactly the dependency metadata cargo check --all-targets already
    produced, so it costs one rustdoc pass — 15.8 s over the whole workspace,
    measured — instead of a second dependency build, and it adds no cache entry to
    a repository whose Actions caches already total 13.6 GB against a 10 GB limit.
    Being in that job is also what puts it on all three operating systems, which is
    the point: service/{linux,macos,windows}.rs are whole modules behind
    #[cfg(target_os = ...)], so a single-OS doc check would never read two of
    them.

grooveseek 1.0.1

Download grooveseek 1.0.1

File Platform Checksum
grooveseek-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
grooveseek-x86_64-pc-windows-msvc.zip x64 Windows checksum
grooveseek-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
grooveseek-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

groove-tray 1.0.1

Download groove-tray 1.0.1

File Platform Checksum
groove-tray-x86_64-pc-windows-msvc.zip x64 Windows checksum

groove-svc 1.0.1

Download groove-svc 1.0.1

File Platform Checksum
groove-svc-x86_64-pc-windows-msvc.zip x64 Windows checksum