fluid-core/docs/handover/fluid-telegram.md
tegwick 6834c5c3e7 Add the fluid-telegram handover package
Completes FLUID-WP-0008's deliverable in this repository. The handover
records the measured pressure that motivates the interface -- 80 of 94
hall entries exceed Telegram's 4096-character limit -- and names the
three places this workload will strain the framework honestly, so the
strain reads as information rather than as a surprise.

A conformance test asserts the handover's contract compiles with
fluid-core's own validator and stays within the intent's complexity
budget, so a change on either side that broke the handover fails CI
rather than failing at the first publication.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014KmVxhJ35tCo7rE7UnLwWu

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1116572@bnt-lap001
Assistant-Session: 8ba9bb93-a72a-4883-b189-2499cce5c400
2026-09-04 11:07:51 +02:00

6.9 KiB
Raw Blame History

Handover — fluid-telegram

From: fluid-core (FLUID-WP-0008) To: fluid-telegram (FT-WP-0001) Date: 2026-09-04

The first real FLUID interface: a Telegram identity for HelixForge, and a channel publishing hall-of-helix entries.


What this is

fluid-core is finished through Blueprint Phase C. It can run the complete revisionexperimentfitness loop, and TestFirstVerticalSlice proves it with no human steps. What it has never done is carry a real workload.

helix-forge-telegram-publishing is that workload. It was chosen because the pressure it faces is real, measurable and unavoidable rather than contrived.


The pressure, measured

Telegram limits a single message to 4096 characters. Measured against hall-of-helix on 2026-09-04:

Entries 94
Bodies over 4096 characters 80 (85%)
Median body 5767 characters
Largest body 10220 characters
Median parts if split at the limit 2

No entry of typical length can be published as one message. The interface cannot fulfil its mission without deciding how a long entry becomes a post, and that decision has at least two defensible answers.

This is a better first pressure than anything a fixture could stage. It is structural rather than behavioural, so it is real before the interface serves a single request — and InterfaceEvolutionIntent.md §13 permits a structural constraint to found a hypothesis without waiting for repetition.


What is delivered

Everything that could be prepared without credentials.

Artifact Location
Governing intent fluid-telegram/InterfaceEvolutionIntent.md
R-1 contract fluid-telegram/contracts/r1.openapi.yaml
R-1 descriptor fluid-telegram/revisions/R-1.yaml
Seed pressure record fluid-telegram/pressure/P-length-limit.yaml
Competing hypotheses fluid-telegram/hypotheses/H-tg-{teaser,serial}.yaml
First experiment fluid-telegram/experiments/E-tg-length.yaml
Adapter connector contract fluid-telegram/docs/adapter-contract.md
Cohorts, telemetry, redaction fluid-telegram/docs/observation.md
Runbook fluid-telegram/docs/runbook.md
Work fluid-telegram/workplans/FT-WP-0001-*.md

All four seed records validate against fluid-core/schemas/, and the R-1 contract compiles with fluid-core's own validator — conformance/handover_test.go asserts both, so a change on either side that broke the handover would fail CI rather than fail at the first publication.


The competition

The length constraint has two defensible answers, and choosing between them by argument is exactly the habit FLUID exists to break.

H-tg-teaser — publish the title, the author, an opening, and a link back to the hall. A channel post is scanned, not read; let the reader choose to give the entry proper attention somewhere designed for it.

H-tg-serial — split the entry at section boundaries into a small number of linked rich-text messages. A link out of Telegram is a cost most readers will not pay; the audience is already here.

Both are presentation adaptations, which Blueprint §37 identifies as the safest and highest-value place to start: deterministic behaviour preserved, low compatibility risk, rich adoption data.

Neither is obviously right. That is the point.


Where the framework will be tested honestly

Three places where this workload will strain fluid-core, named now so the strain is recognised as information rather than as a surprise.

The experiment will be underpowered, and should say so. At roughly one entry per week, a 90-day experiment yields about twelve entries. The evaluator will report INCONCLUSIVE, and that is the correct answer. The framework was built to refuse a verdict it has not earned; the first live experiment is where that refusal will be inconvenient rather than admirable. Do not shorten the window to force a result.

read_through_rate is not one metric. Telegram reports views per message, not per reader. For the teaser form the measure is link clicks over views; for the serialized form it is views of the last part over views of the first. Those are different measurements wearing one name, and comparing them directly is the weakest part of the first experiment. It belongs in the experiment's amendment record rather than hidden behind a shared label.

Task grouping will overstate repeat counts. The measurer buckets requests by consumer and elapsed time when no chain id is supplied, so a burst of publications will read as one task. The direction of any measurement will be right and the magnitude will not. Supplying chain ids from the publishing job is the fix, and it is cheap.


Human steps

Four things need a person; nothing in the framework can or should do them.

  1. Register the bot through BotFather, and write the token straight to OpenBao.
  2. Create the private test channel first, then the public one. Grant the bot Post Messages and nothing else — the intent forbids it from using a wider right, so granting one would create a permission the system may not exercise.
  3. Generate the pseudonymization salt and store it beside the token. It must never change.
  4. Look at the first publication in the private channel before anything reaches a subscriber. No automated check substitutes for someone reading the post and deciding it is faithful.

The boundary that matters most

InterfaceEvolutionIntent.md §7 forbids the Daimon from editing a hall entry to make it publishable, and §14 sets every generate, experiment and promote authority to no.

A hall entry is a first-person account someone wrote about their own work. The authority to publish it comes from their having written it. An interface that trimmed an entry to fit a platform limit would be quietly rewriting what someone said about themselves in order to make a constraint go away — and it would look, in the audit trail, exactly like a successful publication.

That is why entry_content_loss is a hard guardrail in both hypotheses and why the adapter must refuse rather than approximate. The framework can measure whether readers preferred a teaser or a serialization. It cannot be allowed to decide that a shorter entry would have performed better.


Verification, in order

export FLUID_INTERFACE=helix-forge-telegram-publishing

fluid intent put --version IEI-1 --file InterfaceEvolutionIntent.md --activate
fluid revision publish --file revisions/R-1.yaml --key-file "$FLUID_SIGNING_KEY" \
  --adaptation-classes presentation --approved-by "$USER" --traffic-share 1.0

# then, against the private channel only:
#   publish one entry
#   publish it again; confirm one post, edited
#   confirm no Telegram identity and no token in the evidence store
fluid audit trace R-1

The last command is the deliverable. A trace running from the length-limit pressure through a hypothesis, an experiment and a promotion is what makes this the first FLUID interface rather than a bot that posts to a channel.