#168: revise the front matter, Approaches, and the OpenCode port
- Home and _Sidebar: renamed the product to fleet / fleetd. Dropped the claim
that AgentAPI is a "swappable fallback injector" — it was never built, and no
AgentAPI code exists under fleetd/src/main/java.
- Home also lost two claims that chapters 1 and 2 removed today: there is no SSE
route, and the page no longer names a gateway host as if it were fixed. The
allowed hosts are a config value and differ per deployment.
- Home no longer carries a release number, a ticket count or a test total. Those
go stale in days and then read as current facts; 8-Roadmap holds the record.
- 3-Approaches keeps AgentAPI as discarded research, which is that page's job,
but never in the present tense. Evidence: a search for agentapi under
fleetd/src/main/java finds nothing, and both Profile.kind values run through
HerdrPeerLauncher.
- 12-Claude-to-OpenCode: the sample mount name was `fleetd`, which teaches a
second product name. Every launcher writes the same constant,
PeerLauncher.MCP_MOUNT_NAME = "fleet". A hand-written config using another key
mounts under a name the role-detection ladder never checks.
Match the code cutover: daemon name, config (fleetd.yaml), scripts, launchd/
systemd units, module dir, and MCP tool prefix bridge_* -> fleet_*. Kept:
the BRIDGED_MEMBER security marker, mcp__bridge__ (historical mount name), and
the .bridged-worktrees on-disk path. The portable CLAUDE.md block stays
byte-identical with the repo's CLAUDE.md.
12: how secrets actually reach opencode — and the trap in `{env:…}`
`opencode.json` is committable because it holds no secret, only substitutions.
What was missing is where the values come from, and the answer differs by who
launched opencode — which is exactly the part that fails silently.
`{env:…}` reads opencode's process environment, and opencode has no env store of
its own. This project's secrets are supplied by Claude Code's settings cascade —
files opencode never reads — so `{env:…}` works inside a Claude-Code-spawned
process and fails in a real terminal. Verified both ways: a clean login shell has
none of the three variables, and `opencode mcp list` is green in one and
`needs authentication` in the other.
The launch paths also disagree on names: a bridge-spawned worker receives
GITEA_TOKEN + GITEA_HOST from applyGitToken, not GITEA_ACCESS_TOKEN. So a config
written against the terminal's environment breaks inside a worker and vice versa.
Documented as a table keyed on launcher: `{file:}` for a human, `{env:}` for a
worker, with `.secrets/` gitignored and therefore absent from a worktree — the
same tracked-files-only rule that makes opencode.json worth committing.
Adds the `.autoenv` route that keeps Claude Code on that one store: it exports
`.secrets/` into the environment so `.mcp.json`'s `${VAR}` resolves without
duplicating tokens as literals in settings.local.json. Two verified caveats
recorded — an unset `${VAR}` degrades to the literal text rather than failing,
and leaving the directory does not unload.
Finally, the verification step now distrusts `opencode mcp list`: connected is
not working. A stdio server missing its credential completes the handshake and
reports green — verified with gitea, which showed connected and then failed the
first call with `token is required`. Exercise one authenticated tool per server.
OpenCode reads CLAUDE.md natively (and ~/.claude/CLAUDE.md globally), so
the translate-then-hand-fix cycle that made the Codex port fragile does
not exist. The chapter is now one JSON mapping plus the rules for what
must not cross.
Keeps four verified Codex findings in an appendix — no CLAUDE.md
fallback, no config interpolation, a scrubbed MCP child environment, and
trust-gated project config — because they are what the comparison rests
on and were established by hand.