The Telegram channel publishes posts written from hall entries, not the
entries themselves, so the handover's pressure, competition and
guardrails are rebuilt around that. Composition sits outside the
interface because Blueprint 48.1 forbids an LLM in the mandatory request
path, and because a post about a named person's work deserves a human
read that a request-path step would never get.
Adds FLUID-WP-0009 for the pr- campaign repository convention and for
reducing the Hall of Helix case from the thing this framework is for to
an example of using it. The prefix deliberately includes "propaganda":
a campaign repository that cannot name what it is doing will not govern
it well.
The workplan starts only after the loop has closed once on real traffic.
Extracting a seam before using it is how you learn you cut it in the
wrong place.
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
T01, T04-T07 and T09 are delivered. T02 (bot registration), T03 (channel
creation) and T08 (the live experiment) are marked blocked rather than
done: they need a Telegram account, real credentials and an audience,
and recording them as complete would be the kind of invented completion
the Hall of Helix exists to discourage.
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
Completes FLUID-WP-0007. The seven minimal-conformance requirements and
the mechanically checkable architectural invariants are asserted as
tests rather than claimed in a README, because a conformance claim
nobody re-checks is one that quietly stops being true. Only the
checkable subset of the invariants is asserted; pretending a test can
settle the rest would be worse than leaving them to review.
TestFirstVerticalSlice runs all eleven steps of Blueprint 50 with no
human steps: two revisions, explicit routing, telemetry, a cohort
dimension, detected pressure, a hypothesis, a candidate, a 90/10
experiment, fitness comparison, promotion, and a complete audit trail.
Requests per completed task fall from 5.65 to 1.00 against a 1.20
target. A companion test runs the loop twice and requires the same
verdict, since a loop whose conclusion depended on run order would be
measuring the harness rather than the interface.
The failure-containment matrix covers Blueprint 34 directly: the data
plane keeps serving with the evidence store closed, with telemetry
wedged against a sink that never returns, after a failed build, after an
experiment rollback, and with the adaptive concurrency limit saturated.
Fixes a real bug the suite exposed. Drain closed the emitter outright,
so every request after the first flush emitted into a dead emitter and
was silently lost -- the kind of fault that makes a later measurement
quietly wrong rather than loudly broken. Emitter.Flush now waits for
delivery without stopping it.
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
The gateway can now enforce a revision's declared contract, which makes
"a deterministic API contract" -- the first minimal-conformance
requirement -- something the framework actually checks rather than
assumes.
The JSON Schema support is a documented subset. Keywords outside it are
reported as unsupported rather than skipped, because a validator that
silently ignores a constraint it does not understand is worse than none:
it reports success it did not earn. The same reasoning refuses remote
$refs, which would make request-path validation depend on a network
fetch, and refuses to serve a revision whose contract is not registered.
String lengths are counted in runes. A 4096-character limit that
rejected a 3000-character hall entry because of its accents would be
wrong in exactly the case this framework was built to publish.
Literal routes are matched before templated ones, so /entries/latest is
not swallowed by /entries/{id} -- which matters, since a latest-entry
convenience route is the Blueprint's own worked example.
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
Completes FLUID-WP-0006. The loop now runs end to end from the command
line: two competing presentation hypotheses, an experiment that issues a
routing policy rather than touching traffic, an amendment, a stop that
returns traffic to the default, a confirmed outcome, a resolved
competition, and a promotion the gate can refuse.
Starting or stopping an experiment returns the routing policy for the
operator to install rather than installing it. Blueprint 17 keeps the
controller out of the traffic path, and installing from the handler
would put it straight back in; emitting the document keeps the
separation visible instead of implied.
`fluid audit trace` now answers the section 25 questions from events
rather than summary records, and names the rivals a hypothesis beat: an
audit asking which hypotheses were considered is not answered by naming
only the winner.
Two fixes found by driving the CLI rather than only the tests. Go's flag
package stops at the first positional, so ids given after flags silently
swallowed them; ids are now taken before parsing. And there was no way
to attach a revision to the hypothesis that produced it, which left
`audit trace` unable to say why a revision existed -- `hypothesis attach`
closes that.
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
Completes FLUID-WP-0005. Normalization and redaction live on one path,
shared by the in-process emitter and the ingest endpoint: two paths with
two normalizations would eventually disagree, and the disagreement would
surface as a pressure finding that is really a pipeline bug.
Telemetry kind is inferred from event shape rather than defaulting to
"request", since an error filed as a request understates the interface's
failure rate. A malformed event in a batch does not discard the rest.
Feedback is stored as evidence and creates no pressure and no hypothesis
on its own, per API Standards 15, with the consumer recorded as the
actor so their untrusted status stays visible in the audit trail. The
feedback endpoint is the only consumer-reachable part of the control
plane.
The observation endpoints are not served at all when no pseudonymization
salt is configured, rather than served with a generated one: a salt that
changed per run would make the same consumer look new every time and
every cohort count wrong.
Adds an end-to-end test driving real traffic through the gateway and
confirming it becomes a classified pressure record, with no raw consumer
identity reaching the store.
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
Completes FLUID-WP-0004. The Revision and Intent APIs (Blueprint 44.1
and 44.5) are served by fluid-control, which is deliberately off the
request path and must never be reachable by interface consumers: it is
the mechanism that evolves the interface in response to their behaviour.
Intent amendment is a proposal, never an edit. Rewriting a recorded
version returns 409, because changing what a version says would change
what already-published revisions were governed by.
A rejected candidate comes back as 422 with its full stage report rather
than as a server fault. Rejection is a normal outcome (invariant 14) and
the reasons are the evidence a later hypothesis needs.
Also closes a real hole this workplan opened: `fluid revision publish`
previously wrote straight into the evidence store, which was a way
around the deterministic policy gate for anyone with shell access. It
now runs the same pipeline the control plane does and requires a signing
key.
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
Completes FLUID-WP-0003. The evidence store is append-only at the
database, not by convention in Go: a trigger blocks UPDATE and DELETE on
fluid_events in both SQLite and Postgres, so the guarantee binds a psql
session and the CLI equally, not just callers who go through the Go API.
Records are derived summary state and may be superseded; the event log
stays the authority.
The intent store makes a recorded version immutable and content
addressed, since reassigning what governed a revision after the fact
would break the one audit question Blueprint 27 exists to answer. The
unfilled InterfaceEvolutionIntent template is rejected rather than
defaulted, because a template still listing every FLUID-N mode has not
been completed and defaulting it would pick a permissive authority by
accident.
The CLI reads the evidence store directly rather than through the
control-plane API, so an operator can reconstruct history when the
control plane is down.
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
Completes the request path for FLUID-WP-0003 T01-T03 and T05-T07. The
gateway resolves a revision, routes to the adapter process, and records
what happened, without ever depending on the control plane to serve.
Three behaviours carry tests because the architecture rests on them:
Emit never blocks against a stalled sink (Blueprint 34.2), the gateway
keeps serving after control-plane loss (invariant 2), and backend
internals do not leak into error responses (5.7).
The connector retries only idempotent methods, so a slow adapter cannot
cause a hall-of-helix entry to be published twice, and breakers are
per-revision so a broken candidate does not take the stable revision
down with it.
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
Completes FLUID-WP-0002. The record types in internal/contract are
generated from schemas/ by a dependency-free generator; fixtures
transcribed from the spec's worked examples validate against those
schemas and round-trip through the generated types with
DisallowUnknownFields, so a spec change that misses the schemas fails
CI rather than drifting silently.
Adds identifier prefix helpers, Makefile, GitHub Actions, and five ADRs
recording the Go choice, out-of-process attachment, the wire contract as
boundary, the evidence store, and revision identity.
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
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
Adds the repository structure, INTENT.md declaring the wire-contract
boundary, and seven workplans covering Blueprint Phases A-C plus the
fluid-telegram handover.
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