CB-623: create the fleet org, transfer the repo, rename it to fleetd #127

Closed
opened 2026-08-22 21:34:43 +02:00 by ltms · 1 comment
Owner

Part of CB-621 (#125). Runs after CB-622 and before CB-624.

Scope

  1. Create the org fleet on git.ltms.dev. Leave lms untouched: it keeps alms, alms-fe and alms-memory, which are the real LMS product.
  2. Transfer lms/claude-bridge -> fleet/claude-bridge.
  3. Rename fleet/claude-bridge -> fleet/fleetd.
  4. Transfer the wiki companion repo the same way, then fix .gitmodules.
  5. In the existing local clone, run git remote set-url origin <new>.

What is already known to be safe

  • Redirects. A probe on a throwaway repo showed a rename gives web 301, API 301, and a working git ls-remote on the old SSH URL. A further cross-org transfer keeps redirects chaining from the original org and name.
  • CI. lms has 0 org-level runners and the repo has 0 repo-level runners, yet CI has 384 runs with a green one today. The runners are therefore instance-level and serve every org. .gitea/workflows/ references no secrets.*.
  • Open PRs. #121 and #122 are closed; Gitea reported changed_files: 0 for both.

What is NOT known to be safe - handle explicitly

  • The wiki submodule. .gitmodules pins ssh://git@git.ltms.dev:2224/lms/claude-bridge.wiki.git. The probe tested the repo redirect, not the .wiki.git companion, and wiki repos are special in Gitea. Do not assume the redirect covers it. Transfer it, then update .gitmodules and commit, then prove it with a fresh git submodule update --init in a scratch clone.
  • Wiki visibility. A wiki follows its repo's visibility. Making fleetd private makes the wiki private, and the portable CLAUDE.md block links to that wiki. Update the block's URL, or the link 404s for anyone outside the org.
  • The worker forge token. WORKER_GITEA_TOKEN gets its write access through org membership or a collaborator entry. A cross-org transfer can reset team-based access. This fails late and silently: workers spawn fine and only fail when they try to open a PR. Re-grant access, then prove it by having one worker open a real PR. Do not accept a green spawn as proof.

NOT in this ticket

Do not rename the local checkout directory. That is CB-624, deliberately separate, so that a broken issue link or wiki remote can be traced to one step.

Do not reclone. See CB-624 for why.

Acceptance criteria

  • https://git.ltms.dev/lms/claude-bridge 301s to the new path.
  • git ls-remote on the old SSH URL still works.
  • All 14 open issues and their cross-references still resolve.
  • A fresh git submodule update --init in a scratch clone checks out the wiki.
  • A CI run triggers and goes green on the transferred repo.
  • One worker opens a real PR against fleet/fleetd.
Part of CB-621 (#125). Runs **after** CB-622 and **before** CB-624. ## Scope 1. Create the org `fleet` on git.ltms.dev. Leave `lms` untouched: it keeps `alms`, `alms-fe` and `alms-memory`, which are the real LMS product. 2. Transfer `lms/claude-bridge` -> `fleet/claude-bridge`. 3. Rename `fleet/claude-bridge` -> `fleet/fleetd`. 4. Transfer the wiki companion repo the same way, then fix `.gitmodules`. 5. In the existing local clone, run `git remote set-url origin <new>`. ## What is already known to be safe - **Redirects.** A probe on a throwaway repo showed a rename gives web 301, API 301, and a working `git ls-remote` on the old SSH URL. A further cross-org transfer keeps redirects chaining from the original org and name. - **CI.** `lms` has 0 org-level runners and the repo has 0 repo-level runners, yet CI has 384 runs with a green one today. The runners are therefore instance-level and serve every org. `.gitea/workflows/` references no `secrets.*`. - **Open PRs.** #121 and #122 are closed; Gitea reported `changed_files: 0` for both. ## What is NOT known to be safe - handle explicitly - **The wiki submodule.** `.gitmodules` pins `ssh://git@git.ltms.dev:2224/lms/claude-bridge.wiki.git`. The probe tested the repo redirect, not the `.wiki.git` companion, and wiki repos are special in Gitea. Do not assume the redirect covers it. Transfer it, then update `.gitmodules` and commit, then prove it with a fresh `git submodule update --init` in a scratch clone. - **Wiki visibility.** A wiki follows its repo's visibility. Making `fleetd` private makes the wiki private, and the portable `CLAUDE.md` block links to that wiki. Update the block's URL, or the link 404s for anyone outside the org. - **The worker forge token.** `WORKER_GITEA_TOKEN` gets its write access through org membership or a collaborator entry. A cross-org transfer can reset team-based access. This fails late and silently: workers spawn fine and only fail when they try to open a PR. **Re-grant access, then prove it by having one worker open a real PR.** Do not accept a green spawn as proof. ## NOT in this ticket Do not rename the local checkout directory. That is CB-624, deliberately separate, so that a broken issue link or wiki remote can be traced to one step. Do not reclone. See CB-624 for why. ## Acceptance criteria - `https://git.ltms.dev/lms/claude-bridge` 301s to the new path. - `git ls-remote` on the old SSH URL still works. - All 14 open issues and their cross-references still resolve. - A fresh `git submodule update --init` in a scratch clone checks out the wiki. - A CI run triggers and goes green on the transferred repo. - One worker opens a real PR against `fleet/fleetd`.
ltms added this to the 2.0 — one operation centre, many hosts milestone 2026-08-22 21:34:43 +02:00
Author
Owner

Done — lms/claude-bridge is now fleet/fleetd

Org fleet (id 16, public) created; repo transferred, then renamed. Commits: 555715c (path rewrite) and wiki d361486.

Acceptance criteria

criterion result
old URL 301s to the new path web 301, API 301, issue URLs 301 — redirects chain through both the transfer and the rename
git ls-remote on the old SSH URL works
open issues and cross-references resolve 24 preserved with the same numbers; #125/#126/#127/#131/#137 spot-checked 200
fresh clone + git submodule update --init wiki checks out over the new URL, 15 files
a CI run triggers and goes green run 211 green on fleet/fleetd; also 212 (PR) and 213 (merge)
a worker opens a real PR #139, opened by agent, base main on fleet/fleetd, merged as c135583

Local build after the rewrite: 878 tests, 0 failures.

Three corrections to this ticket

1. Step 4 does not exist — the wiki is not a separate repo. /repos/lms/claude-bridge.wiki returned 404 and lms owned only 4 repos, none of them a .wiki. The wiki moved with the repo: both the old and the new wiki SSH URLs resolve to the same sha. Only .gitmodules needed the edit. There was never a second transfer to do.

2. 24 open issues, not 14.

3. One reference was a real break, not a doc link. .claude/skills/implementer/SKILL.md:88 hardcoded the worker PR endpoint at the old repo path, so every worker PR would have posted to the old address. That was the only functional item among the 15 references rewritten across 9 files.

The worker-token risk was real, and it fired

The ticket said this fails late and silently. It did. Measured before the transfer:

  • lms/claude-bridge collaborators: [] — empty
  • lms team agents: includes_all_repositories: true, repo.code/issues/pulls = write, single member agent
  • so WORKER_GITEA_TOKEN's write access came from org membership, which a cross-org transfer does not carry

Right after the transfer the worker token read {admin: false, push: false, pull: true}. Fixed by recreating the team in fleet (id 15, byte-identical units, permission: none so branch protection still binds workers) and adding agent. Push returned to true, and PR #139 by agent is the proof — a green spawn was explicitly not accepted as proof.

Order matters for anyone repeating this: create the team before the transfer. The team's includes_all_repositories: true then covers the repo on arrival and access never drops.

Not done, deliberately

Repo visibility is unchanged (still public), because this ticket does not ask for it. So the "a private wiki 404s the CLAUDE.md link" risk has not been triggered — it returns whenever fleetd is made private.

The parent's wiki submodule pointer still reads d526b43, not the new d361486, because the parent never commits that pointer. Pre-existing behaviour, unchanged here.

Found on the way (separate tickets needed)

  1. sonnet and opus spawns fail; opencode profiles are fine. The pane starts and exits by itself, and the launcher reports did not reach injectable state within 20000ms — a symptom 20s downstream. Ruled out by running the real binary with the real argv: auth/usage limit, the full launcher argv (--mcp-config, --append-system-prompt, --agent dev, --session-id, --model), and the CB-618 cause (all three .claude/agents/*.md have name:). Both affected profiles are subscription: true claude-code. Same reporting weakness as CB-618: the launcher never captures what the spawned process printed.
  2. memberCredentials policy has drifted. Every spawn logs a gap of 4 names on neither known: nor allow: — AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, JENKINS_MCP_AUTH, N8N_WEBHOOK_TOKEN — inherited unblocked by every member pane. The detection works; the config was never updated. Fix is in bridged.yaml, which is gitignored, so no worker can do it and no PR will show it.
  3. A CI false red, fixed in passing (#139). The contract job published host port 5672:5672 while reaching the broker by network alias, so two concurrent runs collided and the service container failed to start. Evidence: run 209 (PR) green and run 210 (the merge of identical code) failed with every step including checkout marked cancelled, both at 22:08; re-running 210 alone passed. Note the limit of the proof: run 212 shows the alias path still works without the mapping, but no post-fix concurrent run has been observed yet.
## Done — `lms/claude-bridge` is now `fleet/fleetd` Org `fleet` (id 16, public) created; repo transferred, then renamed. Commits: `555715c` (path rewrite) and wiki `d361486`. ### Acceptance criteria | criterion | result | |---|---| | old URL 301s to the new path | web `301`, API `301`, issue URLs `301` — redirects chain through **both** the transfer and the rename | | `git ls-remote` on the old SSH URL | works | | open issues and cross-references resolve | 24 preserved with the same numbers; #125/#126/#127/#131/#137 spot-checked `200` | | fresh clone + `git submodule update --init` | wiki checks out over the new URL, 15 files | | a CI run triggers and goes green | run 211 green on `fleet/fleetd`; also 212 (PR) and 213 (merge) | | a worker opens a real PR | **#139, opened by `agent`**, base `main` on `fleet/fleetd`, merged as `c135583` | Local build after the rewrite: 878 tests, 0 failures. ### Three corrections to this ticket **1. Step 4 does not exist — the wiki is not a separate repo.** `/repos/lms/claude-bridge.wiki` returned `404` and `lms` owned only 4 repos, none of them a `.wiki`. The wiki moved with the repo: both the old and the new wiki SSH URLs resolve to the same sha. Only `.gitmodules` needed the edit. There was never a second transfer to do. **2. 24 open issues, not 14.** **3. One reference was a real break, not a doc link.** `.claude/skills/implementer/SKILL.md:88` hardcoded the worker PR endpoint at the old repo path, so every worker PR would have posted to the old address. That was the only functional item among the 15 references rewritten across 9 files. ### The worker-token risk was real, and it fired The ticket said this fails late and silently. It did. Measured before the transfer: - `lms/claude-bridge` collaborators: `[]` — empty - `lms` team `agents`: `includes_all_repositories: true`, `repo.code`/`issues`/`pulls` = `write`, single member `agent` - so `WORKER_GITEA_TOKEN`'s write access came from **org membership**, which a cross-org transfer does not carry Right after the transfer the worker token read `{admin: false, push: false, pull: true}`. Fixed by recreating the team in `fleet` (id 15, byte-identical units, `permission: none` so branch protection still binds workers) and adding `agent`. Push returned to `true`, and PR #139 by `agent` is the proof — a green spawn was explicitly not accepted as proof. **Order matters for anyone repeating this:** create the team *before* the transfer. The team's `includes_all_repositories: true` then covers the repo on arrival and access never drops. ### Not done, deliberately Repo visibility is unchanged (still public), because this ticket does not ask for it. So the "a private wiki 404s the `CLAUDE.md` link" risk has not been triggered — it returns whenever `fleetd` is made private. The parent's `wiki` submodule pointer still reads `d526b43`, not the new `d361486`, because the parent never commits that pointer. Pre-existing behaviour, unchanged here. ### Found on the way (separate tickets needed) 1. **`sonnet` and `opus` spawns fail; opencode profiles are fine.** The pane starts and exits by itself, and the launcher reports `did not reach injectable state within 20000ms` — a symptom 20s downstream. Ruled out by running the real binary with the real argv: auth/usage limit, the full launcher argv (`--mcp-config`, `--append-system-prompt`, `--agent dev`, `--session-id`, `--model`), and the CB-618 cause (all three `.claude/agents/*.md` have `name:`). Both affected profiles are `subscription: true` claude-code. Same reporting weakness as CB-618: the launcher never captures what the spawned process printed. 2. **`memberCredentials` policy has drifted.** Every spawn logs a gap of 4 names on neither `known:` nor `allow:` — `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `JENKINS_MCP_AUTH`, `N8N_WEBHOOK_TOKEN` — inherited **unblocked** by every member pane. The detection works; the config was never updated. Fix is in `bridged.yaml`, which is gitignored, so no worker can do it and no PR will show it. 3. **A CI false red, fixed in passing (#139).** The `contract` job published host port `5672:5672` while reaching the broker by network alias, so two concurrent runs collided and the service container failed to start. Evidence: run 209 (PR) green and run 210 (the merge of identical code) failed with every step including `checkout` marked `cancelled`, both at 22:08; re-running 210 alone passed. Note the limit of the proof: run 212 shows the alias path still works without the mapping, but no post-fix *concurrent* run has been observed yet.
ltms closed this issue 2026-08-23 05:43:13 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: fleet/fleetd#127