SemiLayerDocs

Channel scope — /semilayer here

When you run /semilayer search, similar, query, feed, or status in a chat channel, the bot has to figure out which org, project, environment, and lens you mean. Typing --org=acme --project=docs --env=prod --lens=help_articles every time would be a slog. ChatOps resolves missing scope from four layers, in priority order:

PrioritySourceSet by
1Explicit flags on the commandThe invoker, ad-hoc
2Channel-pinned scope (/semilayer here)Org admin, once per channel
3User defaults (/semilayer config set)Each linked user, per workspace
4Inferred fallback (single-org membership)Implicit

The first layer that supplies a value wins. Layers can be partial: a channel can pin only org, leaving project to come from your personal defaults; you can override the channel's lens with a single --lens= flag.

Why pin a channel?

Most chat usage clusters around one product surface per channel. #support cares about acme/docs/prod/help_articles. #growth cares about acme/marketing/prod/landing_pages. Pinning the scope once means anyone in the channel can run a flag-less command and get the right answer.

# Org admin in #support runs once:
/semilayer here set org=acme project=docs env=prod lens=help_articles

# Now every linked member in #support can:
/semilayer search refund policy

# …and the bot resolves to acme/docs/prod/help_articles
# without anyone typing flags.

Inspecting the chain — /semilayer here

Bare /semilayer here shows you the resolved chain for the current channel + your personal defaults. The winning value is bold:

Resolved scope for *#support* (channel scope is pinned):

• `org` — channel: *acme* · you: acme
• `project` — channel: *docs* · you: _(unset)_
• `env` — channel: *prod* · you: _(unset)_
• `lens` — channel: *help_articles* · you: _(unset)_

_Channel scope last set 2026-05-02 14:30 UTC._

If no channel scope is pinned, the layout switches to "no channel scope pinned" and your personal defaults appear bolded instead. Org admins also see a one-line hint about how to pin or clear.

Pinning — /semilayer here set … (admin-only)

Owner or admin role on the org bound to the workspace. Inline key=value tokens or --key=value flags both work:

# Inline tokens:
/semilayer here set org=acme project=docs env=prod lens=help_articles

# Or flags:
/semilayer here set --org=acme --lens=help_articles

# Updating one field while keeping the others:
/semilayer here set lens=overview
# (preserves the existing org/project/env)

You can pin partial scope. Pinning only org=acme is fine — users still need to fill in project/env/lens via flags, defaults, or their own /semilayer config set.

Clearing — /semilayer here clear (admin-only)

Removes the channel pin. Subsequent commands fall through to the user-defaults + inference layers:

/semilayer here clear
→ Channel scope cleared for *#support*.

If the channel had no pin, the bot says so instead of silently no-opping.

Personal defaults — /semilayer config set

Identical shape, but writes to your chat_user_links row instead of the channel:

/semilayer config set org=acme project=docs env=prod lens=help_articles
/semilayer config show
/semilayer config clear

Personal defaults are per-workspace. Linking the same SemiLayer account into a Slack workspace and a Discord guild gives you two independent default sets — useful when you use one chat for staging work and the other for production.

Inferred fallback

If no flag, channel pin, or personal default fills a slot, the bot tries to infer:

  • Org is inferred when the user belongs to exactly one org (the unambiguous case). Multi-org members must specify an org by flag / pin / default.
  • Project, env, lens are never inferred — too many ambiguities.

When any field is inferred, the bot appends a one-line annotation to the result so you know:

_(I picked **acme/docs/prod/help_articles** because lens wasn't
pinned — set defaults with `/semilayer config set …` or pin the
channel with `/semilayer here set …`.)_

That annotation is the bot's way of inviting you to make the implicit choice explicit, without nagging on every command.

Worked examples

Single-team workspace, mostly one project

# Org admin pins the workspace's main org once, in #general.
/semilayer here set org=acme project=docs env=prod

# Anyone in #general can now:
/semilayer search refund policy --lens=help_articles
# (only --lens is missing from the channel pin)

# A power user sets their personal default to make even that
# implicit:
/semilayer config set lens=help_articles

# Now their flag-less commands Just Work in #general.

Multi-team workspace, one channel per surface

# Each team's channel pinned to its own scope:
#docs       → /semilayer here set org=acme project=docs env=prod lens=help_articles
#marketing  → /semilayer here set org=acme project=marketing env=prod lens=landing_pages
#support    → /semilayer here set org=acme project=support env=prod lens=tickets

# Members run commands without thinking about scope:
#docs:      /semilayer search rate limits
#marketing: /semilayer search hero copy
#support:   /semilayer search refund

FAQ

Can I pin different scopes in different channels? Yes — chat_channel_scopes rows are per-(workspace, channel). Each channel is independent.

What if a developer disagrees with the channel pin? A flag always wins. Run with --lens=other_lens for that one command. Set personal defaults with /semilayer config set if you want a persistent override (your defaults override the channel pin only on layers your defaults set — the channel pin still wins on layers you leave unset). To overrule the channel pin entirely on every command, ask an admin to clear it.

What happens if a project is renamed after I pinned its slug? The next command will surface a clean error from the platform service ("project not found") rather than silently rewriting the pin. Re-pin with the new slug.

Are pins audit-logged? Workspace install + revoke are audit-logged today. Channel-scope sets and clears are part of the upcoming Phase 5 admin surface.