KVS as a concurrent + AI-first forge — the server/host face of Koder Version System

ratified

One line. Make KVS = Koder Version System the end-to-end version system — keep its existing clientengine face, and add a *erverhost face (the next-gen forge, Koder-Flow's successor) whose differentiators are (1) conflict-free concurrent writes for fleets of AI agents and (2) an AI-first/MCP surface co-equal to git+web — on a recursive namespace tree*over kdb-next + kdb-obj.

0. Status & relationship to prior art

This RFC is not greenfield. It extends stack-RFC-006 §5 (the concurrent VCS layer, jj-style, which already named products/dev/kvs as the home) and the already-decided object plane (§3/§7, owner-ratified 2026-06-10: BUILD kdb-obj). It inherits rather than re-derives:

  • refs on kdb — DONE as a primitive (FLOW-147 spike PASS + FLOW-148

    productionize + #156-165). Single-statement CAS = exactly-one-winner under concurrency (the concurrency keystone). Shadow-write in Flow today.

  • kdb-obj object plane — owner-ratified to build (RFC-006 §7 + infra/data/oss

    ADR-001, 2026-06-08: compose s3s + reed-solomon-simd + kdb metadata behind a swappable ObjectEngine trait). It is its own component infra/data/oss (the object-storage substrate under the kdb family), NOT kdb core. Build is already underway: OSS-007 done (crate skeleton + ObjectEngine trait); OSS-008-011 pending (s3s API + Koder ID auth/RLS · reed-solomon EC placement + kdb meta · OSS-010 wires the first consumers = FLOW-148 git objects + Hub depot · OSS-011 drives the self-hosted-pairs row-18 G1→G5 gates / MinIO flip). Flow's modules/kdb_obj/ is a stub consumer awaiting OSS-010.

  • KVS engine pieces — KVS#179 conflict-as-data, KVS#180 virtual-branch-cli,

    KVS#184 cross-link, KVS#202 concurrent-commit + provenance trailers.

  • kdb building blocks — kdb#542 BlobRef column type, kdb#733 blobref cascading

    delete, kdb#717 WAL bottomless S3 archive tier.

What this RFC changes vs RFC-006 §5: §5 split the work as *KVS = client/engine, Flow = host. The owner's direction (2026-06-10) makes *KVS the host too*— the forge that supersedes Flow. This RFC reconciles that shift: KVS absorbs the host role; Flow becomes the legacy host we migrate off (§9).

1. Motivation — the real drivers

The motivation is not the residual gitea strings in Koder Flow (those are deliberate fork-residue — license headers, upstream imports, the .gitea/ Actions path; the rebrand is DONE). The real, structural drivers are:

  1. Rigid 2-level data model. Gitea/Flow bakes owner_id → repo into thousands

    of queries. The owner wants an arbitrary namespace tree (a namespace contains namespaces and repos, any depth — GitLab-subgroup-like) which a fork cannot retrofit cheaply.

  2. Flow is an island. Own DB, own auth — not a Stack-native citizen. KVS-host

    is kdb-native (data), Koder-ID-native (auth), Jet-served, KDS-skinned.

  3. The AI-concurrent regime. Git/GitHub assume humans serializing via PR. KVS

    assumes most commits come from a fleet of AI agents editing concurrently at high frequency — the exact pain of N /k-go sessions clobbering this monorepo today. That regime needs conflict-free concurrent writes + AI surfaces as first-class, not bolted on.

2. Decision 1 — build vs fork-extend (the host)

Decision: greenfield Koder-native host that EMBEDS git (does NOT rewrite git's core), reusing the KVS engine + the kdb durable tier. This is the Layer mechanism of RFC-006 §5.2 (new front-end + working-copy model over an intact git store; interop day 1, reversible), explicitly not the "Own engine" (E) last resort.

Option Long-term Why not
Fork-extend Flow Retrofit a namespace tree into Gitea's owner_id→repo schema The 2-level model is woven through thousands of queries (D9 migration cost is enormous; D1 wrong abstraction stays baked). Rejected.
Greenfield, rewrite git core (E) Full control of the object model Loses native git interop; "eternal liability" (RFC-006 §5.2 E). Rejected for v1; a Koda-native git is a north star, not a start.
Greenfield host embedding git (L) — CHOSEN New data model (namespace tree) + UI + Stack-native, with git plumbing embedded (shell-out / go-git) and the durable tier on kdb refs + kdb-obj Interop day 1; the hard solved part (smart-http/ssh, pack, LFS) is reused, not rebuilt; matches RFC-006 §5 strategy.

Trade-off accepted (Quality > Speed, stack-principles §2): we pay the design + integration cost of a Stack-native host instead of the fast path of patching Flow, in exchange for the namespace tree + concurrency + AI surfaces being structurally correct (D1) rather than retrofitted onto the wrong abstraction.

3. Data model — the recursive namespace tree (the keystone)

The keystone, and the one thing a fork can't retrofit:

  • A namespace is a recursive node: it may contain child namespaces and

    repos, to arbitrary depth. There is no privileged "organization" level — "org", "team", "project", "personal" are all just namespaces with policies.

  • Path = the namespace chain (a/b/c/repo), resolved through the tree, not a

    flat owner/repo.

  • Storage: the tree + repo metadata live in kdb-next (relational/tree

    queries, MVCC); large immutable bytes (git objects/packs) live in kdb-obj (content-addressed); refs live in kdb (transactional CAS).

  • Permissions resolve through the tree via Koder ID — inherited down the

    chain, overridable per node. Multi-tenancy per specs/multi-tenancy/contract.kmd (D5): cross-tenant access 404s; tenant_id on every row.

  • Moves/renames are cheap (re-parent a subtree) — vs Gitea's transfer pain.

Open question OQ-1 (§12): the exact tree-permission resolution model (inheritance + override + visibility) — needs its own spec section before implementation.

4. Concurrency model — conflict-first-class (Pillar 1)

Insight: git objects are immutable + content-addressed → writing an object never conflicts (same content → same hash, idempotent; different content → different hash, both stored). The only contention point is the mutable ref. So "extreme concurrency" reduces to making ref-advance non-blocking and auto-merging:

  1. CAS object store on kdb-obj — conflict-free by construction; inherits kdb's

    apply-order-independent concurrent writes (kdb#790#791#792) + group-commit.

  2. Mergeable ref DAG, no locks — a branch is not "one SHA under CAS-lock";

    concurrent pushes to the same branch trigger server-side AST/block merge (the KVS engine, KVS#179/#202) → both land, zero non-ff rejection. No per-repo / per-ref lock (the opposite of Gitea). The refs→kdb single-statement CAS (FLOW-148) gives the exactly-one-winner primitive the merge loop builds on.

  3. Conflict = explicit committable state, never silent corruption — when

    auto-merge can't resolve, the result is a first-class conflict object (KVS#179 conflict-as-data / jj model) surfaced as a needs-resolution state — not a rejection and not a silent overwrite. (We just lived the silent-.git/index-corruption pain; this contract is the antidote.)

  4. Stateless host frontends + kdb shared concurrent data-plane → scale

    frontends horizontally; concurrency lives in the data plane.

Acceptance bar (the differentiator): N agents concurrent-push the same branch → all land via server-side merge, 0 non-ff rejections, conflicts (if any) materialize as explicit conflict objects. This is the walking-skeleton keystone (§8) — prove it first.

Open question OQ-2 (§12): the precise "can't-auto-merge → conflict object" contract + how a merge driver is selected per file/language (RFC-006 §5.2 maps semantic merge to the Driver mechanism: per-language merge driver via .gitattributes). This is the research-y core; the KVS engine is the head-start.

5. AI-first / MCP surface (Pillar 2)

MCP is a co-equal surface to git + web, not a plugin:

  • Parity: every operation (namespacerepo read, file readedit, branch, PR,

    comment, code search, diff, merge, conflict-resolve) is an MCP tool/resource. Port Koder Flow's MCP lessons (FLOW-094108178/192): resource hierarchy, scope-gated tools, per-token rate limit, cross-tenant 404.

  • Agent identity is first-class (not only humans): scoped tokens + identity via

    Koder ID / SVID; provenance on every op (KVS#202 trailers) → "which agent did what" auditable (D8).

  • AST/block-level ops exposed — agents edit at the structural level (the same

    engine as the merge) → semantic edits + clean merges (direct synergy with §4).

  • Token-efficient structured APIs (diffsearchfile-read; the Koder IRIS

    "10× fewer tokens" principle); conform to stack-RFC-002-mcp-integration.

6. Git plumbing strategy

Embed, don't rewrite (RFC-006 §5.2 mechanism table). v1: shell-out to system git for smart-http/ssh + pack ops behind a thin server (proven; how Gitea does much of it), with go-git watch-listed for pure-Go paths. The durable tier is kdb refs (transactional CAS) + kdb-obj (objects/packs) — refs→kdb and objects→kdb move from Flow's shadow to KVS's primary (§11). A Koda-native git engine stays a north star (mechanism E), explicitly out of v1 scope.

7. Stack integration (reuse-first, D10)

Concern Reused Stack component
Auth / identity / agent tokens Koder ID (OAuth/OIDC + SVID)
Relational/tree data + refs kdb-next
Object/pack bytes (CAS) kdb-obj (RFC-006 §3)
Serving / TLS / vhost Koder Jet (policies/web-server.kmd)
UI tokens / theme KDS / Verge
Multi-tenancy specs/multi-tenancy/contract.kmd
Observability 3-signal (policies/observability-first.kmd)
MCP conventions stack-RFC-002-mcp-integration
Concurrent merge engine the existing kvs client engine

8. Phased plan + walking skeleton

Milestone 0 — walking skeleton (prove the bet cheaply). Acceptance: recursive namespace tree on kdb-next + Koder-ID auth + a repo you can git clone/push (objects on kdb-obj, refs on kdb) + N-agent concurrent push to the same branch all land via server-side merge (0 rejections) + a minimal MCP endpoint (read repo / read file / open branch) + minimal KDS UI. No issues/PR UI/CI yet — prove data model + git round-trip + concurrency + MCP + Stack integration end-to-end.

Then, feature-by-feature (each importing parity from Flow): browse/diff, PRs (with conflict-as-data), issues, code search, webhooks/Actions, packages, mirroring. Sequence detail lives in subsequent tickets, not this RFC.

9. Migration — Koder Flow → KVS

  • Importer Flow → KVS is a first-class requirement (Flow already has the

    inverse gitea_migrations driver as a reference).

  • Coexistence, no big-bang: KVS mirrors/imports from Flow until parity;

    cutover per repo/namespace when ready. KVS's host role supersedes Flow's RFC-006 §5 host role at cutover; Flow is decommissioned after.

  • Per policies/self-hosted-first.kmd, KVS-host vs Flow is a Koder-replaces-Koder

    succession — promotion gated on functional + regression parity.

10. Naming & registry

KVS = Koder Version System is the umbrella product spanning client (the existing concurrent working-copy CLIengine) and server (this forgehost). "Concurrent" is the differentiator, not a separate name. The forge lives inside products/dev/kvs/ as an RFC-006 sector (backend/ + app/web, alongside the existing cli), not a new top-level module. component-names.md row updates to expand the acronym + note client+server scope, via the audit-naming gate.

11. Dependencies & sequencing (foundational critical path)

kdb-obj substrate (infra/data/oss OSS-008-011, building)     ──┐
                                                               ├─► objects shadow→PRIMARY  ──► KVS host stores repos 100% on kdb
refs→kdb (FLOW-148, exists shadow) ──► refs shadow→PRIMARY  ──┘
  • kdb-obj substrate is the foundational dependency and is *lready an active,

    independent build in infra/data/oss (OSS-007 done; 008-011 pending) — its contract is layer-independent (content-addressed bytes; mergenamespaceprovenance live above it), so it serves Flow + Hub depot + model-weights regardless. No ticketization needed (they exist). KVS's stake: OSS-010*(the git-objects + Hub-depot consumer wiring) is the piece KVS-host consumes — track + co-design it so the consumer contract fits KVS-as-primary, not only Flow's shadow.

  • Flow left objects at stub and refs at shadow; *VS forces both to

    primary*— that is the gate from "forge stores on filesystem" to "forge stores on kdb".

12. Open questions

  • OQ-1 — RESOLVED 2026-06-10specs/kvs/namespace-tree.kmd:

    recursive node model, nearest-ancestor-wins + explicit-deny resolution, monotonic visibility clamp, cheap re-parent moves, root=tenant boundary, agents as first-class subjects (R1-R7 + R-AI + T1-T7).

  • OQ-2 — RESOLVED 2026-06-10specs/kvs/concurrent-merge.kmd:

    objects-never-conflict + lock-free auto-merging ref advance, Driver-selected three-way (AST-aware), conflict-as-committable-object (never reject/overwrite), exactly-one-winner optimistic-bounded-retry on the FLOW-148 CAS, provenance per merge (R1-R7 + T1-T6).

  • OQ-3 — namespace-aware object placement on kdb-obj (does the flexible tree

    drive trust-tiering/placement policy? RFC-006's ObjectEngine placement vocabulary is the extension point).

  • OQ-4 — ActionsCI: keep `.giteaworkflows` compat for migration, or a

    Koder-native concurrent CI surface? (out of v1 skeleton scope.)

13. Decision log

  • 2026-06-10 — owner: KVS name unified (client + server), greenfield host embedding

    git, concurrency + AI-first as first-class pillars. /k-arch deliberation (this session) ratified RFC-first with the kdb-obj substrate parallelizable. This RFC is the durable form of that deliberation.

  • 2026-06-10 — owner RATIFIED this RFC (status: draft → ratified). KVS-host

    program is GO. Per §8/§12 the next step is the OQ-1 (namespace permission model) + OQ-2 (mergeable-ref conflict-object contract) spec sections, then the walking skeleton. kdb-obj substrate (infra/data/oss OSS-008-011) building in parallel; KVS's stake = OSS-010's consumer contract.