"Time can never mend The careless whispers of a good friend To the heart and mind, ignorance is kind There's no comfort in the truth, pain is all you'll find" — George Michael, Careless Whisper
whisper is a Rust CLI that makes the incitaciones whisper skill deterministic.
The whisper skill asks an agent to manage ~/.whisper/ — canonical repo keys, branch slugs, worktree slots, and scope-based knowledge routing — by hand-rolling shell pipelines. Every invocation is a fresh chance for the model to mis-derive a path. This tool turns that mechanical layer into a binary: the skill prompts call the CLI, and the same inputs always produce the same outputs.
The command is turu — following the song's turututu riff. turututu and whisper run as aliases, so existing scripts and skill prompts keep working.
Part of the charly-vibes tool suite; built on genesis-vibes for the JSON envelope, config, and CLI conventions shared across the family.
Why: agents accumulate operational knowledge across sessions, but "where does this note go?" is a question models answer unreliably by hand-rolling shell pipelines over
~/.whisper/— every invocation is a fresh chance to mis-derive a canonical repo key or scope path.turuturns that mechanical layer into a deterministic binary: same inputs, same outputs, every machine. Status: beta · core key/resolve/append/recall/distill shipped and used by other ecosystem tools · Motivation & design · charly-vibes Tool Ecosystem
turu key— canonical repo key, branch slug, and worktree slot for the current checkout (the pure determinism core)turu resolve <scope>— the exact destination path for a knowledge scope:global,repo,branch,worktree, orgroupturu append <scope> --text "..." [--topic k] [--supersedes id]— structured, idempotent entries (sha2 ids over scope + second-precision UTC + text) written into the right file; freeform content preserved verbatimturu recall <scope> [--topic k] [--budget bytes] [--include-superseded]— ranked, budget-bounded slice serving (allcomposes scopes in precedence order); the envelope reports the context-horizon boundary (served_bytes,budget_unused,entries_skipped)turu distill <scope> --begin|--commit --revision id— two-phase contract: turu snapshots into immutable revisions and guards the commit against concurrent drift; the calling agent does the semantic rewrite into the working fileturu bundle pack|unpack— deterministic, transport-agnostic knowledge bundles keyed by repo key; unpack merges extend-without-duplicate and never overwritesturu init— create the workspace layoutturu status— one envelope with every relevant path and existence flagturu check— detect legacy key variants, undefined groups, missing filesturu doctor— deep diagnostics: layout integrity, group health, legacy keys, managed block, skill pack stalenessturu sync— inject the deterministic routing map intoAGENTS.mdas a<!-- TURU:START -->managed block, so agents read paths from a file instead of re-deriving themturu feedback <kind>— file a well-contexted GitHub issue (bug,feature,question,chore): redacted context bundle, optional--from-last-errorscratch recall,--dry-runpreview (viagenesis::feedback)turu skill install— ship the whisper skill from this repo: router + sub-skills (including manual fallbacks), content-hashed soturu doctorflags staleness. Targets~/.claude/skillsor any dir; incitaciones keeps a thin pointer to it
V=$(basename "$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
https://github.com/charly-vibes/whisper/releases/latest)" | sed 's/^v//')
TGT="$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/^x86_64$/amd64/; s/^aarch64$/arm64/')"
curl -fsSL "https://github.com/charly-vibes/whisper/releases/download/v${V}/turu_${V}_${TGT}.tar.gz" | tar xz
chmod +x turu turututu whisper && sudo mv turu turututu whisper /usr/local/bin/cargo install whisper-vibesOr from source:
git clone git@cv:charly-vibes/whisper.git && cd whisper && just installWhere knowledge gets written is layered. Precedence: repo > group > global.
Global — ~/.config/whisper/config.toml:
workspace_root = "~/.whisper" # default
[groups.cv-tools]
root = "~/para/areas/dev/gh/charly/knowledge"
repos = ["cv/charly-vibes/whisper"] # explicit membership (optional)A group routes knowledge from a set of repos into one shared workspace directory instead of each repo's private slot.
Repo (private) — <repo>/.whisper/config.toml (gitignored — never committed):
group = "cv-tools" # join a group defined in the global config
workspace_root = "/path/to/dir" # or fully override the workspace rootA repo can join a group two ways: privately, via its own .whisper/config.toml, or centrally, by listing its canonical key in the group's repos array.
Note: a repo-private
workspace_rootoverrides everything — including the global scope, so the repo'srules.mdresolves inside the private root instead of the shared workspace.turu doctorreports this shadowing and warns when the tworules.mdfiles diverge. A relativeworkspace_rootis anchored to the directory containing the repo config (not the process cwd), so calls from any subdirectory resolve to the same root.
Where knowledge lives depends on the scope and where the command runs:
| Scope | In a checkout (default) | --global escape hatch |
|---|---|---|
repo |
<repo>/.whisper/env.md (committed) |
<workspace>/repos/<key>/env.md |
branch |
<repo>/.whisper/branches/<slug>/notes.md (committed) |
<workspace>/repos/<key>/branches/<slug>/notes.md |
--private repo/branch |
<repo>/.whisper/private/… — gitignored, never pushed |
— |
Transport decision: the repo's own git carries the shared knowledge. Repo-local
publication assumes a pushable checkout — --global is the fallback for
read-only checkouts (CI, no-push contributors).
Machine-specific knowledge (local paths, hostnames, credentials) belongs in the
private zone: turu append <scope> --private routes into
<repo>/.whisper/private/, which turu init/turu sync keep effectively
ignored — the rule is appended to the root .gitignore only when
git check-ignore does not already report the path (text presence is not the
truth; a nested .gitignore or your global excludes file counts).
turu doctor enforces the privacy contract with three checks:
turu.private-ignore— the zone is effectively ignored (warning + fix hint otherwise)turu.private-tracked— fails prominently if any file underprivate/is trackedturu.private-leaks— advisory lint for machine paths, hostnames, and token-shaped strings in public repo-local files (surfaces viawarnings[])
git history is forever — prevention only. No turu verb can retract committed knowledge; that is exactly why the private zone exists and why the tracked-files check fails instead of warning.
The distilled whisper skill in incitantes replaces its shell-snippet procedures with:
turu key # derive repo key / branch slug / worktree slot
turu resolve branch
turu append repo --text "deploy requires vault login"
turu recall repo --topic deploy --budget 400 # slice, newest first, boundary reported
Agents in any repo with a TURU managed block read the routing map straight from AGENTS.md — no prompt bookkeeping required. turu sync refreshes the block; turu doctor flags it when it drifts.
Determinism guarantee: canonical key derivation is a pure function of the remote URL; the same repo always yields the same key on every machine.
turu consolidate— migrate legacy repo-key directories into the canonical key (detection already ships inturu doctor)
MIT
Rendered docs are generated artifacts; the repository sources are authoritative — edit the repo sources, not the rendered output.