Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 66 additions & 3 deletions .agents/skills/fleet-onboarding/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ missing or a `thurbox-cli` is below the manifest's floor.
| recommended | a named capability degrades — `quota-axi` for fuel and `refuel`, `glab` for GitLab |
| gate | only `./scripts/check.sh` needs it — `lua`, `shellcheck`, `rumdl`, `prek`, plus the git commit-signing configuration, which is not a tool |

The two authentication rows are the ones worth reading rather than skimming,
because neither CLI's own status command answers the question fleet has.
`gh auth` is decided **per account**, so one expired token among three reads
`3 of 4 accounts` and the broken login is named on stderr — not `missing`.
`glab auth` is decided **per host** and names the instance that answered:
`GITLAB_HOST` decides when it is set, and otherwise one working credential is
enough. An operator authenticated to their company's GitLab and not to
gitlab.com has a working setup, and this row says so.

`gh` is required even on a fleet whose work is entirely on GitLab: it is what
builds the repo map from `registry/owners.txt`, which is a list of GITHUB
owners. `quota-axi` is the one most often missed, and it is not decorative —
Expand Down Expand Up @@ -189,9 +198,11 @@ so start from the tracked example rather than from memory:
edits it later by hand.
- Replace the two `# your-github-username` / `# your-org` placeholder lines with
the confirmed owners, one per line, username first.
- On a **re-run** there are no placeholders left. Add only owners not already
present, and leave the existing order alone — the sync emits owners in this
file's order, so reshuffling it churns the generated map for nothing.
- On a **re-run** there are no placeholders left, and appending by hand is no
longer the way to do it: `./scripts/add-owner.sh <owner>...` appends, leaves
the existing order alone — the sync emits owners in this file's order, so
reshuffling it churns the generated map for nothing — and refuses a
duplicate. **What the operator gains afterwards**, below, is the fuller path.

Verify before moving on; the sync refuses a file with no active entries, and it
is better to catch that here:
Expand Down Expand Up @@ -464,6 +475,58 @@ So do not refuse on an already-configured clone. Detect it —
extension healthy, `plugin check` green — say which parts are already in place,
and offer to refresh the map rather than redoing everything.

### What the operator gains afterwards

The thing that actually happens after a first run is not a re-run: the operator
gains an owner, a repository, or a whole `gh` or `glab` account, and the map and
the checks have to catch up. That is **one command**, and offering it is the
narrow thing this section exists for — not the seven steps again:

```bash
./scripts/add-owner.sh # what is new; writes nothing
./scripts/add-owner.sh --all # add every new owner, then sync
./scripts/add-owner.sh <owner> [<owner>...] # add the ones they picked
```

The report groups owners **by the account that reaches them**, because after a
`gh auth login` that is the shape of the question: this account is now readable,
it reaches these owners, N of them are not in your map. `*` marks an owner
already in `registry/owners.txt`, `+` one that is not, and an owner already
there is never offered twice. A login's own namespace is an owner as well as its
orgs — a new account usually brings at least two.

**ASK before you add.** Same rule as step 3 and the same reason: which owners
the map covers is the operator's call, not a consequence of which tokens happen
to be on the machine.

- **Add all of them** — every owner marked `+`
- **A subset I name** — they pick from the `+` rows
- **None** — the report was the answer

Both add forms append, keep the file's comment header and its order, refuse a
duplicate, and then sync and report **what moved** — owners added, repositories
gained or lost, the totals before and after — rather than printing the map back.

Three things it does not do, each deliberate:

- **It logs nobody in.** `gh auth login` and
`glab auth login --hostname <host>` are interactive and the operator's. Hand
the command over and let them run it; then run the report again.
- **A GitLab host never becomes an owner.** `registry/owners.txt` is read by
`gh`. Authenticating one changes two other things and the report says so: the
`glab auth` row in `preflight.sh` starts naming that host, and a task can
target a repository there through the forge seam in `scripts/lib/forge.py`.
- **It does not onboard a fresh clone.** With no `registry/owners.txt` it
refuses and points back at step 3, where the candidates come from three
sources rather than one.

Two preflight rows answer the same incremental question, so re-read them rather
than the exit code alone when an operator says a credential is fine and fleet
disagrees. `gh auth` is decided **per account** — one expired token among three
is `3 of 4 accounts`, not a failed setup — and `glab auth` **per host**, naming
the instance that answered, because a self-hosted GitLab is the ordinary case
and gitlab.com is often one the operator has never used.

The one thing a re-run does **not** fix is a **rename**. thurbox names a session
when it SPAWNS it and has no verb that renames one, and `ensure_extension`
matches a declared session to a live one by NAME — so a manifest edit alone
Expand Down
19 changes: 16 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,22 @@ names every path and the reason for each.
EVERY `gh` ACCOUNT, not just the active one, there and in
`scripts/sync-registry.sh` — a machine with several logins reaches a
different set of repositories per login. `scripts/lib/gh-accounts.sh` is the
seam both go through and its header owns the mechanism; the one thing to
know here is that it reads each login's token BY NAME and never switches the
account the operator's `gh` is pointing at.
seam every reader goes through and its header owns the mechanism; the one
thing to know here is that it reads each login's token BY NAME and never
switches the account the operator's `gh` is pointing at. **Neither CLI's own status
command answers the question preflight has**, so both authentication rows go
through a seam instead: `gh auth` is decided per ACCOUNT, and `glab auth` per
HOST through `scripts/lib/glab-hosts.sh` — a bare `glab auth status` is
all-or-nothing across every instance glab has configured, so it called a
self-hosted-only setup broken, which the forge seam says is the ordinary one.
- `scripts/add-owner.sh` — the incremental half, for what the operator gains
AFTER a first run: an owner, a repo, or a whole account. It names the owners
the current `gh` accounts reach that `registry/owners.txt` does not list,
grouped by the account that reaches them; with `--all` or a named list it
APPENDS them — header and order kept, a duplicate refused — then syncs and
reports what moved rather than the whole map. It logs nobody in, and a GitLab
host is reported as evidence and never as an owner. The fleet-onboarding
skill's **Re-running** section owns the ask that goes with it.
- `.agents/skills/<name>/SKILL.md` — agent skills, in one agent-agnostic tree.
`.claude/skills` is a **symlink** to it, so Claude Code and opencode (which
auto-discovers `.claude/skills`) both load the same copy. Never add a second
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ fleet — it is what builds the repo map.

That done, open the Mission Control session in thurbox and give it a goal.

Afterwards, when you gain an owner, a repository or a whole `gh` account, one
command says what your map does not cover yet and catches it up:

```bash
./scripts/add-owner.sh # what is new, grouped by the account that reaches it
./scripts/add-owner.sh --all # add them, then sync and say what moved in the map
```

It logs nobody in and writes nothing until you ask it to.

## Watching it

**The queue pane** is the live view: the queue in a thurbox column, so you do
Expand Down
Loading