feat(onboarding): decide auth per account and per host, and add owners after the first run - #71
Merged
Merged
Conversation
…er the first run Preflight called a working setup broken twice over, both times by reading an all-or-nothing exit code as an answer about one credential: - `glab auth status` exits non-zero when ANY configured instance fails, so an operator authenticated to their self-hosted GitLab and not to gitlab.com — which they never use — read `missing glab auth` beside a remedy they had already run. That contradicts the forge seam, where which hosts a CLI owns comes from that CLI's own variable and a self-hosted instance is ordinary. - `gh auth status` has the same shape: one expired token among three logins made a REQUIRED row read `missing` with two working accounts sitting there. Both rows now go through a seam. `gh auth` reuses scripts/lib/gh-accounts.sh and reads `N of M accounts`, naming the login that failed on stderr rather than swallowing it; `glab auth` gets scripts/lib/glab-hosts.sh, which asks per host — GITLAB_HOST decides when set, otherwise one working credential is enough and the row names it. Each keeps its old single-answer path as the fallback for a CLI too old to enumerate. The second half is the path that did not exist: what an operator gains AFTER a first run. scripts/add-owner.sh names the owners the current gh accounts reach that registry/owners.txt does not list, grouped by the account that reaches them — the shape of the question after a `gh auth login`. With `--all` or a named list it appends them, keeping the file's comment header and its order, refusing a duplicate, then syncs and reports what moved rather than the map. It logs nobody in, refuses a clone with no owners file, and a GitLab host is reported as evidence and never becomes an owner. Covered offline in scripts/onboarding-selftest.sh §6-§8 against stubbed gh and glab on a PATH built from scratch, including the self-hosted-only case, the expired-token case, and an incremental add on a machine that already has a map.
…ner and auth seams
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Fleet's setup only answered honestly on a first run, and only told the truth about credentials it happened to find on the default host. Two halves, from a real complaint on this operator's machine.
Half one: preflight reported a working setup as broken, twice, both times by reading an all-or-nothing exit code as an answer about one credential.
glab auth statusexits non-zero when ANY configured instance fails, so this operator — authenticated to gitlab.metyis.technology where 32 of their clones live, and not to gitlab.com which they never use — read "missing glab auth" beside a remedy they had already run. That contradicts fleet's own forge seam (scripts/lib/forge.py), where which hosts a CLI owns comes from that CLI's own variable and a self-hosted instance is the ORDINARY case rather than a special one.gh auth statushas the identical shape: with three gh accounts, one expired token makes it exit non-zero, andgh authis a REQUIRED row, so one lapsed credential of three reported the whole setup as unrunnable.The decision: make each row go through a seam rather than the CLI's exit code.
gh authreuses scripts/lib/gh-accounts.sh, which an earlier task landed for the registry and discovery — explicitly reusing that seam rather than writing a second enumeration, as the brief required — and reads "N of M accounts", passing the seam's own stderr warning about a skipped login through verbatim rather than swallowing it (an account that goes missing in silence is the failure that file exists for).glab authgets a new counterpart, scripts/lib/glab-hosts.sh, which asks per host: GITLAB_HOST decides when set (glab's own variable, so a host named there is the one that must work), otherwise one working credential among the configured instances is enough and the row names which. Both keep their old single-answer path as the documented fallback for a CLI too old to enumerate — that keeps the floor exactly where it was. glab's mechanics were verified against the real glab 1.117.0 on this machine before anything was written.Half two: onboarding is a seven-step FIRST run that converges on a re-run, but there was no path for the thing that actually happens later — the operator gains an owner, a repo, or a whole gh/glab account and wants the map and the checks to catch up. New scripts/add-owner.sh names the owners the current gh accounts reach that registry/owners.txt does not list, grouped BY THE ACCOUNT THAT REACHES THEM, because after a
gh auth loginthat is the shape of the question. With --all or a named list it appends them, then syncs and reports what MOVED — owners added, repositories gained or lost, totals before and after — rather than printing the whole map.Constraints that were deliberate and may look surprising in the diff:
Verification: the gate is ./scripts/check.sh and it is green end to end, including the sync check that arrived on main during this work. The new behaviour is covered in scripts/onboarding-selftest.sh sections 6, 7 and 8, which run OFFLINE against stubbed gh and glab on a PATH built from scratch — no network, no live gh/glab, no touching the operator's real config or map, which is that selftest's standing rule. The three glab cases the brief named are all covered (self-hosted-only reads ok and names the host; GITLAB_HOST pointing at a host with no credential reads missing with a remedy naming that host; nothing authenticated reads missing), plus the one-expired-token gh case and the incremental add on a machine that already has owners and a map. Both halves were also verified against this operator's real machine: the glab row now reads "ok glab auth gitlab.metyis.technology" and the gh row "3 of 3 accounts", and add-owner.sh's report was driven against their real accounts in a scratch root so nothing of theirs was written.
Documentation: the fleet-onboarding skill's Re-running section was EXTENDED rather than given an eighth step, because this is not a step of the first run — that was an explicit instruction. AGENTS.md and README.md name the new script and the two seam changes.
Note on history: a first pipeline run failed mid-review when its own agent hit a usage limit. Its preserved head was my commit rebased onto a newer main and carried no pipeline fix commits, so nothing was lost; the branch has since been rebased onto that same base by hand and re-gated.
What Changed
scripts/preflight.sh's two authentication rows no longer read a CLI's all-or-nothing exit code as an answer about one credential.gh authnow goes through the existingscripts/lib/gh-accounts.shseam and reports "N of M accounts" with the logins named, passing that seam's warning about a skipped login through to stderr verbatim;glab authgoes through a newscripts/lib/glab-hosts.sh, which answers per host —GITLAB_HOSTdecides when set (and its remedy names that host), otherwise one working credential amongglab auth status --all's instances readsokand names it. Both rows keep the barestatuscall as the documented fallback for a CLI that cannot enumerate.scripts/add-owner.shcovers the incremental case onboarding had no path for: it lists the owners the currentghaccounts reach thatregistry/owners.txtdoes not, grouped by the account that reaches them, and with--allor named owners appends them, runs the registry sync, and reports what moved (owners added, repositories gained or lost, totals before and after). It writes preserving the file's comment header and entry order, refuses duplicates and non-[A-Za-z0-9-]names without writing, refuses a clone with no owners file and points back atdiscover-owners.sh, logs nobody in, and treats an authenticated GitLab host as reported evidence rather than an owner.scripts/onboarding-selftest.shgains sections 6, 7 and 8 covering the glab-per-host row, the gh-per-account row (including one expired token of three and the no-enumeration fallback) andadd-owner.sh, all offline against stubbedgh/glabon a PATH built from scratch.check.sh's header,AGENTS.md,README.mdand the fleet-onboarding skill's Re-running section document the new script and the two seams.Risk Assessment
✅ Low: The change is well-bounded operator tooling with no production or data path, every intent constraint is implemented and covered by offline selftests that fail for the right reason, and the two remaining issues are a cosmetic input-validation gap and a test that is weaker than its label.
Testing
The configured gate
./scripts/check.shhad already passed as baseline. On top of that I drove both halves live on the reporting operator's own machine: base-commit preflight reproducesmissing glab authand a single-accountgh authrow, and the target commit turns those intook glab auth gitlab.metyis.technologyandok gh auth 3 of 3 accounts, with theGITLAB_HOSTdecider exercised in both directions against the real instances and both rows shown to still fail when they should (empty gh config dir →missing gh auth, exit 1).add-owner.shwas driven end to end against the real accounts in a scratch root — report, append plus real sync with a what-moved summary, and every refusal path including--allwith no account answering — with the files md5-checked as untouched after each refusal. The repo's own offline sections 6–8 were run as coverage, and three mutations (reworded totals line, dropped--paginate,GITLAB_HOSTremoved from the selftest's environment boundary) confirm that coverage fails when the behaviour regresses — but an offline selftest section is not a live drive, so the mixed-tokenN of Mcase that only sections 7a/7b cover is reported untested rather than passed. Two scenarios remain undriven: that mixed multi-account token state, and an account belonging to more than 30 orgs. This is a CLI-only change, so the reviewer-visible evidence is CLI transcripts rather than screenshots. Temp roots were removed and the worktree is clean./tmp/fleet-base/scripts/preflight.sh(base 209a66c) printsmissing glab auth;./scripts/preflight.shon the target printsok glab auth gitlab.metyis.technology— same machine, same real glab 1…GITLAB_HOST=gitlab.com ./scripts/preflight.sh --tier recommended→missing glab authwithinstall: glab auth login --hostname gitlab.com(gitlab.com genuinely has no token here)GITLAB_HOST=gitlab.metyis.technology ./scripts/preflight.sh --tier recommended→ok glab auth gitlab.metyis.technologyGITLAB_HOST=gitlab.com ./scripts/preflight.shfull run exits 0 while the glab row reads missing./scripts/preflight.sh→ok gh auth 3 of 3 accounts — LeTuR, <client-account>, ArthurCesareHerriau, against the base commit'sok gh auth LeTuRGH_CONFIG_DIR=/tmp/gh-empty ./scripts/preflight.shwith the real gh →missing gh auth,install: gh auth login, exit 1./scripts/onboarding-selftest.sh§7a/§7b, which is a stubbed selftest section and not a drive of the realgh; no mixed healthy/expire…./scripts/add-owner.shin a scratch root against the three real accounts — owners grouped per account with*/+marks, per-account new counts, a 9-owner summary truncated at 8 with+1 more, and…GITLAB — evidence, never an ownerblock names gitlab.metyis.technology, while thenot in registry/owners.txtline contains only GitHub owners./scripts/add-owner.sh Thurbeen— realsync-registry.shrun,MAP CHANGEDwith owners added, repositories gained (truncated+21 more) and `67 repos across 2 owners (was 38 repos across 1 owners…group/subgroup,gitlab.metyis.technology/group,.leading-dot, and a valid name beside an invalid one all exit 1 with no write — md5 of owners.txt and repos.generat…GH_CONFIG_DIR=/tmp/gh-empty ./scripts/add-owner.sh --all→ "No gh account answered...", exit 1, nothing written; with the real accounts and every owner already listed the same flag prints "Nothing n…./scripts/add-owner.shin this worktree (no registry/owners.txt) → exit 1 naming./scripts/discover-owners.shand the owners.example.txt copy--alland<owner>forms all driven above;--helpprints the header,--no-syncand--watboth exit 2 with the usage lineGITLAB_HOST=gitlab.com ./scripts/check.sh onboardingis green on this branch; the same tree with GITLAB_HOST removed from the selftest's environment boundary FAILs 6a — the reported regression repro…--paginatefrom the user/orgs call makes §8a/8b/8d/8e FAILEvidence: preflight before/after on the real machine (the reported bug, and the fix)
BEFORE — base commit 209a66c: ok gh auth LeTuR missing glab auth reading a merge request needs a credential for the host it lives on install: glab auth login # GITLAB_HOST=... for a self-hosted instance AFTER — target commit 7dfae4d, same machine, same credentials: ok gh auth 3 of 3 accounts — LeTuR, <client-account>, ArthurCesareHerriau ok glab auth gitlab.metyis.technology (exit 0) $ GITLAB_HOST=gitlab.com ./scripts/preflight.sh --tier recommended missing glab auth a merge request is read with a credential for ITS host, not for every host glab knows install: glab auth login --hostname gitlab.comEvidence: add-owner.sh driven against the operator's real gh accounts (report, add, every refusal)
$ ./scripts/add-owner.sh ACCOUNTS gh HOLDS — and the GitHub owners each one reaches LeTuR * LeTuR, + sobri-it, + Thurbeen (2 new) <client-account> + <client-account>, + <client-org> (2 new) ArthurCesareHerriau + ArthurCesareHerriau, + Metyis-Porto, + Metyis-Global, + Metyis-Global-Test, + Climbing-District (5 new) * already in registry/owners.txt + not in it yet GITLAB — evidence, never an owner authenticated: gitlab.metyis.technology ... It adds no owner here: registry/owners.txt is a list of GITHUB owners, read by gh. 9 owners not in registry/owners.txt: sobri-it, Thurbeen, ..., +1 more $ ./scripts/add-owner.sh Thurbeen added to registry/owners.txt: Thurbeen fetching every accessible repository ... MAP CHANGED owners added Thurbeen repositories gained Thurbeen/fleet, Thurbeen/thurbox, ..., +21 more totals 67 repos across 2 owners (was 38 repos across 1 owners)Evidence: offline sections 6-8 green, and three mutations proving they are not vacuous
GITLAB_HOST exported by the operator: without the fix: FAIL 6a a credential on one configured host is not reported missing with the fix: ok onboarding: scripts/onboarding-selftest.sh add-owner totals line reworded: FAIL 8d the map's own owner count moved --paginate dropped from user/orgs: FAIL 8a/8b/8d/8ePipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
scripts/add-owner.sh:285---allprints a false claim when no gh account answered — round 1 selected this for fix and the target commit does not contain it. Trace: gh is installed but every credential is expired or logged out (exactly the machine this change is about).gh_accountsreturns nothing, theask_account ""fallback fails ongh api userand is swallowed by|| true(line 151), soACCOUNT_ORDERandNEW_ORDERare both empty.--allthen reaches line 284 and prints "Nothing new: every owner these accounts reach is already in registry/owners.txt." and exits 0 — asserting the map is complete when nothing was compared at all. Report mode handles the same state correctly (report()lines 210-215 prints "No gh account answered, so there is nothing to compare your map against." plus thegh auth loginremedy); the--allbranch is the one place that asymmetry leaks a wrong statement. Remedy: gate line 284 on${#ACCOUNT_ORDER[@]} -eq 0first and emit the same "no account answered" message the report emits.scripts/onboarding-selftest.sh:77- AmbientGITLAB_HOSTdecides §6's answers, so the new glab coverage is environment-dependent. Line 77 unsetsGH_TOKEN GITHUB_TOKEN GH_HOST(and lines 66-72 clearGIT_CONFIG_*) precisely because a caller's environment must not decide a stubbed probe's answer, but this change makesGITLAB_HOSTa first-class decider at scripts/preflight.sh:263 and never adds it to that boundary. §6a (line 901) and §6d/§6e runplain_preflightwith noGITLAB_HOSTprefix, inheriting whatever the operator exports. Concrete failure: withGITLAB_HOST=gitlab.comexported, §6a'sGLAB_HOSTS="gitlab.com gitlab.metyis.technology" GLAB_OK="gitlab.metyis.technology"run takes theGITLAB_HOSTbranch,glab_host_ok gitlab.comexits 1, preflight recordsmissing, andrefute "6a a credential on one configured host is not reported missing"fails — so./scripts/check.sh onboarding(and therefore the repo's own gate) breaks on a machine that has done nothing wrong. WithGITLAB_HOSTset to a self-hosted host instead, §6a passes through the wrong branch and never exercises the per-host enumeration it claims to cover. Remedy is the file's existing pattern: addGITLAB_HOSTto theunsetat line 77.scripts/add-owner.sh:65- Simplification:--no-syncis a new mode the stated intent does not require, and round 1 selected its removal — the target commit still carries it. The intent specifies exactly three behaviors for this script: report ("names the owners the current gh accounts reach that registry/owners.txt does not list"), and "With --all or a named list it APPENDS them ... then syncs and reports what MOVED". There is no requirement for a form that writes owners.txt and deliberately leaves the map stale; it also creates the one state the repo's own rules warn about (an owners file the generated map no longer matches), which the script then has to explain away at line 330. Recommend removing the flag and its branch (lines 60, 65, the usage string at line 71, lines 329-332, the--no-syncline in the header at line 38, and the--no-syncsentence added to .agents/skills/fleet-onboarding/SKILL.md) so add mode always converges on a synced map.scripts/add-owner.sh:122-gh_api_as "$token" user/orgs --jq '.[].login'is unpaginated, so GitHub's defaultper_page=30caps it — round 1 selected this for fix and it is not in the target commit. An operator who belongs to more than 30 orgs on one account gets a silently truncated candidate set:NEW_ORDERomits the 31st org onward, so the report can say "Nothing new: every owner these accounts reach is already in registry/owners.txt" while an uncovered org exists, and--allthen adds an incomplete set — a wrong answer with no error. Remedy is mechanical:gh_api_as "$token" --paginate user/orgs --jq '.[].login'. Note the §8 gh stub dispatches oncase "$1 $2", so the fixture's"api user/orgs")arm needs to become the--paginateshape alongside it. The identical unpaginated call exists at scripts/discover-owners.sh:109 (pre-existing, unchanged here), so fixing only this one leaves the two paths disagreeing; scripts/sync-registry.sh:93 already paginates its endpoint.scripts/onboarding-selftest.sh:1189-expect "8d the map's own owner count moved" "owners" "$out"is vacuous, and round 1's selected fix is not in the target commit.$outalways contains the literalowners added ...line printed unconditionally by scripts/add-owner.sh:351, so the substringownersmatches regardless of whether the map's owner total changed at all. The label claims coverage the assertion does not provide, and it would keep passing if thetotalsline (add-owner.sh:363) regressed or disappeared. In this fixture the map goes from 3 repos across 2 owners to 3 repos across 3 owners, so the honest assertion is that phrase — e.g.across 3 owners (was— which scripts/add-owner.sh:363 emits frommap_totals.scripts/add-owner.sh:306- Simplification: the rule for what a GitHub owner name is has two definitions back to back. The firstcase(lines 306-309) requires a leading alphanumeric; the second (lines 310-316) rejects any character outside[A-Za-z0-9-]. For every input that can reach here the second subsumes the first —.foo,group/subgroupandgitlab.example.com/groupall fail both — and the first's only unique coverage is a leading-, which the argument parser already intercepts at line 70 with a usage error (exit 2) and which no GitHub login can be. Collapsing to the single*[!A-Za-z0-9-]*case removes the dead branch and leaves the more informative refusal message as the one an operator sees.🔧 Fix applied.
2 infos still open:
scripts/add-owner.sh:314- Collapsing the two owner-name checks into*[!A-Za-z0-9-]*dropped the one input the removed[A-Za-z0-9]*case uniquely covered: the EMPTY string. Verified glob semantics —case "" in *[!A-Za-z0-9-]*)does not match, so an empty name is accepted, while the old leading-alphanumeric case refused it. Reachable path:./scripts/add-owner.sh "$OWNER"withOWNERunset or empty (the argument parser sends "" toWANTEDvia the*)arm at line 71, since only-*is intercepted). It then passes the duplicate check,printf '%s\n' ""appends a blank line to the operator's registry/owners.txt at line 330, line 331 printsadded to registry/owners.txt:naming nothing (list_some skips empty items and returns early), and a full sync-registry run follows. The written file is still parseable — both add-owner.sh:93-97 and sync-registry.sh:49-55 skip blank lines — so the damage is a stray line plus a success message for an owner the operator never named, rather than a broken map. Remedy is one token inside the branch the prior round already touched:case "$owner" in "" | *[!A-Za-z0-9-]*).scripts/onboarding-selftest.sh:923- §6c is the only new preflight case with no positive assertion, so it cannot distinguish the behavior it claims to cover from preflight emitting no glab row at all. Its singlerefute "missing glab auth"passes whenever that string is absent — including ifrecord recommended "glab auth" ok "$GITLAB_HOST"(scripts/preflight.sh:266) were deleted outright, or if preflight died before reaching the glab section. That branch — GITLAB_HOST naming a host that DOES authenticate — is covered by no other case: 6a takes the enumeration path, 6b takes the GITLAB_HOST-fails path, 6d the no-credential path. §6a and §7d both pair their refute with a positiveexpectfor exactly this reason. Remedy: addexpect "6c and the row names the host GITLAB_HOST pointed at" "gitlab.metyis.technology" "$out"alongside the existing refute.✅ **Test** - passed
✅ No issues found.
/tmp/fleet-base/scripts/preflight.sh(base 209a66c) printsmissing glab auth;./scripts/preflight.shon the target printsok glab auth gitlab.metyis.technology— same machine, same real glab 1…GITLAB_HOST=gitlab.com ./scripts/preflight.sh --tier recommended→missing glab authwithinstall: glab auth login --hostname gitlab.com(gitlab.com genuinely has no token here)GITLAB_HOST=gitlab.metyis.technology ./scripts/preflight.sh --tier recommended→ok glab auth gitlab.metyis.technologyGITLAB_HOST=gitlab.com ./scripts/preflight.shfull run exits 0 while the glab row reads missing./scripts/preflight.sh→ok gh auth 3 of 3 accounts — LeTuR, <client-account>, ArthurCesareHerriau, against the base commit'sok gh auth LeTuRGH_CONFIG_DIR=/tmp/gh-empty ./scripts/preflight.shwith the real gh →missing gh auth,install: gh auth login, exit 1./scripts/onboarding-selftest.sh§7a/§7b, which is a stubbed selftest section and not a drive of the realgh; no mixed healthy/expire…./scripts/add-owner.shin a scratch root against the three real accounts — owners grouped per account with*/+marks, per-account new counts, a 9-owner summary truncated at 8 with+1 more, and…GITLAB — evidence, never an ownerblock names gitlab.metyis.technology, while thenot in registry/owners.txtline contains only GitHub owners./scripts/add-owner.sh Thurbeen— realsync-registry.shrun,MAP CHANGEDwith owners added, repositories gained (truncated+21 more) and `67 repos across 2 owners (was 38 repos across 1 owners…group/subgroup,gitlab.metyis.technology/group,.leading-dot, and a valid name beside an invalid one all exit 1 with no write — md5 of owners.txt and repos.generat…GH_CONFIG_DIR=/tmp/gh-empty ./scripts/add-owner.sh --all→ "No gh account answered...", exit 1, nothing written; with the real accounts and every owner already listed the same flag prints "Nothing n…./scripts/add-owner.shin this worktree (no registry/owners.txt) → exit 1 naming./scripts/discover-owners.shand the owners.example.txt copy--alland<owner>forms all driven above;--helpprints the header,--no-syncand--watboth exit 2 with the usage lineGITLAB_HOST=gitlab.com ./scripts/check.sh onboardingis green on this branch; the same tree with GITLAB_HOST removed from the selftest's environment boundary FAILs 6a — the reported regression repro…--paginatefrom the user/orgs call makes §8a/8b/8d/8e FAIL./scripts/check.sh/tmp/fleet-base/scripts/preflight.sh(base commit 209a66c) against the real gh/glab — reproducesmissing glab auth./scripts/preflight.shon the same machine —ok gh auth 3 of 3 accounts,ok glab auth gitlab.metyis.technology, exit 0GITLAB_HOST=gitlab.com ./scripts/preflight.sh --tier recommended— missing, remedyglab auth login --hostname gitlab.com, full run still exit 0 (recommended)GITLAB_HOST=gitlab.metyis.technology ./scripts/preflight.sh --tier recommended— ok, names the hostGH_CONFIG_DIR=/tmp/gh-empty ./scripts/preflight.shwith the real gh —missing gh auth, exit 1./scripts/add-owner.shin a scratch root against the three real gh accounts (report mode)./scripts/add-owner.sh Thurbeen— real append + realsync-registry.sh, 38→67 repos across 1→2 owners./scripts/add-owner.sh Thurbeen/LeTuR/sobri-it sobri-it/group/subgroup/gitlab.metyis.technology/group/.leading-dot/sobri-it bad/name— refusals, files md5-verified unchangedGH_CONFIG_DIR=/tmp/gh-empty ./scripts/add-owner.sh --all— "No gh account answered", exit 1, nothing written./scripts/add-owner.sh --allwith every reachable owner already listed — "Nothing new", exit 0./scripts/add-owner.shin this worktree (no registry/owners.txt) — refused, points at discover-owners.sh./scripts/add-owner.sh --helpand--no-sync/--wat— help prints, unknown flags exit 2./scripts/check.sh onboardingand./scripts/onboarding-selftest.sh(§6, §7, §8 all green) — offline coverage, not a live driveGITLAB_HOST=gitlab.com ./scripts/check.sh onboarding— green, versus the same tree with GITLAB_HOST removed from the selftest environment boundary, which FAILs 6amutation: add-owner's totals line reworded — §8d FAILs; mutation:--paginatedropped from the user/orgs call — §8a/8b/8d/8e FAIL✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.