Skip to content

Weft: the plaza's own version control in place of Forgejo, the review graph, and GitHub, GitLab and Forgejo connections - #60

Merged
Zarathos94 merged 25 commits into
mainfrom
feat/weft
Oct 19, 2026
Merged

Zarathos94 merged 25 commits into
mainfrom
feat/weft

Conversation

@Zarathos94

Copy link
Copy Markdown
Contributor

Weft replaces Forgejo as the plaza's version control. It is part of the hub (one binary, its own storage, no Postgres): agents work in lanes, every turn is a signed draft, a change lands through the review graph, and git is only an export. Forgejo, the git relays and the plaza-git tools are gone. The owner connects GitHub, GitLab or Forgejo repositories at the account, organisation or repository level and chooses what the plaza may use.

Weft (crates/weft)

  • The store: an append-only, hash-chained log of signed statements (Ed25519), file contents by BLAKE3 in zstd packs (large files as content-defined chunks), and state by replay. Who may sign what is enforced on replay: agents on their own lanes and never reviewing their own change; the hub for lanes, queues and landing; the owner for repos, rules and rulings.
  • Packs, diffs and change trees: tree-sitter grammars as WebAssembly (19 to start), loaded only when a file needs one. A change tree names the definitions a revision changes, what they touch, who wrote each line across drafts, renames by lineage, and divergence from other open lanes.
  • weft serve: loopback only, behind the internal token. It serves repos, changes, revisions, diffs, blame, symbol history, queries, the op log, packs and events, applies path rules on reads and STOP ALL on writes, and moves objects by hash only. A node's weft serve --cache answers its VMs from disk.
  • Landing: one queue per ref. Changes merge by lines and, where lines clash, by definition. Stacked lanes, reverts, re-checks of the merged candidate, and weft bisect.
  • Git, one way: Weft reads and writes git itself (objects, packs, smart HTTP). After a landing, the export writes one commit per intent, authored by the owner as the platform knows them, with no AI credits, signed with the hub's SSH key, fast-forward only. Import reads a repository's first-parent history once and checks every tree against git's. This repository's 1,129 commits import with every tree matching.
  • Releases: notes from the intents landed since the last release, artifacts with SLSA provenance, the owner's signature, a signed tag and a GitHub Release.

The hub

  • apid starts weft serve beside it and is its only door: the owner's /v1/weft, the agents' gateway (each agent's statements signed with its own key from the vault), and node caches.
  • A claimed task opens its lane; the harness checks it out and snapshots every turn with its tool calls. The worker's done seals the lane. A task is done, and its worker paid, when its change lands. A clash or a failed re-check sends it back to its worker.
  • The review graph: versioned recipes (code, docs and research to start); steps as work items for agents of the step's role, never the worker; checks with measured scores; findings anchored to definitions and carried into the next round; a new rework state with two rounds before the owner decides; and the owner's review card (Pass, Send back, Fail). Every verdict is a review record in Weft, signed by its reviewer.
  • After a landing, the recipe's post-land suite runs on main. A failure lands a signed revert at once and opens a fix task.
  • The owner's direct edits land at once as their own changes.
  • The cut-over: git.rs, the agents' git relay, the owner's smart-HTTP relay, /v1/git and the plaza_git tool are removed, as are setup's Forgejo container and checks. The IDE, plan documents and the editor mirror read Weft. An editor session linked to a repository works in a lane of its own.

Git platforms

  • GitHub: the plaza's own GitHub App, created from a manifest in one click and installed on an account or an organisation, where GitHub's own picker chooses the repositories. Installing signs the owner in, so exports are authored by them.
  • GitLab and Forgejo (Codeberg, Gitea): an OAuth app the owner registers, signed in with PKCE and renewed automatically.
  • Any of them: a pasted token for the account, one organisation or group, or one repository.
  • Choose what the plaza may use: every repository of a namespace, or the ones named. Connecting a granted repository to a project imports its history once (if the project has none) and can register the hub's signing key on the owner's account.
  • Secrets live in the vault, which now takes the hub's own consumers as hub:<id> bindings. Weft's keys used a binding the vault refused, so they had quietly fallen back to files; they now go into the vault, and the existing files are still read.
  • The browser comes back to a public callback that acts only on a state an owner's call made, once, within 15 minutes.

Consoles

  • Web: History in place of Git (landings, lanes, a change's sign-off chain, releases, the map, files with blame), the review graph on a task, the owner's review card, Recipes, and Git platforms.
  • Desktop: History, the review card in Approvals, Setup's Weft row, and Git platforms.
  • CLI: agentplaza weft, tasks review, tasks rule, recipes, and platforms.
  • OpenAPI, Bruno, the architecture doc, README and a Git platforms guide are updated.

macOS

The whole workspace builds, tests and lints on macOS. agent-harness imported Linux-only modules without a gate, so it did not compile there, on main as well. The vmm's hvf code had a clippy finding.

Verification

  • cargo test --workspace (133 suites), cargo clippy --workspace --all-targets -- -D warnings and npm --prefix apps/web run check pass on macOS. The agent harness's Linux tests pass in Docker as a non-root user (266).
  • End to end on a scratch hub: a code task went through rework and the owner's ruling to landing, then a git export of one commit per intent. A research brief was sent back on a measured accuracy finding, then landed.
  • Git platforms, end to end against stand-ins for GitHub, GitLab and Forgejo and real local git repositories: the app is created and installed on an organisation, a repository is connected with its history imported, and the next edit is exported as the owner. A GitLab sign-in can connect only the repository it granted, and a Forgejo repository token reaches only its repository. Expired or unknown states are refused. The web screen was also clicked through on a demo hub.
  • Not covered: real github.com, GitLab or Codeberg accounts. The GitHub App's permission names are confirmed only when the app is created for real. The desktop's new screens were not checked by eye; their tests and clippy pass.

For review

  • Weft is the only history. There is no Forgejo data to migrate.
  • Exports are one-way. A platform's own commits come back only when the owner adopts them, as a lane that goes through review.

🤖 Generated with Claude Code

Zarathos94 and others added 15 commits October 18, 2026 19:47
… by replay)

crates/weft: the history Weft keeps, on its own storage (no Postgres).

- log: append-only segments of hash-chained records, fsynced per record; a torn tail is cut on open, damage
  anywhere else is refused.
- blobs: file contents by BLAKE3, zstd, in append-only packs; files over 4 MB as content-defined chunks.
- record: statements signed by whoever acted (Ed25519); the log adds the sequence and the chain.
- state: replays the log; enforces who may sign what (agents on their own lanes, never reviewing their own
  change; the hub for lanes, queues and landing; the owner for repos, rules and rulings; the hub's
  rule-for-owner capability marks console rulings).
- store: verify, check, write, apply; trees from deltas; verify --deep replays everything.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Language and format packs (tree-sitter grammars as WebAssembly, 19 to start)
load only when a file needs one and unload when idle. Change trees name the
definitions a revision changes, what they touch, who wrote each line across
drafts, renames by lineage, intents, and divergence from other open lanes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
weft serve answers on loopback behind the internal token: signed statements in,
repos, changes, revisions, change trees, diffs, blame, symbol history, queries,
the op log, packs, keys, verification and events out, with path rules on reads
and STOP ALL on writes. Objects move by hash only (missing, bundles, ranges,
chunked uploads), so a node's weft serve --cache answers its VMs from disk. The
CLI checks lanes out, snapshots each turn (offline into an outbox), names
intents, seals, and reads history.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each ref has a queue; a step merges its head onto the ref: as it is when it
starts from the head, else by lines and, where lines clash, by definition
through the file's pack. A rebased candidate can wait for its re-check while the
next item is merged on top of it; a stalled head lets a commuting change pass.
A clash moves the lane onto the head with the files marked for its agent.
Stacked lanes follow the change below them, reverts merge their undo onto the
head, and weft bisect finds the first bad landing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Weft writes and reads git itself: objects, trees, commits, tags, loose and
packed storage with deltas, pack files, and smart HTTP or local remotes.

- Export: after a landing, one commit per intent on top of what the connection
  received last, authored and committed by the owner as the platform knows
  them, the message the intent's title and summary, no AI credits; signed with
  the hub's SSH key (SSHSIG, verified by git); fast-forward only; paths the
  rules keep out stay out. A remote that moved on its own stops the export;
  adopting its commits makes a lane, and the export joins the remote's head
  with a merge commit once it lands.
- Import: a repository's first-parent history, once, each commit's tree checked
  against git's; tags become imported releases; AI co-author trailers are kept
  as provenance. This repository's 1,129 first-parent commits import with
  every tree matching.
- Connections read the owner's account from GitHub (name and verified email,
  or the noreply address) and can register the hub's signing key.
- Releases: notes from the intents landed since the last release, targets from
  the build files, artifacts with SLSA provenance, the owner's signature, a
  signed tag and a GitHub Release with SHA256SUMS and provenance files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
apid starts weft serve beside it (the binary next to apid's, in-process when
there is none), hands it the hub's keys from the vault over stdin, and is its
only door: the owner's /v1/weft, agents' gateway (each agent's statements are
signed with its own key from the vault, inside its own call), and node caches.

- A claimed task opens its lane (stacked on the lane of the task it runs
  after); the work item carries it, the harness checks it out and snapshots
  every turn with that turn's tool calls; the worker's done seals it and signs
  written. STOP ALL holds Weft's writes. Weft's events reach the bus, a landing
  is exported to the repo's connections, a clash gives the lane's agent a
  resolve item. weft_* tools replace reading git; laws T-020 to T-023.
- The review graph: versioned recipes (code, docs, research to start), first
  rules, steps as work items for agents of the step's role (never the worker),
  checks with measured scores, sub-reviews within limits, scores and findings
  anchored to definitions and carried into the next round, the gate's rules, a
  new rework state with two rounds before the owner decides, and the owner's
  review card with Pass, Send back and Fail. Every step's verdict is a review
  record in Weft signed with that reviewer's key; tools and the gate by the
  hub; the owner's ruling for the owner from the console.

End to end on a scratch hub: a code task goes through rework and the owner's
ruling to landing and a git export of one commit per intent; a research brief
is sent back on a measured accuracy finding, then lands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ft CLI

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wner edits

- The gate's pass queues the change; the task is done, and the worker paid,
  when the change lands. A clash on landing or a failed re-check sends the
  task back to its worker, whose resolution is the next round.
- A merged landing candidate waits for the recipe's checks, run on the
  candidate's tree (weft checkout --candidate) as a re-check step.
- After a landing, the recipe's post-land suite runs on main; a failure lands
  a signed revert at once and opens a fix task for the author's role.
- The owner's direct edits land at once as changes of their own (POST
  repos/{repo}/edits), signed for the owner; the owner's CLI without the owner
  key signs through the console.
- Every store starts with Markdown; the other packs Weft knows install with
  one call (packs/available, packs/missing, packs/install).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
apz-link, which already carries a node's VM gateway calls to the hub, keeps
the node's Weft objects: a VM's object or bundle read is answered from the
node's cache, and a miss is fetched once from the hub's node door, signed by
the node, for the asking agent. The same cache code as weft serve --cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- agentplaza weft passes its words to Weft's command line on the CLI's own
  connection to the hub (its URL, owner token and pin), signing with the
  owner's key when this machine has it, else through the console.
- agentplaza tasks review <id> prints a task's review runs: the verdict, the
  readings, the steps and the findings; tasks rule <id> pass|rework|fail rules
  on the owner's review card. Tasks sent back read as such.
- agentplaza recipes list, show, put, proposals, approve, decline.
- Bruno: the weft folder.
- apid keeps the owner's key where the CLI looks for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…or read Weft

- The IDE's repo workspaces are a project's repo in Weft, on main: folders and
  files from main's head, a write is the owner's edit that lands at once (a
  stale hash is still a conflict), changes are a diff against the landing
  before (or a named revision or change), checkpoints are what landed.
  Branches and pull requests are gone with the git host (410).
- Plan documents are read from the project's repo in Weft.
- A new project's repo is created in Weft.
- agentplaza acp --repo mirrors the editor's committed HEAD into an editor
  lane (editor/<branch>, the owner's, never landed) instead of pushing to the
  git host; the hub reads that lane's latest draft for the agents.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eview card, Recipes

Web:
- History replaces the Git screen: repos with their connection state; a
  repo's changes as a line of landings with open lanes beside it, a query box
  and presets; a change's sign-off chain (written, checked, reviews, gate,
  ruling, landed) with an Expert view of its revisions, records, tree and
  diff; releases with notes, artifacts, Sign and Export; the map with
  Where is…; files on main with blame.
- The review graph on a task: a verdict strip, then an animated radial graph
  (the four readings around the task, intents that open into their
  definitions and what those touch) and the review's flow; Expert shows every
  step, the score board and the findings.
- The owner's review card: the verdict, what needs the owner, the four
  readings, and Pass, Send back and Fail.
- Recipes: the recipes and their graphs, a new version from TOML, the
  orchestrator's proposals. Weft and review events reach the live layer.

Desktop: History in place of Git, the review card in Approvals, Setup's
Weft row; the Git screen is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The hub has no git host any more: git.rs, the agents' git relay, the
  owner's smart-HTTP relay, /v1/git and the plaza_git tool are removed (and
  from the laws, the robots' behaviour map and the agent wizards, where the
  Weft tools take its place). OpenAPI is blessed again.
- Link chips: the plaza-git kinds are gone from apz-rich and its ports (web,
  desktop, CLI) and from the unfurl, which reads GitHub only. "PR #N" is plain
  text.
- An editor session linked to a repository (agentplaza acp --repo) works in a
  lane of its own in Weft, acp/<session>, stacked on the editor's mirror and
  checked out in the agent's VM; the files it changed come back to the editor
  as diffs with a link to the change in History, and write-back applies them.
- The web console's Git pages, the IDE's "Open PR" and the project page's
  branch lookup are gone (repos open on main); the desktop's too. The IDE's
  diff of a repo takes its default base (the landing before main's head).
- History: an imported change shows its git author and commit instead of an
  empty sign-off; a proposed release says it waits for the owner's signature
  (an imported one does not), in the web and the desktop.
- Setup no longer has a Forgejo container, check or fix; the hub checks in
  the web, the desktop and the CLI show Weft instead of the git host.
- Docs: README, architecture, the editors guide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- agent-harness: bash.rs is Linux-only like the modules it uses (files,
  trust), so the crate builds on macOS (its main is a stub there); the
  command-line parser stays built everywhere so its tests run on any host.
- agent-harness: statvfs's field widths differ by target; the casts say so
  instead of tripping clippy on 64-bit ARM Linux.
- vmm (hvf): is_multiple_of for the page alignment check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sation or repository level

The owner lets the plaza in on a git platform, chooses what it may use there,
and connects repositories to projects; their Weft repos then export to them.

- Authorize three ways. GitHub: the plaza's own GitHub App, created from a
  manifest in one click and installed on the owner's account or an
  organisation, where GitHub's own picker chooses every repository or some;
  installing signs the owner in, so exports are by them (W19). GitLab and
  Forgejo (Codeberg, Gitea): an OAuth app the owner registers, signed in with
  PKCE and renewed when it expires. Any of them: a pasted token, for the
  account, one organisation or group, or one repository.
- Choose what the plaza may use: per namespace, every repository or the ones
  named. An installation starts with what GitHub was given; a sign-in or a
  user token with nothing.
- Connect a granted repository to a project: the connection with the owner as
  author, its history imported once when the project's repo has none, and the
  hub's signing key registered on the owner's account on request. Disconnect
  and remove undo it.
- Secrets (client secrets, the app's key, tokens) are vault entries; the
  record holds none. Weft gets a fresh token when it pushes or fetches (an
  installation's minted with the app's JWT, RS256), with the user name each
  platform wants; the owner's release exports and adopts get theirs too.
- The browser comes back to a public callback that acts only on a state an
  owner's call made, once, within 15 minutes.
- Consoles: a Git platforms screen in the web console and the desktop app
  (authorizations first, then adding one), and `agentplaza platforms` in the
  CLI, which opens the platform's page and waits for it.
- The vault takes the hub's own consumers as `hub:<id>` bindings. Weft's keys
  used the binding `weft`, which the vault refused, so they had fallen back to
  files; they now go into the vault (existing files are still read).
- Tested end to end against stand-ins for the three platforms and real git
  repositories; OpenAPI, Bruno, the architecture and a guide updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Zarathos94 and others added 10 commits October 19, 2026 22:02
…builds with

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tware's pinned release)

tree-sitter's wasm runtime, under weft's language packs, builds wasmtime's C API with cmake. The runners
have none, so .github/ci/cmake.sh fetches the 3.31.6 release once into the runner's cache, checks its SHA-256
and puts it on PATH; macos.yml and windows.yml run it after the checkout (PRs, nightly and release).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… workspaces

The vault starts with Weft's hub key and export signing key, and the projects the run opens earlier list their
repositories as repo workspaces. The two Bruno tests that expected both lists empty now check exactly that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…when Weft loads a language pack

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ut has no symlinks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…alls it directly (LNK4217)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the tick cannot both start one round

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…// mirrors)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cremental cache

The runners keep the build directory, and an incremental optimised build can link stale codegen units
(undefined .llvm.<n> symbols on the Intel Mac). Failing tests (exit 100) are never retried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…en from an empty incremental cache

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Tests: passed

Where Result Passed Failed Time
Linux arm64 passed 669 0 10 s
Linux x86_64 passed 3623 0 43 s
macOS Intel passed 3088 0 55 s
macOS Apple Silicon: build only (cannot run here) passed
Windows arm64: build only (cannot run here) passed
Windows x64 passed 3128 0 101 s

Commit 7ba87c2 · the run

@github-actions

Copy link
Copy Markdown
Contributor

Lint: passed

Check Result
rustfmt passed
clippy (warnings fail) passed
cargo deny (advisories, licences, sources) passed
migrations (applied ones unchanged, new ones in order) passed

Commit 7ba87c2 · the run

@github-actions

Copy link
Copy Markdown
Contributor

Web console: passed

Check Result
type-check passed
build (with the wasm engine) passed
tests passed

Commit 7ba87c2 · the run

@github-actions

Copy link
Copy Markdown
Contributor

Hub API (Bruno): passed

215/215 API requests pass · 135/504 operations tested · 17 fuzzing findings (reported, they do not fail the pull request)

The report

Commit 7ba87c2 · the run

@Zarathos94
Zarathos94 added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit 9508b4f Oct 19, 2026
11 checks passed
@Zarathos94
Zarathos94 deleted the feat/weft branch October 19, 2026 21:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant