Suggest roster-aware agent names#239
Conversation
orangewk
left a comment
There was a problem hiding this comment.
Review (draft) — findings first
Overall this matches the agreed minimal design and reads well. One blocking item, otherwise non-blocking + nits. Reviewed the branch locally.
🔴 Blocking
B1 — empty-roster suggestion errors on bash 3.2 (macOS).
scripts/lib/roster.sh:99 (and defensively :110): agmsg_roster_contains "$candidate" "${roster[@]}". whoami.sh runs under set -euo pipefail, and on first run / a brand-new team the roster array is empty. On bash < 4.4 (macOS /bin/bash is 3.2) "${empty[@]}" under set -u raises unbound variable; bash 4.4+ is fine. Verified working on bash 5.2 (Git Bash) — it emits 5 names with an empty roster — so this is macOS-3.2-specific and not reproducible on Linux/Windows CI. agmsg explicitly targets bash 3.2 (see the lib/registry-lock.sh rationale).
Effect: the command-substitution subshell errors; whoami masks it via the assignment so it does not hard-fail, but suggested= comes back empty (plus an unbound variable line on stderr) — i.e. the feature silently no-ops on a primary platform, exactly on the first-run path #178 targets.
Fix (one line, both sites): ${roster[@]+"${roster[@]}"} (bash-3.2-safe alternate-value expansion), or an early [ "${#roster[@]}" -eq 0 ] branch. The "${pool[@]}" at :108 is already guarded non-empty at :93.
🟡 Non-blocking
- Test gap (would have caught B1): no test exercises an empty roster under
set -u.test_roster.batsusesbash -cwithoutset -u, and thewhoami not_joinedtest pre-joins a team soFIRST_TEAMis non-empty. Add a true no-teamswhoamirun, orbash -c 'set -u; source …; agmsg_suggest_names <empty-team> 5'. - Reuse-path collision scope: in the
suggest=truepath the names are checked only againstFIRST_TEAM's roster; if the user joins a different team the "unused" property doesn't hold. Advisory, so fine — a one-line note in the template ("suggestions are relative to the first listed team") would clarify.
⚪ Nit
- Pool ordering: the pool is alphabetical, so the linear walk yields same-initial clusters (offset
b→banach bell bernoulli boole brahe). Interleaving domains/initials inname-pool.txtwould make contiguous picks feel more varied; determinism is unaffected.
✅ Confirmed good
roster_namesis Windows/CRLF-safe (agmsg_sqlite_memstrips CR;agmsg_sql_readfile_pathdoescygpath -w).- Names are JSON keys, so
roster_namesis registration-shape-agnostic — no legacy-array normalization needed (correct). whoamiadditions are line-end additive;agent=/multiple=paths untouched → existing parsers safe.- Deterministic (cksum offset, no
$RANDOM) — verified identical across runs. - Templates use
__SKILL_NAME__, not a hardcoded/agmsg. - Pool is identity names, lowercase ASCII, no tool labels — matches the #178 intent; charset is re-enforced at read time.
- Scope is the agreed minimal cut (spawn auto-pick + guaranteed-unique allocation excluded and noted in the PR body).
Fix B1 and I'd consider this mergeable.
45bcee2 to
835c47b
Compare
orangewk
left a comment
There was a problem hiding this comment.
Re-review — B1 resolved ✅
Verified 835c47b locally.
- B1 fixed correctly.
scripts/lib/roster.sh:99and:110now use${roster[@]+"${roster[@]}"}, the canonical bash-3.2-safe empty-array expansion. Re-ran the failing condition (set -u+ empty roster): exit 0, 5 names, clean stderr.bash -nclean. Correct by construction for bash < 4.4 as well. - Regression tests added —
roster: suggestions are safe with empty roster under set -u(asserts count == 5) andwhoami: first run with no teams includes suggested names. The first is the solid guard for B1.
⚪ New nit (test quality, non-blocking)
tests/test_roster.bats:40 — [[ ! "$output" =~ "suggested=$" ]]. Quoting the RHS makes $ a literal, so this matches the literal string suggested=$ and passes vacuously (it does not assert the value is non-empty). Verified: both suggested=ada,… and an empty suggested= pass it. Drop the quotes (=~ suggested=$) to actually anchor end-of-line. Non-blocking — the empty-roster count == 5 test already covers non-emptiness; this assertion is just redundant-and-inert as written.
Caveat (same as before): both empty-array regression tests only bite on a bash < 4.4 leg — on bash 4.4+ the pre-fix code also passed. Worth confirming CI exercises a bash-3.2 / macOS-system-bash leg so the guard isn't latent.
B1 cleared. From my side this is mergeable once it comes out of draft; the remaining items are non-blocking (NB2 reuse-scope note, pool-ordering nit, the test nit above).
835c47b to
fa20b6c
Compare
Summary
This draft implements the onboarding half of #178: when an agent is not yet registered for a project,
whoami.shnow appends roster-aware unused identity name suggestions.The goal is to avoid defaulting humans and agents toward ambiguous tool labels like
cc/codexwhen multiple sessions of the same type may coexist. The suggestions are identity names from a bundled pool, e.g.noether,lovelace,turing,gauss, rather than type prefixes.Design
scripts/lib/roster.shas a read-only helper:agmsg_roster_names <team>lists current team member names from the team registry.agmsg_suggest_names <team> [count]walks a bundled identity-name pool deterministically and skips names already present in the roster.scripts/data/name-pool.txtas read-only data, not sourced code.join.shsemantics.whoami.shonly on join-needed paths:not_joined=true ... suggested=<n1,n2,...>suggest=true ... suggested=<n1,n2,...>SKILL.mdso agents showsuggested=as optional unused identity names.Explicitly out of scope for this draft
spawn.sh <type>work without a positional name.registry-lock.Those are reasonable follow-ups, but this PR keeps #178 to an additive suggestion flow.
Verification
bash -n scripts/lib/roster.sh scripts/whoami.sh scripts/join.sh scripts/team.shnot_joinedincludessuggested=suggested=suggest=trueincludes unusedsuggested=namessuggested=git diff --checkBATS was not available in the local Git Bash environment. I added
tests/test_roster.batsand extendedtests/test_team.bats; CI should run them.