Package the channel as a plugin, so it stops needing the development flag #105

Open
opened 2026-08-25 01:38:44 +00:00 by jlxq0 · 0 comments
Owner

Julian, 2026-08-25: "Do 1: package."

The problem it solves, which is not cosmetic

server: channel entries always require --dangerously-load-development-channels. That is not a preview restriction with an allowlist path — the CLI's own message is unambiguous:

server: entries need --dangerously-load-development-channels

The flag shows a full-screen confirmation at startup and waits for Enter. Under launchd nobody presses Enter, so every agent that starts unattended hangs at that dialog.

There is a keeper answering it today by scraping the pane for "I am using this for local development" and sending Enter. It works and it is committed. It is also screen-scraping a confirmation dialog, so it breaks silently the next time the wording changes — and the failure mode is every agent in the fleet failing to start.

What I verified, and the part that is not settled

Read out of the CLI binary at 2.1.243 rather than from the README:

  • server: entries need --dangerously-load-development-channels — confirmed. There is no allowlist path for a server: entry at all, so packaging is necessary.
  • … is not plugin-sourced; channel_enable requires a marketplace plugin — a channel must come from a marketplace plugin.
  • … is not on the approved channels allowlist (use --dangerously-load-development-channels for local dev) — and a plugin still has to be on an approved allowlist.

So packaging is necessary and may not be sufficient. README.md:80 already says so in as many words: "--channels accepts only plugins on an Anthropic-maintained allowlist, and a private marketplace does not qualify, so any self-hosted channel uses the development flag permanently."

If that is still true, packaging changes the entry from server:matrix to plugin:matrix@<marketplace> and the flag stays — the keeper stays with it, and the win is smaller than it looks. If it has changed since that sentence was written, the flag and the keeper both go.

There is a second source, and it is not Anthropic's. The allowlist the check runs against comes from

K(e) => if (e) return {entries: e, source: "org"}; return {entries: P(), source: "ledger"}

so a managed-settings allowedChannels replaces the built-in ledger rather than appending to it. "A private marketplace does not qualify" is a claim about P(), and P() is not the only source — an org entry is a real path to running our own plugin under plain --channels.

The experiment cannot hang. The confirmation dialog is gated on the development list being non-empty, so a plain --channels invocation never reaches that branch: it either registers the channel or skips it and prints the reason. Worst case is "not on the approved channels allowlist" in a throwaway session, thirty seconds, no dialog.

The trap, before anybody edits managed settings

isChannelsPolicyBlocked reduces to: with no managed-settings file, e === null and channels are not blocked. That is the state today — there is no /Library/Application Support/ClaudeCode/managed-settings.json on this machine, verified.

Creating that file without channelsEnabled: true turns every channel on the machine off, and the CLI's own remedy string is "have an administrator set channelsEnabled: true in managed settings". So somebody adding allowedChannels to approve our plugin, without knowing about the sibling key, kills the fleet's entire Matrix path in the act of trying to fix it — and the symptom is inbound messages quietly not arriving, which is the hardest failure in this system to notice.

Do it in a staging config first, the way config/install.sh <dir> already forces for the rest of the fleet's settings.

Done when

claude --channels plugin:matrix@<marketplace> starts a session with the channel attached and no confirmation dialog — or this issue records, with the error text, that a self-hosted marketplace cannot reach the allowlist, and the keeper is documented as permanent rather than as a workaround.

Julian, 2026-08-25: *"Do 1: package."* ## The problem it solves, which is not cosmetic `server:` channel entries **always** require `--dangerously-load-development-channels`. That is not a preview restriction with an allowlist path — the CLI's own message is unambiguous: server: entries need --dangerously-load-development-channels The flag shows a full-screen confirmation at startup and **waits for Enter**. Under launchd nobody presses Enter, so every agent that starts unattended hangs at that dialog. There is a keeper answering it today by scraping the pane for *"I am using this for local development"* and sending Enter. It works and it is committed. It is also screen-scraping a confirmation dialog, so it breaks silently the next time the wording changes — and the failure mode is every agent in the fleet failing to start. ## What I verified, and the part that is not settled Read out of the CLI binary at 2.1.243 rather than from the README: - **`server: entries need --dangerously-load-development-channels`** — confirmed. There is no allowlist path for a `server:` entry at all, so packaging is **necessary**. - **`… is not plugin-sourced; channel_enable requires a marketplace plugin`** — a channel must come from a marketplace plugin. - **`… is not on the approved channels allowlist (use --dangerously-load-development-channels for local dev)`** — and a plugin still has to be **on an approved allowlist**. **So packaging is necessary and may not be sufficient.** `README.md:80` already says so in as many words: *"`--channels` accepts only plugins on an Anthropic-maintained allowlist, and a private marketplace does not qualify, so any self-hosted channel uses the development flag permanently."* If that is still true, packaging changes the entry from `server:matrix` to `plugin:matrix@<marketplace>` and the flag stays — the keeper stays with it, and the win is smaller than it looks. If it has changed since that sentence was written, the flag and the keeper both go. **There is a second source, and it is not Anthropic's.** The allowlist the check runs against comes from K(e) => if (e) return {entries: e, source: "org"}; return {entries: P(), source: "ledger"} so a managed-settings `allowedChannels` **replaces** the built-in ledger rather than appending to it. "A private marketplace does not qualify" is a claim about `P()`, and `P()` is not the only source — an org entry is a real path to running our own plugin under plain `--channels`. **The experiment cannot hang.** The confirmation dialog is gated on the *development* list being non-empty, so a plain `--channels` invocation never reaches that branch: it either registers the channel or skips it and prints the reason. Worst case is "not on the approved channels allowlist" in a throwaway session, thirty seconds, no dialog. ## The trap, before anybody edits managed settings `isChannelsPolicyBlocked` reduces to: with no managed-settings file, `e === null` and channels are **not** blocked. That is the state today — there is no `/Library/Application Support/ClaudeCode/managed-settings.json` on this machine, verified. **Creating that file without `channelsEnabled: true` turns every channel on the machine off**, and the CLI's own remedy string is *"have an administrator set `channelsEnabled: true` in managed settings"*. So somebody adding `allowedChannels` to approve our plugin, without knowing about the sibling key, kills the fleet's entire Matrix path in the act of trying to fix it — and the symptom is inbound messages quietly not arriving, which is the hardest failure in this system to notice. **Do it in a staging config first**, the way `config/install.sh <dir>` already forces for the rest of the fleet's settings. ## Done when `claude --channels plugin:matrix@<marketplace>` starts a session with the channel attached and **no confirmation dialog** — or this issue records, with the error text, that a self-hosted marketplace cannot reach the allowlist, and the keeper is documented as permanent rather than as a workaround.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jlxq0/matrix-mcp#105
No description provided.