Not everything your agents reach is an account. Some of it is yours: what you know, what you have to do, the files you keep, the procedures you have written down, who you are, who everybody else is, and the secrets that make the rest work.
These have no OAuth, no vendor, no rate limit somebody else imposes, and nothing to connect. A new profile arrives with them already granted, because there was never anything for a connect step to authorise.
$ lanes link check --profile personal --workspace localconnections:
- { id: main, provider: memory, account: Memory }
- { id: main, provider: tasks, account: Tasks }
- { id: main, provider: assets, account: Assets }
- { id: main, provider: skills, account: Skills }
- { id: main, provider: vault, account: Vault }
- { id: main, provider: entities, account: Entities }What each one is for
| Memory | what is true | a fact, a preference, how something works |
| Tasks | what is to be done | each with a status, so it can be closed |
| Assets | a file | kept under its own name |
| Skills | a procedure | your own, invoked by you rather than chosen by a model |
| Identity | who you are | so an agent can write as you and not as itself |
| Entities | who everyone else is | so an address is looked up, not recalled |
| Vault | a credential | used to do the thing that needs it, never quoted back |
| Audit | what happened | every call, allowed or refused |
One more, setup, is the read-only surface an agent reads to tell you what you would have to run to
connect something. It has no write bundle at all, and a test asserts that. See
Connections for what it answers.
Which store a thing goes in
Worth knowing, because nothing refuses the wrong choice.
"Remember to chase the invoice" is a task, not a memory entry. Written into memory it becomes a note nothing can ever close, served back to every later session as something that is true, so the invoice is still being chased months after it was paid.
The distinguishing property is state. A fact does not finish, so memory has no status field, and that is exactly why a task could not simply be a memory entry with one. Your agents are told this too, in the endpoint's own instructions.
"Jan's address is jan@acme.test" is the same mistake in a different direction. As a memory entry it is findable only by substring and comes back as prose a model has to read; as an entity it is a field, and a lookup either answers or says it cannot.
Every one has a CLI
The same bytes your agents reach, reachable by you:
$ lanes link memory search "postgres" --profile personal --workspace local
$ lanes link tasks add "chase the invoice" --due 2026-09-01 --profile personal --workspace local
$ lanes link assets list --profile personal --workspace local
$ lanes link skills add ./release-checklist.md --profile personal --workspace local
$ lanes link identity list --profile personal
$ lanes link entities find Jan --profile personal --workspace local
$ lanes link vault set stripe-key --profile personal --workspace local
$ lanes link audit tail --limit 25 --profile personal --workspace localWithout this, the stores holding your own data would be reachable only by an agent, which is the wrong way round.
Where it all lives
Everything follows the workspace. Locally that is files under your workspace; on a deployed workspace it is the same keys in your bucket.
Memory, tasks, skills and entities are plain Markdown files with YAML frontmatter, and the directory is one you are invited to open: a file you drop in by hand is an entry, and an edit you make in a text editor is what the next read returns. There is no index, deliberately, because an index would be a second copy of the truth that could disagree with the file it described.
Entities is the one exception, and it earns it: a lookup that read every file would be a thousand
requests against a bucket. Its _index.json is a cache stamped with a fingerprint of the files it
was built from, so a file you edit by hand invalidates it and the next read rebuilds. It cannot
quietly disagree.
The vault is different. It is one encrypted document under its own key, and it is never kept in a repository.
Nothing crosses a profile
Everything belongs to the profile you stored it under. A second profile starts empty and stays that way, and nothing you store in one is visible from another. That is also the only way to give one agent a narrower view than another, because policy names capabilities rather than connections.
Turning one off
Deleting a connection row does not switch a store off: the next start, connect, or deploy puts
it back. A deny is how one stays off.
$ lanes link policy deny 'memory.write' 'memory.forget' --profile personal --workspace localName every capability that changes something, or the surface is not read-only: memory.write alone
leaves memory.forget granted, and entities takes three.
Making memory read-only is the one worth a decision rather than a preference, with entities close behind it.
Next: Memory, or the audit log for what is recorded when any of this is touched.