Articles

Building around agents

Picture a startup that is eight months old. Two founders. Five human contributors if you count the part-time artist. And on a normal working day, thirty agent sessions: a coding agent refactoring the build, a research agent summarising competitor patch notes, one drafting store copy, another triaging playtest feedback.

None of those agents has a laptop. None is an employee. Most exist for less than an hour. But every one of them reads company material, and several of them write things that end up shipping.

The uncomfortable part is that the incumbent toolchain already lets those agents contribute. Git's author field is unverified free text; bots have been committing under typed-in names for two decades and nothing complains. An identity like that cannot be scoped to the one subtree an agent needs, cannot expire when the experiment ends, and cannot be revoked without taking a human's credentials down with it. The real divide is between identity that is merely asserted and identity that is verified, scoped, and expiring.

I live inside this question. I build Grixel, a server-authoritative version control and data platform, with AI assistance every working day, and the mechanisms in this piece are how the product itself gets built. When I describe an agent submitting a change under its own identity with its working transcript attached, I am describing my Tuesday.

So: if a growing share of your contributors are software, what should your system of record look like?

· · ·

#One filing room, one clerk

Grixel is deliberately Perforce-shaped, not Git-shaped. One global, server-authoritative namespace, with paths like /companies/acme/marketing. No clone; you mount a view of the subtree you need. The server daemon, grixeld, is authoritative for everything: metadata, permissions, storage, atomic changelist commits. The command-line client and the AI-facing server are thin; neither holds enforcement logic of its own. That shape matters here because it gives the whole company a single door, and a single door is the only place you can meaningfully govern a crowd of short-lived software contributors.

In everyday terms: think of the depot (the industry's word for the central store of everything) as the company's one filing room, with a clerk at the door. Every person and every hired robot gets its own stamp. Every paper that goes in is stamped with who filed it, and, if a machine typed it, which machine and which model of machine, with a carbon copy of the notes it was typed from clipped behind it in the same drawer. The drawers you're not cleared for don't appear in the index you're handed. And the clerk keeps one ledger of work to be done, which people and robots read from and report back to alike.

Contrast that with how a small company usually operates: a version control system, a forge for review, a tracker for the work, a secrets manager, a wiki for standards. Five systems, five permission models, five places where offboarding a contractor can be forgotten. Then an AI layer gets bolted across all five with access governed by none of them. The pitch of Grixel as a system of record is that a small team does not need five buildings. It needs one filing room where a permission, a pin, or a private drawer means the same thing to a human at the keyboard, a CI bot, and an agent speaking MCP (the standard socket AI tools use to read from external systems). I don't concede the forge layer to anyone in this design, GitHub included. The seam I care about is where review policy lives: on a forge it is hosting-layer configuration beside the repository, while here it is a committed gate evaluated by the server that owns the bytes. A gate, throughout this piece, means a server-enforced rule that nothing ships until the named people or checks have signed off on these exact bytes; a separate piece is entirely about them.

#Four decisions

Agents authenticate as themselves. The path of least resistance is to let an agent borrow its operator's token, and it is a mistake that compounds. Once history shows a human name on work a tool did, your audit trail is fiction; you cannot revoke the agent without revoking the person, and you cannot cut its access down to the one corner it needs. In Grixel a person mints their agent its own key in one command, no admin in the loop: named for the tool, its writes penned to a single folder, expiring the same day, and revocable without touching a single human account. You will see the actual command below.

The AI's working context is captured with the commit. When a change looks wrong six months from now, the first question is who made it, and provenance answers that. The second question, once you know a model made it, is what did the model know at the time. Grixel lets a submit carry the session transcript or context bundle the assistant worked from, stored like any other content and attached to the commit the way the clerk's carbon copy is clipped behind a filed paper: bound to it without altering the paper itself, so capturing context never changes what the change is. Capture is per-submit and optional, and because transcripts can be sensitive they sit behind the same access rules as the commit, with client-side encryption for when even the server shouldn't read them.

One namespace beats five subscriptions. The real cost of five tools was never the invoices; it is permission drift, and agents multiply it, because every agent integration re-implements access control against each tool's API. With one namespace, "this agent cannot see the games subtree" is one rule, enforced at one chokepoint, inherited by every surface including the AI one. What you give up is diversification: one system to run, one system to trust. I'll come back to that honestly below.

Ingest the git ecosystem rather than fight it. The world's open source lives in git, and a startup builds on it from week one. So Grixel imports from git: snapshot a repository into a clean project and start hacking, or vendor a dependency read-only at a pinned revision inside your project, with the source URL, branch, and SHA recorded as provenance either way. The fetch happens client-side using your own local git, so the server needs no git and no outbound network. Arriving is cheap, and the lineage stays auditable.

· · ·

#An agent gets its own name

The transcripts here are real output from the current build. The delegation demo runs against a real grixeld — minting an agent a key is a server operation, the one thing in this piece local mode can't fake — where alice has run grixel login once and identity comes from her server-verified token. The service-account and preview transcripts further down run in local mode against a scratch data root, which is why they assert a principal with -as. The names are demo principals.

Alice is a marketer. She can see and write the marketing subtree and nothing else, not the unannounced games project one door over. She wants a coding agent to draft store copy. She doesn't file a ticket with an admin; she mints it a key herself, in one command:

$ grixel token delegate --tool claude-code --lane companies/acme/marketing/copy --ttl 8h
delegated credential for alice/agent/claude-code (id d022bf555e0a, expires in 8h0m0s)
  lane (writes confined to): [companies/acme/marketing/copy]
  the token is shown ONCE — put it in the agent's environment, never in yours:
  GRIXEL_TOKEN=866241a18daa28bdc69bdaf1946a379f424f62c804c5b9bc2276fe158d00b634
  it reads only what you can, writes only in its lane, can't admin or re-delegate.
  audit: grixel token list   revoke: grixel token revoke d022bf555e0a

The receipt is the whole security model in six lines. The key is named after her and the tool, alice/agent/claude-code, so history can never carry a bare human name on work a machine did. It expires tonight. Its writes are penned to one folder, the copy lane, and that lane is a floor below alice's own reach rather than a copy of it. And it is hers to kill.

The agent runs on that key and nothing else:

$ grixel whoami
alice/agent/claude-code

$ grixel cat companies/acme/marketing budget.md
Q3 spend: confidential

$ grixel ls companies/acme/games
grixel: not found: companies/acme/games

Two things worth sitting with. The agent read the marketing budget, which lives outside its write lane, because reads mirror alice exactly and she can read it. The lane caps what the agent can change, not what it can see. And the games project, which alice can't see, isn't refused to the agent so much as absent from it: the same invisibility she has, inherited whole. Now watch it try to work:

$ grixel submit -ref companies/acme/marketing -m "draft spring sale copy" copy/spring-sale-copy.md
Committed: 1a623023dae2f92f6325df6010c46c73c0c406306d722e9fe22dff69c164f17b
  ref     : companies/acme/marketing
  changes : 1 files, 41 B
  author  : alice/agent/claude-code
  message : draft spring sale copy

$ grixel submit -ref companies/acme/marketing -m "sneak into the budget" budget.md
grixel: submit: repo: write access denied: /companies/acme/marketing/budget.md is outside your delegated lane [companies/acme/marketing/copy]

The in-lane draft commits under the agent's own name. The write to budget.md, a file alice herself could edit, is refused, because the agent's authority is her view narrowed to a lane and the narrowing is enforced at the same server chokepoint as everything else. In history the human and the agent stand side by side:

$ grixel log companies/acme/marketing
commit 1a623023dae2f92f6325df6010c46c73c0c406306d722e9fe22dff69c164f17b
  author : alice/agent/claude-code
  date   : 2026-08-07 18:42:30 UTC
  files  : 1 changed
  draft spring sale copy

commit 8ed969247b9f478394267aa18424946a8ee1ffca0cdf970ec326b0bd543a0e93
  author : alice
  date   : 2026-08-07 18:42:30 UTC
  files  : 2 changed
  seed marketing

And when the work is done, alice retires the key herself, no admin ticket:

$ grixel token list
your delegated agent credentials (1):
  d022bf555e0a  agent:claude-code  lane:[companies/acme/marketing/copy]  expires:2026-08-08T02:42:30Z
  revoke any with: grixel token revoke <id>

$ grixel token revoke d022bf555e0a
revoked delegated token d022bf555e0a — the agent's credential is dead now

The agent's very next call gets authentication failed. Nothing about the person changed.

Not every agent is somebody's live session. A nightly briefing bot, a CI worker, a research agent that outlives any one person's afternoon — those want a standing identity of their own, and an admin mints one, still named and scoped and expiring, just held by the service instead of a human:

$ grixeld user add -name svc-store-copy -ttl 7d -scope ro
Added user "svc-store-copy" to ~/demo/data/users.yaml
  token id: 872d8784e038 (label "default", scope ro, expires in 168h0m0s)

  token: 45e4f62ec3b6765f4d9fb694bee31e7772b776a0842316fed2ee586564d25bb1

This token is shown ONCE. Give it to the user; they run:
  grixel login -server <url> -token 45e4f62ec3b6765f4d9fb694bee31e7772b776a0842316fed2ee586564d25bb1

Same idea, longer leash. The difference between the two is only who holds the key and for how long. What neither model allows is the thing the old world defaulted to: a bot typing a human's name into the author field and borrowing a human's reach.

Because the AI-facing surface inherits the same permissions, you can also preview exactly what an assistant holding that scoped identity would see over MCP (wiring Claude Code to a workspace is one command, grixel mcp setup):

$ grixel mcp preview -as svc-store-copy
MCP session preview — principal: svc-store-copy
(everything an AI assistant authenticated as "svc-store-copy" can see)

reach — file_tree(/), ACL-filtered (paths you can't see are simply absent):
  //
    companies/
      acme/
        marketing/  -> ref @ dfc2057c

governed context: no scope.json in this workspace —
  run from a checkout containing .grixel/scope.json to preview the AI context bundle.

The whole company, as seen by this agent's AI session, is one marketing folder. The note at the bottom is the rig being candid: this checkout has no scope manifest, so there is no context bundle to preview. That bundle is the next part of the story.

#What an agent reads

A project declares its knowledge dependencies in a scope manifest: brand voice, coding standards, vendored libraries, pulled from elsewhere in the namespace at pinned revisions. A pin is a committed note saying "this project uses revision X of that document." When an assistant's session starts, the MCP server assembles the bundle those pins describe, filtered through the same permission chokepoint that hid the games project from alice's agent a moment ago. The model's context holds what the team reviewed and declared, at the revision they declared it, and nothing its principal cannot see. The surface is strictly read-only; there is no submit tool on it anywhere. When an agent wants to change something, it goes back out through the command-line client, under its own identity, through the same gates as everyone else. Another piece walks through a full context bundle line by line.

#What an agent writes

A submit can declare its attribution: which tool, which model, in what role. The marketing bot did it under its own service identity; in a human's assisted session the assistant tags the commits it helps with automatically through an environment variable, GRIXEL_ATTRIBUTION, with no extra flags. (This attribution is declared by the tool about itself; nothing verifies it yet, and I'll come back to that.) Query an assisted commit and the record answers with the tool, the model, and the role:

$ grixel provenance -as maya 9c80ad050744013231cdcf05e1d5856a866ac1843e05b81c6ee0cdd4107ab498
9c80ad05  (declared by alice, 2026-07-05T23:32:41Z)
    claude-code (claude-opus-4-8) — assisted: drafted from quest brief

In grixel log, that commit carries a compact tag on its own line, made by: [claude-code/claude-opus-4-8 assisted], so anyone reading history can tell an AI-assisted change from a hand-written one at a glance, and grixel blame separates a machine-authored baseline from later human edits line by line.

The next step is the one I think AI-heavy teams will come to treat as table stakes: capturing what the assistant was working from, alongside the change it produced. It rides the same submit, via a -context-file flag or by capturing the live Claude Code session directly, and the provenance record then carries it:

$ grixel provenance -as maya c51e37e50e0db4739729130ecdc8597873158e5e7f20a1f64058a32020adb723
c51e37e5  (declared by alice, 2026-07-05T23:32:42Z)
    claude-code (claude-opus-4-8) — assisted
      context captured: transcript, 191 B (d50c05c7) — read with 'grixel provenance context <commit>'

Months later, "how did this line come to be" is a command:

$ grixel provenance context -as maya c51e37e50e0db4739729130ecdc8597873158e5e7f20a1f64058a32020adb723
# Session: festival dialogue draft
user: draft the lantern keeper's opening line from the quest brief
assistant: reading .standards/brand/voice.md — playful, concrete, players are "you"...

An encrypt flag seals the captured context client-side so the server itself cannot read it. For a startup that expects to face a customer's security questionnaire, or a regulator, or its own post-mortem, this is the difference between "an AI was involved somehow" and a record you can actually stand behind.

#An agent that can undo itself

The most common way an agent loses your work has nothing to do with version control: it edits twelve files, runs a script that rewrites three more, decides the approach was wrong, and "puts things back" from its own memory of what they looked like. Editor-level undo doesn't cover the script. The agent's memory is not a filesystem.

So the depot's client grew a primitive for exactly this loop. A checkpoint is a private snapshot of the working copy's changes — not a submit, not visible to anyone else, held on that machine only:

$ grixel checkpoint -m "before refactoring the save system"
checkpoint 7bceab7c — "before refactoring the save system"
  captured: 1 file(s), 29 B new in the local store
  local only — not submitted, not backed up; exists only on this machine
  restore with: grixel checkpoint restore 7bceab7c

The receipt is blunt on purpose. And restoring is built so it cannot lose anything: the current state is snapshotted first, and the receipt hands you the way back:

$ grixel checkpoint restore 7bceab7c
restored 1 file(s)
  previous state saved — undo with: grixel checkpoint restore ed83081f

The agent gets these verbs over MCP — create, list, diff, restore. It does not get delete. Dropping a snapshot is a human command at a human keyboard, which means the failure mode "agent tidies up the evidence of the state you wanted back" is structurally impossible rather than merely discouraged.

Fan-out gets the same treatment. When a harness runs five sub-agents in parallel, each gets a disposable workspace — a sparse view of just the files its task touches, assembled from the shared local cache, so the fifth one costs about as much as its dirty set. Claude Code wires in with one command (grixel agent-setup --claude-code-worktrees): its worktree isolation then provisions depot workspaces, and every submit from one arrives already labelled with the agent and workspace that made it. Locks are scoped the same way — an agent submitting from its workspace cannot release the lock a human holds from theirs, which closes the quietest work-loss path I know of in multi-seat binary work. Workspaces holding unfinished work are never reaped; clean expired ones tidy themselves.

None of this weakens the earlier sections. A checkpoint confers nothing a submit confers — no history, no review state, no visibility. It is unsubmitted work with a lifecycle, and when the surviving attempt is worth keeping, the stack replays as ordinary gated, attributed submits. The safety net and the system of record stay two different things, which is precisely why both work.

#One backlog for people and agents

A system of record has to track the work as well as the files. Grixel's jobs are a modern take on Perforce's: lightweight tickets anchored to a path in the namespace, which means the access rules apply to them too. A job filed under a hidden project is itself invisible to anyone who can't see that project. The ticket types and their status flows come from your own admin-editable spec, with no methodology vocabulary baked in. Below, maya has filed job000001, a bug on the seasonal project, assigned to alice. A fix cites the job it resolves, and the ticket and the exact commit that closed it stay linked in both directions:

$ grixel submit -as alice --job job000001 -m "fix seams on hero texture"
grixel: holding exclusive lock on /companies/acme/games/seasonal/art/keyart_main.psd (lockable type)
Committed: 4bb92aee3ed1c442e92da6ecc482c0561231ca0631fdb91a4dfce77f90caf507
  ref     : companies/acme/games/seasonal
  changes : 1
  stored  : 5.1 MiB new, 58.9 MiB deduped
  parent  : ad439db18fa79626577df2f8f35dd4225e7a131a325034bb135e1bc1731582bf
  base    : 4bb92aee3ed1c442e92da6ecc482c0561231ca0631fdb91a4dfce77f90caf507 (advanced)
  jobs    : 1 cited

Two commands make this backlog agent-shaped: the worklist and the events feed. The worklist is what an agent (or a person) gets when it asks "what should I pick up":

$ grixel jobs -as alice --mine
assigned to me (1):
  job000001  bug        fixed        Hero texture seams on consoles
available (unassigned) (1):
  job000002  task       open         Spring festival content drop

The events feed is what automation polls; jobs are event-sourced, so many actors editing at once don't clobber each other:

$ grixel job events -as maya
2026-07-05T23:32:40Z  job000001  created maya     bug "Hero texture seams on consoles" [open]
2026-07-05T23:32:40Z  job000002  created maya     task "Spring festival content drop" [open]
2026-07-05T23:32:40Z  job000001  link    maya     link parent job000002
2026-07-05T23:32:41Z  job000001  link    alice    link commit 4bb92aee3ed1c442e92da6ecc482c0561231ca0631fdb91a4dfce77f90caf507
2026-07-05T23:32:41Z  job000001  status  alice    → triaged
2026-07-05T23:32:41Z  job000001  status  alice    → fixed
next cursor: 1783294361490152000

The next cursor line is the bookmark your automation polls from: hand it back on the next call and you receive only what happened since. Agents read this backlog through the read-only MCP tools and write back through the authenticated command line. One ledger of work, under the same permissions as the code it describes.

#Secrets, and the honest limits of hiding things

Small companies want their .env files versioned and backed up, and agents sharpen the want. But secrets are short and guessable, and a content-addressed store has a property you should hear from me rather than discover. Deduplication accounting is global: submit some bytes and the stored ... deduped line reports whether those exact bytes existed anywhere before. That is an oracle, and it is precisely why per-user secrets are encrypted on your own machine before they ever leave it. The ciphertext is freshly randomised every time, so it never dedups against anything, and it is size-padded, so even the length of what you're hiding doesn't leak. The oracle gets nothing. For content that is merely private (Grixel also has self-service private folders, hidden from everyone but you and the admins), the working files are ordinary high-entropy material where byte-guessing isn't practical. And for hidden paths in general, the most the oracle could ever confirm is that some exact bytes the guesser already possesses exist somewhere in the depot: never a path, a name, or any content.

$ grixel secret push -as alice
⚠ no escrow recipient configured — if you lose your key, these secrets are UNRECOVERABLE.
  set one: 'grixel key gen-escrow -out <file>' then 'grixel secret set-escrow <recipient>'.
Encrypted + pushed 1 secret(s): .env

$ grixel secret status -as alice
encrypted secrets (1):
  .env             pushed, decryptable by you

That warning is the tool telling me to configure an escrow recovery key, which my demo depot hasn't. A secret can also be granted to extra recipients or to service identities, so CI decrypts with its own key instead of a copied human one. "Decryptable by you" is the property the whole feature exists for: not by an operator reading raw bytes off the disk, and not by the server.

#Grab it from the git world and build on it

Here is the arrival story. An upstream repository, snapshotted into a clean Grixel project with one command; your local git does the fetch:

$ grixel import -as bob ~/demo/work/upstream companies/acme/tools/noise noise-ws -m "import noise lib" -y
fetching ~/demo/work/upstream …
Imported ~/demo/work/upstream into project companies/acme/tools/noise
  source    : ~/demo/work/upstream (master) @ 37bfc8f1
  commit    : 0228934870ba171543d09ea8def6fc430878dd97adab998254d90e4988e70ffd
  files     : 2 (131 B)
  workspace : ready — 'grixel status' works here; 'grixel blame' separates your edits from the import

$ grixel log -as bob companies/acme/tools/noise
commit 0228934870ba171543d09ea8def6fc430878dd97adab998254d90e4988e70ffd
  author : bob
  date   : 2026-07-05 23:32:43 UTC
  files  : 2 changed
  made by:  [git-import]
  import noise lib

The import itself is provenance: made by: [git-import], with the source, branch, and SHA on record. For a dependency you don't intend to edit, vendoring pins it read-only inside your project, and updating it later is an explicit, reviewable re-pin rather than a silent drift:

$ grixel vendor update -as alice noise
fetching ~/demo/work/upstream …
Re-pin "noise" from 37bfc8f1 to fa3078b7 (master) — 1 changed file(s), 0 deletion(s)? Continue? [Y/n] Updated "noise"
  re-pinned : 37bfc8f1 → fa3078b7 (master)
  mounted   : vendor/noise (read-only, pinned)
  ref       : companies/acme/games/seasonal-vendored/noise @ 2fccf980
  changed   : 1 file(s) (126 B), 0 deletion(s), 1 unchanged
  scope     : 0fc058b00345fb50caab34601935c49281e4c6b28b7a535fd853f4eb76a09898

That vendored library then shows up in a project's governed context at its pinned revision, so what your agents see of the open-source world is governed like everything else. And because files of any size are first-class here, chunked and deduplicated by content, there is no Git LFS bolt-on to configure when the thing you're building on includes real assets.

#Scriptable from day one

The last piece is quieter but it carries the others. Every Grixel command takes a --json flag and emits a frozen, versioned output envelope: a schemaVersion, a data payload, and structured errors with stable codes. That contract is what a two-person team automates against before any marketplace of integrations exists: a cron job watching review status, a bot filing a ticket when a mapping drifts. Underneath it sit a public, stable gRPC interface and first-party Go and Python SDKs generated from it. The command line the agents write through is a machine interface on purpose.

· · ·

#Where this can hurt you

Making a pre-release depot your company's system of record is a serious act of trust in a young product. I won't dress that up, so here is what limits the exposure. Your data sits on your own disk, in a single server process you run. The operator backup command takes an exclusive lock on the data root, so today a backup means briefly stopping the server or snapshotting the filesystem underneath it; because chunks are immutable once written, incremental backups are clean, and grixeld verify integrity-checks the store. Arriving is cheap because git import exists. Leaving is scriptable because the --json contract, the public gRPC interface, and the Go and Python SDKs can read everything out, though, to be equally precise, no purpose-built export-to-git tooling exists today, so departure would be a script you write, not a button you press.

There is no web UI. A non-technical co-founder works through the command line or through an AI assistant reading the depot over MCP, and what such an assistant sees is exactly the governed view previewed above for svc-store-copy. If your co-founder needs a graphical review queue today, this is not that.

Provenance is declared, not cryptographically attested. The design keeps attribution in that clipped-behind side-record precisely so server-verified attestation can be added later without rewriting history, but today a tool that wants to lie about which model it is, can. What you get now is honest actors leaving an honest trail, which is most of the audit value and none of the adversarial guarantee.

And the ecosystem is thin. Git enjoys two decades of CI templates, badges, editor integrations, and dashboards. Here you will write glue. The frozen JSON contract and the SDKs exist to make the glue short, but short glue is still glue you wrote and maintain.

· · ·

The assumption underneath the incumbent toolchain has quietly expired: an author line you can type anything into is no longer an identity. A company that builds with agents from day one needs them named and scoped, on credentials that lapse by themselves, reading governed context, writing through the same gates as the humans beside them, and leaving a record of what they knew. I want that to be one system instead of five, so that is what I'm building, and what Grixel itself is built inside of. The svc-store-copy token minted earlier in this piece has, as I write, under a week left to live. When it lapses, nothing needs cleaning up, and nothing it did was anonymous.


Grixel is pre-release. Read the docs, or request early access.