Files
Sylpheed/docs/agents/WORKFLOW-gitea.md
MechaCat02 1f138b3db4
Some checks failed
CI / Native — ubuntu-latest (push) Failing after 7m52s
CI / WASM — Web (push) Failing after 6m57s
CI / Formatting (push) Failing after 54s
CI / Native — macos-latest (push) Has been cancelled
CI / Native — windows-latest (push) Has been cancelled
agents: move the working surface to Gitea -- issues, PRs, and where files live
The human wants to direct this project from a web UI rather than chat or Remote
Control, so Gitea becomes the working surface. No new store: adding a second
copy of the truth is this project's defining failure mode, and Gitea already
holds the code. Its first-party MCP server (gitea/gitea-mcp v1.7.0, checked) has
issues, labels, milestones, PRs, attachments and notifications.

ISSUES replace BLOCKED.md. Milestones are bundles the human defines; issues are
items agents propose and the human approves. The state labels end in
`needs-human`, which is the state the whole model turns on and the one no
off-the-shelf tool models -- the market has converged on removing the human.
`blocked` uses Gitea's DEPENDENCY EDGES rather than prose, so "the Port is
blocked on the Decoder answering X" becomes queryable and closes itself.

PULL REQUESTS, the human's proposal, adopted -- and a bigger improvement than it
looks. Today's long-lived auto/* branches have drifted 280 and 373 commits apart,
which is unreviewable by construction. One PR per item makes the human gate
NATIVE rather than a label convention, binds the change to its item, and enforces
the sizing rule: an item too big to review in one sitting was too big to be an
item.

🔴 Agents must not merge their own PRs, and pull_request_write includes merge --
so this goes in BRANCH PROTECTION on main, not in a document asking them not to.
Same principle that fixed the build-jobs cap: policy where the agent cannot reach
it.

WIKI -- the human suggested it for RE findings, and that half is declined with
reasons. A finding's value is that it sits beside its evidence, versioned with
the code that consumes it; the wiki is a separate git repo, so a decode
correction and the exporter change depending on it could never be one reviewable
PR. And wiki edits bypass review: the REFUTED.md reclassification changed the
file both agents read to decide what not to try, and as a wiki edit it would have
been an unreviewed mutation of shared ground truth. The wiki takes human-facing
orientation instead -- runbook, navigation, container notes, and a landing page,
which closes the real gap that there is no view of what is happening except
container logs.

FILES: three needs, three homes. Agent-to-agent transient stays in /exchange.
Evidence a HUMAN must look at attaches to the issue it belongs to -- it travels
with the item and cannot be orphaned from the claim. Evidence a finding cites
stays in git. Note the MCP exposes attachment_read only; upload needs a direct
REST call.

tools/gitea-setup creates the labels and bundles, idempotently, with --dry-run.
Blocked on a token with write:issue -- the push credential is write:repository
and every issue endpoint refuses it, checked rather than assumed.
2026-09-04 15:46:57 +02:00

6.6 KiB

The working surface: Gitea issues, pull requests, and where things live

Set by the human, 2026-09-04. Replaces chat and Remote Control as the way a person directs this project, and replaces BLOCKED.md as the way agents track what is open.

Why not a new tool

We looked. The market has converged on removing the human from the loopagent-kanban's own tagline is "Take human out of the loop" — and this project is built entirely around a human gate. Meanwhile every candidate adds a second store of truth to keep in sync with git, and documents drifting out of sync is this project's defining failure mode: a 1,227-line BLOCKED.md whose anti-staleness convention was constant by construction, 41 % of citations not resolving, 21 inter-agent messages sent into a void with no delivery feedback.

Gitea is already deployed, already holds the code, and its first-party MCP server (gitea/gitea-mcp v1.7.0) exposes issues, labels, milestones, pull requests, attachments and notifications. So: no new store.

The four surfaces, and what belongs in each

surface holds why not somewhere else
Issues work items, asks between agents, defects durable, stateful, owned, and dependency edges close themselves when the blocking issue closes — the thing prose could never do
Pull requests every change to main the human gate becomes native instead of a label convention
Git (docs/) RE findings, decisions, evidence a finding must be versioned with the code that consumes it
Wiki orientation for a person: runbook, navigation, container notes browsable and branch-independent, but unreviewed — see below

Issues = bundles and items

Milestones are bundles (the human defines them). Issues are items (agents propose, the human approves). Labels carry the state:

state/proposed → state/approved → state/in-progress → state/needs-human → closed
                                            ↘ state/blocked

state/needs-human is the one the whole model turns on, and the one no off-the-shelf tool models. Its issue body must say what to look at and what pass and fail look like — a person should be able to judge it in under a minute without reading anything else.

⚠️ state/blocked uses Gitea's dependency edges, not prose. "The Port is blocked on the Decoder answering X" becomes a queryable link that resolves itself. That is the single highest-value change here after PRs.

Pull requests = how work reaches main

Adopted 2026-09-04, the human's proposal, and it is a bigger improvement than it looks. Today agents commit to long-lived auto/* branches that a human merges by hand — and those branches have drifted 280 and 373 commits apart, which is unreviewable by construction.

One PR per item, closing its issue:

  • the review surface is a diff in a browser, not a human reading commits in a terminal;
  • Closes #123 binds the change to the item, so "what did this fix" stops being archaeology;
  • PRs enforce the sizing rule. An item too big to review in one sitting was too big to be an item. The discipline stops depending on an agent's judgement.

🔴 Agents must not merge their own pull requests. The MCP's pull_request_write includes merge, so this cannot be left to instruction — it goes in branch protection on main, requiring review. Same principle that fixed the build-jobs cap: policy belongs where the agent cannot reach it, not in a document asking it not to.

🔴 The wiki is NOT for the RE corpus

The human suggested it for RE findings. Half right, and the wrong half is worth saying plainly, because it would undo two things we paid for:

  1. A finding's value is that it sits next to its evidence, versioned with the code that consumes it. "Decoded, with a disc-wide check" is backed by a test in this repository. A wiki is a separate git repo, so a decode correction and the exporter change that depends on it could never be one atomic commit, or one reviewable PR.
  2. Wiki edits bypass review. The REFUTED.md R1 reclassification changed the file both agents read to decide what not to try. It was a reviewed commit with a stated rationale. As a wiki edit it would have been an unreviewed mutation of shared ground truth by whoever typed last.

So the corpus stays in docs/, reached through PRs.

What the wiki IS good for — human-facing orientation that is not evidence and should not be branch-dependent:

  • the runbook (docs/port/RUNNING.md's content — how to actually play the port)
  • docs/game/navigation.md — how the game is navigated, written for a person
  • container notes, credentials setup, the things a human reads once
  • a landing page: current bundles, what each agent is on, links into git

That last one addresses a real gap: there is no view of what is happening except container logs and multi-megabyte transcripts.

Where files go — three needs, three homes

Currently everything transient goes to /exchange, and a human cannot browse it at all.

the file is goes to
agent → agent, transient, no human involved /exchange via share, unchanged — it records sender, time, commit and dirty-tree
evidence a human must look at (a screenshot, a film, a capture behind a state/needs-human item) attached to the issue it is evidence for
evidence a finding cites git, beside the finding. It is the proof

Attaching to the issue is strictly better than both alternatives for the middle case: it travels with the item, a person sees it in the browser, and it cannot be orphaned from the claim it supports.

⚠️ The MCP exposes attachment_read only — uploading needs a direct REST call (POST /repos/{owner}/{repo}/issues/{index}/assets). Worth a small helper rather than each agent re-deriving it.

Notifications = the wake-up, with delivery you can inspect

notification_read / notification_write replace the message channel that lost 21 consecutive messages to a stale session ID with no error of any kind. An @mention on an issue is durable, addressed by name, and has a read state a supervisor can inspect. The old rule still stands and gets easier: the message carries a pointer — now an issue number — and the repository holds what was found.

What does not change

  • Findings are still classified decoded / measured / undecodable.
  • An agent still cannot verify its way out of its own role.
  • REFUTED.md is still the file to grep before proposing anything, and entries still name their ⟨instrument⟩.
  • The oracle is still the real game in Xenia Canary.