The channel publishes a post written from a hall entry -- condensed, personal, reach-optimized -- not the entry itself. That changes what this interface is for and where its boundary sits. Composition is deliberately outside the interface. Composing is a probabilistic editorial task, and Blueprint 48.1 forbids an LLM in the mandatory request path, so an interface that composed on demand would be non-deterministic exactly where determinism is the whole claim. It is also editorial: a post speaks about a named person's work in HelixForge's voice, and a review step inside the request path is a review step nobody performs. The contract now takes a composed post with a required reviewer, a cited source entry and a consent basis. A post carrying none of those is refused. Absence of objection is not consent, and in an audit trail an unfaithful post looks exactly like a faithful one -- the defence is that a human read it, the source is named, and both are recorded. The first experiment is rebuilt accordingly. The old competition asked how to fit a whole entry into Telegram; that question no longer exists. The new one asks whether the portrait earns the 3072 characters of caption limit it costs, which is a delivery question this interface actually owns. Competition over editorial voice belongs to the campaign and runs on the per-variant engagement this interface reports. Adds T05b (composition and review), T05c (consent basis for the 94 existing participants, blocking public publication) and T11 (extracting the campaign into pr-hall-of-helix). 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
306 lines
11 KiB
Markdown
306 lines
11 KiB
Markdown
---
|
|
id: FT-WP-0001
|
|
type: workplan
|
|
title: "Establish HelixForge's Telegram identity and publish the Hall of Helix"
|
|
domain: infotech
|
|
repo: fluid-telegram
|
|
status: active
|
|
owner: worsch
|
|
topic_slug: fluid-telegram
|
|
created: "2026-09-04"
|
|
updated: "2026-09-04"
|
|
planning_priority: high
|
|
planning_order: 1
|
|
depends_on:
|
|
- FLUID-WP-0008
|
|
related_repos:
|
|
- fluid-core
|
|
- helix-forge
|
|
- hall-of-helix
|
|
state_hub_workstream_id: "a660ed65-700e-5b54-8d91-a556b73518f0"
|
|
---
|
|
|
|
# FT-WP-0001 — Telegram identity and the Hall of Helix channel
|
|
|
|
Establish a Telegram identity for HelixForge and a channel publishing composed
|
|
posts about hall-of-helix work, as the first real FLUID interface.
|
|
|
|
**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 and is a different piece of writing; the entry is the
|
|
source and the check, never the payload.
|
|
|
|
Composition happens before this interface is called. That boundary is
|
|
architectural: composing is a probabilistic editorial task, and
|
|
`ArchitectureBlueprint.md` §48.1 forbids an LLM in the mandatory request path.
|
|
It is also editorial: a post speaks about a named person's work in HelixForge's
|
|
voice, and that deserves a human read before it goes out.
|
|
|
|
Everything that could be prepared without credentials has been: the governing
|
|
intent, the R-1 contract, the adapter's connector contract, the observation
|
|
configuration, the seed pressure record, and two competing hypotheses for the
|
|
first experiment. See `docs/` and the handover package at
|
|
`fluid-core/docs/handover/fluid-telegram.md`.
|
|
|
|
What remains needs either a person with a Telegram account or a running
|
|
adapter.
|
|
|
|
## T01 — Register the bot
|
|
|
|
```task
|
|
id: FT-WP-0001-T01
|
|
status: todo
|
|
priority: high
|
|
state_hub_task_id: "a5449e86-3181-54b6-a0fe-e5c761b3e4ba"
|
|
```
|
|
|
|
**Human step.** Register the HelixForge bot through BotFather (Canon BOT-01).
|
|
Bots are first-class Telegram accounts and need no phone number.
|
|
|
|
Set the bot's name, description and profile image to something a reader
|
|
encountering it cold would recognise as HelixForge.
|
|
|
|
Write the token to OpenBao immediately; do not paste it anywhere else, not even
|
|
briefly. Consistent with `HF-WP-0002` (bao.coulomb.social).
|
|
|
|
## T02 — Create the channels
|
|
|
|
```task
|
|
id: FT-WP-0001-T02
|
|
status: todo
|
|
priority: high
|
|
state_hub_task_id: "597ab1b7-5903-5a5d-a510-0a6946325404"
|
|
```
|
|
|
|
**Human step.** Create the **private test channel first**, then the public
|
|
channel (Canon PUB-01). Add the bot as administrator with **Post Messages**
|
|
only — the intent forbids it from using any wider right, so granting one would
|
|
be a permission the system is not allowed to exercise.
|
|
|
|
Every verification below runs against the private channel. Nothing reaches the
|
|
public channel until the rendering has been seen by a person.
|
|
|
|
## T03 — Generate and store the redaction salt
|
|
|
|
```task
|
|
id: FT-WP-0001-T03
|
|
status: todo
|
|
priority: high
|
|
state_hub_task_id: "bbe5da73-e604-5dfe-b25f-fba802f67618"
|
|
```
|
|
|
|
`openssl rand -hex 32`, stored in OpenBao beside the token, injected as
|
|
`FLUID_REDACTION_SALT`. It must never change: see `docs/observation.md` for why
|
|
rotating it silently invalidates every longitudinal comparison.
|
|
|
|
## T04 — Record the intent and publish R-1
|
|
|
|
```task
|
|
id: FT-WP-0001-T04
|
|
status: todo
|
|
priority: high
|
|
state_hub_task_id: "13a92a96-2f87-5de2-a69c-7edc21f3a0c7"
|
|
```
|
|
|
|
```bash
|
|
export FLUID_INTERFACE=helix-forge-telegram-publishing
|
|
fluid intent put --version IEI-1 --file InterfaceEvolutionIntent.md --activate
|
|
# fill the digest in revisions/R-1.yaml, then
|
|
fluid revision publish --file revisions/R-1.yaml --key-file "$FLUID_SIGNING_KEY" \
|
|
--adaptation-classes presentation --approved-by "$USER" --traffic-share 1.0
|
|
```
|
|
|
|
Generate a real signing key pair for this; `--ephemeral-key` is development
|
|
only, and a revision signed with one stops verifying after a restart.
|
|
|
|
## T05 — Build the adapter
|
|
|
|
```task
|
|
id: FT-WP-0001-T05
|
|
status: todo
|
|
priority: high
|
|
state_hub_task_id: "c89782da-9896-5957-b729-7c35165a0067"
|
|
```
|
|
|
|
Implement the three operations in `contracts/r1.openapi.yaml` against the
|
|
connector contract in `docs/adapter-contract.md`. TypeScript with grammY is the
|
|
natural choice; the wire contract makes the language irrelevant to fluid-core.
|
|
|
|
Three requirements carry the weight: publication is idempotent on `post_id`; a
|
|
post arriving without `reviewed_by` or a consent basis is refused with 403; and
|
|
a post that exceeds the limit for the form being published is refused rather
|
|
than truncated. The adapter renders and delivers. It never writes.
|
|
|
|
## T05b — Establish the composition step
|
|
|
|
```task
|
|
id: FT-WP-0001-T05b
|
|
status: todo
|
|
priority: high
|
|
```
|
|
|
|
Build the step that turns a hall entry into a post: condensed, personal,
|
|
entertaining, reach-optimized, carrying a link back to the source entry.
|
|
|
|
For now this lives here, as a script plus a review queue. It is temporary by
|
|
design — T11 extracts it into `pr-hall-of-helix` — so keep the seam clean. The
|
|
composition step's only interface to publishing is `POST /v1/channel-posts`,
|
|
and it must not reach into the adapter or the evidence store.
|
|
|
|
Each composition records the `variant` label of the strategy that produced it.
|
|
Without that label the campaign cannot later compare strategies, and inferring
|
|
it from timestamps is the kind of reconstruction that quietly stops being
|
|
accurate.
|
|
|
|
Human review is not a nicety here. A generated condensation can put a claim in
|
|
someone's mouth that their own entry never made, and in the audit trail an
|
|
unfaithful post looks exactly like a faithful one. The reviewer reads the post
|
|
against the entry, and their name goes in `reviewed_by`.
|
|
|
|
## T05c — Record the consent basis for hall participants
|
|
|
|
```task
|
|
id: FT-WP-0001-T05c
|
|
status: todo
|
|
priority: high
|
|
```
|
|
|
|
Ninety-four entries already exist, written by people and agent sessions who
|
|
took a seat in the hall without anyone mentioning a Telegram channel.
|
|
|
|
Decide and record the basis on which HelixForge may write publicly about that
|
|
work. If `hall-of-helix/ENTRY.md` is to carry a standing agreement, add it and
|
|
say plainly that it is revocable. Contributors who predate it should be asked
|
|
rather than assumed into it.
|
|
|
|
Absence of objection is not consent, and the interface refuses a post carrying
|
|
no basis, so this blocks T08.
|
|
|
|
## T06 — Publish one post to the private channel
|
|
|
|
```task
|
|
id: FT-WP-0001-T06
|
|
status: todo
|
|
priority: high
|
|
state_hub_task_id: "317bef32-e82e-586a-8947-8cbb330f6c98"
|
|
```
|
|
|
|
The first real test. Compose one post from one entry, have it reviewed, publish
|
|
it to the private channel, and confirm by looking at it:
|
|
|
|
- the post reads well and is worth a stranger's attention;
|
|
- it does not claim anything the source entry does not support;
|
|
- the source link works and the attribution is right;
|
|
- re-publishing the same `post_id` edits rather than duplicates;
|
|
- the evidence store holds the post text but no Telegram user identity and no
|
|
bot token;
|
|
- `fluid audit trace R-1` reconstructs the publication, naming the reviewer and
|
|
the source entry.
|
|
|
|
The second bullet is the one that needs a person. Everything else can be
|
|
automated; whether a condensation is fair to the person it describes cannot.
|
|
|
|
## T07 — Implement both delivery forms as R-2 and R-3
|
|
|
|
```task
|
|
id: FT-WP-0001-T07
|
|
status: todo
|
|
priority: medium
|
|
state_hub_task_id: "6a91ea08-8814-58f3-8297-a7ca63405294"
|
|
```
|
|
|
|
R-2 implements `H-tg-visual` — portrait attached, and Telegram's 1024-character
|
|
caption limit with it. R-3 implements `H-tg-textonly` — a text message with the
|
|
full 4096 available. Both are presentation adaptations over the same contract,
|
|
so neither needs a contract change. Verify both against the private channel
|
|
before either sees a subscriber.
|
|
|
|
The two arms impose different length limits on the composer, which is the one
|
|
place delivery and composition genuinely couple.
|
|
|
|
## T08 — Open the public channel and start publishing
|
|
|
|
```task
|
|
id: FT-WP-0001-T08
|
|
status: todo
|
|
priority: medium
|
|
state_hub_task_id: "5e5cd89a-e7b1-5aaf-9331-ece424afe5e3"
|
|
```
|
|
|
|
Point the production adapter at the public channel. Blocked on T05c: no post
|
|
goes out about anyone's work without a recorded consent basis.
|
|
|
|
Do not batch-publish the backlog. Ninety-four posts in a burst is a rate-limit
|
|
problem, an unkind introduction for a new subscriber, and — more to the point —
|
|
ninety-four compositions nobody has had time to read properly. Publish
|
|
selectively and at a human pace, and let the backlog be a source to draw on
|
|
rather than a queue to drain.
|
|
|
|
## T09 — Run the first delivery experiment
|
|
|
|
```task
|
|
id: FT-WP-0001-T09
|
|
status: todo
|
|
priority: low
|
|
state_hub_task_id: "649e7df6-6c07-5cc8-a022-d1eadcdb7236"
|
|
```
|
|
|
|
Start `E-tg-delivery` once the channel has roughly 100 subscribers. Before then
|
|
the evaluator will report INCONCLUSIVE, and that is the correct answer rather
|
|
than a reason to shorten the window.
|
|
|
|
At one post per week, a 90-day experiment yields about twelve posts. That is
|
|
thin, and the honest expectation is that the first run is inconclusive and
|
|
informs a better-powered second one. Record that expectation in the
|
|
experiment's amendments rather than discovering it as a disappointment.
|
|
|
|
## T10 — Close the loop
|
|
|
|
```task
|
|
id: FT-WP-0001-T10
|
|
status: todo
|
|
priority: low
|
|
state_hub_task_id: "b469b9b8-a1a8-5f76-a1bb-dd51dd4d2ce5"
|
|
```
|
|
|
|
Record the hypothesis outcome, resolve `CG-tg-delivery`, and promote the winner.
|
|
Then confirm `fluid audit trace` reconstructs the whole chain, from the register
|
|
mismatch through to the promoted revision.
|
|
|
|
That trace is the deliverable. It is what makes this the first FLUID interface
|
|
rather than a bot that posts to a channel.
|
|
|
|
## T11 — Extract the campaign into pr-hall-of-helix
|
|
|
|
```task
|
|
id: FT-WP-0001-T11
|
|
status: todo
|
|
priority: medium
|
|
```
|
|
|
|
Everything about *what to say and when* moves to a new repository,
|
|
`pr-hall-of-helix`, under the `pr-` prefix for public-relations campaigns. What
|
|
stays here is the deterministic delivery interface.
|
|
|
|
The split follows the boundary the intent already draws (§7):
|
|
|
|
| Moves to `pr-hall-of-helix` | Stays in `fluid-telegram` |
|
|
|---|---|
|
|
| Composition and the editorial voice | The R-1 contract and its revisions |
|
|
| Choosing which work is worth a post | The adapter |
|
|
| Variant strategies and their competition | Delivery experiments (`CG-tg-delivery`) |
|
|
| Consent records and the review queue | Per-variant engagement reporting |
|
|
| The publishing cadence | Bot and channel configuration |
|
|
|
|
The campaign becomes a *consumer* of this interface — cohort
|
|
`hall-publishing-jobs` — and runs its own FLUID loop over its own artifacts,
|
|
using the per-variant engagement this interface reports.
|
|
|
|
Two things this buys. `fluid-telegram` becomes reusable for any HelixForge
|
|
campaign rather than being about the Hall of Helix specifically. And the Hall of
|
|
Helix campaign becomes an ongoing offering with its own intent, budget and
|
|
cadence, rather than living inside a workplan that was supposed to finish.
|
|
|
|
Do this once the loop has closed at least once (T10). Extracting a seam before
|
|
you have used it is how you find out you cut it in the wrong place.
|