Reframe the interface around composed posts, not republished entries
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
This commit is contained in:
parent
aa95a09ab6
commit
3aa8cb7eaf
14 changed files with 793 additions and 521 deletions
|
|
@ -22,8 +22,20 @@ 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
|
||||
hall-of-helix entries, as the first real FLUID interface.
|
||||
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
|
||||
|
|
@ -115,12 +127,57 @@ 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.
|
||||
|
||||
The two requirements that carry the most weight: publication is idempotent on
|
||||
`entry_id`, and an entry that cannot be converted faithfully is refused rather
|
||||
than approximated. `entry_content_loss` is a hard guardrail in both competing
|
||||
hypotheses and can only be honest if the adapter refuses.
|
||||
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.
|
||||
|
||||
## T06 — Publish one entry to the private channel
|
||||
## 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
|
||||
|
|
@ -129,15 +186,22 @@ priority: high
|
|||
state_hub_task_id: "317bef32-e82e-586a-8947-8cbb330f6c98"
|
||||
```
|
||||
|
||||
The first real test. Publish a single hall entry to the private channel and
|
||||
confirm, by looking at it:
|
||||
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 rendering is faithful and readable;
|
||||
- re-publishing the same entry edits rather than duplicates;
|
||||
- the evidence store contains no Telegram user identity and no bot token;
|
||||
- `fluid audit trace R-1` reconstructs the publication.
|
||||
- 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.
|
||||
|
||||
## T07 — Implement both presentation forms as R-2 and R-3
|
||||
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
|
||||
|
|
@ -146,11 +210,16 @@ priority: medium
|
|||
state_hub_task_id: "6a91ea08-8814-58f3-8297-a7ca63405294"
|
||||
```
|
||||
|
||||
R-2 implements `H-tg-teaser`, R-3 implements `H-tg-serial`. 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.
|
||||
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.
|
||||
|
||||
## T08 — Open the public channel and publish the backlog
|
||||
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
|
||||
|
|
@ -159,14 +228,16 @@ priority: medium
|
|||
state_hub_task_id: "5e5cd89a-e7b1-5aaf-9331-ece424afe5e3"
|
||||
```
|
||||
|
||||
Point the production adapter at the public channel and publish the existing
|
||||
entries. 94 entries at once would be both a rate-limit problem and an unkind
|
||||
introduction for a new subscriber; publish them oldest-first at a human pace.
|
||||
Point the production adapter at the public channel. Blocked on T05c: no post
|
||||
goes out about anyone's work without a recorded consent basis.
|
||||
|
||||
Whichever of R-2 or R-3 is used here becomes the de facto control for the
|
||||
experiment, which is why `E-tg-length` names R-2 as control rather than R-1.
|
||||
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 experiment
|
||||
## T09 — Run the first delivery experiment
|
||||
|
||||
```task
|
||||
id: FT-WP-0001-T09
|
||||
|
|
@ -175,14 +246,14 @@ priority: low
|
|||
state_hub_task_id: "649e7df6-6c07-5cc8-a022-d1eadcdb7236"
|
||||
```
|
||||
|
||||
Start `E-tg-length` once the channel has roughly 100 subscribers. Before then
|
||||
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 entry per week, a 90-day experiment yields about twelve entries. That is
|
||||
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.
|
||||
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
|
||||
|
||||
|
|
@ -193,9 +264,43 @@ priority: low
|
|||
state_hub_task_id: "b469b9b8-a1a8-5f76-a1bb-dd51dd4d2ce5"
|
||||
```
|
||||
|
||||
Record the hypothesis outcome, resolve the competition group, and promote the
|
||||
winner. Then confirm `fluid audit trace` reconstructs the whole chain from the
|
||||
length-limit pressure through to the promoted revision.
|
||||
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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue