com um clique
com um clique
Manage Slack channel access control — pairing, allowlist, channel opt-in
Configure Slack channel tokens (bot token + app-level token)
CCSC lifecycle command center — fresh install walkthrough, health doctor, verify round-trip, auto-repair, Slack app manifest export, reset, tour, and uninstall. One skill for the full install lifecycle.
| name | policy |
| description | Author MCP tool-call policy rules without hand-editing access.json |
| version | 1.0.0 |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| license | Apache-2.0 |
| user-invocable | true |
| argument-hint | list | lint | add <id> <effect> <json-match> [--reason "..."] [--ttl-ms N] [--approvers N] [--priority N] | remove <id> |
| allowed-tools | ["Read","Write","Edit","Bash(cmd:bun)","Bash(cmd:chmod)"] |
Author, lint, and remove policy rules under access.json's top-level policy field.
The evaluator (evaluate() in policy.ts) is the veto layer for every MCP tool
call — this skill is the ergonomic front door to authoring rules without opening
access.json in a text editor.
See ACCESS.md §Policy schema for the full
rule shape and semantics. This skill does not replace the hand-edit path; it
complements it.
/slack-channel:policy list
/slack-channel:policy lint
/slack-channel:policy add <id> <effect> <json-match> [--reason "..."] [--ttl-ms N] [--approvers N] [--priority N]
/slack-channel:policy remove <id>
Effect is one of auto_approve, deny, require_approval.
json-match is a JSON object literal for the match field — e.g.
'{"tool":"read_file","pathPrefix":"/workspace/docs"}'. At least one field
must be populated; the validator rejects empty matches.
| Effect | Required | Optional |
|---|---|---|
auto_approve | — | --priority |
deny | --reason "…" (1-200) | --priority |
require_approval | — | --ttl-ms, --approvers, --priority |
Defaults: priority=100, ttl-ms=300000 (5 min), approvers=1.
~/.claude/channels/slack/access.json — the policy field is a JSON array.
A missing or empty array means "no authored rules" and is valid.
Parse $ARGUMENTS and execute the matching subcommand. Before every write, run
the validator script. Exit cleanly without writing if validation fails.
list~/.claude/channels/slack/access.jsonpolicy field is missing or empty, print No policy rules authored. Evaluator applies defaults — see ACCESS.md §Default-branch behavior. and return.id | effect | match summary | extras.
tool=read_file pathPrefix=/workspace (omit undefined fields).deny show reason=…; for require_approval show ttlMs=… approvers=….lintbun scripts/policy-validate.ts ~/.claude/channels/slack/access.jsonok: false, show the error message verbatim.ok: true:
count rules loaded.SHADOW: rule '<later>' is shadowed by '<earlier>'.FOOTGUN: <message>.Clean: no shadow or footgun warnings.add <id> <effect> <json-match> [opts]<effect> is one of auto_approve, deny, require_approval; otherwise stop with a usage error.<json-match> as JSON. If invalid, stop with Invalid json-match: <parser error>.deny without --reason ⇒ stop with deny rule requires --reason.access.json. Initialize policy: [] if the field is missing.id, stop with Rule '<id>' already exists — use 'remove <id>' first, or pick a new id.{ "id": "<id>", "effect": "<effect>", "match": <json-match>, "priority": <priority>, ... }
policy[].~/.claude/channels/slack/access.json.tmp, then rename to access.json (atomic) and chmod 0o600.bun scripts/policy-validate.ts ~/.claude/channels/slack/access.json. If validation fails, roll back by removing the appended rule and re-writing atomically. Report the error to the operator.Added rule '<id>' (<effect>). Restart the server for the change to take effect:
- Stop the running server (Ctrl-C in the terminal where it runs, or kill the PID)
- Start it again: `bun server.ts`
Hot reload is intentionally not supported — see ACCESS.md §"Where policies live".WARNING: lines but do not roll back. Warnings are informational, not failures.remove <id>access.json.id, stop with No rule with id '<id>' found.policy array.bun scripts/policy-validate.ts ~/.claude/channels/slack/access.json to confirm the remaining set is still valid (belt-and-suspenders — editing the file by hand could have introduced pre-existing issues).Removed rule '<id>'. Restart the server for the change to take effect./slack-channel:policy,
but authoring policy rules is an operator action, not a user action.access.json.tmp, then rename. Never truncate-and-write
in place — a crash mid-write would leave the operator with a half-written policy.add or
remove is only effective after restart. Print this in every success message.parsePolicyRules() +
detectShadowing() + detectBroadAutoApprove() from policy.ts — the same
functions the server uses at boot. A rule that parses clean here will load clean.# Allow claude-process reads under the workspace docs root
/slack-channel:policy add safe-reads auto_approve '{"tool":"read_file","pathPrefix":"/workspace/docs"}'
# Deny shell execution in this channel
/slack-channel:policy add no-shell deny '{"tool":"run_shell"}' --reason "Shell execution is not permitted from this channel."
# Two-person quorum for file uploads
/slack-channel:policy add upload-quorum require_approval '{"tool":"upload_file"}' --approvers 2 --ttl-ms 600000
# Lint — check shadows + footguns before you forget
/slack-channel:policy lint
# Remove
/slack-channel:policy remove safe-reads