Files
fleetd/.claude/skills/implementer/SKILL.md
T
Dai Ha 2e138a199b CB-634: one shared "fleet" workspace + rename bridged -> fleetd cutover
Two changes ship together here.

1. One shared herdr workspace. The lead and every worker now live in one
   workspace called "fleet", so the operator sees one "session" with many
   windows, not two. Before, the lead sat in a "leads" workspace and workers
   in "bridged-workers", which read as two sessions. The lead is still told
   apart from workers by its exact tab label ("lead: <name>"), so putting them
   in one space is safe. LeadTabScanner keeps the exclude-by-label mechanism
   for split layouts; Fleetd now passes an empty exclude set.

2. Rename the daemon from "bridged" to "fleetd" (the binary, config, scripts,
   launchd/systemd units, module dir, and MCP mount).
   - Module dir bridged/ -> fleetd/; jar finalName -> fleetd.jar.
   - Log line, comments, docs, and CLAUDE.md updated to say fleetd.
   - Scripts renamed: redeploy-bridged.sh -> redeploy-fleetd.sh,
     bridged-launchd-wrapper.sh -> fleetd-launchd-wrapper.sh.
   - Deploy units renamed: dev.ltms.bridged.plist -> dev.ltms.fleetd.plist,
     bridged.service -> fleetd.service; launchd Label -> dev.ltms.fleetd.
   - Config default bridged.yaml -> fleetd.yaml; the legacy bridged.yaml is
     still read as a fallback, and still gitignored.
   - MCP: drop the deprecated bridge_* tool twins; only fleet_* remain. The
     server name is "fleet". The mount name in the local .mcp.json becomes
     "fleet" (gitignored, not in this commit).
   - Env var defaults BRIDGED_API_TOKEN -> FLEETD_API_TOKEN, fixture
     BRIDGED_WORKER_TOKEN -> FLEETD_WORKER_TOKEN.

Kept on purpose: the BRIDGED_MEMBER marker. Renaming it is a coupled change to
the credential-scrub security control (an operator secrets.sh may guard on it),
so it stays until that migration is done on its own.

Metrics were already fleet_* (CB-632); MetricNamesTest still guards that no
name says bridged_.

The canonical CLAUDE.md block and the wiki template stay byte-identical
(wiki working tree edited, committed to the wiki repo separately).

949 tests pass (mvn clean install). 4 fewer than before = the 4 removed
bridge_* alias tests.
2026-08-25 04:01:08 +02:00

5.7 KiB

name, description
name description
implementer Implementer-role procedure for a fleetd worker — verify your worktree, implement the scope, commit, push, open your own PR, and hand off the PR URL. Load this when the lead delegates you an implementation task over fleetd.

Implementer worker — procedure

The turn contract (one fleet_reply, fleet_ask for the lead's decisions, honest reporting, never merge, never commit .mcp.json or wiki/) is in CLAUDE.md → Bridge communication → Worker and already applies. This skill is only the implement-and-hand-off procedure.

You run in an isolated git worktree on your own branch — a full peer of the primary (same repo, CLAUDE.md, skills), differing in the model behind you and the branch you sit on. Your MCP surface is only what your launcher mounted (the bridge): the primary's IDE and forge servers are not yours, and the worktree's .mcp.json is deliberately emptied so you cannot inherit them. The worktree model is documented in docs/Worker-Git-Workflow.md.

1. Confirm where you are — then never leave

Before touching anything:

git rev-parse --show-toplevel   # your worktree root — NOT the primary's main tree
git branch --show-current       # your dedicated branch: worker/<ticket>-<nonce>
git status                      # should be clean at the start

Do all work here, on this branch. Never git checkout main, never rebase onto or push to main. The branch is your isolation — respect it.

Every path you read, edit, or build is relative to that root. Work from $PWD; if a tool, a brief, or your own memory hands you an absolute path, check it starts with your worktree root before you touch it, and stop if it doesn't. An absolute path pointing anywhere else is the primary's checkout — editing there while building here means every build you run is of code that does not contain your changes, and it passes while your work goes nowhere. This has happened: a worker made all 59 of its edits in the primary's tree and never noticed.

test "$(git rev-parse --show-toplevel)" = "$PWD" || cd "$(git rev-parse --show-toplevel)"

2. Implement

  • Implement exactly the scope the lead named. Keep the diff focused; note anything out of scope in your reply instead of widening it.
  • Match the surrounding code's style, naming, and idioms.

Acceptance criterion — a green build, quoted. Your work is not done until this passes inside your worktree:

cd "$(git rev-parse --show-toplevel)/fleetd" && mvn clean install
echo "exit=$?"

Read its full output — never pipe it through tail/head/grep, which hide a failure behind a zero exit. Then quote the real Tests run: … Failures: … Errors: … line and the BUILD SUCCESS/FAILURE verbatim in your reply. If it does not go green, say so with the actual error; a failing build honestly reported is a usable result, a claimed-green one is not. You have no IDE MCP tools, so mvn is your only verification — never claim a check you had no way to run.

3. Commit

git add <the files you changed>     # explicitly — never `git add -A` / `git add .`
git commit -m "<ticket>: <clear one-line summary>"

.mcp.json is neutralized and --skip-worktree in your worktree — never git add it, and never "restore" it from the primary's copy. Same for wiki/ (a submodule with its own remote).

4. Push

git push -u origin HEAD

Push is over SSH as the same user — no extra credential needed. Never force-push over anything you did not create.

5. Open your own PR to main

Via the gitea REST API. The daemon injected a repo-scoped token (GITEA_TOKEN) and the forge host (GITEA_HOST) into your env for exactly this — the token can create a PR but cannot merge.

API="${GITEA_HOST%/}/api/v1/repos/fleet/fleetd/pulls"
BRANCH="$(git branch --show-current)"
curl -sS -X POST "$API" \
  -H "Authorization: token ${GITEA_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "$(cat <<JSON
{"head": "${BRANCH}", "base": "main",
 "title": "<ticket>: <concise change summary>",
 "body": "<what changed and why; reference the ticket; note tests run and their result>"}
JSON
)"

The response JSON carries "html_url" — that is your PR URL. On a non-2xx, read the error body, fix it if the cause is yours (e.g. branch not pushed yet), and report the failure rather than inventing a URL. If GITEA_TOKEN is unset your profile was not granted PR-create: push the branch and report its name so the lead opens the PR.

6. Hand off — what goes in fleet_reply

The reply is the entire handoff; the lead cannot see your terminal.

PR:      <html_url from step 5, or "not created: <reason>" + branch name>
branch:  <your branch>
root:    <git rev-parse --show-toplevel — proves you worked in your own worktree>
files:   <worktree-relative paths you changed>
build:   <the verbatim "Tests run: …" and BUILD SUCCESS/FAILURE lines — or "not run: <why>">
summary: <2-3 lines: what you implemented and any caveat the reviewer needs>
sequenceDiagram
    autonumber
    participant L as Lead
    participant I as Implementer (you)
    participant G as git / gitea

    L->>I: delegated task (you are in a worktree on your branch)
    I->>I: "implement here — every path under $PWD"
    I->>I: "mvn clean install in this worktree, unpiped, until green"
    I->>G: git commit (never .mcp.json / wiki)
    I->>G: git push -u origin HEAD
    I->>G: POST /pulls (GITEA_TOKEN) — open PR to main
    G-->>I: html_url
    I->>L: fleet_reply(PR url, branch, files, tests)
    Note over L,G: the lead reviews the PR and merges on green — you never merge

The implement turn: work in the worktree, commit → push → open the PR, hand off the URL.