You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 85fca68
Browse filesBrowse the repository at this point in the historyBrowse files
feat(s071): the Telegram gateway, and two fixes to the gateway core
Slice 071. Every automatic criterion runs against a local fake Bot API.
The live run needs the owner's bot token and is queued with exact steps.
Two security defects in slice 070's core, each reproduced red first:
- F1. Router.prompt_for/1 sent an unknown sender the very pairing code it
was meant to read on /gateways, so anyone who found the bot could pair
by echoing the prompt back. 070's own test asserted the leak. The
prompt now says where the code is, never what it is, restoring
docs/07's rule ("shown on /gateways and nowhere else").
- F2. Approval ids are UUIDv7, so the 8-character short id is shared by
every request raised within about 65 seconds, and /approve <short>
decided whichever came first. Commands.find_pending/1 now refuses an
ambiguous prefix, and buttons carry the full id.
The gateway:
- Bot API calls over Req, already in the lock: telegex has only an old
release candidate and ex_gram keeps its offset in memory, so neither
meets AC5. The token is read on every call and never stored; errors
never carry the URL, which holds it; Req's retry step is off.
- MarkdownV2 conversion that only emits a closed entity, with chunking
checked after conversion and properties against an independent parse
checker.
- An outbox that throttles edits to at least 1 s and keeps the final
text; long polling with the offset persisted before routing (at most
once); photos fetched only after admission, size-capped and
magic-checked, stored by digest; approval buttons only under the
channel cap.
- Trinity.Gateways.Supervisor starts the configured gateways, chosen by
TRINITY_GATEWAYS; nothing in the app started a gateway before.
- Images reach a session row and a :vision model, and are replaced by a
note otherwise. The log filter and secret scanner learn the token's
shape.
Red evidence R1 to R10 is in the slice NOTES.
Signed-off-by: Ayla Croft <aylacroft@proton.me>
Copy file name to clipboardExpand all lines: VERSIONS.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -94,7 +94,7 @@ never pin a version hex marks as retired or vulnerable.
94
94
|`stream_data`|~> 1.4 | ✅ in `mix.lock`| Property-based testing: generated input for `test/property`. Apache-2.0; 1.4.0 measured on hex.pm 2026-09-24, released 2026-07-14. Test only, so it ships in no artifact. Elixir has no focused fuzzing library and property-based testing is what the OpenSSF gold criterion `dynamic_analysis` accepts in its place, which is why this is a dependency rather than a habit. Added at Slice 004. |
95
95
|`jose`|~> 1.11 | ✅ in `mix.lock`| JOSE (JWK, JWS, JWKS) over OTP's crypto, for the MCP resource server's token validation and the personal profile's embedded authorization server. MIT; 1.11.12 measured on hex.pm 2026-09-22. Not joken, a layer over it this tree does not need. Added at Slice 062. |
96
96
|`oban_web`|~> 2.13 | ✅ in `mix.lock`| The Oban dashboard, a LiveView mounted at /oban (dev, and behind `config :trinity, :oban_web, true` elsewhere). Apache-2.0 on hex.pm since the 2.12 line (2.13.0 measured 2026-09-22); the plan of 2026-09-05 wrote it in when it was commercial. Added at Slice 050. |
97
-
|`req`|~> 0.5 | ✅ in `mix.lock`| HTTP client. |
97
+
|`req`|~> 0.5 | ✅ in `mix.lock`| HTTP client. Since Slice 071 also the Telegram Bot API client, in place of a Telegram library. |
98
98
|`req_llm`|~> 1.22 | ✅ in `mix.lock`| Provider layer (streaming, tools, structured output, usage). ⚠️ The pin was `~> 1.10` against a recorded latest of 1.10.0; the real latest was twelve minors ahead. Check event shapes against the current version at Slice 011, not against this file's prose. Added at Slice 011. |
99
99
|`beam_mcp`|~> 0.9 | ✅ in `mix.lock`| MCP server core, Apache-2.0, ADR-0007 decision 5 (owner decision 2026-09-08, recorded 2026-09-20). 0.9.0 on hex.pm (2026-09-22): the :server seam on both transports and the core server as a named behaviour, which slice 061's wrapper implements; standing before 1.0.0. Server side only: the client, MRTR and OAuth are Trinity's, above it. Added at Slice 059, bumped at 061. The earlier candidate list (anubis_mcp, fastest_mcp, gen_mcp) is history. |
100
100
|`jido`| not used (ADR-0009, decided 2026-09-20) | 🔍 not a single package | Measured at the Slice 012 checkpoint and not adopted: the agent runtime duplicates PubSub, Oban and the gateways and adds a second tool executor; the action shape is written in-tree at Slice 020 with `jsv` for its schemas. The row stays so the decision is visible where a reader would look for the package. |
@@ -141,7 +141,8 @@ never pin a version hex marks as retired or vulnerable.
141
141
|`burrito`|~> 1.6 | ✅ in `mix.lock`| ⚠️ ERTS availability drives the OTP pin, and Slice 000 measured it: only the OTP 28 line is fetchable for macOS and Linux. Corrected 2026-09-05: this row previously read `~> 1.5 / 1.5.0 ✅`; that mark was not measured. Added at Slice 001. |
142
142
|`ex_tauri`|~> 0.2 | ✅ in `mix.lock`| ⚠️ Declares `otp_release: "~> 27.0"`, and Slice 000's probe refutes the reason it gives: OTP 28 macOS universal returns 200 and OTP 27 returns 404. Whether it runs on the pinned OTP is Slice 001's first measurement. ⚠️ 439 downloads all-time, so the ADR-0004 fallback matrix carries real weight. |
143
143
|`nostrum`|~> 0.10 | 🔍 not yet a dependency | Discord. ⚠️ No release in roughly 18 months. R11's trigger already fires. Check intents and components against the current gateway before Slice 072. |
144
-
|`telegex`|**not pinned**| 🔍 not a single package | Telegram. ⚠️ The latest release on hex is a release candidate, roughly two years old, and this file's own rule forbids pinning an `-rc`. Alternative: ex_gram. Slice 071 decides with the measurement. |
144
+
|`telegex`| not used (measured at Slice 071, 2026-10-08) | 🔍 not a single package | Telegram. Measured at Slice 071: the latest release on hex is `1.9.0-rc.0` (2024-09-18) and the last stable `1.8.0` (2024-05-28); this file's own rule forbids pinning an `-rc`. Not used: `Trinity.Gateways.Telegram` speaks the Bot API with `req` (slice 071 NOTES, "The library, measured"). The row stays so the decision is visible where a reader would look for the package. |
145
+
|`ex_gram`| not used (measured at Slice 071, 2026-10-08) | 🔍 not a single package | Telegram. Measured at Slice 071 on `0.71.0` (2026-10-01): its poller keeps the `getUpdates` offset in process state and starts at `-1`, so a restarted poller reprocesses or skips unconfirmed updates (Slice 071's AC5 is that property); its file download host is a module attribute that cannot be pointed at a test server; Beerware licence; 18,054 lines for what is here a handful of JSON calls. Not used: `Trinity.Gateways.Telegram` speaks the Bot API with `req` and owns its poller. |
145
146
|`phoenix_streamdown`| not used (measured at Slice 013, 2026-09-20) | 🔍 not a single package | Streaming markdown renderer for LiveView. Measured at Slice 013: 1.0.0-beta.4 (2026-05-03) was still the latest release with no stable behind it, and this file's own rule forbids a pre-release. It is 801 lines over `mdex`, whose own `streaming: true` option completes fragments; the rest is a rendering rule Slice 013 keeps anyway. The row stays so the decision is visible where a reader would look for the package. |
146
147
|`mdex`|~> 0.13 | ✅ in `mix.lock`| Markdown renderer for the chat (`TrinityWeb.Markdown`), streaming fragments completed by its `streaming: true` option, raw HTML omitted (`unsafe: false`) and the default sanitizer on top. Added at Slice 013 after the measurement in its NOTES.md: `earmark` 1.4.49 is retired on hex with an open XSS advisory (EEF-CVE-2026-48591), which the gate refuses. ⚠️ A Rust NIF (`mdex_native`): the first in the bundle. Measured at Slice 013 (NOTES finding 13): neither precompiled artifact loads in Burrito's musl ERTS on Linux, so the linux package builds it from source for musl with Zig as the linker (`rustler` below, `scripts/zig-cc-musl`, the three settings in config/config.exs); macOS and Windows load the precompiled artifact. The `--smoke` path prints whether it rendered, and the `package` workflow reads that line on every target. |
147
148
|`jsv`|~> 0.23 | ✅ in `mix.lock`| JSON Schema (2020-12) validation of tool arguments in `Trinity.Tools.Schema`, with `cast: false` so a malformed call is refused and never repaired (docs/07). Was transitive through req_llm; direct since Slice 020 because a module of ours calls it (ADR-0009: Trinity's own tool behaviour, jsv for its schemas). |
0 commit comments