Skip to main content

Local repositories

Overview​

The Local repository integration gives Vantik a git repository that is on the disk of the machine that runs the server. It needs no account and no token. You give the path of the repository.

A local repository is a source for modules, as a git host is. Read How to link a module to a repository.

The server never reads the work tree of the directory. It fetches the commits from the directory, and it pushes the branch of an agent run back to it. It does not open a pull request.

Only a workspace admin can add or remove a local repository. Each member can see the list.

The Local repository settings, with one repository and the field for a new
path

The directory that the server can read​

The server takes a repository only from inside one directory. The operator of the server sets this directory with LOCAL_REPO_ROOT.

  • If LOCAL_REPO_ROOT is not set, the server uses the home directory of the account that runs it.
  • In the Docker Compose deployment, Docker mounts LOCAL_REPO_ROOT into the server container at the same path. If it is not set, the server gets an empty directory, and you cannot add a local repository.

Warning: Do not set LOCAL_REPO_ROOT to your home directory. The server can then read each file in it, for example the files in ~/.ssh. Set it to the directory that holds your checkouts, for example /Users/you/Code.

How to add a local repository​

  1. Open Settings → Integrations, and click View on Local repository.
  2. Type the absolute path of the repository, for example /Users/you/Code/your-project.
  3. Click Add.

The name of the repository in Vantik is the name of its directory.

The server checks the path before it adds it. It refuses the path if:

  • the path is relative;
  • the path is not inside LOCAL_REPO_ROOT, or it is LOCAL_REPO_ROOT itself;
  • the path does not exist, or it is a file;
  • the directory has no .git. A .git file is correct, so a git worktree can be a local repository;
  • the workspace has the path already.

Vantik shows the reason below the field.

To remove a local repository, click the delete button on its row. This does not change the directory on the disk.

The repository mirror​

The server keeps its own copy of each repository that it reads. This copy is the repository mirror. The server makes a mirror for each source: a local repository, a git host, and GitHub.

A mirror is a bare git repository. It holds the branches of the repository, and no tags. The server makes it the first time that a part of Vantik needs the code.

These parts of Vantik read the code from the mirror:

  • Agent runs in the hosted sandbox. The server makes the checkout of a run from the mirror. To push the branch of the run, it makes a clone of the mirror, and pushes from that clone to the source.
  • The folder picker of a module. The folders that you can select for a module come from the mirror.
  • The knowledge bank. The knowledge verifier and the checks of the citations read the cited files from the mirror. Read Knowledge.

How current the mirror is​

The server fetches the source again when the mirror is more than 60 seconds old. Before the checkout of an agent run, the server always fetches. If a part of Vantik asks for a commit that the mirror does not have, the server fetches at once. It does this a maximum of one time in 10 seconds.

The size limit​

To start a hosted agent run, the server makes a compressed archive of the files at the start commit. The archive holds no history. If the archive is more than 256 MB, the run fails with a message that gives the size.

Where the mirror is​

The operator of the server sets the directory of the mirrors with REPO_MIRROR_ROOT. The default is ~/.vantik/repos. In the Docker Compose deployment, the directory is /data/repos on the repo-mirrors volume.

You can delete this directory. The server then fetches each repository again. The server does not delete a mirror when you remove a repository.

No page of the webapp shows the mirror.

The issue mirror​

An agent often has the repository and no access to Vantik. For example, a sandbox can have no network, a harness can have no MCP, or nobody gave the session a token. The issue mirror is for these agents. It puts the issues of a team in the repository. The agent reads them there, and it hands proposals back through git.

The mirror is off for each repository until an admin turns it on.

Warning: Each person and agent that can read the repository can read the mirrored issues. Each one that can write to it can propose changes. Choose the teams with this in mind.

How to turn it on​

  1. Open Settings → Integrations, and click View on Local repository.
  2. Find the repository. Tick each team whose issues it must carry.

To turn the mirror off, clear all the boxes. Vantik then stops the passes. It leaves refs/vantik/issues in the repository, because the ref is data in your repository and you can delete it.

Only a workspace admin can change this setting. The route is POST /api/v1/local_repo/<repository id>/git_issues, with the body {"teamIds": [...]}. One repository can carry only one team for each identifier. If two teams use the identifier ENG, the server refuses the second one.

A repository of a git host​

A repository that you added to a git host can carry the mirror too. Open Settings → Integrations, click View on the host, and tick the teams for the repository. The route is POST /api/v1/git_remote/<connection id>/repositories/<repository id>/git_issues, with the body {"teamIds": [...]}. Only a workspace admin can use it.

Vantik pushes with the token of the connection. Some hosts refuse a push to refs/vantik/*. Then Vantik writes one log line for the repository in each pass, and it does not retry inside the pass. The inbox stays unapplied until the host accepts the ref. A GitHub repository that you connect through the GitHub app does not carry the mirror yet.

What Vantik does in the repository​

The server never writes into your checkout. It works in its own copy, the repository mirror, and it uses two refs in your repository:

RefWho writes itWhat it holds
refs/vantik/issuesVantikA commit whose files are the issues
refs/vantik/inbox/<name>An agentOne hand-off. Vantik deletes it after it applies it

Each minute (GIT_ISSUES_CRON), Vantik does these steps for each repository:

  1. It fetches refs/vantik/issues and refs/vantik/inbox/* from the repository into its mirror. This fetch does not change the fetch of the branches.
  2. It reads each inbox as a set of changes, and it applies the changes.
  3. It writes a new snapshot commit in the mirror, and it pushes the commit to refs/vantik/issues. The push fails if somebody moved the ref after step 1.
  4. It deletes each inbox ref that it applied. It deletes a ref only if the ref did not move. It does this only after the push worked. If the push fails, the inbox stays and the next pass reads it again.

Vantik runs no hook of your checkout. It starts git with hooks and core.fsmonitor off. For a push into a local directory, it also starts the receive-pack of that directory with hooks off. A pre-receive or post-receive hook in your checkout does not run.

The refs are outside refs/heads, so they are not branches. git branch, git status and a plain git clone show nothing. The ref is in git log --all. Your HEAD, your index and your work tree do not change.

What the snapshot holds​

FileWhat it is
README.mdHow an agent reads and proposes, with the valid states and labels
index.mdThe open issues of each team
issues/<KEY>/issue.mdOne issue: front matter, then the description
issues/<KEY>/checklist.mdThe definition of done of the issue. Each item has an id in backticks
issues/<KEY>/comments/*.mdThe comments of the issue

An open issue is always in the snapshot. A closed issue stays for 30 days after it entered its closed state. After that, it leaves the snapshot. A pass that finds nothing new writes nothing, so the history of the ref is the history of the issues.

What an agent does​

The README.md of the snapshot is the reference. In short, an agent does these steps:

  1. Read an issue: git show refs/vantik/issues:issues/ENG-42/issue.md.
  2. Check out the snapshot in a detached worktree, edit the files, and commit.
  3. Hand the commit in under a name of its own: git update-ref refs/vantik/inbox/<name> HEAD. From a clone, use git push origin HEAD:refs/vantik/inbox/<name>.

Vantik answers in the message of the next snapshot commit. The message has a Vantik-Inbox: <name> trailer. This message is the only reply that the agent gets.

Sessions​

To make a session visible on an issue, the agent ends its commit message with trailers:

ENG-42: in progress

Vantik-Session: 7f3a9c
Vantik-Harness: omp

Vantik-Session is the id of the session. Vantik-Harness is optional and names the harness. Vantik-Origin is read but not stored yet. For each issue that the hand-off changes, Vantik creates or updates one agent session. The session has the channel GIT_INBOX and the bot of the repository as its actor. A commit without Vantik-Session makes no session.

Notes, ticks and facts​

An agent can append lines to issues/<KEY>/outbox.jsonl. Each line is one JSON object. The agent only adds lines at the end of the file.

LineWhat Vantik does
{"v":1,"type":"note","body":"..."}Adds a comment to the issue
{"v":1,"type":"criterion","id":"<id>","evidence":"..."}Ticks one item of the definition of done. The evidence is required
{"v":1,"type":"remember","content":"...","kind":"FACT"}Proposes a fact. A person or the triage must accept it

The id of a criterion is in checklist.md. It must belong to the issue of the file. Vantik does not read a question from git. One hand-off can hold 10 notes, 10 facts and 200 lines for each issue. Vantik ticks a criterion when it applies the hand-off. It does not wait for the end of a run.

How to close an issue​

To move an issue to a state of the completed kind, the agent changes state: and adds resolution: "how it was resolved" to the front matter, in the same commit. Vantik posts the resolution as a note first, and then changes the state. This is the same order as close_task. Vantik refuses a resolution when the state does not change to a completed state.

An agent can change the title, the state, the priority, the labels and the description of an issue. An agent can add a comment. An agent can file an issue as a file under new/, and the issue goes to the triage of its team. Vantik refuses everything else and gives the reason. An inbox ref that points at a blob or a tree is refused, and Vantik deletes it.

An agent can make a second hand-off on top of its first one. Vantik adds each inbox commit that it applied as a parent of the next snapshot. The second hand-off is then compared with the first, and no change is applied twice.

How Vantik applies a change​

Vantik never merges the commit of an agent. It compares each file with the snapshot that the agent started from. It reads the difference for each field, for example "state from Backlog to In Progress". So two agents can change different fields of one issue at the same time.

Vantik refuses a change to a field that a person changed in Vantik after that snapshot. The agent gets the refusal and the current value, and it starts again from the newer snapshot.

A hand-off has limits. It can change a maximum of 200 files. One file can have a maximum of 256 KiB. The files of one hand-off can have a maximum of 8 MiB in total. Vantik refuses a file over a limit and says which one.

Vantik writes each change as the bot of the local repository. It records the author of the commit as the person who proposed the change. Vantik does not check the author of the commit against its users. An agent cannot assign an issue from git. An assignment starts a run, and a commit must not do that.

What it does not cover yet​

A cloud sandbox that can push only to its own branch cannot write an inbox ref. A GitHub repository does not carry the mirror yet.