Skip to content

Run open_mess as a server next to Paperclip (stage 1) - #14

Merged
SychPL merged 6 commits into
mainfrom
feat/paperclip-plugin
Nov 5, 2026
Merged

SychPL merged 6 commits into
mainfrom
feat/paperclip-plugin

Conversation

@SychPL

@SychPL SychPL commented Nov 5, 2026

Copy link
Copy Markdown
Owner

Change

Stage 1 of open_mess as a Paperclip plugin. The owner runs Paperclip (agent orchestration) on a server and wants open_mess as one of its connectors, without Paperclip reaching the owner's computer. So the daemon has to run on that server, in its own container next to Paperclip, where there is no Credential Manager, no window and no toasts.

Outside Windows the daemon now:

  • keeps its secrets in secrets.json in the data folder (FileStore: mode 0600, folder 0700, whole-file atomic writes with fsync of file and folder, one in-process lock, 1 MiB cap); the CLI installs the same store and only reads it;
  • listens on every interface of its container with OPEN_MESS_LISTEN=0.0.0.0 (the only accepted value, so the CLI's 127.0.0.1 always reaches it);
  • generates an administrative token beside the agents' token; om server-tokens prints both for the owner to put into Paperclip's secrets;
  • stops on SIGTERM the way it stops on Ctrl+C (docker stop);
  • serves the configuration window's commands as POST /admin/{command} behind the administrative token: modules, accounts, permissions, waiting actions and sign-in. Each token opens only its own routes; without the administrative API (Windows) every /admin/ path is 404;
  • signs in without a window: sign_in_start returns at once and sign_in_result reports the outcome; the user opens open_url in a browser and pastes the address the sign-in ended on, which must be HTTPS under the module's redirect prefix.

On every platform, a sign-in page off the module's approved sign-in hosts is now refused before any front end shows it (the same technical refusal the window gives today, only earlier). The send description no longer names only a Windows notification. Windows otherwise keeps its behaviour.

Stages 2-4 (Teams sign-in without WAM, the TypeScript plugin, the container deployment) come in later PRs with their own specs.

Spec

.specs/2026-11-03-paperclip-plugin.md, reviewed by Codex and GLM: round 6, both APPROVE (rounds 1-5 REJECT; every fix is in the spec's round changelog, rebuttal register empty). The design spec gets one pointer each in 8.1, 8.4 and 8.6.

The headless sign-in rests on a live probe with the owner present (spec 9.5): auth code + PKCE with the Teams desktop client id and the nativeclient redirect, signed in in the owner's browser, the code redeemed and refreshed from the server. The tenant accepted it; only statuses and claim names were recorded, nothing was stored.

Tests

  • tests/file_store.rs: set, read, delete; a second store sees the secrets; a damaged file fails and stays untouched; a write over the limit changes nothing; concurrent writes lose nothing; the module host uses the installed store; file and folder modes (Unix).
  • tests/admin.rs: each token opens only its own routes; unknown commands 404, bad arguments 400; no administrative API means 404; a sign-in starts at once, a second one is refused, a wrong pasted address is refused while the prompt stays, the right one (outside Windows) finishes the sign-in.
  • tests/server.rs (Unix only): the daemon starts on 0.0.0.0 with secrets in the data folder, two different 64-hex tokens, om server-tokens before and after the first start, the CLI reaches it with the token from the file, SIGTERM exits 0, tokens survive a restart.
  • tests/sign_in.rs: a page off the approved hosts never shows and the module gets the refusal; open_url carries the whole address.
  • Unit tests: listen_ip, check_pasted, the administrative token in secrets.rs.

cargo xtask ci on Windows: green (fmt, clippy -D warnings, all tests, module build). The Unix-only tests and the pasted-address path run for the first time in this PR's Linux CI; that is why it is pushed now.

Commit reviews

  • e58c626 (spec): Codex APPROVE, GLM APPROVE. GLM P3 rejected: the changelog keeps R1's wording as history, R4 records the move to stdout.
  • 9ac36ca (server mode): Codex APPROVE. GLM P1: two older tests asserted that a sign-in page can only be cancelled, which no longer holds outside Windows and would fail on Linux. Fixed in 148ee31.
  • 148ee31 (test fix): Codex APPROVE, GLM APPROVE.

All three have .reviews/<sha>.processed.

Coexistence (platform modules only)

No platform module changes; nothing here talks to Teams. The live probe only listed one conversation-list entry from the server and marked nothing as read.

Checklist

  • No secrets, tokens or real message contents in code, fixtures, logs or this PR
  • No unwrap / expect / panic! / unchecked indexing in non-test code
  • New tool available over both MCP and the CLI (no new tool: the administrative API carries window commands, not registry tools)
  • New dependencies named here, with their licence and why (none)

The owner wants open_mess as a connector inside Paperclip, which runs on
a server, without Paperclip reaching the owner's computer. The spec puts
the daemon in its own container next to Paperclip, adds a Linux server
mode (file secret store, listen address, generated agent and admin
tokens, an admin API, headless sign-in by pasting the redirect address),
and stages the Teams sign-in without WAM, the plugin and the deployment.
A live probe confirmed that the tenant accepts the auth code flow with
the code redeemed from the server. Reviewed by Codex and GLM, round 6.
Stage 1 of the Paperclip plugin spec: open_mess must run on the server
beside Paperclip, which has no Credential Manager, no window and no
toasts. Outside Windows the daemon now keeps its secrets in
secrets.json in the data folder (mode 0600, atomic writes), can listen
on every interface of its container with OPEN_MESS_LISTEN=0.0.0.0,
generates an administrative token beside the agents' token, prints both
with `om server-tokens`, and stops cleanly on SIGTERM.

The window's commands are served as /admin/{command} behind that token,
for the plugin's page: modules, accounts, permissions, waiting actions
and sign-in. A sign-in starts at once and reports its result later; the
user pastes the address the browser ended on, which must be HTTPS under
the module's redirect prefix. A sign-in page off the module's approved
hosts is now refused before any front end shows it, on every platform.
Windows keeps its behaviour.
Two older tests asserted that a sign-in page can only be cancelled from
the window. That still holds on Windows, but outside Windows the
administrative API now accepts the address the sign-in ended on, so the
tests would fail on Linux CI (GLM review of 9ac36ca). They now answer
with an address off the redirect prefix, refused on every platform, and
check the Windows-only refusal where it applies.
# Conflicts:
#	crates/open-mess/src/daemon.rs
Clippy on Linux CI refused `file["open_mess"][user]` in a helper of
tests/server.rs: helpers outside #[test] functions don't get clippy.toml's
test allowances. The file is Unix-only, so Windows never compiled it.
@SychPL
SychPL merged commit 8ccf895 into main Nov 5, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant