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
Slice 020: tool protocol and registry. PROOF.md at slices/020-tool-protocol-registry/PROOF.md; gate and postgres jobs green on the closing tree.
Signed-off-by: Ayla Croft <aylacroft@proton.me>
Copy file name to clipboardExpand all lines: VERSIONS.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -135,6 +135,7 @@ never pin a version hex marks as retired or vulnerable.
135
135
|`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. |
136
136
|`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. |
137
137
|`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. |
138
+
|`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). |
138
139
|`rustler`|~> 0.38 | ✅ in `mix.lock`| Build time only (`runtime: false`): what `rustler_precompiled` needs to compile `mdex_native` from source when `MDEX_NATIVE_BUILD=1`, which the linux package sets (owner decision 2026-09-20, Slice 013 NOTES finding 14). Nothing in the tree calls it. |
Every state transition is persisted before it is broadcast. A crash between persist and broadcast is safe
114
116
(rehydrate re-broadcasts the last state).
115
117
118
+
**Tool calls (Slice 020):** at `{:done, :tool_calls}` the Session hands the turn's calls to
119
+
`Trinity.Sessions.ToolRunner.run_all/2`, the seam whose implementation in force is `Trinity.Tools.Runner`
120
+
(config, so a test can put the stub back). The runner runs every call at once under
121
+
`Trinity.Tools.TaskSupervisor`, each with its tool's timeout: lookup, `jsv` validation of the arguments
122
+
(refused, never repaired), `Trinity.Permissions.decide/3` once, `execute/2`, the result cap. A crash, a timeout
123
+
and an unknown name are error results the model reads; the Session writes one `tool` row per answer with the
124
+
tool's definition digest. Each turn's request carries the declared surface (`Trinity.Tools.to_llm_tools/0`) and
125
+
the assistant row records it (`provider_meta.tool_surface`); `Trinity.Tools.surface_diff/1` over a history names
126
+
the calls a turn made outside it. Sessions depends on Tools; Tools depends on Permissions and never on Sessions
127
+
(the runner implements the seam's functions without naming the behaviour, which would close a cycle).
128
+
116
129
**Effect path (Slice 024):**`Session → Permissions.decide → Effects.execute → Authority → tool.execute/2 (local) or a proposal (external adapter) → Receipts.append`. `Effects` is the only caller of `execute/2` for effectful tools; a census test enforces it. Reads emit query receipts.
117
130
118
131
**The page (Slice 013):**`TrinityWeb.SessionLive.Show` subscribes to `session:<id>` on mount, calls
| content | text | plain text or JSON for tool payloads |
38
38
| parts | map | structured content parts (text, tool_call, tool_result, image ref). Every part carries `origin`, `source_ref`, `digest` and `taint ∈ {trusted, untrusted, blocked}`; summaries inherit the maximum taint of their inputs (Slice 022) |
39
-
| tool_call_id | string, nullable ||
39
+
| tool_call_id | string, nullable |the assistant row's call id a `tool` row answers (Slice 012); its `parts` carry `tool`, `ok`, `tool_result` (`content`, `truncated`, `meta`, `artifacts`, or `error`) and `tool_definition_digest`, and the assistant row's `provider_meta.tool_surface` maps every declared tool name to its digest (Slice 020) |
0 commit comments