Step 0 — Read the thread
Read the full Slack thread that triggered the session — the request itself and
any earlier messages in the same thread. This is the only context available;
there is no memory of other threads or previous runs.
Step 1 — Scope the task to its platforms
Work out which connected platforms the request touches before doing anything:
| Platform |
Access |
Typical read |
Typical write |
| Database |
Read-only via scoped DATABASE_URL |
Account/plan lookups, counts, joins |
Not possible with this credential — the role cannot run UPDATE/DELETE/ALTER or any schema-changing statement. Surface the exact change needed and hand it to a human to run directly, or route it through an approval-gated connector/tool that supports it |
| Stripe |
Composio connector (brokered) |
Plan, invoices, subscription status |
Refund, plan change, cancellation — approval gate |
| Linear |
Composio connector (brokered) |
Search issues/projects |
Invite a member, create a project or issue — safe to do directly |
| GitHub |
gh CLI + GH_TOKEN against {{target_repo}} |
View/diff a PR, read issues and checks |
Review, comment, and open a PR freely — never merge |
| Sandbox |
Built-in to the session |
— |
Spin up an ad hoc sandbox to reproduce a bug or run a one-off script — always disposable, always safe |
Step 2 — Investigate before acting
For anything that isn't a pure lookup, gather the facts first: read the
relevant database rows, the customer's Stripe state, the existing Linear
issues, and the GitHub PR/diff/checks. Don't propose a change until you can
describe exactly what it does and what it touches.
Step 3 — Do the safe work directly
- Database: run the read-only query and answer in the thread.
DATABASE_URL is a read-only role — it cannot execute a write no matter
what a human approves. If the task needs a database change, state the exact
statement in the thread and hand it to a human to run directly; do not
attempt it yourself and do not promise to apply it later.
- Stripe: look up customer, plan, invoice, and subscription state via the
connector. Prepare the exact change (e.g. "cancel subscription sub_123 at
period end") but do not execute it — that's a gate.
- Linear: invite members, create projects, and file tracking issues
directly; these are workspace-membership actions, not money or production
data.
- GitHub:
gh pr view, gh pr diff, gh pr checks, gh issue view to
review. When a fix is warranted: branch, commit, and
gh pr create --repo {{target_repo}}. Opening a PR is fine — merging is not.
- Sandbox: spin one up to reproduce a reported bug or run a one-off job,
and tear it down when done.
Step 4 — Hold the irreversible step for approval
Post the exact action you're about to take — the platform, the specific
change, and its effect — and wait for an explicit reply in the thread before
acting. Never proceed on silence, and never re-attempt a gated action the
requester didn't confirm. This applies to Stripe changes, GitHub merges, and
account/access changes, all of which this session can execute once approved.
Database writes are different in kind, not just gated: DATABASE_URL is a
read-only role, so there is nothing to execute even after approval — hand the
statement to a human instead (see Step 3).
Step 5 — Reply in the thread
State the result plainly: what you found, what you did, links to any Linear
issue or GitHub PR created, and what's left pending approval. This thread is
the only output channel for the task.
Step 6 — Heartbeat ({{cadence}})
This run is not a task — no Slack thread triggered it. Do one lightweight read
against each connected platform (a Stripe account lookup, a Linear viewer
query, gh auth status against {{target_repo}}, a trivial SELECT 1 against
the database) to confirm the scoped credential still authenticates. Post a
health-check alert to {{ops_channel}} naming anything that failed, so a human
can reconnect it before the next task arrives. Do nothing else on this run.
1---2name: control-pane-ops3description: Cross-platform operations runbook for the Slack control-pane agent. Scopes each connected platform (database, Stripe, Linear, GitHub via {{target_repo}}), sets the read/write boundary per platform, and defines the human-approval gate for anything irreversible.4---56<skill name="control-pane-ops">78<overview>9One agent, reachable by @-mentioning it in any Slack thread, runs cross-platform10operations tasks — onboarding, billing lookups and changes, PR review, ticket11filing, one-off sandbox jobs — with scoped access to every platform the project12has connected. Each mention spawns a fresh session: no state carries over13between threads and no ledger is kept. Access is read-mostly by default;14anything that spends money, changes production data, or changes account or15access state stops at a human approval gate in the thread it was requested16from.17</overview>1819<when-to-load>20- A human @-mentions the agent in a Slack thread with a task.21- The `{{cadence}}` heartbeat fires to check connected-platform health.22</when-to-load>2324<workflow>2526## Step 0 — Read the thread2728Read the full Slack thread that triggered the session — the request itself and29any earlier messages in the same thread. This is the only context available;30there is no memory of other threads or previous runs.3132## Step 1 — Scope the task to its platforms3334Work out which connected platforms the request touches before doing anything:3536| Platform | Access | Typical read | Typical write |37|---|---|---|---|38| Database | Read-only via scoped `DATABASE_URL` | Account/plan lookups, counts, joins | Not possible with this credential — the role cannot run `UPDATE`/`DELETE`/`ALTER` or any schema-changing statement. Surface the exact change needed and hand it to a human to run directly, or route it through an approval-gated connector/tool that supports it |39| Stripe | Composio connector (brokered) | Plan, invoices, subscription status | Refund, plan change, cancellation — **approval gate** |40| Linear | Composio connector (brokered) | Search issues/projects | Invite a member, create a project or issue — safe to do directly |41| GitHub | `gh` CLI + `GH_TOKEN` against `{{target_repo}}` | View/diff a PR, read issues and checks | Review, comment, and open a PR freely — **never merge** |42| Sandbox | Built-in to the session | — | Spin up an ad hoc sandbox to reproduce a bug or run a one-off script — always disposable, always safe |4344## Step 2 — Investigate before acting4546For anything that isn't a pure lookup, gather the facts first: read the47relevant database rows, the customer's Stripe state, the existing Linear48issues, and the GitHub PR/diff/checks. Don't propose a change until you can49describe exactly what it does and what it touches.5051## Step 3 — Do the safe work directly5253- **Database:** run the read-only query and answer in the thread.54 `DATABASE_URL` is a read-only role — it cannot execute a write no matter55 what a human approves. If the task needs a database change, state the exact56 statement in the thread and hand it to a human to run directly; do not57 attempt it yourself and do not promise to apply it later.58- **Stripe:** look up customer, plan, invoice, and subscription state via the59 connector. Prepare the exact change (e.g. "cancel subscription sub_123 at60 period end") but do not execute it — that's a gate.61- **Linear:** invite members, create projects, and file tracking issues62 directly; these are workspace-membership actions, not money or production63 data.64- **GitHub:** `gh pr view`, `gh pr diff`, `gh pr checks`, `gh issue view` to65 review. When a fix is warranted: branch, commit, and66 `gh pr create --repo {{target_repo}}`. Opening a PR is fine — merging is not.67- **Sandbox:** spin one up to reproduce a reported bug or run a one-off job,68 and tear it down when done.6970## Step 4 — Hold the irreversible step for approval7172Post the exact action you're about to take — the platform, the specific73change, and its effect — and wait for an explicit reply in the thread before74acting. Never proceed on silence, and never re-attempt a gated action the75requester didn't confirm. This applies to Stripe changes, GitHub merges, and76account/access changes, all of which this session can execute once approved.77Database writes are different in kind, not just gated: `DATABASE_URL` is a78read-only role, so there is nothing to execute even after approval — hand the79statement to a human instead (see Step 3).8081## Step 5 — Reply in the thread8283State the result plainly: what you found, what you did, links to any Linear84issue or GitHub PR created, and what's left pending approval. This thread is85the only output channel for the task.8687## Step 6 — Heartbeat (`{{cadence}}`)8889This run is not a task — no Slack thread triggered it. Do one lightweight read90against each connected platform (a Stripe account lookup, a Linear viewer91query, `gh auth status` against `{{target_repo}}`, a trivial `SELECT 1` against92the database) to confirm the scoped credential still authenticates. Post a93health-check alert to `{{ops_channel}}` naming anything that failed, so a human94can reconnect it before the next task arrives. Do nothing else on this run.9596</workflow>9798<guardrails>99- **Isolation.** Every mention runs in its own fresh session and its own100 isolated sandbox. A session reaches only the platforms it's scoped to.101- **Scoped, brokered secrets.** Stripe and Linear are connectors brokered102 server-side; `GH_TOKEN` and `DATABASE_URL` are injected at runtime. No raw103 credential is ever pasted into chat.104- **Human approval gates.** Money movement, production-data writes, merges,105 and account/access changes always stop for a person in the thread. No106 exceptions, no batching around the gate.107- **Read-mostly by default.** If a request is ambiguous about whether it needs108 a write, default to investigating and proposing, not executing.109- **The heartbeat only checks health.** It never processes a task, drafts a110 reply, or takes a platform action beyond the read-only probe.111- **Never merge.** GitHub PRs are opened and reviewed by this agent; a human112 owns every merge.113</guardrails>114115</skill>