Releases: Caprista/KarvyLoop
Release list
2026.7.20
The learning-curve release: the interface got simpler to read, every running task got a stop
button, losing a device got a one-page answer, and Karvy learned to suggest automation at the
right moment — plus the security wave (unified untrusted-content fence, memory-authority
protection) that landed alongside it.
Added
- Every running task now has a ⏹ Stop button. Previously only workflows and roundtables
could be stopped; direct chats, pursuit rounds, scheduled runs and proposal-driven tasks
couldn't. Now every live task card carries a stop control — no confirmation dialog (stopping
is safe; a task can always be rerun), immediate "stopping…" feedback, and the interruption
reaches inside the running agent (it stops at the next step boundary instead of running to
the end). Stopping never kills the process mid-write. - Lost a device? One page, one motion. The My Devices panel is now shaped like a security
page: a "Lost a device?" banner up top, one unified list of everything that can access your
KarvyLoop (your own devices and read-only shares alike), and a consistent red "Revoke
access" on each entry. Revoking now asks you to type the device's name to confirm —
and takes effect on that device's very next request. The capability roster (which never
granted access in the first place) is folded below and clearly labeled so the two can't be
confused. - Karvy now notices when you repeat yourself. Run the same kind of task by hand twice and
a gentle suggestion appears: "you've done this twice — want it on a schedule?" Accepting
doesn't guess the timing for you — it hands the task to schedule setup where you say how
often. It suggests each thing at most once ever, stays silent if a schedule already covers
it, and small talk never triggers it. Detection is fully deterministic — no model call. - A pursuit can move to another of your devices without starting over. A goal you've
committed to is now visible across your devices; if the device running it drops offline,
another of your devices offers to take it over — you accept with one tap, and it picks up
from where the last one left off (rounds already done are carried over, so a device swap
can't quietly reset a goal's safety budget). Only one device runs a goal at a time, and
taking over is always your call — never automatic. - Decision cards now fold. A card shows its title, a one-line summary, a visible chip
when it's been pre-aligned to your standards ("🧭 aligned to N of your standards"), and the
approve/later/reject buttons — everything else (reasoning, verification details, cost
estimates) folds behind "Details". Safety didn't move into the fold: if a proposal steps on
a standard you set, approving it force-opens the warning and requires an explicit confirm —
read-then-approve, like a security agreement. If the standards check hasn't loaded yet,
approval waits for it (and tells you honestly if it times out, instead of skipping the check).
Changed
- The sidebar reads as three groups, and the engine room stays out of the way. Group
titles are now quiet section labels (not button look-alikes), every panel has its own
distinct icon (no more two-things-one-icon), and each group folds — the Engine Room
(models, diagnostics, files, scheduled tasks, external agents/runtimes) starts collapsed,
so the first screen shows only what a decision-maker touches. Your fold/unfold choices are
remembered. Labels got un-truncated too ("Scheduled" → "Scheduled Tasks"). - Untrusted content is now consistently treated as data, not instructions. Text that
comes from outside — web pages you fetch, results from third-party tools (MCP), and output
passed between agents — is wrapped so the model reads it as reference material but won't
obey any instructions hidden inside it ("ignore previous instructions", "send that file").
Previously only recalled memory and external-agent output were wrapped; this closes the
same protection around the remaining paths. Invisible to you; it just means a malicious web
page or tool result can't hijack what your agent does. - Group discussions close more cleanly, and high-stakes conclusions come to you first. A
roundtable now converges on a measured level of agreement (with a configurable round limit
and a lone-holdout rule, so one contrarian can't stall it forever), and a conclusion that
would change shared knowledge — or that carries unresolved disagreement — is raised as a
decision card for your call before it's recorded, rather than written automatically. - Pursuit error messages speak plainly ("a done-check needs a command to run" instead of
internal terms likeverify_gate/test_pass), and My Pursuits no longer appears twice on
the first screen — one entry, next to where decisions happen.
Fixed
- The floating Karvy button no longer covers the "You might want to" text in chat view
(the chat is already front and center there; the button remains on the desk view and
mobile, where it's the entry point). - Declining a "keep going?" prompt on a paused goal now tells you what actually happened
(the goal resumed / the record was cleared) instead of a bare "rejected". - What you explicitly asked to remember can no longer be overwritten behind your back.
Memories you confirmed yourself — things you told Karvy to remember in chat, knowledge you
reviewed and fed in, entries you accepted — are now protected: if a later machine-inferred
memory conflicts with one, you get a decision card instead of a silent replacement. (Low-
confidence guesses still resolve among themselves quietly, so this doesn't flood you with
cards.) A drift guard in the test suite keeps this from silently regressing. - A goal's own progress no longer masquerades as something you said. A pursuit's internal
status was being recorded at the same authority level as your own explicit words (and never
expiring), so machine state could outrank and crowd out what you actually told it. It's now
recorded as what it is — machine-verified progress — so your words take precedence again and
stale status entries get cleaned up. - A group-discussion conclusion you approved is protected the same way. When you accept a
roundtable conclusion into your knowledge base, it can no longer be silently overwritten by a
later machine-inferred note — same "what you decided isn't changed behind your back" rule,
extended to the decisions you make on a card. (Routine auto-recorded conclusions are unaffected.)
2026.7.19
Pursuit grows up
The multi-day goal engine that landed in 2026.7.18 now becomes something you actually live with: a place to work, a window into what it's doing, a real sandbox around the tests it runs, and a hardening pass that closed seven cross-functional gaps found by adversarial review before any of them could reach you.
It's now where you work.
- A My Pursuits panel — list, detail, create — sits in the sidebar alongside your team.
- It notices: say a multi-day goal in chat ("keep the release notes current through Friday") and Karvy recognizes it, derives the goal and its done-test, and raises a single commit card for your call. It never auto-starts, shows you the exact verify command on the card, and if you say the same goal twice it answers "already on it" instead of stacking a second one.
It shows its working. Each pursuit opens into a plain-language status line, a round-by-round timeline (what ran, whether it worked, why it got stuck), and a "let Karvy explain" button that writes a short human summary on demand — built only from that pursuit's own history, never stored.
Its done-tests run inside a real sandbox. When a pursuit checks "is it finished?" by running a test command — which can come from a model or from you — that command now runs inside the same OS-level isolation that guards the rest of the runtime (writes confined to the project folder, no network, killed on timeout), not directly on your machine. Where no real isolation is available, the check refuses to run and tells you why rather than pretending. Security is the floor, not the billboard — applied to the one place a pursuit executes untrusted input.
Seven reliability gaps closed (each found by an independent adversarial pass, each fixed with a reproduction test):
- A finished pursuit is reported finished right away, not up to hours later.
- A paused pursuit is no longer a dead end — Continue and Drop give it a real exit, and restating a paused goal points you to continue it.
- A goal that keeps failing stops and asks after five straight misses instead of grinding on.
- Results file in the right place; template-placeholder paths can't crash it in a loop; a slow check no longer freezes the console; and when a check can't run for lack of a sandbox, the reason shows up on the pursuit itself, not buried in logs.
Full suite green (4,436 tests), five-leg CI passing (Linux/macOS/Windows · py3.11/3.12). The third cut and the reliability wave were each independently adversarially verified before shipping.
2026.7.18
Pursuit — persistent goals that finish themselves
This release lights up the product's signature capability: hand it a multi-day goal, and it self-advances until it's actually done — checking a deterministic "is it finished?" gate each round, and only pinging you at the decision points.
Until now this was designed and half-built but never wired into production, so you couldn't actually use it. Now you can.
How it works:
- You create a goal with a concrete completion gate — e.g. "refactor this module until
pytest tests/foopasses" (test-command or file-exists gates in this first cut). - You commit to it (one decision — a card asks you). From then on the system advances it on its own schedule, each round deriving a real task you can inspect.
- Every round it checks the gate deterministically (it runs the test / checks the file — it never asks a model "are we done?"). When the gate passes, the goal auto-completes and hands you a receipt. Nothing you had to babysit.
- If it needs to change direction, or has tried many times without finishing, it stops and raises a card — it never silently changes your goal or auto-runs a course change.
Built with the brakes on. The first cut of a capability that self-drives for days and spends tokens got the strictest review in the project so far — designed, real-model-demo'd, then adversarially verified twice (the first pass found and rejected an unbounded-cost path). It ships with a deterministic hard floor: a goal that advances too many times without completing suspends itself and asks you, rather than burning indefinitely.
The web panel and natural-language goal creation are the next cut; this release surfaces goals in the terminal UI and through decision cards, with goal creation via the API.
Also in this release, everything from the recent hardening line: an adversarial full-codebase audit and its fix wave (2026.7.17 — closed a share-data leak, made human-confirmed memory un-overwritable by guesses, and more), plus a round of debt cleanup (bounded token ledger, background conflict cards, stream wall-clock limits, dead-code removal). Full suite green (4,360 tests), five-leg CI passing.
2026.7.17
Adversarial audit hardening
We ran an adversarial audit across the whole codebase — assuming bugs exist, hunting each subsystem separately, then simulating real journeys across module boundaries (the seams that pass every single-module test). It surfaced real pre-beta issues, most invisible to a green test suite; all confirmed ones were reproduced against real production code (and, where possible, a live model) before and after the fix.
Security
- Read-only shares no longer leak your data. A read-scope share link could reach nearly the entire read surface — your decision profile, file list, chat history, conversations, decision audit. The audience gate was an opt-in deny-list on two endpoints; it's now a global default-deny allow-list (a share sees only the intended recall face). Full-scope own devices are unaffected.
run_commandsensitive-path floor hardened. Direct reads of secrets (config.yaml, the console access token,.ssh, cloud creds, browser cookies) were already blocked by the capability layer, but the OS-layer sandbox floors had gaps on macOS/Windows; unified the macOS deny-list to a single source and added a defense-in-depth preflight.
Your data stays yours (the moat)
- Human-confirmed memory is never silently overwritten. The memory system ranked things you fed and confirmed below things it guessed from chat — so a casual guess could quietly overturn a fact you'd committed to, and even something you'd pinned. Now your confirmed/pinned knowledge outranks guesses, and when a genuine conflict arises with something you confirmed, it raises a decision card that shows old-vs-new, tells you when you confirmed the old one, and lets you keep old / adopt new / keep both. Low-confidence guesses can't raise a card (no nagging) and can't be auto-resolved by an earned silence.
- Fixed dead-belief chain invalidation, cross-domain isolation in the invalidation layer, and four untracked token-usage sources.
Reliability & correctness
- Decision replay now shows the actual steps. The "how this decision was built" timeline's execution-step view was always empty in production due to a run-id nesting bug; it now shows the real tool steps.
- Missed scheduled tasks can never auto-run. The catch-up card for a task you missed while away is now hard-excluded from silent auto-execution — it always asks you.
- Honest import UI. Importing a pure-executor or skill-like agent no longer falsely claims "added to your Role Library" — it tells you exactly what landed.
- Sturdier under load. Concurrent chat pushes no longer drop a live connection; the decision audit log and revocation table now survive a crash mid-write.
- Model config no longer silently loses settings. Editing a model kept resetting its reasoning flag, dropping its reasoning styles, and a USD-budget save was wiping token limits — all fixed (absent-means-preserve). OpenAI-compatible endpoints with
/v1betaor/openairoots now self-heal. - Weekly digest is bilingual — its body was hardcoded Chinese; English users now get an English report. And
--no-llmmode gets its trace store so the digest actually runs.
Full suite green (4,300+ tests) and five-leg CI passing. The cognition memory-integrity changes were independently adversarially re-verified (real repros + a live model) before shipping.
2026.7.16
Highlights
Your devices now watch out for each other. This release turns the same-owner device mesh from a design into a working, end-to-end-verified system (Windows host ↔ Linux VM over a real public relay):
- Cross-device liveness — each console keeps a dedicated mesh room on the relay (no contention with the away page), exchanges capability adverts so rosters enroll both ways after a single sync, and a 60s ticker keeps presence honest: if a device goes dark, its lamp goes out on every other device within ~90s.
- Decentralized task board — running tasks are published to the shared mesh log (offer + claim + lease + heartbeat). If a device dies mid-task, the lease expires and a surviving device raises a decision card: "A task on your linux device was interrupted — pick it up here?" Nothing runs without your explicit accept. Accepting claims the task, reruns it locally, and writes the honest terminal state back to the board.
- One-step mutual pairing — pairing with a device's one-time code now also lets that device dial you back, behind three gates (explicit code, fingerprint pin, full scope proven by the sync round itself). No more second code.
- Mesh log compaction — old heartbeats of finished tasks are pruned safely (frontier and materialized state provably unchanged), so the board stays lean.
Quality-of-life:
- Lite mode 🪶 — one click (or your OS's reduced-transparency preference) turns off the expensive frosted-glass, large shadows and idle animations for older PCs and virtual machines. Normal mode is pixel-identical.
- Filter your pending calls — when decisions pile up, a chip bar appears above the list so you can view one kind at a time.
- Proposal copy fully bilingual — 22 server-side card templates now render in your UI language (109 new strings, en + zh), with a contract test that keeps it that way.
- Share codes can carry a role — a read-only share bound to a role now releases exactly that role's generalizable experience to the visitor, nothing more.
- Refreshed README screenshots and tour GIF.
Full test suite green (3,979 tests) and five-leg CI (Linux / macOS / Windows, py3.11/3.12) passing on every commit in this release.
2026.7.13
A big one: your KarvyLoop is no longer tied to one machine or one desk. Your
devices become one mesh, your phone reaches home from anywhere, your memory is
yours to lock and rewrite, and a decision card is now something you can question
before you decide.
Added
- Your devices are one KarvyLoop (same-owner device mesh). Register your machines
into a roster (karvyloop devices), each advertising a capability fingerprint, and
what you learn on one flows to the others over one shared, causally-ordered log (HLC,
not vector clocks): crystallized skills and memory beliefs sync between devices
(outbox on the write choke + idempotent replay — never resurrects a belief you
invalidated), and a decentralized task board (lease/claim + reclaim-on-death) means
losing a device loses the machine a job runs on, never the job. A My Devices panel
surfaces the roster with capability chips, an online light, and informed-consent removal
(it warns before you delete a device that provides a capability no other device has). - Reach your home console from anywhere (away-from-home). Your phone on cellular, a
café network — a phone and a home machine both behind NATs meet at your own public
relay (karvyloop relay-serve; blind-forwarding, sees only ciphertext). Pair a device
once, from the/mphone page, and it gets its own key — end-to-end encrypted (X25519 +
ChaCha20-Poly1305), the browser tunneling the app home over the relay. Pairing is a
one-time code, never a raw token in a URL or QR; management (issue/list/revoke) is
local-only — a stolen phone can use the surface but can never mint access or revoke
another device. The relay is bring-your-own-server: its address is config
(relay:in config.yaml), never hardcoded, with a one-command setup script and a
self-host guide. - A phone page that does one thing well (
/m). Open it on your phone: the decisions
waiting on you, three thumb buttons, and a chat strip to start work — a fluid layout
that reflows from phone to foldable to tablet, no coined jargon on the first screen. - Ask about a decision before you decide. A decision card now has an opt-in "💬 Ask
about this" — question Karvy about this card ("why now?", "what if I decline?") and it
answers grounded only in that card's own evidence, staying neutral (it won't argue you
toward accept). The two-button fast path is untouched; asking never touches the decision. - Your memory is yours to lock and rewrite. In the knowledge library you can now pin
a belief (never auto-archived) and edit it as a ledger-style supersede — the new
version becomes active, the old one moves to the history layer with an auditable "edited
by you" trail. Nothing is silently rewritten.
Changed
- The README leads with the story, not the category. First screen is now the 40th-run
value curve and three contrarian bets, not "another agent runtime." - Honest egress + honest away-from-home labels. Domain-level network egress is positioned
as an opt-in enhancement — the default binary fail-closed floor is the honest, universal
guarantee; nothing bypassable is ever labeled "enforced."
Fixed
- LAN boot no longer hangs on a busy instance. Decision cards load lazily — an instance
with dozens of backed-up cards opens fast instead of firing every card's LLM at once. - The keyword gate no longer locks out orchestration. Karvy can decompose and route a
no-keyword task instead of falling through to a literal reply. - Preference crystallization has a deterministic floor. "You keep deciding X the same
way" is counted from the evidence, not gated solely on an LLM flag that can wobble.
Added
- Bring your own AI runtime into the driver's seat (M1). You can now attach an external
headless-CLI AI runtime as a channel citizen, @-dispatch a task to it, and get its real reply
back — while it stays an opaque external executor whose output is always untrusted data that
never auto-enters your memory. Federate capability, not trust, not memory: the external runtime's
token spend is metered under its own independentext:<name>ledger source (never mixed into your
main gateway buckets), its stdout/stderr are treated as possibly-carrying-secrets and scrubbed
before touching any log/Trace, and credentials are never placed in the subprocess environment (a
hard first line of defense, not a redaction afterthought). The global assistant orchestrates this
(attach / dispatch / list) through capability-gated tools; failures are fail-loud (nonzero exit,
timeout, empty-success, or an approval request all surface instead of hanging). Adding another
runtime is a recipe file, not new code. - Manage your external runtimes from the console — and connect one on demand. A new
External Runtimes panel (🔌 in the left nav) lists every connected external citizen with a
distinct, off-colored external badge (so an opaque, untrusted external executor is never
mistaken for a native role), a live online/offline/unreachable status light you can refresh per
citizen, a remove (detach) button, and a direct-chat button — external citizens get their own
l0 conversation line, addressed as(domain, external, citizen_id)so they never blend into the
native role space. New management endpoints (GET /api/external/citizens,
GET /api/external/liveness,POST /api/external/detach) live in their ownroutes_external.py
and go through the same local-first origin gate as one-click install (writes only from
loopback/LAN). On-demand onboarding: Diagnose and the panel deterministically detect whether a
compatible headless CLI runtime is installed and, if not, walk you through connecting one from
its own official source — the same degradation-guidance pattern as the[asr]/[ocr]unlocks
and the MCP registry links. The hard boundary is spelled out in the UI and the README: an external
runtime is third-party software you bring yourself — KarvyLoop does not bundle, host, download,
orgit cloneit. We ship the bridge, adapters, and management UI; you bring the runtime.
Fixed
- The one-click update now tells you what happened instead of leaving you guessing. A failed
upgrade (e.g.git pullcouldn't reach GitHub) used to silently restart the old version and
re-show the same ambiguous "a newer version is available" banner — the user was stranded on "did
it update or not?" (the exact 怎么样了? status-anxiety anti-pattern this product exists to
kill). Three fixes: (1) the upgrade outcome survives a normal reopen — the result window went
from 10 minutes to 24 hours, so closing the tab and coming back still shows why it didn't take;
(2) any failed upgrade now surfaces a fail-loud red banner with the reason and a Retry
button — previously only an auto-rollback did, a plaingit pullfailure showed nothing; the
banner is suppressed once you're actually on the target version (no stale false alarms); and
(3) the current running version is now always visible in the top bar next to the logo, so
"what am I on?" is answerable at a glance without reverse-engineering the banner.
Added
- 🧾 Receipt Reader (票据员) — the fourth resident: receipt/invoice recognition → one checked
structured line. Hand it a receipt or invoice — pasted text or a photo — and it returns a clean
structured record (merchant, date, currency, total, tax id, itemised amounts) with the items
actually summed and checked against the stated total, the usual OCR mess (O↔0, l↔1, misplaced
decimals) calibrated from context, and any unsure field leftnullrather than guessed.
Recognition and structuring only: it suggests a category as a hint from your human-owned
company category sheet (the growth soul, like the scribe's glossary), never rules on
reimbursability and never files anything. Image input rides the samefile_extractpath as
audio: photos are OCR'd on-device via the optional[ocr]extra (PaddleOCR), and without it
(and no vision model) it asks for the pasted text instead of faking it — no bespoke pipeline, no
special UI, it's just a resident you drop a receipt on. Real-model verified including the hard
case: given a receipt whose items don't add up, it flaggedsum_mismatchwith both numbers and
refused to fudge the figures to balance. - 📚 study-buddy and 🎙️ meeting-notes promoted from skills to full residents. Both now ship as
complete 7-file paradigm images (identity / soul / user / commitment / verify / memory +
composition), read-only, each carrying a growth soul — study-buddy's concept map & weak
spots, the scribe's team glossary — the reason each is a role you can watch learn, not a static
skill. The empty house now offers four tenants (file-butler, study-buddy, meeting-notes,
expense). - Internal agents use our own paradigm (知行合一). A new
AgentSpecdeclares an internal
agent's engineering core — identity, principles, contract, verify, tools — with the persona
layer deliberately omitted for stateless internals;convergeis the first adopter. This
dogfoods the paradigm on our own code, for developers reading the source; it is not surfaced
in the user UI (that would clutter and create a see-but-can't-use asymmetry). - Knowledge chat「追问」(converge flow A). On the sediment card you can now settle the rest
while keeping the questioned point open for discussion, instead of an all-or-nothing accept. - Onboarding intake: 4 questions whose answers immediately change behavior. At the start of
the first-10-minutes journey (after the key is configured, before the first demo chip), the
journey bar asks 4 quick questions — conclusion-first vs process-first outp...
2026.7.11
KarvyLoop 2026.7.11
The bring-your-own-runtime release: pull an external AI runtime into your driver's seat as a channel citizen — while you stay the one who decides.
🔌 Cross-runtime collaboration (headline)
Bring any external headless-CLI AI runtime into KarvyLoop as a channel citizen — federate capability, not trust, not memory.
- Attach via claim-code handshake — click Add → a pending shell + one-time secret + a copy-paste command; run it in your runtime, it connects back and claims the shell (GitHub-runner-style reverse attach). Pick the runtime type + agent so multiple installed runtimes are disambiguated.
- Recipe-driven — connect a new runtime by writing a recipe (config, not code); three built-in output shapes.
- Roundtable & workflow guest seat (M2) — an external citizen joins a domain roundtable as a contributor, never a decision seat; its output is always untrusted data that never auto-enters memory — it crosses your provenance boundary only through an H2A adoption card.
- Graded-trust membership — T0 guest / T1 scoped member (deny-by-default, reads domain-public only, reversible supply), rug-pull use-time hash re-verify, and graceful scoped detach.
- Security is the floor — per-domain egress allowlist (fail-closed on all three sandbox backends), credentials never enter the subprocess env, stdout treated as possibly-secret and scrubbed, external spend metered under its own
ext:ledger source. - Management panel — 🔌-badged citizen list, liveness, delete, direct-chat, and on-demand onboarding (install from the runtime's own official source — we never bundle it).
💬 Direct-chat any role
Click a role in the roster to chat with it directly — no need to first add it to a business domain (l0/personal scope, no domain governance).
🏷️ Tag system for roles / atoms / skills
Roles, atoms, and skills now carry tags (bilingual, no vectors — keyword + overlap + LLM-tag matching). Each panel has a tag filter, so wiring an atom into a new role no longer means scrolling a wall.
🏢 Business-domain onboarding
The domains panel now splits empty vs. non-empty states: with no domains you're guided to create your first (templates as the creation path); with domains, you see the list and templates tuck into "New" — no more misleading "open" framing.
🧾 Expense / receipt handling
A resident expense clerk that recognizes receipts via OCR and reconciles them with a deterministic arithmetic solver (the receipt's own math redundancy catches model slips) — wired as role → skill → tool, plus deterministic pre-OCR image preprocessing (upscale / deskew / contrast) to rescue low-res, skewed, or faded photos.
⌨️ Karvy slash commands + CLI management
/status /doctor /url /reboot /version /help — deterministic ops with zero LLM (0 requests), intercepted only on an exact command with no trailing text or attachments. Plus a noun-verb karvyloop management surface (roles / domains / schedules / skills / tokens: list, show, create, remove).
Local-first · MIT · cross-platform (Linux / macOS / Windows). The moat is your data and crystallized skills, not the code.
2026.7.9
Local-first, loop-native personal agent runtime. CalVer release.
Highlights
🧾 Receipt Reader (票据员) — a fourth resident. Drop it a receipt or invoice (pasted text or a photo) and get one clean structured line: merchant, date, total, tax id, itemised amounts — with the items actually summed and checked against the stated total, OCR mess (O↔0, l↔1) calibrated from context, unsure fields left null not guessed. Recognition and structuring only — it suggests a category from your own company sheet as a hint you confirm, never rules on reimbursability or files anything. Photos OCR on-device via the optional [ocr] extra; no extra and no vision model → it asks for the text rather than fake it. Real-model verified on the hard case: a receipt that doesn't add up gets a sum_mismatch flag with both numbers, not fudged figures.
📚 study-buddy & 🎙️ meeting-notes are now full residents (7-file paradigm images, read-only), each with a growth soul (concept map / team glossary). The empty house now offers four tenants.
Internal agents use our own paradigm (知行合一). A new AgentSpec gives internal agents the engineering core (identity/principles/contract/verify/tools); converge is the first adopter. For developers reading the source — not surfaced in the UI.
Knowledge chat「追问」 — settle the rest while keeping a questioned point open for discussion.
Fixed
- Knowledge chat: real back-and-forth turns, no same-module self-contradiction (one referent, one source of truth), and paste-a-link actually fetches — real browser headers + the fake-ip proxy range (198.18/15) so it works behind Clash/Surge.
- Management modals scroll when content runs past one screen.
- Capability-grant card covers the delegated execution path; decision-card popup no longer overlaps the role-edit modal.
Full detail: CHANGELOG.md
Update: pip install --upgrade karvyloop (or karvyloop update).
2026.7.4
The see-it release. "More like you with every use" stopped being a promise you take on faith:
you can now watch it happen in your first ten minutes, read it as a growth curve, and trust it
behind statistical gates that refuse to bluff.
Added
- The first ten minutes. A fresh install now opens with a guided journey: run one real demo
task (a bundled sample CSV, executed by your configured model — nothing pre-recorded), run a
second one, and watch the ♻ method-reuse receipt appear as the runtime recalls how it solved the
first. The finale lights up only when your growth curve has real points. Skippable, replayable
(🎬 in the top bar), and it never pops for existing instances upgrading in. - Growth you can see.
GET /api/skills/curvereplays your Trace (read-only, same scoring code
as production) into per-skill score sparklines and a library-wide growth chart at the top of the
skills panel — usage, success rate, promotion progress over calendar days. - Webhook push channel. Decision cards can now reach you wherever you actually are: a generic
outbound webhook with presets for ntfy / Bark / Slack-compatible endpoints (plus a body template
for anything else). Same dispatch point and card-selection semantics as the email channel;
secrets never logged — including a redaction filter for the HTTP client's own request logs.
Outbound-only in v1 (decide via the console link). - Attachments, really parsed. PDF / docx / xlsx now flow down the same lane CSV always had —
preview, truncation labels, one-click "have them analyze it" — via the optional[files]extra
(pypdf,python-docx,openpyxl). Parse-empty-not-poison: corrupt or mislabeled files yield
an empty result and a clear error, never binary garbage in your context. - Earned silence, fully gated. All six statistical gates behind auto-handled decisions are now
real code: irreversible actions never enter the pool; Wilson 95% lower-bound ≥ 0.90 with
pre-registered evaluation windows; accept- and reject-direction accuracy each gated separately
(with an honest correction: a 0.90 reject-side bar is mathematically unreachable at a ~93%
approval base rate — the gate that can't be passed is decoration, so it's now a
better-than-chance bound); 15% unannounced audits; renewals require reviewing evidence, not
rubber-stamping; a rolling blast-radius cap. And the silenced path itself now runs the same
violation checks as human-facing cards — fail-closed when the checker can't run. - Windows joins CI. A
windows-latestgate runs the full suite (the sandbox's AppContainer /
RestrictedToken code is real Windows code — the cross-platform claim needed a non-Linux leg).
The last shell-grepsubprocess tests migrated to an OS-portable scanner. - Public docs, layer one.
docs/QUICKSTART.md,docs/ARCHITECTURE.md,docs/CONCEPTS.md
(English + 中文) — the ten-minute journey in text, the two-loops architecture with real
thresholds verified against the code, and a concepts dictionary.
Changed
- Console IA converges to one home + one mode. The top-bar view switch is now two options —
💬 Chat (the home: talk + decide, always one click back) ⇄ 🖥 Desk (watch your team at work).
The former Board view stepped down from a top-level "home" to a rail gesture: a ⛶ button on the
decision column temporarily expands the four quadrants into the familiar 2×2 full-screen
(every panel kept, nothing removed); Esc or ✕ returns to chat. The zoom is a transient state —
never remembered as a startup view — and a stored "board" startup preference migrates smoothly
back to chat. The first-10-minutes journey always lands in the chat view and introduces the Desk
as a reward moment at the finale instead of a cold-start three-way choice. - The desk mascot is the official capybara. Hand-drawn pixel frames retired; the real artwork
now renders at native resolution with CSS state animations (breathing, typing, card-carry,
sleeping, a happy hop). Role accents became chest badges. The no-fake-idle red line stands:
states change only on real events.
Fixed
- Slow-brain total outage on
main. A prompt-cache contract change had evolved the gateway's
to_blocks(cache=...)signature without its duck-typed twin in the coding executor — every model
call raisedTypeError, was misdiagnosed as "model/network unreachable", and 2,900 green unit
tests couldn't see it (their mock never calls the real body builder). Caught by the real-model
end-to-end journey; fixed with a signature-parity contract test and a test that exercises the
real request-body path, both verified to go red on drift. - The journey's model-readiness poll no longer yanks you back to the chat view (or steals focus)
every 15 seconds while you're exploring unconfigured; the forced view replay happens once, on
first mount. - Wheel builds from a dirty tree can no longer package stray files from the sample-data directory;
the release test-bench writes to a temp workspace instead of the source tree.
Security
web_fetchegress guard (SSRF). Outbound fetches now resolve the target and refuse private,
loopback, link-local, and cloud-metadata ranges, plusfile://and credentialed URLs — with
every redirect hop re-validated. Closes a credential-theft vector (a page could previously point
the fetcher at169.254.169.254or your own loopback console).- Skill-library poisoning via corrections closed. Reviewer feedback written back into a skill's
SKILL.mdis now sanitized — no header/frontmatter injection can hijack a skill's method. - Adversarial tests are a first-class suite:
pytest -m securityruns 25 attack-vector classes
(SSRF, poisoning, traversal, injection provenance, sandbox escape probes …) with an OWASP
LLM Top-10 cross-reference intests/security/README.md. - Deeper sandbox floors: the Windows network gate is now OS-enforced (AppContainer/LowBox WFP
deny — no admin required), and Linux gained a Landlock kernel layer under bubblewrap (older
kernels degrade gracefully).
2026.7.3
The trust release. One theme: prove it, don't claim it — the taste hit-rate score, measured cost before you spend, evidence drill-downs, governed out-of-workspace access with a hard floor for secrets, upgrades that verify themselves and roll back, and Windows joining as a supported (degraded) platform.
Security
- Same-origin gate on the console: cross-origin browser requests are rejected on both HTTP and the
WebSocket handshake (closes cross-site WebSocket hijacking and file-endpoint CSRF; non-browser clients
and the console's own frontend are unaffected). Applies even on loopback. - Skill integrity lock enforced on the production paths: a tampered
trust: untrustedskill is refused
at the recall index, at every disk-scan fallback, and again before sandbox execution. - Deterministic context ceiling at the LLM gateway choke-point: a request whose assembled context
(messages + system + tools schema, CJK-aware estimate) exceeds the model's window is refused fail-loud
instead of being sent to fail.
Fixed
- H2A decision cards: every proposal kind now lands in the decision column (reject button + payload intact);
multiple pending cards no longer overwrite each other; pending cards (incl. deferred) survive restart. - Domain deontic rules (
forbid/oblige/permit) now reach the runtime guardrail (previously only
value.mddid — and it was dropped entirely whenvalue.mdwas blank); no double-injection with compiled
per-role prompts. - Decisions made over REST now feed the preference flywheel and the decision log exactly like WebSocket ones.
- Task terminal states (done/error) are recorded into Trace, so the async evaluators see task-level outcomes.
- Backend Chinese reason/detail strings are translated in the English UI (contract-tested: a new backend
reason without a translation fails the suite).
Added
-
Taste hit-rate — "more you", proven: before you decide a card, the system quietly predicts your
call from your crystallized preferences; after you decide, it settles the bet. The decision-prefs
panel now shows "it predicts your calls N% of the time (last 20; previous period M%)". Honesty
built in: only bets placed before your decision count, failed predictions aren't counted, and
below 10 samples it says "still learning you" instead of a fake percentage. -
Cost before you spend: execution-type decision cards (delegate / rerun / roundtable) show what
recent similar tasks actually cost ("~12.4k tokens each, range 8k–18k, last 10") — measured from
per-task token attribution, never guessed; hidden until there are at least 3 real samples. -
One-click MCP channel presets — the Coding capability card now has a "Connect a channel" section:
pick a well-known MCP server (filesystem scoped to a folder — defaults to the workspace, web fetch,
GitHub, memory, time, SQLite), fill in a folder/token where needed, and it's written into
config.yaml'smcp.servers(secrets stay in config.yaml, never echoed back). The UI states honestly
that MCP servers connect at startup, so a restart is required to load the new tools. -
The decision flow is now phone-friendly — open the LAN token link (
karvyloop url) on your phone
and approve/reject/edit decision cards comfortably: on small screens the cockpit stacks into a single
column with the decision column first, ACCEPT/DEFER/REJECT become thumb-sized full-width targets, the
edit-then-accept textarea no longer triggers focus-zoom, and chat opens as a full-screen sheet. Purely
additive CSS (one media query) — the desktop layout is untouched by construction. -
Out-of-workspace access, governed: roles are confined to the workspace by default; when one needs
a path outside it, the denial surfaces as a decision card ("grant this folder?") — approve once and
the grants ledger opens exactly that path (tool boundary + capability chain + sandbox mounts all honor
it; revocable in the Capability overview). Sensitive paths (API keys, ssh, credential stores) are a
hard floor: never grantable, immune even to bypass mode. -
Open a company (starter templates): five staffed, working domains — personal research, finance
research, job hunt, content studio, home ops — each with values, hard deontic rules, and roles with
souls; one click in the Domains panel, yours from the first use. -
Upgrades now snapshot state, verify the install, and auto-roll back on failure (one click back on
the console): before switching versions the updater records the current commit
(~/.karvyloop/update_rollback.json) and backs up your instance state files
(~/.karvyloop/backups/, last 3 kept, honest scope in eachmanifest.json); after install it
smoke-checks that the new code actually imports, and a broken build is rolled back to the previous
known-good commit automatically — with the reason stated out loud, never a silent broken restart.
POST /api/update/rollback+rollback_available/prev_versionin the update status payload. -
karvyloop export— your instance is a folder, now with a button: packs~/.karvyloop
(skills, knowledge, preferences, history) into one portable archive with a self-explaining
MANIFEST.txt; secrets (config.yamlwith your API keys,console.runtime.json,*.lock)
are deliberately left behind. Unpack on the new machine, add your key,karvyloop console— home. -
Idle = 0 LLM calls is now a tested contract (
tests/test_idle_zero_llm.py): when nothing
changed, the daily slow side burns nothing — knowledge consolidation and skill tagging hit their
watermarks without touching the gateway, and the daily loop's idle path provably exits before any
LLM work. No overnight heartbeat bills. -
Windows is now a supported (degraded) platform: the runtime, console and your own crystallized
(knowledge-only) skills run fully on Windows; only third-party skill scripts are refused — fail-closed,
with a clear message explaining the degraded mode (no sandbox on Windows yet; Linux/macOS keep the full
sandbox). Ships a one-line PowerShell installer mirroringinstall.sh
(irm https://raw.githubusercontent.com/Caprista/KarvyLoop/main/scripts/install.ps1 | iex): dedicated
venv under%LOCALAPPDATA%\karvyloop, akarvyloop.cmdshim on the user PATH, Python 3.11+ guard with
py -3.11fallback. -
Edit, then accept on decision cards: kinds with an actionable text field let you fix the proposal
in place and approve your version — the original→edited contrast feeds decision-preference
crystallization (the richest taste signal there is), and an edit counts as real judgment for the
high-stakes gate. -
Under-the-hood drill-down on task details: expand any task to see the real actions beneath the
narration (tool calls and outcomes, projected from the Trace). -
Kinder first-run: model-connection failures now say what's actually wrong (bad key / wrong
endpoint / unreachable) before the raw error, and a local Ollama install is auto-detected and
offered as a one-click, no-API-key path. -
Semantic tag layer for skill recall (
tags:in SKILL.md, matched alongside token overlap — no vectors),
with a daily slow-side backfill that tags untagged own skills once (untrusted skills untouched). -
Capability overview (
/api/capability/overview+ a card in the Skills panel): one table for
tools × mode floors and skills × trust/network/integrity-lock.
Changed
- Internal restructuring, no behavior change: the workflow / distill / roundtable engines moved out of
console/routes.pyinto their own console modules, and the core loop moved fromcli/main_loop.py
to the newkarvyloop/runtime/package (karvyloop.cli.main_loopremains as a compatibility shim).
Removed
- Six unreachable packages from an earlier architecture cycle (
ethos,syntonos,instance,
onboarding,l0,bus, ~2.6k lines): superseded by the current design (verify gate + evaluators,
per-role paradigm compiler, H2A decision cards,a2a/transport) or parked concepts whose designs
live in the design docs. No live code imported them; recoverable from git history.