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
51 lines
1.4 KiB
Go
51 lines
1.4 KiB
Go
package conformance
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/tegwick/fluid-core/internal/validate"
|
|
)
|
|
|
|
// TestTelegramHandoverContractCompiles checks that the contract shipped in the
|
|
// fluid-telegram handover is one this gateway can actually enforce.
|
|
//
|
|
// A handover that shipped a contract the framework cannot parse would fail at
|
|
// the first publication, after the bot and channel had already been created.
|
|
// The check is skipped when the sibling repository is absent, so CI in a bare
|
|
// checkout still passes.
|
|
func TestTelegramHandoverContractCompiles(t *testing.T) {
|
|
const path = "../../fluid-telegram/contracts/r1.openapi.yaml"
|
|
|
|
raw, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Skipf("fluid-telegram not checked out beside fluid-core: %v", err)
|
|
}
|
|
|
|
c, err := validate.ParseOpenAPI(raw)
|
|
if err != nil {
|
|
t.Fatalf("the handover contract does not compile: %v", err)
|
|
}
|
|
|
|
ops := c.Operations()
|
|
want := map[string]bool{
|
|
"GET /v1/channel-posts": false,
|
|
"POST /v1/channel-posts": false,
|
|
"GET /v1/channel-posts/{post_id}": false,
|
|
}
|
|
for _, op := range ops {
|
|
if _, tracked := want[op]; tracked {
|
|
want[op] = true
|
|
}
|
|
}
|
|
for op, found := range want {
|
|
if !found {
|
|
t.Errorf("the contract does not declare %s; it has %v", op, ops)
|
|
}
|
|
}
|
|
|
|
// The interface's complexity budget allows a maximum of 8 operations.
|
|
if len(ops) > 8 {
|
|
t.Errorf("the contract declares %d operations, over the intent's budget of 8", len(ops))
|
|
}
|
|
}
|