Skip to content

Releases: Caprista/KarvyLoop

2026.7.20

Choose a tag to compare

@Caprista Caprista released this 20 Jul 09:51

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 like verify_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

Choose a tag to compare

@Caprista Caprista released this 18 Jul 20:49

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

Choose a tag to compare

@Caprista Caprista released this 18 Jul 06:46

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/foo passes" (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

Choose a tag to compare

@Caprista Caprista released this 17 Jul 14:21

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_command sensitive-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 /v1beta or /openai roots now self-heal.
  • Weekly digest is bilingual — its body was hardcoded Chinese; English users now get an English report. And --no-llm mode 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

Choose a tag to compare

@Caprista Caprista released this 16 Jul 00:58

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

Choose a tag to compare

@Caprista Caprista released this 13 Jul 06:46

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 /m phone 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 independent ext:<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 own routes_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,
    or git clone it.
    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 pull couldn'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 plain git pull failure 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 left null rather 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 same file_extract path 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 flagged sum_mismatch with 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 AgentSpec declares an internal
    agent's engineering core — identity, principles, contract, verify, tools — with the persona
    layer deliberately omitted for stateless internals; converge is 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...
Read more

2026.7.11

Choose a tag to compare

@Caprista Caprista released this 11 Jul 13:05

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

Choose a tag to compare

@Caprista Caprista released this 09 Jul 02:54

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

Choose a tag to compare

@Caprista Caprista released this 04 Jul 12:44

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/curve replays 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-latest gate 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-grep subprocess 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 raised TypeError, 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_fetch egress guard (SSRF). Outbound fetches now resolve the target and refuse private,
    loopback, link-local, and cloud-metadata ranges, plus file:// and credentialed URLs — with
    every redirect hop re-validated. Closes a credential-theft vector (a page could previously point
    the fetcher at 169.254.169.254 or your own loopback console).
  • Skill-library poisoning via corrections closed. Reviewer feedback written back into a skill's
    SKILL.md is now sanitized — no header/frontmatter injection can hijack a skill's method.
  • Adversarial tests are a first-class suite: pytest -m security runs 25 attack-vector classes
    (SSRF, poisoning, traversal, injection provenance, sandbox escape probes …) with an OWASP
    LLM Top-10 cross-reference in tests/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

Choose a tag to compare

@Caprista Caprista released this 03 Jul 00:57

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: untrusted skill 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.md did — and it was dropped entirely when value.md was 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's mcp.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 each manifest.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_version in 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.yaml with 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 mirroring install.sh
    (irm https://raw.githubusercontent.com/Caprista/KarvyLoop/main/scripts/install.ps1 | iex): dedicated
    venv under %LOCALAPPDATA%\karvyloop, a karvyloop.cmd shim on the user PATH, Python 3.11+ guard with
    py -3.11 fallback.

  • 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.py into their own console modules, and the core loop moved from cli/main_loop.py
    to the new karvyloop/runtime/ package (karvyloop.cli.main_loop remains 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.