# 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 composed posts about hall-of-helix work. **The channel does not republish entries.** A hall entry is a considered first-person account written for a colleague reading a repository. A channel post is short, personal, entertaining and written to travel. The post is composed *from* the entry; the entry is its source and its check, never its payload. --- ## What this is fluid-core is finished through Blueprint Phase C. It can run the complete revision–experiment–fitness 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 A hall entry and a channel post are written for different readers. 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 | | Entries with a portrait | 72 (77%) | The length figures are the visible symptom. The mismatch is one of register and audience, and it would remain if the limit were ten times larger: an entry written under fixed headings for someone already invested does not become a post that stops a stranger scrolling by being shorter. 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. ## Where composition sits, and why Composing a condensed, entertaining post is a probabilistic editorial task. It happens **before** this interface is called, for two reasons: 1. `ArchitectureBlueprint.md` §48.1 names an LLM in the mandatory request path as an anti-pattern. An interface that composed on demand would be non-deterministic at exactly the point where determinism is its whole claim. 2. A post speaks about a named person's work in HelixForge's voice. That deserves a human read, and a review step inside the request path is a review step nobody performs. So the contract takes a *composed post*: body text already within the limit, a cited source entry, a named reviewer, and a consent basis. A post carrying none of those is refused with 403. This also draws the line that `pr-hall-of-helix` will later be extracted along. The campaign owns what to say and when; this interface owns delivery and measurement. --- ## 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-register-mismatch.yaml` | | Competing hypotheses | `fluid-telegram/hypotheses/H-tg-{visual,textonly}.yaml` | | First experiment | `fluid-telegram/experiments/E-tg-delivery.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 This interface's first experiment is about **delivery**, which is what it owns. **H-tg-visual** — attach the portrait; publish as a photo with the post as its caption. *Reach in a scanned feed is won by stopping the scroll, and 72 of the portraits already exist.* **H-tg-textonly** — publish as text with a source link, no visual. *Telegram caps a caption at 1024 characters against 4096 for text. The scarce resource in a condensed post is room to say something specific, and a generated portrait is interchangeable in a way that a concrete detail is not.* They cannot both be right, which is what makes the pair worth running. Both are presentation adaptations — Blueprint §37's safest and highest-value place to start. **Composition competitions are the campaign's, not this interface's.** Every post carries an opaque `variant` label, and the interface reports engagement grouped by it. That is the whole of its involvement: it does not know what `variant: warm-specific-v2` means and must not acquire an opinion. The campaign runs its own FLUID loop over its own artifacts using that data. --- ## 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. **`engagement_rate` is a proxy, and a noisy one.** Telegram reports views, reactions and forwards per message, not per reader, so the denominator is subscribers rather than people who saw the post. At small subscriber counts that is weak. It belongs in the experiment's amendment record rather than hidden behind a confident-looking number. **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 interface from composing, rewriting, shortening or embellishing post text, and §14 sets every generate, experiment and promote authority to `no`. A post is a condensation written in HelixForge's voice about a named person's work. It can flatter, it can misstate, and it can put a claim in someone's mouth that their own entry never made. In the audit trail an unfaithful post looks exactly like a faithful one. The defence is not that the composer is careful. It is structural: a human read the post, the post names the entry it came from, the subject's consent has a recorded basis, and all three are stored before anything reaches a subscriber. `unreviewed_publication`, `missing_source_attribution` and `missing_subject_consent` are hard guardrails, and a post carrying none of them is refused rather than logged. Ninety-four entries already exist, written by people who took a seat in the hall without anyone mentioning a Telegram channel. `FT-WP-0001` T07 exists to settle that before T10 opens the public channel. Absence of objection is not consent. --- ## Verification, in order ```bash 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 register mismatch 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. ## What comes after `FT-WP-0001` T13 extracts the campaign into `pr-hall-of-helix`, under a `pr-` prefix for public-relations campaigns. After that split, publishing the Hall of Helix is an *example* of using fluid-core and fluid-telegram rather than the thing they are for — which is the state this framework needs to reach before `fluid-x` and `fluid-substack` are worth starting. Do it after the loop has closed at least once. Extracting a seam before you have used it is how you find out you cut it in the wrong place.