b3os-team-member-lifecycle · diff

git:20260726.20a4aa2 to git:20260801.9cc5479

1 added, 0 removed. Audit A to A.

---
name: b3os-team-member-lifecycle
description: Use when adding, testing, disabling, offboarding, or archiving a b3rys team member across Claude Code channel, OpenClaw, Hermes Agent, or future runtimes.
+ trigger: add·remove a member
---
# b3rys Team Member Lifecycle
Use this skill for team-member onboarding(영입), offboarding(퇴사/비활성화), runtime migration(실행 환경 이전), and lifecycle dry-runs.
## Onboarding(영입) — do NOT execute this file's checklist
**The recruit flow is documented in full elsewhere, and that documentation is the current one. Go there first.**
| What you need | Where |
|---|---|
| The recruit flow itself — dashboard wizard **and** API, OT stages, pairing | `skills/b3os/references/recruit.md` |
| Runtime prerequisites — install, auth, what preflight actually checks | `skills/b3os/references/runtime-setup.md` |
| A member that joined but won't answer | `skills/b3os/references/troubleshooting.md` |
Fastest path is the dashboard: **Settings ▸ + 영입**. One form takes `id`, name, role, runtime, mention aliases and persona together; the bot token and the rest are collected during provisioning.
For BYO runtimes (Hermes / OpenClaw) the runtime picker shows a setup link — **follow it before recruiting.** Preflight blocks activation until that runtime's auth exists, and finding that out mid-recruit wastes a cycle.
The numbered onboarding steps further down are a **policy checklist, not a procedure**: read them for the gates the recruit flow does not decide for you (owner routing, context visibility, approval boundaries).
Authoritative context — note which of these a fresh clone actually has:
| File | Present in a fresh clone? |
|---|---|
| `<repo>/rules/SHARED.md` | yes |
| `<repo>/rules/TEAM-OS.md` | **no** — render output, generated at startup from `rules/TEAM-OS.template.ko.md`. Edit the template, never the output. |
| `<repo>/agents.json` | **no** — per-machine roster, deliberately untracked. `loadRegistry` returns `[]` until someone is recruited. |
Never tell a reader to open a file their clone does not have.
Authoritative context — note which of these a fresh clone actually has:
- Team rules: `<repo>/rules/TEAM-OS.template.md` — **this is the tracked source.** The rendered
`<repo>/rules/TEAM-OS.md` is generated at server startup / on settings save and is **not** in a
fresh clone (gitignored). Edit the template, never the output.
- Shared state: `<repo>/rules/SHARED.md` — tracked, present in a fresh clone.
- Registry: `<repo>/agents.json` — per-machine team roster, **created when the first member is
registered.** Not in a fresh clone (gitignored); `loadRegistry` returns `[]` when it is absent.
Never tell a reader to open a file their clone does not have. (There is no
`docs/TEAM_MEMBER_ONBOARDING.md` — recruiting lives in `skills/b3os/references/recruit.md`.)
## Principles
- One lifecycle, multiple surfaces: Telegram commands and dashboard UI must execute the same checklist.
- Prefer dry-run before mutation.
- Use a temporary member rehearsal to harden this skill before applying it to a formal long-lived member.
- Secrets never go to stdout, chat, git, or docs. Mention paths or variable names only.
- Destructive steps need the team lead confirmation: token revoke, workspace deletion, production service restart, public posting, data deletion.
- Live-change gates are per step, not a broad "test approval": continue safe docs/drafts/dry-runs autonomously, but pause at credential, runtime, service, wake, visible-send, and destructive cleanup boundaries.
- Offboarding defaults to disable/archive, not hard delete.
- Every lifecycle action ends with a short status note: changed files, verification, blockers, rollback path.
- Scope group-chat rules correctly: TEAM-OS group-room rules apply to the shared team group/routed group context only. 1:1 DM/direct bot chats are separate surfaces; keep security and confirmation gates, but do not require @mention/sticky-owner silence rules there.
- Response mode defaults to mention-only. For b3rys only, unassigned operational messages may use default_intake_scope to route to PM/coordinator agents such as coordinator/maintainer.
- Communication owner gates must be enforced in every inbound path, not only in team-collab. If a runtime has its own Telegram/Slack gateway, configure that gateway so TEAM-OS owner priority still holds before the model sees the message.
## b3rys Role Model
- coordinator owns PM, coordination, lifecycle design, phase boundaries, and final integration judgment.
- developer is the intended main development executor after onboarding: implementation, refactoring, tests, debugging, and review-response work.
- maintainer is the ops/infra reviewer and activation gate: runtime, deployment, restart, gateway, token/env, bus, and team-collab safety review.
- agent B is the search/AI/model/evaluation specialist. In this lifecycle project, involve agent B only when search, semantic ranking, benchmark, model, or evaluation quality is in scope.
- the team lead should receive phase-boundary reports and explicit approval requests, not every small implementation step.
## Runtime Selection
- `claude_channel`: Claude Code + Telegram/tmux channel. Best for external-user reproducibility and Claude-heavy workflows.
- `openclaw`: OpenClaw (model-hosted gateway) runtime. Best for model-hosted agents, long engineering work, and OpenClaw-native routing.
- `hermes_agent`: Hermes profile + gateway. Best for Hermes-specific provider/profile experiments and service/strategy roles.
Record the selected runtime and reason in the lifecycle report.
## Communication Gate Matrix
For every new runtime, verify the same owner policy at every possible inbound path.
- team-collab router path: @mention > reply owner > sticky owner > default intake.
- runtime-native gateway path: the runtime must not bypass the router by responding to visible group messages that target someone else.
- explicit other-agent mention: if a message replies to this bot but contains a different team member @mention, the other @mention wins and this bot stays silent.
- sticky owner: do not remove sticky to solve over-response. Fix the higher-priority gate instead.
- example/quote mentions: for b3rys internal use, mentions inside `''' ... '''` blocks or below the team lead's `—-` example separator are examples, not live calls. Keep this as instance config, not a public default.
- reaction/ack gate: owner-only reaction or one-line ack must be checked separately from reply delivery. The member should react/ack when owner and stay silent, including no reaction, when not owner.
- context visibility: specialists receive only addressed message/reply context by default. Full team context is for approved coordinator roles.
- observed context: disable gateway features that store unmentioned team-room messages unless the team lead explicitly approves them for the member's role.
## Onboarding Policy Checklist
> These are **gates to verify**, not steps to type. The actual recruit procedure lives in
> `skills/b3os/references/recruit.md`; steps 1–6 below are handled by the dashboard form and
> provisioning. Read them to know **what the flow assumes**, and spend your attention on 7–14,
> which the flow does not decide for you.
1. Define identity: `id`, display name, Korean name, role, aliases, owner, intended permanence.
2. Choose runtime. **BYO runtimes need their auth in place first** — see `runtime-setup.md`.
3. Prepare workspace/persona; reference TEAM-OS and SHARED instead of copying common rules.
4. Connect credentials/channel; store tokens only in approved runtime env/credential locations.
5. For OpenClaw agents, verify `openclaw.json` Telegram account + `tokenFile` registration. The team-collab bridge reads this token for group reactions and visible replies.
6. Register in `agents.json`.
7. Add router aliases, role hints, and tests. Verify default-intake cannot route to `mention-only` members unless they are explicitly addressed.
8. Configure group response policy: default to mention/reply-only; for b3rys internal use only, set `default_intake_scope` when the member is a PM/coordinator fallback.
9. Configure runtime mention aliases. Test both the official bot username and team aliases such as Korean names, short names, and English aliases. If the runtime only recognizes official bot usernames, add explicit mention patterns.
10. Configure runtime self gate: explicit @mention to another team member must beat reply-to-this-bot, sticky owner must remain valid, and non-owner visible context must not trigger a response.
11. Configure context visibility. Approved coordinator roles may receive full team context; specialist members should not observe/store unmentioned shared team-room messages by default. Runtime-specific flags such as Hermes `observe_unmentioned_group_messages` must be checked.
12. Enable bus wake only after dry-run and approved activation.
13. Verify: local one-shot, router dry-run, bus DM smoke test, dashboard/status, team visible test after Telegram group invite.
14. Document SHARED, onboarding docs, runtime docs, and memory/learning notes as needed.
### Surface-Specific Checks
- Team group: verify explicit mention routing, sticky/reply owner behavior, and visible reply delivery. OpenClaw final answers may be private unless the runtime uses its visible send path.
- Team group mention aliases: verify official bot handle and local aliases separately. Example: Hermes requires both `@example_hermes_bot` and alias patterns like `@헤르메스`, `@헤르`, `@hermes`.
- Explicit mention precedence: when a message replies to member A but contains `@memberB`, only member B may respond. Member A must treat the message as visible context only.
- Sticky owner: do not disable sticky for specialist members. If the member is the active owner and no higher-priority @mention/reply owner overrides it, the member remains owner.
- Example/quote mention suppression: verify that `@mentions` inside `''' ... '''` blocks do not summon a member. For the team lead's b3rys instance only, also verify that mentions below a `—-` example separator are ignored when the separator config is enabled.
- Reaction/ack: verify owner-only behavior. Owner messages should get the configured reaction/ack path, while non-owner messages, example mentions, and other-agent explicit mentions should get no reaction and no visible reply.
- Context visibility: verify that specialist members do not ingest or store ordinary team-room chatter as background context unless the team lead explicitly approves that capability for the role.
- Default intake option: for b3rys internal registry/dashboard only, expose `default_intake_scope` as `none | general_pm | infra_ops | custom`; do not include it as an external-skill default.
- Dashboard/registry field: expose `response_mode=mention-only` as the default team response policy.
- 1:1 DM/direct chat: verify direct response separately. Do not treat group @mention/owner rules as required in 1:1 rooms.
- Bus DM and team visible tests are different gates. Passing one does not prove the other.
## Offboarding / 퇴사 Workflow
1. Mark intent: temporary test, replacement, pause, or permanent departure.
2. Disable first: remove from wake allowlist or mark inactive.
3. Stop runtime service/session as appropriate.
4. Preserve workspace/logs unless the team lead approves deletion.
5. Update registry, docs, dashboard state, and tests. Registry sync must delete DB/dashboard rows for members removed from `agents.json`; upsert-only sync is not enough.
6. For OpenClaw agents, clean up the `openclaw.json` Telegram account and `tokenFile` after explicit confirmation from the team lead for credential deletion.
7. Token revoke or credential deletion requires explicit confirmation from the team lead.
8. Verify router no longer targets the member and bus has no pending delivery. Unknown retired `@aliases` must go to `ask_team_lead` and wake nobody; do not let them fall through to the default intake.
### Rehearsal Lessons Pinned 2026-06-01
- New aliases must come from `agents.json` `nicknames`; do not add code-level built-in aliases for new members.
- Default intake can only route to default-intake candidates: `response_mode=default-intake`, non-`none` `default_intake_scope`, or the explicit coordinator fallback. A `mention-only` temporary member must never be selected by default intake.
- Removing a member from `agents.json` must also remove stale DB/dashboard rows on registry sync.
- After offboarding, old `@aliases` are unknown mentions and must wake nobody.
- Claude Channel runtime start requires a token file at `~/.claude/channels/telegram-<id>/.env`; without it, stop at runtime start and still complete registry/router/offboarding verification.
- For named Claude Telegram bots, do not rely on `/telegram:access pair <code>` inside Claude Code. That slash command checks the default `~/.claude/channels/telegram/` state directory, not the named `telegram-<id>` one. The approval path that always works: edit `~/.claude/channels/telegram-<id>/access.json` — add your own Telegram DM chat id to `allowFrom` and set `dmPolicy` to `allowlist` (same as hint [F] printed by activate). `promote-pending.sh <id> <code>` from the external `setup-claude-telegram-bot` skill does the same thing, but that skill is **not part of this repo and is not installed by `install.sh`** — only use it if you already have it. Note the dashboard's `pair-approve` is openclaw-only and is a no-op (`skipped:true`) for `claude_channel`.
- Test bus wake only after DM pairing succeeds. Add the temporary member to `BUS_DISPATCH_AGENTS` for the shortest possible smoke window, reload team-collab, send one directed DM, then remove the allowlist entry and reload again.
- A temporary member should treat agent-originated smoke prompts as external input. If the prompt implies visible team-room posting or live side effects and the team lead did not directly approve that exact action, the correct behavior is to refuse or ask the team lead rather than replying.
- `launchctl kickstart` restarts an existing LaunchAgent but may not reload changed plist environment values. For env allowlist changes, use a reload path that actually re-reads the plist; on this host `launchctl load <plist>` successfully restored the service after `bootout`/`bootstrap` returned an I/O error.
### Rehearsal Lessons Pinned 2026-06-02
- Router correctness is not enough. A runtime-native Telegram gateway can still wake on reply-to-me messages, so every runtime needs a self gate that applies TEAM-OS owner priority before responding.
- Reply-to-me is lower priority than a fresh explicit @mention in the message body. If the body names another member, the replied-to member must not answer or react.
- For b3rys internal use, example markers must be filtered before mention detection: `''' ... '''` blocks are quoted examples, and the team lead's configurable `—-` separator can mark everything below it as example text.
- Reaction support is a separate onboarding check. A runtime may have reaction code but keep it disabled by config, so verify both enabled owner reactions and suppressed non-owner reactions.
## Required Report
```text
Lifecycle: onboard|offboard|dry-run
Member: id / name / runtime / role
Changed: files/services/settings
Verified: tests and results
Blocked: missing credentials, bot invite, service restart approval, etc.
Rollback: how to undo safely
Next: one concrete next step
```