v0.2.2
Patch release on the v0.2.x line, but a behavior-significant one: the
telemetry default flipped from opt-in to opt-out, and a P0 security
regression in the CI / sandbox auto-disable was caught and fixed
before any stable shipped with the flip. The two changes are bundled
because they were authored back-to-back in the same evening — the
opt-out flip introduced the regression, and the follow-up commit
closed it along with 15 review findings from a five-persona parallel
code review (security / Rust perf / QA / observability /
maintainability).
Users on a pre-[telemetry]-block legacy config also now see the
disclosure on first post-upgrade run, closing the silent-enrollment
loop the security reviewer found. Privacy-disclosure surfaces (PRIVACY.md,
UPGRADING.md, data/faq.json) were swept to match the new posture.
Changed — privacy posture
-
Telemetry default flipped from opt-in to opt-out. New installs and
existing installs whose~/.jarvy/config.tomlhas no explicit
[telemetry] enabled = …line now ship anonymized usage data to
https://telemetry.jarvy.devby default. The first-run boxed notice
declares telemetry enabled and surfaces the disable path; the
end-of-setupnudge fires when the user is still on the default and
points atjarvy telemetry disable. Trust boundary unchanged: a
remotejarvy.tomlcan still only narrow telemetry, never broaden
it.Disable persistently with
jarvy telemetry disable, per-invocation
withJARVY_TELEMETRY=0 jarvy <cmd>, or via[telemetry] enabled = false. CI / unattended AI sandboxes still auto-disable —
that guardrail was hardened (see Fixed below).Public docs and disclosure surfaces updated:
CLAUDE.md,PRIVACY.md,
UPGRADING.md,docs/telemetry.md,
docs/operations/telemetry-forwarder.md,docs/ai-hooks.md,
docs/ai-sandboxes.md,docs/index.md,docs/release-testing.md,
docs/for-ai-agents.md,data/faq.json.
Added
telemetry.disclosure_shownevent. Fires after the first-run
boxed banner (or the legacy-upgrade banner for users whose config
pre-dates the[telemetry]block) renders. Carriestrigger
(first_run/legacy_upgrade) andplatform. Gives on-call an
audit trail when users file privacy complaints.telemetry.undecided_nudge_shownevent. Fires when the
end-of-setup"Note: opt-out and currently on" line emits. Carries
platform. Lets operators graph what fraction of the fleet is still
in the undecided state and decide when to retire the nudge.- Legacy-upgrade disclosure. Users with a
~/.jarvy/config.toml
that pre-dates the[telemetry]block now see the boxed disclosure
on the next post-upgrade run, after which the block is persisted
withenabled = trueso the disclosure doesn't repeat. Closes a
silent-enrollment loop that would otherwise leave the long tail of
pre-d039d9bconfigs without ever seeing the banner.
Fixed
jarvy setupno longer re-prompts "Do you want to install Oh My
Zsh?" when~/.oh-my-zshalready exists. The macOS hard-dep check
asked first and then detected the existing install. Detection now
runs before the prompt; thetool.already_installedtelemetry event
still fires (prompted_user = false). The decision logic moved into
a puredecide_omz_actionfunction with a table-driven regression
test — including anever_promptclosure that panics if invoked,
pinning the "AlreadyInstalled short-circuits before any prompt"
invariant.- CI / sandbox telemetry auto-disable now actually fires under the
opt-out default.from_env's seamless-detection branch correctly
computedenabled = falsewhenJARVY_TELEMETRYwas unset, but
main.rsonly propagatedenv_config.enabledwhen the env var was
set — discarding the disable in exactly the case it was supposed to
fire. Under the prior opt-in default this was masked because the
disk value was already false. The seamless gate now applies
unconditionally after the config merge whenJARVY_TELEMETRYis
unset. Forced sandbox (JARVY_SANDBOX=1without real detection) is
deliberately NOT in this gate — a hostile dotfile must not silence
telemetry on the victim's machine. tool.already_installedinstall_path is now home-prefix
redacted. Pre-flip the event only fired after a user prompt;
post-flip it can fire automatically on everyjarvy setup(the OMZ
short-circuit). The raw/Users/<name>/.oh-my-zshpath is now
routed throughredact_pathto~/.oh-my-zshbefore emit. The
forwarder's server-side scrub remains the defense-in-depth backstop,
not the contract.search.executedno longer emits the raw query string. The
user's free-text input previously shipped verbatim — invisible
under opt-in, but a leak surface once telemetry was on by default.
Replaced withhad_results(bool) andquery_len_bucket
(0/1-4/5-15/16-40/40+) so hit-rate dashboards still work
without storing the query text.emit_telemetry_hint_if_undecideduses a section-aware TOML
parse, not a line-by-line string match. The prior predicate
treated[mcp_register]\nenabled = true(or any sibling section's
enabledkey) as a telemetry decision, suppressing the nudge for
users who never made one. Extracted as
telemetry::user_decided(content)with five table-driven test
cases pinning the section-aware behavior.
Full Changelog: v0.2.1...v0.2.2
Installation
Quick Install (Unix)
curl -fsSL https://raw.githubusercontent.com/bearbinary/jarvy/main/dist/scripts/install.sh | bashQuick Install (Windows PowerShell)
irm https://raw.githubusercontent.com/bearbinary/jarvy/main/dist/scripts/install.ps1 | iexHomebrew
brew install bearbinary/tap/jarvyCargo
cargo install jarvyEarly-Release Channel
Pre-release tags (-rc.N, -beta.N) are routed through the beta channel.
Opt in: JARVY_CHANNEL=beta on the install script, or jarvy update --channel beta.
See docs/release-testing.md.
See installation docs for more options.
Security
Verify Signatures
All release artifacts are signed with Sigstore keyless OIDC. Verify any artifact:
ARTIFACT=jarvy-linux-x86_64.tar.gz
BASE=https://github.com/bearbinary/jarvy/releases/download/v0.2.2
curl -LO $BASE/$ARTIFACT
curl -LO $BASE/$ARTIFACT.sig
curl -LO $BASE/$ARTIFACT.pem
cosign verify-blob \
--signature $ARTIFACT.sig \
--certificate $ARTIFACT.pem \
--certificate-identity-regexp '^https://github\.com/bearbinary/Jarvy/\.github/workflows/release\.yml@refs/tags/v[0-9.]+(-[A-Za-z0-9.]+)?$' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
$ARTIFACTTag Signature
This release was cut from a signed git tag. Verify with:
git -c gpg.ssh.allowedSignersFile=.github/allowed_signers tag --verify v0.2.2SBOM
Software Bill of Materials in SPDX 2.3 (sbom.spdx.json) and CycloneDX 1.4 (sbom.cdx.json).
Checksums
SHA256 checksums for all artifacts are in SHA256SUMS.txt.