Field notes
Channel-specific soul mandate & approvers
Date: 2026-06-20
Status: shipped on feat/channel-soul-overrides
What#
SOUL.md previously parsed into a single global SoulData; mandate and
approvers were workspace-wide. Agents living in multiple Slack channels now get
per-channel mandate and approvers, authored in the soul and resolved at
runtime by the active channel.
Mechanism#
- Authoring: a repeatable
## Channel <#Cxxx|name>H2 block with nested### Mandateand### Approverssubsections. Either subsection may be omitted (falls back to global). - Schema:
ChannelOverrideSchema({ channel, mandate?, approvers[] }) added toSoulData.channelOverrides. The extraction prompt emits it; the grounding check (assertIdsGroundedInPersona) now also grounds channel ids and per-channel approver ids so the LLM can't invent allowlist entries. - Resolution:
effectiveSoulForChannel(channelId)starts fromsoulData()(runtime overlays preserved) and, on a channel match, replaces mandate (when set) and replaces approvers (when ≥1). No match / no channel / any failure → global view, so gates never break. - Mandate injection:
manager.ts#startSessionappends a<channel-mandate>directive aftersoulSystemBlock()when the channel mandate differs from the global. The global mandate stays inside the unedited<persona>text, so "replace" is realised by a higher-priority instruction rather than rewriting the persona. - Approver consumption:
approval-gate#resolveApprovers(req)useseffectiveSoulForChannel(req.channel); admin-auth (isManagerOrApprover,/model) resolves per-channel where a channel id is in scope.
Key decision: manager is never locked out#
Replace semantics could strip a global catchall approver from the approval gate
inside an overridden channel. Per operator decision, withManagerApprover
always injects the manager and backup as catchall approvers into the
resolved channel approver set (unless already present). A channel block can
therefore only add approvers, never remove the operator. manager/backup admin
authority was already a separate check and is unaffected.
Limitations#
- Regex fallback (LLM extraction unavailable) yields global approvers only, no channel overrides — consistent with the other LLM-only soul fields.
- Out of scope (YAGNI): per-channel trust level, redact patterns, approval timeout, blocked/dm users. Schema is extensible if wanted later.
Spec: docs/superpowers/specs/2026-06-20-channel-soul-overrides-design.md.