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:
tegwick 2026-09-04 11:57:28 +02:00
parent aa95a09ab6
commit 3aa8cb7eaf
14 changed files with 793 additions and 521 deletions

View file

@ -0,0 +1,68 @@
# The interface's first experiment: does the portrait earn its place?
#
# This tests DELIVERY, which this interface owns. The competition about which
# editorial voice travels belongs to the campaign and is run on the per-variant
# engagement this interface reports — see docs/observation.md.
#
# fluid experiment design --file experiments/E-tg-delivery.yaml
# fluid experiment start E-tg-delivery --generation 2 \
# --default-revision R-2 --policy-out rp.json
# fluid policy put --file rp.json
fluid_experiment:
schema_version: "0.1"
id: "E-tg-delivery"
interface_id: "helix-forge-telegram-publishing"
hypothesis_refs:
- "H-tg-visual"
- "H-tg-textonly"
# R-2 attaches the portrait, R-3 publishes text only. Neither is an
# incumbent: R-1 publishes without either treatment being settled, so this
# is a comparison between two answers rather than against a baseline.
control_revision: "R-2"
candidate_revisions:
- "R-3"
cohorts:
- "telegram-subscribers"
allocation:
control: 0.5
candidate: 0.5
# An even split because there is no incumbent to protect. The usual 90/10
# caution limits exposure to an unproven candidate; here both arms are
# equally unproven and the scarce resource is posts, not safety.
metrics:
primary:
- "engagement_rate"
guardrails:
- "unreviewed_publication"
- "missing_source_attribution"
- "missing_subject_consent"
- "error_rate"
secondary:
- "source_link_rate"
- "forward_rate"
learning:
- "time_to_first_view"
start_conditions:
- "both revisions verified against the private test channel"
- "channel has at least 100 subscribers"
stop_conditions:
- "hard_guardrail_violation"
- "unreviewed_publication"
- "manual_stop"
- "max_duration_reached"
max_duration_hours: 2160 # 90 days
result:
state: "PLANNED"
preferred_revision: null
evidence_refs: []

View file

@ -1,68 +0,0 @@
# The first live experiment: which presentation serves readers better.
#
# Do not start this until the private test channel has confirmed both forms
# render correctly, and the public channel has enough subscribers for the
# result to mean anything. The intent (section 12) is explicit that an
# underpowered window should report INCONCLUSIVE rather than be shortened.
#
# fluid experiment design --file experiments/E-tg-length.yaml
# fluid experiment start E-tg-length --generation 2 \
# --default-revision R-2 --policy-out rp.json
# fluid policy put --file rp.json
fluid_experiment:
schema_version: "0.1"
id: "E-tg-length"
interface_id: "helix-forge-telegram-publishing"
hypothesis_refs:
- "H-tg-teaser"
- "H-tg-serial"
# R-2 implements the teaser form, R-3 the serialized form. Neither is the
# control in the usual sense: R-1 cannot publish a long entry at all, so
# this is a comparison between two answers rather than against a baseline.
control_revision: "R-2"
candidate_revisions:
- "R-3"
cohorts:
- "telegram-subscribers"
allocation:
control: 0.5
candidate: 0.5
# An even split because there is no incumbent to protect. The usual 90/10
# caution exists to limit exposure to an unproven candidate; here both arms
# are equally unproven and the scarce resource is entries, not safety.
metrics:
primary:
- "read_through_rate"
guardrails:
- "entry_content_loss"
- "error_rate"
- "messages_per_entry"
secondary:
- "reaction_rate"
- "forward_rate"
learning:
- "time_to_first_read"
start_conditions:
- "both revisions verified against the private test channel"
- "channel has at least 100 subscribers"
stop_conditions:
- "hard_guardrail_violation"
- "entry_content_loss"
- "manual_stop"
- "max_duration_reached"
max_duration_hours: 2160 # 90 days: roughly 12 entries at current cadence
result:
state: "PLANNED"
preferred_revision: null
evidence_refs: []