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
11 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | planning_priority | planning_order | depends_on | related_repos | state_hub_workstream_id | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| FT-WP-0001 | workplan | Establish HelixForge's Telegram identity and publish the Hall of Helix | infotech | fluid-telegram | active | worsch | fluid-telegram | 2026-09-04 | 2026-09-04 | high | 1 |
|
|
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
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
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
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
id: FT-WP-0001-T04
status: todo
priority: high
state_hub_task_id: "13a92a96-2f87-5de2-a69c-7edc21f3a0c7"
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
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
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
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
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_idedits rather than duplicates; - the evidence store holds the post text but no Telegram user identity and no bot token;
fluid audit trace R-1reconstructs 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
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
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
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
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
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.