Skip to content
Open
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
24 changes: 18 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ Slack ←→ ECS Fargate (Bolt app) ←→ DynamoDB ←→ GitHub API

### Three slash-command namespaces share one router

`/nf-core` handles top-level help, GitHub commands, and on-call commands.
`/hackathon` handles all hackathon commands. Both are registered in `app.py` and
delegate to `commands/router.py` which parses subcommands and dispatches to
handlers.
`/nf-core` handles top-level help, GitHub, on-call, security and Seqera
commands. `/hackathon` handles all hackathon commands. Both are registered in
`app.py` and delegate to `commands/router.py` which parses subcommands and
dispatches to handlers.

### Multi-step modal flow (the critical cross-file path)

Expand Down Expand Up @@ -88,6 +88,15 @@ The same flow adds the Slack user to the Seqera `nf-core/megatests` workspace
DynamoDB. `scheduler/seqera_jobs.py` removes recorded users who have left the
GitHub org once a week (log-only while `SEQERA_REMOVAL_DRY_RUN` is on).

### Seqera access commands

`/nf-core seqera add|remove|list` (`commands/seqera/manage.py`, `@core-team`
only, checked in `_route_seqera()`) manages Seqera access by named group. Groups
are `SeqeraGroup` entries (workspace + role, or org team) returned by
`seqera_groups()` in `checks/seqera.py`: `megatests` from config plus
`SEQERA_GROUPS`. Add, remove and the weekly removal sync all go through
`checks/seqera.py` and only touch access the bot recorded in DynamoDB.

### On-call rotation

The on-call system manages a weekly rotation for `@core-team` members. All
Expand Down Expand Up @@ -140,8 +149,11 @@ metadata is in YAML files. `db/hackathons.py` no longer exists.
### Seqera key patterns

- `PK=SEQERA#<workspace-id> SK=USER#<slack-user-id>` — a workspace participant
the bot added (GitHub username, email used, Seqera participant ID). Read by
the weekly removal sync in `scheduler/seqera_jobs.py`.
the bot added (GitHub username, email used, Seqera participant ID, group
name). Read by `/nf-core seqera` and the weekly removal sync in
`scheduler/seqera_jobs.py`.
- `PK=SEQERA#TEAM#<team-id> SK=USER#<slack-user-id>` — the same for an
organisation team (`participant_id` holds the team member ID).

### On-call key patterns

Expand Down
59 changes: 54 additions & 5 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -531,15 +531,64 @@ of every open advisory (`triage`, `draft`, or `published` — excludes
ephemerally, so anyone there can see the result. Falls back to DMing you if the
bot can't post where the command was run (e.g. a channel it isn't a member of).

## Seqera Platform Commands

These commands manage access to Seqera Platform by named group. All require
`@core-team` Slack user group membership. Replies are ephemeral.

Groups are defined in code: `megatests` (the `nf-core/megatests` workspace with
the read-only role, configured as described in
[Deployment](deployment.md#seqera-megatests-workspace-access)) plus any entries
in `SEQERA_GROUPS` in `src/nf_core_bot/checks/seqera.py`. A group targets either
a workspace (with a role) or an organisation team.

### `seqera help`

```
/nf-core seqera help
```

Show Seqera command help.

### `seqera add`

```
/nf-core seqera add @user <group> [--email foo@bar.com]
```

Add a Slack user to a group. Uses their Slack email unless `--email` gives their
Seqera Platform email. The user needs a GitHub username on their Slack profile,
so the weekly removal sync can check they are still in the nf-core GitHub org.
Each add is recorded in DynamoDB.

### `seqera remove`

```
/nf-core seqera remove @user <group>
```

Remove a Slack user from a group. Only works for access the bot recorded; remove
anything granted by hand in Seqera Platform.

### `seqera list`

```
/nf-core seqera list
/nf-core seqera list @user
```

With no argument, lists the groups and how many members the bot added to each.
With a user, lists the groups the bot added them to and the email used.

---

## Permission Model

| Level | Who | Access |
| ------------------ | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| **User** | Everyone | `/hackathon list`, `/hackathon register/edit/cancel`, `/hackathon sites` |
| **Site organiser** | Per-hackathon, per-site (stored in DynamoDB) | `/hackathon export` |
| **Admin** | `@core-team` Slack user group members | All commands including `/hackathon admin *`, `/nf-core github *`, `/nf-core on-call *`, `/nf-core security *` |
| Level | Who | Access |
| ------------------ | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **User** | Everyone | `/hackathon list`, `/hackathon register/edit/cancel`, `/hackathon sites` |
| **Site organiser** | Per-hackathon, per-site (stored in DynamoDB) | `/hackathon export` |
| **Admin** | `@core-team` Slack user group members | All commands including `/hackathon admin *`, `/nf-core github *`, `/nf-core on-call *`, `/nf-core security *`, `/nf-core seqera *` |

Admin membership is checked via `usergroups.users.list` and cached for 5
minutes.
17 changes: 12 additions & 5 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,20 @@ any question whose text mentions "Platform" or "Seqera" and "email", and uses
the first email address in the answer. This is configured in Slack, not in this
repo.

**Other groups.** `/nf-core seqera add|remove|list` manages access for
`megatests` and any other group listed in `SEQERA_GROUPS` in
`src/nf_core_bot/checks/seqera.py` (a workspace ID and role, or an organisation
team ID). Adding a group is a code change; only the token and org ID live in
SSM. The token needs permission to add and remove members of every group's
workspace or team. See [Commands](commands.md#seqera-platform-commands).

**Weekly removal sync.** Every Monday at 09:00 UTC the bot checks each recorded
participant against the nf-core GitHub org
member of every group against the nf-core GitHub org
(`GET /orgs/nf-core/memberships/{username}`). Anyone with neither an active
membership nor a pending invitation is removed from the megatests workspace and
their record is deleted. Only people the bot recorded are touched, and only in
the configured workspace. GitHub or Seqera errors for a person are logged and
that person is skipped until the next run.
membership nor a pending invitation is removed from that group and their record
is deleted. Only people the bot recorded are touched, and only in the configured
groups. GitHub or Seqera errors for a person are logged and that person is
skipped until the next run.

**Dry run.** `SEQERA_REMOVAL_DRY_RUN` (plain environment variable in
`infra/stacks/bot_stack.py`, default `true`) makes the removal sync log
Expand Down
Loading