Canvis — a personal agent system
Canvis is my personal agentic system: a long-running, autonomous agent built on Claude Code that operates as an extension of how I think and work, rather than a collection of single-task tools.
The bet is simple. Most "AI productivity" stops at the chat window. Canvis goes further: persistent context, its own memory, scheduled routines that run without me, and a governance layer that decides what the agent can do on its own versus what needs me in the loop. The scarce input in the whole system is my review attention, so everything is designed to spend it on judgement, not on catching errors.
What it does
- Research. Scoped, cited research that persists as durable files with a freshness status, not throwaway chat answers. A research request gets routed by scale: a single fact stays an inline lookup, a standard topic goes to one research agent producing one structured file, and a broad, contradiction-heavy question gets the multi-agent treatment with adversarial verification. Most requests do not need the expensive tier, and the routing is what stops them getting it.
- Content. Drafts thinking on AI transformation and agentic engineering, grounded in things I have actually built rather than in generic commentary. The posts on this site come through that pipeline.
- Strategy and ops. Keeps a decision ledger so settled questions do not get re-litigated, runs daily and weekly review routines that look at their own output, and surfaces the small number of calls that genuinely need my judgement.
How autonomy works
The part I care most about is the governance, because an autonomous system has two ways to fail and both are common. It can ask about everything, which trains me to rubber-stamp, so the approval queue becomes a tax on my time that adds no safety. Or it can act on everything silently, and quality drifts without anyone noticing.
Canvis is built to avoid both. Autonomy is assigned per task, not as one global setting. Some work the agent proposes and waits for my approval; some it executes and reports; a few things it only ever presents as options for me to decide. Trust graduates on evidence: a task type moves from propose to execute once the agent has repeatedly got it right and I have approved without changing anything. There is a hard floor underneath all of it. Anything touching authentication, secrets, or access control stops for human review regardless of how autonomous the task would otherwise be.
Every change ships as a pull request. Deterministic checks run first, with no model involved: a size limit on the always-on context, scans for committed secrets, and reference-integrity checks. Trusted content merges automatically; anything touching the rules or governance always gets a review. That PR gate is what lets the system act on its own without the acting becoming unaccountable.
The gate has since split by why a change needs a human at all. Some work needs my direction, meaning is this the right thing and does it match my taste. Some only needs its correctness checked, meaning is it done right. Those are different questions and only the first genuinely needs me, so correctness-gated changes now go to a second vendor's model, which reviews the diff adversarially and merges it on a clean pass with no human involved. Real defects loop back for a fix inside a hard cap of two or three rounds, and anything the cap does not settle comes to me. A different vendor has different blind spots, which is the entire point, because a same-vendor review tends to echo the same mistakes it would have made. The security floor is exempt from all of it.
How it is built
The core idea is a template factory: every capability is generic and reusable, routed through a layered system. An always-on core holds only what must be true for every task and is kept deliberately small, because every line in it is read on every turn. Below that sit modular rules that apply in specific situations, on-demand skills, deterministic hooks that enforce the things a written convention cannot guarantee, and specialised sub-agents for bulk or independent work.
The factory itself was not designed up front. Several real builds run in parallel, each pulling shared capability into existence only when it actually needs it, and the reusable parts get promoted the second time an independent build hits the same problem. That way the shared infrastructure is extracted from the friction of shipping real things, rather than guessed at in the abstract and then forced onto work that does not fit it.
What it tracks about itself
A system that acts without me has to be able to show its own work, or drift goes unnoticed until something has been wrong for weeks. Three layers exist for that.
Every session writes its own log, uniquely named, pushed the moment the session is real rather than at the end, because the container it runs in can be reclaimed without warning and a best-effort save at shutdown is exactly how traces get lost. There is no hand-maintained index over those logs; the aggregate is derived by reading them, on the principle that a stale index is worse than none. What it buys is the ability to ask which threads were started and quietly never closed.
Commitments get the same treatment with more teeth. When a session creates an obligation, a decision I owe, an account to provision, a follow-up the build owes itself, it has to declare that in the pull request, and a deterministic check blocks the merge if it does not. The declaration is copied to a durable log automatically at merge, and the live items land in a tracker I actually read on my phone. Before this existed, the agent would tell me what it needed from me and that sentence died with the session.
The third is duller and catches a real problem. Several documents here are markdown rendered to HTML. Hand-edit the HTML, or change the markdown and forget to re-render, and the two diverge silently. So the pairs are declared in a manifest, a job re-renders and commits any drift, a check flags it on the way in, and a hook refuses to let anything edit a generated file directly.
How it has grown
It started as a way to stop being the bottleneck in my own projects. The pattern I was trying to break is that I get things to eighty percent and then move on, so the design principle became consistency over intensity: reward showing up, catch the drop coming, and never let building the system become the thing that starves the work the system exists to ship.
It now runs several builds at once as its test cases: an autonomous research engine that selects and produces fresh research on a schedule, this personal site and its content pipeline, an adaptive tutor engine, and a local-business web-presence outreach engine. Each one is a real deliverable and also a probe into what the factory needs next. The governance and the review routines are what let all of that run without me watching it every minute. The tracking layers are what tell me when it has not run, which is the harder problem of the two.