Table of contents
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Operational postmortem — Buzz retirement and forge migration
- Date: 2026-08-04
- Type: operational postmortem; service disruption and migration recovery
- Scope: Buzz retirement, fenrisulfr → bifrost forge cutover, agent identity minting, agent wiki/issue access gaps
- Relation to other postmortems: the architecture postmortem covers the flake composition failure (2026-07-29). This one covers the operational failures of the following week.
Summary
The fleet moved its execution tracker from Buzz (self-hosted Nostr, tried
2026-08-01 to 2026-08-03) back to Forgejo + Matrix, and moved the forge itself
from fenrisulfr (jo.fen.et0.pw) to bifrost (jo.et0.pw) on 2026-08-03. The
move was necessary — Buzz was ratified out as too early — but it surfaced three
operational gaps that cost significant operator time and blocked the caretaker
agent from resuming ownership of the repository.
No production outage or secret exposure resulted. The cost was operator time and agent effectiveness.
Timeline
- 2026-08-01 to 2026-08-03 — Buzz trial. Buzz (self-hosted Nostr relay with
NIP-34 issues-as-tickets) was trialed as a replacement for Matrix + Forgejo.
The trial was ratified out: Buzz was too early, the relay was fragile, and
the
buzzCLI was removed from repo tooling. The decision to return to Forgejo + Matrix was correct and is not in question here. - 2026-08-03 — Forge cutover. The forge moved from fenrisulfr
(
jo.fen.et0.pw) to bifrost (jo.et0.pw), hosted alongside the Matrix node. The instance was stood up fresh, so repository IDs restarted: this repo is id 1, not the 3 it was on fenrisulfr. - 2026-08-03 — Agent identity minting. Per-identity persona accounts were
minted on the new forge instance (
just forgejo mint <persona>). Theagent.odinpersona (id 4,[email protected]) was created at 03:24. - 2026-08-04 — Wiki migration.
agent.omomigrated 20 planning documents to theflaky-mesh.wikirepo, classified them inHome.md, reconciled executable work into issues #1–#6, and verified the transfer byte-identical. - 2026-08-04 — Agent access gaps surface. The
agent.odinpersona, despite carrying validFORGEJO_URLandFORGEJO_ACCESS_TOKENcredentials in its rendered environment, could not reach the forge through its tool surface for approximately one hour of operator-assisted debugging.
What went wrong
1. The forgejo-mcp registration had two surfaces, not one
Root cause: The forgejo-mcp server has to be registered independently in
two places: the NixOS module (modules/implementations/hermes.nix, the
mcpServers block for the Hermes harness) and the per-user config
(~/.config/opencode/opencode.json, for the opencode TUI). The agent initially
assumed a single declaration surface and spent time investigating the NixOS
module when the actual gap was in the per-user opencode config.
Contributing factor: The NixOS module's mcpServers.forgejo block contained
a placeholder URL (https://your-forgejo-instance.org) rather than the real
jo.et0.pw, which looked like the bug and delayed diagnosis.
Lesson: When a tool has multiple registration surfaces (harness-level declarative + per-user config), each surface must be verified independently. A correct declaration in one surface does not propagate to the other. Document both surfaces in AGENTS.md so the next agent does not assume a single path.
2. The token transport was not verified end-to-end
Root cause: The forgejo-mcp server requires its authentication token as a
CLI flag (--token), not as an environment variable. The opencode config
registered the command with --url but not --token, and the MCP child process
inherited a sanitized environment that did not forward FORGEJO_ACCESS_TOKEN.
The persona env file at /run/secrets/rendered/profile.odin.env was correctly
rendered (the credentials were present in the agent's shell environment), but
the MCP child process did not inherit them, and the MCP server did not read
from environment variables even if it had.
Lesson: Token transport must be verified by a live tool call, not by the
presence of credentials in the parent shell. An env var in $ENV is not proof
that a child MCP process can see it. Always run forgejo-mcp --help to discover
the actual auth surface before assuming env-var passthrough.
3. The wiki repo was not provisioned with agent write access
Root cause: The flaky-mesh.wiki repo was created by agent.omo during
the migration. agent.odin had read access (the repo is public) but not push
access, because no per-agent write grant was issued on the wiki repo. The agent
discovered this only after attempting to push a test branch, despite having
previously confirmed read access via clone.
Lesson: Read access and write access are separate grants. A successful clone is not evidence of push access. When a new repo is created on the forge, the creating agent's identity gets write access by default; other agent identities must be granted explicitly.
What worked
- The persona system itself:
FORGEJO_URLandFORGEJO_ACCESS_TOKENwere correctly rendered to theodinpersona's environment through the sops-nix template at/run/secrets/rendered/profile.odin.env. The credential pipeline from secrets.yaml → sops → rendered env → agent shell is sound. - The forge cutover itself:
jo.et0.pw(bifrost) is live, the main repo (larandar/flaky-mesh, id 1) is accessible, and the token authenticates correctly against the API (HTTP 200 on authenticated read paths). agent.omoexecuted the wiki migration and issue reconciliation autonomously and correctly: 20 pages, 8 classified commits, issues #1–#6 with stable IDs and acceptance criteria, round-trip verified.- The Forgejo wiki-as-sibling-repo feature works as intended for durable postmortem and design-intent storage, searchable and version-controlled.
Impact
- Approximately one hour of operator time was spent debugging the
forgejo-mcpregistration and token transport, including a NixOS rebuild that was not strictly necessary (the real fix was in the opencode config). - The
agent.odinpersona was blocked from forge read/write for the duration, delaying the resumption of caretaker duties. - No production service was affected. The forge, Matrix, and all fleet hosts remained operational throughout.
Corrective actions
- Document both MCP registration surfaces in AGENTS.md. The Hermes NixOS module and the per-user opencode config are independent surfaces; both must carry the registration. Add a note under "Issue authority" or a new "Agent tooling" section.
- Fix the placeholder URL in
modules/implementations/hermes.nix. ThemcpServers.forgejoblock still points athttps://your-forgejo-instance.org. Replace with the realjo.et0.pwand wire the token through the persona env, not as a literal in the config. - Establish a write-access grant procedure for new repos. When a new repo is created on the forge (wiki or otherwise), all active agent personas should be granted write access explicitly, not assumed to inherit it.
- Add a one-shot verification step to the persona bootstrap. After sourcing a persona profile, the first forge interaction should be a read+write probe (create a test branch, push, delete) to confirm end-to-end transport before real work begins.
Prevention rules
- A credential in the parent shell is not proof of child-process access. Verify token transport with a live tool call.
- Read access is not write access. A successful clone does not prove push rights.
- When a tool has multiple registration surfaces, each must be verified independently. A correct declaration in one does not propagate to the others.
- The
forgejo-mcpserver reads its token from a CLI flag (--token), not an environment variable. Do not assume env-var passthrough for MCP child processes without checking--helpfirst. - Do not diagnose a config gap by reading the NixOS module alone. The per-user
config (
~/.config/opencode/opencode.json) is an independent surface.
Source disposition
plans/brief.md: ratified fleet requirements (2026-07-28).plans/architecture-postmortem.md: flake composition postmortem (2026-07-29).AGENTS.md(repository): issue authority and tooling rules.- Issue #8 (closed): VCS operational data migration ledger.
- Issues #1–#6 (open): reconciled executable work.
- Live session evidence:
agent.odinforge interactions on 2026-08-04.