Skip to content

feat: one service with TRI CLAW -- export tools and call, admit through service.wasm, retire the tg_* forwarders - #26

Open
gHashTag wants to merge 1 commit into
masterfrom
t27mcp/one-service
Open

gHashTag wants to merge 1 commit into
masterfrom
t27mcp/one-service

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Step 2 of the one-service plan (gHashTag/t27#10483; the rule is specs/t27mcp/service.t27, gHashTag/t27#10484).

What changes

  • The rule runs as wasm. service.t27 is built by the C route into wasm/service.wasm, with its constants in wasm/service_table.mjs. service.mjs only writes a name into the instance's memory. It exports:
    • admit, homeOf, localServes and t27Visible;
    • the table: homes, admit answers, scopes and CODER_TOOLS.
  • The tg_ forwarders retire.* server.mjs keeps only the tools local_serves() accepts, which are the t27_ and t27f_ names. The seven tg_* forwarders, telegram.mjs, wasm/telegram.wasm and wasm/telegram_table.mjs are removed. The same Telegram tools already answer at TRI CLAW's /mcp, which holds the session.
  • A library for TRI CLAW. server.mjs exports tools and call(name, args) so TRI CLAW can mount the t27 tools into its own /mcp (step 3, next PR in gHashTag/999-multibots-telegraf).
    • Imported, the file starts no stdio loop, no health port and no watcher.
    • Run as a program, nothing changes.
  • Packaging. package.json moves to 1.2.0, with exports for . and ./service and an updated files list.
  • Docs.
    • README: a new one-service section with the library imports; the VIBEE_AGENT_KEY and T27_TG_APP rows are removed.
    • wasm/BUILD: a service section with rebuild commands and hashes replaces the telegram section.

Checked on the Railway lab (node 18.20.4, clone of this branch at db98153)

  • Build. service.t27 passes 9 of 9 tests with 0 vacuous; t27c 0.5.2, zig 0.16.0.
  • Hashes. service.wasm e1807a3b…, service_table.mjs e371cfea…, both matching wasm/BUILD.
  • The server run as a program, with JSON-RPC sent over stdin:
    • initialize reports 1.2.0.
    • tools/list returns the 19 t27 tools and 0 tg_* tools.
    • t27_check answers ok: true.
    • tg_dialogs answers Unknown tool.
  • Imported as a library.
    • node --import ./server.mjs /dev/null exits in 165 ms, and ./service.mjs in 113 ms, both with stdin left open.
    • Control: node server.mjs with the same open stdin is still running when the 5 s timeout kills it.
  • Smoke. npm run smoke: all checks passed.

Policy

This edits hand-written JavaScript (server.mjs, the new service.mjs glue), so it needs the owner's owner-approved-foreign label. The logic lives in service.t27; the JS only moves bytes.

🤖 Generated with Claude Code

…gh service.wasm, retire the tg_* forwarders

specs/t27mcp/service.t27 (gHashTag/t27#10484, issue #10483) decides which home owns a tool name, what the
one registry admits and who sees the mounted t27 tools. It is built by the C route into wasm/service.wasm
with its constants in wasm/service_table.mjs; service.mjs only writes a name into the instance's memory.

- server.mjs keeps the tools local_serves() accepts (the t27_ and t27f_ names). The seven tg_* forwarders
  and telegram.mjs / telegram.wasm / telegram_table.mjs are gone: the same tools answer at TRI CLAW's /mcp.
- server.mjs exports `tools` and `call(name, args)`, so TRI CLAW can mount the t27 tools into its /mcp.
  Imported as a library it starts no stdio loop, health port or watcher; run as a program it is unchanged.
- package.json: version 1.2.0, `exports` for `.` and `./service`, files list updated.
- README: the one-service section and the library imports; the VIBEE_AGENT_KEY and T27_TG_APP rows are gone.
- wasm/BUILD: the service section with rebuild commands and hashes replaces the telegram section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tri-claw

tri-claw Bot commented Oct 18, 2026

Copy link
Copy Markdown

Summary by t27-bees

This PR migrates the server to a "one service with TRI CLAW" architecture: the new service.t27 WASM module (service.wasm + service_table.mjs) replaces the retired telegram.t27 forwarders, deciding which home owns a tool name and what the registry admits. The tg_* tools are removed from this server (they now live only at TRI CLAW's /mcp), while server.mjs exports tools and call() so TRI CLAW can mount the t27_/t27f_ tools. The server also gains a dual mode: imported as a library it starts no stdio loop, health port, or watcher; run as a program it behaves as before.

Worth a look

  • service.mjs:17–24 — The put() function writes every name into the same WASM memory region (base). All exported functions (admit, homeOf, localServes, t27Visible) call put() sequentially. Since WASM calls are synchronous and JS is single-threaded this is safe for sequential use, but if TRI CLAW ever calls these concurrently (e.g., via worker threads or async wrappers that yield), the shared buffer will be overwritten mid-call.
  • server.mjs:794–804 — The main detection uses realpathSync(process.argv[1]) compared to import.meta.url. If the entry point is a symlink, realpathSync resolves it while import.meta.url is the real path, so they match. However, if the module is loaded via --import or a custom loader that changes import.meta.url, the detection could misfire, incorrectly enabling/disabling the stdio loop, health endpoint, or watcher.
  • server.mjs:747–748 — tools is filtered at module load by localServes(t.name), which depends on service.mjs having fully instantiated its WASM. The import order (import { localServes } from './service.mjs' at line 29) ensures this, but any future circular dependency or top-level await change in service.mjs could leave localServes unready when the filter runs.
  • package.json:8–9 — exports maps "." to server.mjs and "./service" to service.mjs. TRI CLAW imports tools/call from 't27-mcp' (i.e., server.mjs) and admit/t27Visible/etc. from 't27-mcp/service'. This splits the public API across two entry points; if a consumer imports tools from 't27-mcp/service' they'll get nothing (it's not exported there), which is easy to misuse.
  • wasm/service_table.mjs:37–38 — CODER_TOOLS = ["t27_check", "t27_find", "t27_spec", "t27_examples"] lists the coder persona's tools. The localServes WASM function (used by server.mjs to filter tools) must align with this list and the T27_PREFIXES (t27_, t27f_). A mismatch between the spec's local_serves logic and this table would silently admit or drop tools.

Read: 10 files, +148 -157, the whole diff. Head db98153. Model: openai-compatible/nvidia/nemotron-3-ultra-550b-a55b. Commands: @t27-bees review | summary | help | pause | resume. Free for every repository.

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