{
  "markdown": "# AVCS — Agentic Version Control System\n\n*An AI-native version control system for humans and AI agents working concurrently.*\n\n[![CI](https://github.com/izagood/avcs/actions/workflows/ci.yml/badge.svg)](https://github.com/izagood/avcs/actions/workflows/ci.yml)\n![status](https://img.shields.io/badge/status-experimental-orange)\n![node](https://img.shields.io/badge/node-%E2%89%A522.6-brightgreen)\n![runtime deps](https://img.shields.io/badge/runtime%20deps-0-blue)\n![license](https://img.shields.io/badge/license-Apache--2.0-green)\n\n**An agent should not spend its context on version control.** That is the whole design\ngoal, and it is measured rather than asserted — here is what the same work costs an agent:\n\n| What an agent pays for | git / the full surface | AVCS |\n|---|---|---|\n| Landing a change after someone else's PR merged first (30 KB module) | **18,922** tokens | **279** tokens — *99% less* |\n| Round trips to finish that recovery | 7 | 4 |\n| Tool schema, paid on **every** session | ≈8.8k tokens (39 tools) | ≈3.5k tokens (13, `--profile core`) |\n| What a same-line collision hands the model | the whole file, with conflict markers | one object naming the two contending operations |\n\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"docs/assets/rebase-token-cost-dark.svg\">\n  <img alt=\"Agent tokens to land a change after another PR merged first: git costs 446, 5,249 and 18,922 tokens on 0.7 KB, 8 KB and 30 KB files, while AVCS stays flat at 279\" src=\"docs/assets/rebase-token-cost-light.svg\" width=\"820\">\n</picture>\n\ngit's recovery cost tracks the size of the **file** — a conflict is bytes inside it, so the\nagent reads the whole module and writes the whole module back to change one line. AVCS's\ntracks the size of the **change**: a conflict is an object naming the two contending\noperations, so it stays flat as the file grows. There is also no branch to rewrite and\nnothing to force-push, which is why the round trips differ — and that is *one* cycle,\nrepeated for every PR that merges ahead of yours. Across the file sizes measured the saving\nis 37–99%.\n\nNone of this is a compression trick bolted on afterwards. It falls out of storing the\noperation graph instead of snapshots: there is no rebase to perform, so there is nothing to\nre-read. Method, caveats and the harness that produced the rebase numbers:\n[avcs-demo → what it costs an agent in tokens](https://github.com/izagood/avcs-demo#what-it-costs-an-agent-in-tokens).\nThe schema figures are the advertised MCP surface itself — 35 KB of JSON against 14 KB, at\nthe usual ≈4 bytes per token.\n\n> Git records **when** the code changed.\n> AVCS records **who changed it, with what intent, on what evidence, and through which conflict decisions** the code reached its current state.\n\nAVCS is a new, deliberately Git-incompatible version control system built for a world where humans and **many AI agents edit the same codebase concurrently**. It drops the commit / branch / merge / conflict-marker model and instead stores **intent**, **session**, **operation**, **evidence**, and **decision** as first-class objects. The code tree is not the source of truth — it is a **projection** computed by deterministically *reducing* the operation graph:\n\n```\nstate = reduce(base, operationDAG, decisions, policy, materializer)\n```\n\nThe same objects + the same policy + the same materializer produce the same tree on any replica. Merging is not text selection; it is a pure, deterministic reduction.\n\n> **Status:** research prototype. The implementation is real and test-covered, but every phase is built to a *working-MVP depth* (language-neutral text 3-way merge, ed25519 signing). Structure-aware merge, semantic-break detection, multi-signature trust, and hardened distributed sync are tracked on the [roadmap](docs/07-roadmap.md).\n\n**Jump in:** [install](#install) · [your first five minutes](#your-first-five-minutes-no-server-no-git-required) · [work against a server](#work-against-a-server) · [connect an agent over MCP](#connect-agents-mcp) · [agent quickstart walkthrough](docs/25-agent-quickstart.md)\n\n**See it run first:** [`izagood/avcs-demo`](https://github.com/izagood/avcs-demo) — a runnable\ndemo of the question this design answers: *what happens when two agents edit the same file at\nthe same time?* One `./demo.sh` walks a stale-head land that is absorbed instead of rejected,\na same-file auto-merge with no rebase, and a same-line collision that becomes a signed\ndecision rather than conflict markers.\n\n## Why not a layer on top of git?\n\nEvery \"AI + git\" tool eventually stores the agent's context *beside* the history — commit\ntrailers, PR comments, sidecar JSON. AVCS exists because these objects have to be\n**load-bearing** — consumed by the merge machinery itself — and bolted onto git they can't be:\n\n- **Evidence must gate merging.** git happily merges a behavior change with no passing\n  test. In AVCS that change is graded **L3 — blocked** by the reducer until *trusted*\n  evidence lands, and an operation's own author vouching for it does not count.\n- **Decisions must outlive the merge.** `git merge` resolves a conflict by emitting bytes;\n  the choice and its rationale evaporate. An AVCS `decision` is a signed object —\n  recallable later, and prior decisions bias future auto-resolution.\n- **Concurrent edits must not degrade into conflict markers.** Two agents editing one\n  file meet a deterministic policy reduction (L0–L4 below), not `<<<<<<<` in the tree\n  plus a human holding the pieces.\n- **Intent must travel with the work.** A trailer is inert text. An `intent` (goal +\n  constraints + allowed scope) is what sessions open against, what leases and contention\n  checks are scoped by, and what `avcs.context.build` hands the next agent.\n\ngit stores snapshots and leaves the merge to text selection; AVCS stores the operation\ngraph and makes the merge a computation over intent, evidence, and decisions. That is why\nit is deliberately git-**incompatible** — these objects are the engine, not metadata.\n(git interop still exists, as a bridge: [docs/14](docs/14-git-bridge.md), [docs/20](docs/20-workspace-bridge.md).)\n\n## Core principles\n\n| # | Principle | Contrast with Git |\n|---|-----------|-------------------|\n| 1 | **Operations are history**, not commits | A commit is merely a checkpoint over many operations |\n| 2 | **Identity is the entity ID**, not the file path | Rename + edit can auto-merge |\n| 3 | **Merge is a deterministic reduction**, not text selection | No conflict markers |\n| 4 | **A conflict is a first-class `decision` object**, not a broken file | The rationale stays in history |\n| 5 | **AI output is a proposed operation with attached evidence**, not trusted code | A behavior change with no test cannot be `accepted` |\n| 6 | **Code never defaults to last-write-wins** | Precedence is decided by policy |\n\n## How it works\n\nEvery meaningful thing is a content-addressed, append-only object. Code is a *projection* over the operation DAG, never stored as commits.\n\n| Object | Role |\n|--------|------|\n| `intent` | Why a change is being made (goal + constraints + allowed scope) |\n| `session` | An agent/human work episode against an intent |\n| `operation` | A single semantic change unit — the real history |\n| `evidence` | Machine-checkable proof (test / typecheck / lint / scan) attached to operations |\n| `decision` | A recorded resolution of a conflict or design choice |\n| `checkpoint` | A verified (ops + policy + materializer) state vector — replaces a commit |\n| `view` | A declarative query over the operation graph — replaces a branch |\n| `release` | A signed, provenance-bearing checkpoint — replaces a tag |\n| `policy` | The deterministic merge rules the reducer is parameterized by |\n\n…plus `blob` for raw content and the governance objects (`lease`, `membership`, `protection`, `promotion`, `redaction`, `override`, `approval`, `line`, `integration`) used by the multi-machine and security phases.\n\n## Conflict resolution levels\n\nAVCS never falls back to last-write-wins for code. Contending operations are graded and resolved with a recorded rationale:\n\n- **L0 / L1** — different entities, or **disjoint line regions** in the same file → **auto-merge**\n- **L2** — concurrent edits that overlap the same line region → **policy auto-decision** (human-preferred, trust-weighted); the auto-decision is itself recorded in `autoDecisions`\n- **L3** — a behavior change with no *trusted* evidence → **blocked**\n- **L4** — a public-API break → **requires a human decision**, routed to the scope's owners\n\nEvidence trust matters: an operation's own author cannot vouch for it. Evidence-gating and the passing-test bonus only count evidence produced by a *non-authoring, trusted* actor (CI bot / human).\n\n## What works today\n\nThe reducer and policy engine are the foundation; the higher phases build distributed collaboration, security, and observability on top.\n\n**Foundation (Phases 1–6)**\n\n- **Storage core** — append-only, content-addressed object store (`.avcs/objects`)\n- **Deterministic reducer + policy engine** — the L0–L4 conflict grading above, with a priority ladder, bounded reliability nudges, and auditable auto-decisions\n- **Language-neutral text merge** (Phase 2) — a deterministic N-way line-level 3-way merge (`src/merge/merge3.ts`), so edits to disjoint regions of one file auto-merge regardless of language; overlapping edits become a policy-resolved conflict region. No language parsing in the core\n- **Cryptographic trust** (Phase 3) — ed25519-signed evidence/decision; forged signatures fail the trust gate. Real validation runner, `WorkLease`, `RepairContext`\n- **Decision memory** (Phase 4) — recallable prior human decisions (`recallDecisions`) and distilled \"learned policies\" that bias future auto-resolution\n- **Policy depth** (Phase 5) — code-owner routing and bounded reliability learning\n- **Release & provenance** (Phase 6) — verified checkpoints + CycloneDX SBOM + signed artifacts\n\n**Collaboration, scale & security (Phases 7–12)**\n\n- **Phase 7 — multi-machine:** membership/roles (signed key federation), `pull` (object gossip; two replicas converge to the same `treeHash`), protection + `finalize` CAS (non-fast-forward rejected, so a stale push can't overwrite fresh history)\n- **Phase 8 — lineage:** long-lived divergent lines (e.g. v1.x ∥ v2.x, same path, different content, zero conflict), `portOp` (backport = cherry-pick)\n- **Phase 9 — scale:** entity index, `materializeAt` (time travel), chunked large-blob storage with dedup\n- **Phase 10 — observability:** `blame` (who/why), `logP`, deterministic `bisect`, `diff`\n- **Phase 11 — external contributions:** quarantine tier + `promote` + untrusted-CI gate\n- **Phase 12 — security:** `redact` (byte-eviction of leaked secrets, oid preserved), break-glass `override`, forward-only rollback\n- **Local undo** ([docs/23](docs/23-local-undo.md)) — `avcs undo [--last | <op-oid>…] [--purge] [--no-git]`: drop local ops from the view, and with `--purge` evict the bytes they uniquely reference. Refuses once the ops have been pushed, because that case belongs to admin-gated `redact`. In a git-bridged repo `--purge` clears the **git** copy too — but only where it can prove the rewrite is safe and local (nothing on a remote, the commits at the tip, no other work in them, a clean tree); anywhere else it still does the AVCS side and names precisely what is left and the one command that fits, up to and including \"rotate the credential, it is already published\"\n- **The working tree is genuinely derived** — `checkout` records what it projected\n  (`.avcs/projection.json`, path → blob oid) and, on the next projection, removes the files\n  the target view no longer contains. Files it never wrote — build output, ignored files,\n  anything you just created — are untouched, and a projected file you have since edited is\n  kept and named in a notice rather than silently overwritten. Switching views therefore\n  yields *that view*, not the union of every view projected before it\n\nBranches become **views**, commits become **checkpoints**, tags become **releases**. Agents drive AVCS through a first-class **MCP server** (39 tools, or 13 with `--profile core`); humans use the **CLI**. Since Phase 14 the server runs an **integration queue** (`avcs submit`, `POST /integrate`): a stale submission is never told \"head moved — pull first\" — the server re-reduces the frontier union on the submitter's behalf, and the outcome is always a verdict (`advanced` | `conflict` repair packet | `needs_evidence` — one validation run, never a redo | `queued`). Since Phase 15 replicas converge **live** (`GET /events` long-poll, `avcs sync --watch`, contention early-warning), and Phase 16 completed the MCP surface: `avcs.sync.land` lands work in one call, `avcs.context.build` assembles bounded working context with deterministic truncation, and subscribable resources notify a client when the head moves — see [docs/17](docs/17-sync-convergence.md) and [docs/18](docs/18-mcp-first-class.md). The behavior is pinned by an 827-test contract suite (`test/*.test.ts`, all green) and `tsc` is clean.\n\n## Install\n\nRequires **Node ≥ 22.6** — AVCS runs TypeScript directly via type stripping, so there is **no build step and zero runtime dependencies**.\n\nAVCS is published on npm as [`@izagood/avcs`](https://www.npmjs.com/package/@izagood/avcs). Install it globally to get the `avcs` command on your `PATH`:\n\n```bash\nnpm install -g @izagood/avcs\n```\n\nOr run it without installing, straight from the registry:\n\n```bash\nnpx @izagood/avcs version\n```\n\n### Your first five minutes (no server, no git required)\n\nAVCS is local-first: a repo on your disk is a complete VCS — history, blame, undo,\nreleases — with no server and no git anywhere. In an existing project directory:\n\n```bash\navcs init .                        # create the repo (inside a git repo is fine — .avcs is git-ignored)\navcs import . -m \"initial import\"  # bring the existing tree in as operations\n\n# …edit files as usual, then record the change:\navcs commit -m \"add mul()\"         # authors operations for your working-tree changes\n\navcs status                        # operation / conflict summary\navcs log                           # operation history\navcs blame file:src/math.js        # who owns this file and why (entity key = file:<path>)\navcs conflicts                     # decisions a human still owes\navcs decide <conflict-id> --choose <op-oid> --reason \"…\"   # …and pay one: a signed decision\n\n\navcs undo --last                   # take the last operation back out of the view…\navcs checkout                      # …and re-project the working tree from it\n```\n\nTwo things to notice: `commit` is not a git commit — it authors semantic *operations*,\nthe real history; and the working tree is a *projection* you re-materialize with\n`checkout`, not the source of truth. `avcs help` lists every command.\n\n### Signing identity\n\nAn avcs identity belongs to you and this machine, not to one checkout — the same scope as\n`~/.ssh` or `~/.gnupg`. Provision it once and every repo on the box can sign with it:\n\n```bash\navcs key provision human:you    # writes ~/.avcs/private/human:you.json (0600, dir 0700)\navcs key ls                     # who this machine can sign as, and which keystore each came from\navcs key import <key-file>      # put an existing identity on a NEW machine\n```\n\nThe keystore is `$AVCS_CONFIG_HOME`, else `$XDG_CONFIG_HOME/avcs`, else `~/.avcs`. A repo may\nkeep its own key in `<store>/private/` to sign as a *different* actor (a CI checkout, a second\nidentity); that override is read first. See [12 — Local production](docs/12-local-production.md#개인키-보관소-machine-level-keystore).\n\nYour **id** is your identity — trust, keys and governance key on it. For attribution and\ncontact, set a display name and email the git way; they ride in every operation you author\n(so blame and history can show and reach you) but never gate anything:\n\n```bash\navcs config user.name  \"Ada Lovelace\"\navcs config user.email \"ada@example.com\"\navcs config actor      \"human:ada\"      # the id commits author as (else your sole key / AVCS_ACTOR)\navcs config                              # show what is set\n```\n\nThese live in `.avcs/config.json`; `AVCS_AUTHOR_NAME` / `AVCS_AUTHOR_EMAIL` / `AVCS_ACTOR`\noverride per invocation.\n\n### Work against a server\n\nA repo stays useful with no server at all. Once there is one — [`avcs serve`](#build-your-own-server),\n[avcs-server](https://github.com/izagood/avcs-server), or any conforming implementation — the\nwhole exchange is a handful of commands:\n\n```bash\navcs clone https://your.server/acme/web .      # fetch the graph AND project a working tree\navcs clone https://your.server/acme/web . --at <checkpoint>   # …at one exact checkpoint\navcs sync                                      # pull + push against the remote it recorded\navcs sync --watch                              # live convergence: long-poll + contention early warning\navcs land -m \"add mul()\"                       # push + checkpoint + integrate, in one step\n```\n\n`land` is the one to reach for. A stale head is absorbed by the server's integration queue\nrather than bounced back as \"head moved — pull first\", so the outcome is `landed` or a\nconflict packet for a human to decide — never a redo. `avcs remote add <name> <url>`\nregisters additional servers; `avcs sync <name>` picks one.\n\n**Reading from CI, without handing out a signing key.** The default credential is an\n`AVCS-Sig` signature over the canonical request, which covers the method and the body — a\ncaptured read credential cannot be replayed as a write. That is the right default, and a\npoor fit for an ephemeral reader. So a *read* also accepts a bearer token:\n\n```bash\nAVCS_HUB_TOKEN=… avcs clone https://your.server/acme/web .\n```\n\nThe token is read-only by construction: the write path takes no token parameter at all, so\na leaked variable can clone but can never push, finalize, or rewrite policy. A held signing\nkey always wins over the token, so a signed reader is never silently downgraded. The token's\nformat, lifetime and scope belong to the server — see [docs/26](docs/26-hub-protocol.md).\n\n### Connect agents (MCP)\n\nAgents drive AVCS through its MCP server. Once `avcs` is installed, register it with the Claude Code CLI:\n\n```bash\navcs mcp install            # runs `claude mcp add avcs -- avcs mcp` for you (scope: user)\nclaude mcp list             # confirm \"avcs\" is Connected\n```\n\n`avcs mcp` itself is the stdio server agents spawn (target repo = `$AVCS_REPO`, else the cwd). To register by hand — or for any other MCP client — point it at `avcs mcp`:\n\n```bash\nclaude mcp add avcs -- avcs mcp\n```\n\nThe MCP SDK ships as an optionalDependency, so a normal install includes it; no extra step needed.\n\nEvery tool answers compactly by default — pretty-printing is an opt-in `verbose` flag on the\ncall, because whitespace an agent never reads is still whitespace it pays for.\n\n**The loop an agent runs** — five moves, and landing is one call:\n\n```\navcs.guide                                  # the loop, the rules, error recovery\navcs.context.build   { intentOid }          # provenance, prior decisions, live risks\navcs.operation.propose { path, content }    # never write final files directly\navcs.validate.run + avcs.evidence.attach    # a behaviour change needs passing evidence\navcs.sync.land       { by }                 # push + checkpoint + integrate → landed | conflict\n```\n\n`sync.land` is the point: a stale head is absorbed for you, so the outcome is either `landed` or a conflict packet for a human — never \"pull and redo\". Add `--profile core` to advertise only these 13 tools instead of all 39 — the schema an agent is handed drops from 35 KB to 14 KB, on every session:\n\n```bash\nclaude mcp add avcs -- avcs mcp --profile core\n```\n\nTo upgrade later, re-run `npm install -g @izagood/avcs@latest`; to remove it, `npm uninstall -g @izagood/avcs` (your repo data is left intact).\n\n### Install from source\n\nPrefer to track the latest `main`, or hack on AVCS itself? The bundled `install.sh` clones the repo and wires up an `avcs` launcher that points back at the checkout, so updating is just `git pull` — no reinstall needed.\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/izagood/avcs/main/install.sh | bash\n```\n\nThat one-liner clones the repo to `~/.local/share/avcs` (override with `--dir`/`AVCS_HOME`) and installs an `avcs` launcher to `~/.local/bin`. Re-running it updates the checkout in place. Already have a clone? Run the installer from inside it instead:\n\n```bash\ngit clone https://github.com/izagood/avcs.git && cd avcs\n./install.sh\n```\n\nThe launcher lands in `~/.local/bin` (override with `--bin-dir <dir>` or `AVCS_BIN_DIR`). If `~/.local/bin` isn't on your `PATH` yet, the installer prints the line to add.\n\nOther install-from-source options:\n\n```bash\n./install.sh --bin-dir /usr/local/bin   # system-wide (may need sudo)\n./install.sh --name avcs-dev            # install under a different command name\n./install.sh --dir ~/src/avcs --ref v1  # one-liner mode: clone dir + ref to install\n./uninstall.sh                          # remove the launcher (data is left intact)\n```\n\nIf `node` isn't on your `PATH` at runtime, point the launcher at one with `AVCS_NODE=/path/to/node`.\n\n## Use as a library (`@izagood/avcs`)\n\nA hosting server (e.g. avcshub) can depend on the AVCS core as a versioned package. Development and tests run the raw `.ts` via type stripping, but `npm publish` ships a `tsc`-compiled `dist/` (JS + type declarations via `tsconfig.build.json`), so consumers import it with no build tooling of their own.\n\n```bash\nnpm install @izagood/avcs\n```\n\n```ts\nimport { startHub, type HubHandle } from \"@izagood/avcs/hub\";   // the hub server\nimport { ObjectStore, CorruptObjectError } from \"@izagood/avcs/store\";\nimport { verifyMessage, generateKeypair } from \"@izagood/avcs/identity\";\nimport { Repo } from \"@izagood/avcs\";                            // root: primary public API\n\nconst hub = await startHub({ repoDir: \"./data\", port: 8080, gated: true });\n```\n\nEntry points: `.` (root barrel) · `./hub` · `./hub/client` · `./store` · `./identity` · `./types`.\n\nReleasing: bump `package.json`'s `version` in a PR and merge it to `main` — `.github/workflows/release.yml` detects the new version, runs `npm publish` (with provenance), tags the commit `vX.Y.Z`, and cuts a GitHub Release. The publish steps are guarded by a registry check, so package.json edits that don't change the version are no-ops. Every PR also runs a release dry run (`npm run build` + `npm pack --dry-run`) in CI to catch packaging regressions before merge. Requires an `NPM_TOKEN` repository secret with publish rights to the `@izagood` scope.\n\n## Build your own server\n\nAVCS is a protocol, not a service. **A conforming server needs three endpoints:**\n\n```\nGET  /have            the oids you hold        → [\"operation_ab12…\", …]\nGET  /objects/:oid    one object as JSON       → { … }  (404 if absent)\nPOST /objects         take one object          → { \"oid\": \"operation_ab12…\" }\n```\n\nEverything else is optional. The client reads capability flags from `GET /version`, and when a\nflag is absent — or an endpoint answers `404`/`405`/`501` — it falls back on its own. A\nread-only mirror serving only the first two is a legitimate server; so is one without the\nintegration queue, without batching, without long-poll.\n\nThat is deliberate: avcs is a public client against deployments it does not control.\n\nTwo documents are the contract:\n\n- **[26 — Server protocol](docs/26-hub-protocol.md)** — every endpoint's request/response shape,\n  status codes, capability negotiation, the SSH-style request signature, and a table of the\n  mistakes server authors actually make.\n- **[24 — Canonical interop](docs/24-canonical-interop.md)** — how an oid is computed. Read\n  this first if you are not writing JavaScript: an object's identity is the sha256 of its\n  canonical JSON, and three parts of that canonicalization are easy to get subtly wrong.\n  Diverge and you do not get an error — you get two honest implementations that never\n  converge.\n\nValidate your canonicalizer against [`spec/canonical-vectors.json`](spec/canonical-vectors.json)\n(10 accepted, 4 rejected, each with the expected canonical bytes and oid) before anything else.\n\nThen point the conformance suite at your server:\n\n```bash\nAVCS_CONFORMANCE_URL=https://your.hub/acme/web npm run conformance\n```\n\nIt reports which levels apply — `core` (the three endpoints, and a clone that reproduces the\nsource treeHash), then `sync`, `governance`, `queue` as your capability flags allow. A level\nyou do not advertise is **skipped, not failed**: a partial server is a legitimate one.\n\nWhat `core` checks is **object replication and clone-ability**, not server-side projection.\nThe treeHash comparison runs between two *clients* — one that pushed, one that cloned — so it\nestablishes that your server returned faithfully what it was given, not that your server can\nitself derive a tree from those objects. A server that stores and serves objects correctly but\nnever materializes anything passes `core`, and that is intended: projection is a client\nconcern, and a server that does it too is doing more than the level asks.\n\nThree implementations to start from:\n\n- **[`examples/server.py`](examples/server.py)** — a complete conforming core-level server in\n  one stdlib-only Python file. No JS, no avcs library: its only dependencies are\n  [docs/24](docs/24-canonical-interop.md) and the golden vectors, which is the point — run\n  `python3 examples/server.py --selftest` to see the vectors check its canonicalizer, then\n  point the conformance suite at it.\n\n- **[avcs-server](https://github.com/izagood/avcs-server)** — a standalone, self-hostable,\n  multi-repo server built on this library. Conformance-verified at `core`; run it, read it,\n  or fork it as the starting point for your own deployment.\n- **`startHub` in this repository** — the reference: single-repo, no multi-tenancy, but it\n  serves the whole protocol. Read it as the spec's executable form, or run it with `avcs serve`.\n\n## Running from a checkout\n\nHacking on AVCS itself? Every command runs straight from the checkout with `node`:\n\n```bash\n# Walk all four merge scenarios end to end\nnode --experimental-strip-types src/demo.ts\n\n# Run the behavior-contract test suite\nnode --experimental-strip-types --test test/*.test.ts      # or: npm test\n\n# Human-facing CLI (or just `avcs <command>` once installed)\nnode --experimental-strip-types src/cli.ts init .\nnode --experimental-strip-types src/cli.ts status\nnode --experimental-strip-types src/cli.ts conflicts\nnode --experimental-strip-types src/cli.ts log\n\n# Agent-facing MCP server (`avcs mcp` once installed; ships the SDK as an optionalDependency)\nnpm install\nAVCS_REPO=$(pwd) npm run mcp      # = node --experimental-strip-types src/mcp/server.ts\n```\n\n> Type checking (`tsc --noEmit`) needs `npm install`; the runtime itself has no dependencies.\n\n## Code map\n\n| Path | Role |\n|------|------|\n| `src/objects/types.ts` | Object model definitions (single source of truth) |\n| `src/store/objectStore.ts` | Append-only, content-addressed store |\n| `src/core/canonical.ts` | Canonical serialization + content addressing (oid) |\n| `src/core/identity.ts` | ed25519 sign/verify + Keyring (Phase 3) |\n| `src/reducer/reducer.ts` | Operation graph → code tree reduction + conflict grading |\n| `src/reducer/policy.ts` | Policy engine (priority ladder, reliability nudge) |\n| `src/reducer/incremental.ts` | Incremental re-reduce (reuse clean groups) |\n| `src/merge/merge3.ts` | Language-neutral N-way line-level 3-way text merge (Phase 2) |\n| `src/policy/owners.ts`, `reliability.ts` | Code-owner routing · reliability learning (Phase 5) |\n| `src/validation/runner.ts`, `repair.ts` | Validation runner · RepairContext (Phase 3) |\n| `src/concurrency/lease.ts` | WorkLease (Phase 3) |\n| `src/release/sbom.ts` | SBOM generation (Phase 6) |\n| `src/hub/hubServer.ts`, `hubClient.ts` | Multi-machine sync server (Phase 7; API names keep the legacy “hub” term) |\n| `src/api/repo.ts` | High-level facade (shared by CLI, demo, MCP) |\n| `src/api/keystore.ts` | Machine-level private keystore (`~/.avcs/private`) |\n| `src/mcp/server.ts` | Agent-facing MCP interface (39 tools; `--profile core` advertises 13) |\n| `src/cli.ts` | Human-facing inspection/release CLI |\n| `src/demo.ts` | End-to-end scenario |\n\n## Design docs\n\n- [00 — Overview & principles](docs/00-overview.md)\n- [01 — Architecture](docs/01-architecture.md)\n- [02 — Object model](docs/02-object-model.md)\n- [03 — Reducer & conflict levels](docs/03-reducer.md)\n- [04 — Policy engine](docs/04-policy.md)\n- [05 — Views · Checkpoints · Releases](docs/05-views-checkpoints.md)\n- [06 — MCP / Skill interface](docs/06-mcp-interface.md)\n- [07 — Roadmap](docs/07-roadmap.md)\n- [08 — Governance & consensus (avcshub)](docs/08-governance.md)\n- [09 — Git/GitHub use-case coverage & design evolution](docs/09-usecase-coverage.md)\n- [10 — Production design plan](docs/10-production-plan.md)\n- [11 — Incremental reduce](docs/11-incremental-reduce.md)\n- [12 — Local production](docs/12-local-production.md)\n- [13 — Hub production](docs/13-hub-production.md)\n- [14 — Git bridge (real-world compatibility)](docs/14-git-bridge.md)\n- [15 — Language-neutral core](docs/15-language-neutral-core.md)\n- [16 — Workspace scope](docs/16-workspace-scope.md)\n- [17 — Sync convergence: integration queue & live sync (design)](docs/17-sync-convergence.md)\n- [18 — MCP as the first-class connection](docs/18-mcp-first-class.md)\n- [19 — Entity identity: rename × edit commutativity](docs/19-entity-identity.md)\n- [20 — Workspace-first git bridge](docs/20-workspace-bridge.md)\n- [21 — shared-paths: build environments shared across workspaces](docs/21-shared-paths.md)\n- [22 — Region policy arbitration (design)](docs/22-region-arbitration.md)\n- [23 — Local undo: the pre-share escape hatch](docs/23-local-undo.md)\n- [24 — Canonical interop: the language-neutral canonicalization subset](docs/24-canonical-interop.md)\n- [25 — Agent quickstart: driving AVCS from Claude Code (MCP)](docs/25-agent-quickstart.md)\n- [26 — Server protocol: what a conforming server must serve](docs/26-hub-protocol.md)\n\n## Contributing\n\nThis is an early-stage research prototype and the design is still moving. Issues and discussion are welcome — if you're proposing a change, the design docs above are the best starting point for the rationale behind the current model. Please run `npm test` and `npm run typecheck` before opening a pull request.\n\n### Filing an issue\n\nHit something you'd like changed while using AVCS? Please open an issue rather than sending free-form feedback — structured reports are far easier to act on. Two templates are provided under [`.github/ISSUE_TEMPLATE`](.github/ISSUE_TEMPLATE):\n\n- **🔧 Change request** — propose a change to existing behavior, the CLI/MCP interface, defaults, or docs.\n- **🐞 Bug report** — something behaves incorrectly, crashes, or produces a non-deterministic result.\n\n> 🌐 **Any language is welcome.** File your issue in whatever language you're most comfortable with — English, 한국어, 日本語, etc. Maintainers will translate as needed; don't let language be a barrier to reporting.\n\nEvery push and pull request to `main` runs CI ([`.github/workflows/ci.yml`](.github/workflows/ci.yml)): `npm ci` → `npm run typecheck` → `npm test` on Node 22.x and 24.x. PRs are merged only when CI is green.\n\n## License\n\nLicensed under the [Apache License 2.0](LICENSE). Copyright © 2026 jaebin lee. See [NOTICE](NOTICE) for attribution.\n",
  "bytes": 31606,
  "sha": "300d28e975f2b44ddc9e7013d0c34591a3b39097b52108e558ce000d541ecd3e",
  "repo_slug": "izagood/avcs",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_izagood_avcs_b46ee513/readme"
}