Skip to content

Add a "Loop states" section showing the label state machine on the landing page #84

Closed

Description

@baderdean

Context

The landing page explains boucle in prose (why-boucle, how-it-works, the 7 steps) but never shows the thing that makes it deterministic: the label state machine. A visitor reading "deterministic, therefore reliable" has to take it on faith. The states are the product's most concrete differentiator and they are currently invisible.

What to add

A new section between how-it-works and quick-start rendering the loop's states as a progression, driven by a new src/content/loop-states/ collection (one file per state) so the copy stays editable from public/admin like every other section.

Each state needs a label chip, a one-line description of what boucle is doing in it, and a marker for whether it is an autonomous state or one where a human decides.

The states to cover, in order:

Label Autonomous?
boucle:triage autonomous
boucle:spec-review human decides
boucle:todo autonomous
boucle:working autonomous
boucle:review autonomous
boucle:approval human decides
boucle:merging autonomous
boucle:done terminal
boucle:human escalation (terminal)

The two terminal states should read as terminal — they are exits from the loop, not steps in it.

Layout

This is the part that needs design judgement, and the reason a mockup matters:

  • Desktop (≥1024px): a horizontal progression. Nine states will not fit on one row legibly, so it needs to wrap or scroll in a way that keeps the reading order obvious. The two "human decides" states must be visually distinct from the autonomous ones — that contrast is the section's whole point.
  • Mobile (<768px): the horizontal progression cannot survive at 390px. It should become a vertical list with the connector running down the left edge.
  • The escalation state (boucle:human) branches off the main path rather than sitting in sequence; that branching needs to survive the collapse to vertical.

Use the existing tokens from DESIGN.md — --accent gold for the human-decision states, --accent-cyan for autonomous, --surface-raised for the chips. No new colours.

Non-goals

  • No animation or scroll-triggered reveal.
  • Not adding these states to the README or docs — landing page only.
  • Not making the chips link anywhere.

Acceptance criteria

  • New loop-states content collection with a schema, one entry per state, registered in src/content.config.ts.
  • The section renders all nine states in order, with the autonomous/human/terminal distinction visible without reading the text.
  • At 390px wide the section is legible with no horizontal page scroll.
  • At 1440px the progression reads left-to-right without crowding.
  • Editable from public/admin/config.yml like the other collections.
  • npm run build passes.

Activity

  1. baderdean commented on Aug 26, 2026

    @baderdean
    MemberAuthor

    TL;DR

    Add a new "loop states" section to the landing page that visualizes boucle's nine label states as a progression. Autonomous states use cyan, human-decision states use gold, terminal states read as exits. Content is driven by a new loop-states collection so it stays editable from the CMS. Desktop shows a horizontal progression; mobile collapses to a vertical list with the escalation state branching off.

    Preview

    📱 Mobile (390x844)

    Preview 390x844

    🖥️ Desktop (1440x900)

    Preview 1440x900

    Analysis

    The landing page explains boucle in prose and a 7-step slideshow but never shows the label state machine — the product's most concrete differentiator. A visitor reading "deterministic, therefore reliable" has to take it on faith. This issue asks to make the states visible as a rendered progression between how-it-works and quick-start.

    User segment — Product Builders evaluating boucle.dev who want to understand how the loop is deterministic, not just be told it is.

    Pain points — The states are the product's most concrete differentiator and they are currently invisible. Visitors cannot see where humans intervene vs where boucle acts alone. The 7-step slideshow is narrative; the state machine is structural.

    Business context — "Deterministic and reliable" is key message #2. Showing the state machine converts the claim from marketing copy into something verifiable at a glance. The autonomous/human contrast is the section's whole point.

    Success metrics — A visitor can identify the two human-decision points and the two terminal exits without reading the descriptions, by colour alone.

    Docs impact: DESIGN.md (new component spec for the loop-states section), src/content.config.ts (new collection schema), public/admin/config.yml (new CMS collection).

    Draft acceptance criteria

    • Happy path — Given the landing page is loaded, When a visitor scrolls to the section between how-it-works and quick-start, Then all nine states render in order with a label chip, a one-line description, and a type marker (autonomous / human / terminal / escalation)
    • Visual distinction — Given the section is rendered, When a visitor looks at the chips without reading the text, Then autonomous states are visually distinct from human-decision states (cyan vs gold per DESIGN.md tokens) and terminal states read as exits (muted/strikethrough treatment)
    • Desktop layout — Given a viewport ≥1024px, When the section is rendered, Then the states display as a horizontal progression that wraps legibly without horizontal page scroll, and reading order (left-to-right, top-to-bottom) is obvious
    • Mobile layout — Given a viewport of 390px, When the section is rendered, Then the states display as a vertical list with a connector running down the left edge, the section is legible, and there is no horizontal page scroll
    • Escalation branch — Given the boucle:human state, When rendered in either layout, Then it branches off the main path (not in sequence with the other eight) and the branching is visually clear
    • Content collection — Given a new loop-states collection, When the Astro build runs, Then one entry per state is loaded from src/content/loop-states/ with a schema (order, label, description, type) registered in src/content.config.ts
    • CMS editable — Given the Sveltia CMS admin at public/admin/config.yml, When an editor opens the CMS, Then the loop-states collection appears with fields matching the schema, editable like the other collections
    • Build passes — Given the implementation is complete, When npm run build runs, Then the build succeeds with no errors
    • No animation — Given the section is rendered, When the page loads or is scrolled, Then no animation or scroll-triggered reveal is applied to the states
    • No new colours — Given the section's CSS, When inspected, Then only existing DESIGN.md tokens are used (--accent gold for human, --accent-cyan for autonomous, --surface-raised for chips, --text-secondary for terminal)
    • Accessibility — Given the section is rendered, When a screen reader encounters it, Then each state chip has an accessible label and the section has a semantic heading and aria-label

    Must-haves

    • Truths — The section uses only existing DESIGN.md colour tokens; no animation is applied; the nine states render in the specified order; the autonomous/human/terminal distinction is visible by colour alone
    • Artifacts — src/content/loop-states/*.md (9 files, one per state), src/content.config.ts (new loopStates collection in the schema and exports), public/admin/config.yml (new collection entry), src/pages/index.astro (new section HTML + CSS between how-it-works and quick-start)
    • Key links — The new section is placed in the DOM between the how-it-works section and the why-boucle section (which precedes quick-start); the loopStates collection is registered in src/content.config.ts and exported in collections; the CMS collection in public/admin/config.yml mirrors the schema fields

    Non-goals

    • No animation or scroll-triggered reveal on the states section
    • Not adding these states to the README or docs — landing page only
    • Not making the chips link anywhere
    • Not adding new colours beyond the existing DESIGN.md tokens
    • Not modifying the existing how-it-works slideshow or why-boucle cards

    Impacts

    🏗️ ui, data-model

    Diagram

    The state machine the section visualizes — autonomous states (cyan), human-decision states (gold), and the escalation branch:

    %%{init: {"theme":"base","themeVariables":{"background":"transparent","primaryColor":"#f5c842","primaryTextColor":"#0d1117","primaryBorderColor":"#c9a233","lineColor":"#a0a0b8","secondaryColor":"#fdf3d7","tertiaryColor":"#e8e6f5","clusterBkg":"#faf7f2","clusterBorder":"#c9a233","edgeLabelBackground":"#ffffff","fontFamily":"Sora, system-ui, sans-serif","fontSize":"14px"}}}%%
    stateDiagram-v2
        [*] --> triage
        triage --> spec_review
        spec_review --> todo
        todo --> working
        working --> review
        review --> approval
        approval --> merging
        merging --> done
        done --> [*]
        working --> human : escalates
        review --> human : escalates
        human --> [*]
    
    Loading

    Impacted files

    📁 src/content.config.ts, src/content/loop-states/, src/pages/index.astro, public/admin/config.yml, DESIGN.md

    Classification

    Size: M
    Validation: author-required

    Questions

    none

    Disposition

    READY

    Validation

    Review the TL;DR above.

    • Reply with approved (just that word, on its own line) to approve the spec — nothing else approves it.
    • Or add the boucle:approved label to this issue to approve the spec.
    • To amend the spec, reply to this issue with your corrections: triage will re-run, read your reply, and post an updated spec for you to approve. Any other reply never approves the spec.
  2. baderdean commented on Aug 26, 2026

    @baderdean
    MemberAuthor

    approved

  3. baderdean commented on Aug 26, 2026

    @baderdean
    MemberAuthor

    📦 File-impact claim: DESIGN.md,public/admin/config.yml,src/content.config.ts,src/content/loop-states-header/loop-states-header.md,src/content/loop-states/state-1-triage.md,src/content/loop-states/state-2-spec-review.md,src/content/loop-states/state-3-todo.md,src/content/loop-states/state-4-working.md,src/content/loop-states/state-5-review.md,src/content/loop-states/state-6-approval.md,src/content/loop-states/state-7-merging.md,src/content/loop-states/state-8-done.md,src/content/loop-states/state-9-human.md,src/pages/index.astro

  4. baderdean commented on Aug 26, 2026

    @baderdean
    MemberAuthor
    ➰ boucle — loop state (machine-written, safe to ignore)

    Approach

    • Content model — added a loopStates folder collection (one .md per state) and a loopStatesHeader single-file collection, registered in src/content.config.ts. Schema { order, label, description, type, typeLabel } with type ∈ autonomous|human|terminal. All copy is CMS-editable (acceptance criterion 5), mirroring the existing why/cards split.
    • Nine states in order — triage, spec-review, todo, working, review, approval, merging, done, human (state-1..state-9 files). spec-review + approval are human (gold), the rest autonomous (cyan), done + human terminal (muted/strikethrough).
    • Section & layout — new <section class="loop"> between how-it-works and why-boucle in index.astro. Desktop ≥1024px: 4-column grid, left-to-right reading order; 768–1024px: 2 columns; <768px: single column with a connector rail down the left edge (no horizontal scroll at 390px). Conforms to DESIGN §2 (tokens), §3 (no motion), §4 (components).
    • Escalation branch — boucle:human is pulled out of the numbered <ol> into its own branch block beneath the sequence, with a visible join notch + "Escalation branch" tag, keeping the terminal (struck-through) treatment so it reads as an exit. Branch conveyed purely by layout, not a new colour.
    • Colour discipline — autonomous = --accent-cyan chip, human = --accent gold chip, terminal = --text-secondary chip, nodes on --surface-raised. No new colours, no hardcoded hex/rgba in the section CSS. No animation (non-goal).
    • Accessibility — semantic aria-label section + ordered list, each chip carries a visible typeLabel (colour is never the only signal), legend aria-hidden.
    • CMS + docs — added loopStates + loopStatesHeader collections to public/admin/config.yml; added a Loop states component spec to DESIGN.md (Docs impact per triage).

    Scope Self-Check

    Task as stated: add a loop-states section (collection, schema, render, CMS, responsive, no animation, no new colour) between how-it-works and why-boucle.
    Files I touched: 9 src/content/loop-states/*.md, loop-states-header.md, src/content.config.ts, src/pages/index.astro, public/admin/config.yml, DESIGN.md.
    Lines I'm tempted to add but won't: none — no animation JS, no chip links, no README/docs additions.
    Abstractions considered and rejected: a single header+state union collection (over-engineered vs the existing split); a per-node arrow/grid connector (fragile).
    Diff size: ~440 insertions.
    Could it be smaller? No — nine states, responsive layout, and CMS wiring are all required by the spec.

    Tried and rejected

    (none yet)

    Awaiting human

    nothing

  5. added a commit that references this issue on Oct 17, 2026
  6. baderdean commented on Oct 17, 2026

    @baderdean
    MemberAuthor

    VERDICT: FAIL

    • 🔴 New loop-states content collection with a schema, one entry per state, registered in src/content.config.ts — verified in source: loopStates folder collection (9 entries, schema: order/label/description/type/typeLabel, type enum autonomous|human|terminal) + loopStatesHeader; schema validated by a fresh npm run build.
    • 🔴 All nine states render in order with the autonomous/human/terminal distinction visible without reading the text — curl HTML + screenshots: cyan number badges/chips for autonomous, gold chips + "HUMAN DECIDES" typeLabel for spec-review/approval, muted struck-through chips for done/human; aria-hidden swatch legend.
    • 🔴 At 390px the section is legible with no horizontal page scroll — headless-Firefox screenshot at 390px: vertical list with connector rail down the left edge; DOM scrollWidth 378 ≤ clientWidth 378 (full page) and 390/390 (isolated section), no clipping or overflow.
    • 🔴 At 1440px the progression reads left-to-right without crowding — screenshot: 4-column grid, states 1–8 in order, escalation branch centred beneath.
    • 🔴 Editable from public/admin/config.yml like the other collections — loopStatesHeader (file collection) and loopStates (folder collection, create: true) both registered.
    • 🔴 npm run build passes — fresh run after clean npm install: build complete, exit 0, 1 page built.
    • 🔴 Escalation state branches off the main path and survives the vertical collapse — mobile: own branch block below state 8 with join notch + "ESCALATION BRANCH — EXITS THE LOOP" tag; desktop: centred beneath the grid.
    • 🔴 Live page renders clean: a raw CSS comment, /* ============ LOOP STATES ============ */ (src/pages/index.astro ~line 1828 — AFTER the closing </style> at line 1589, outside any tag), ships to production as visible text between how-it-works and the loop section. curl shows </section>/* ============ LOOP STATES ============ */<section class="loop" and screenshots at 390px and 1440px show TES ============== */ rendered as page text at the top of the section. Fix: delete the stray comment line in the markup (the one at ~line 1041 inside the style block is fine and can stay).
    • 🟡 Charter docs match production — DESIGN.md §Loop states documents exactly what shipped (collections, token-only colour coding, 1/2/4-column collapse, escalation branch, no scroll on mobile).
    • 💭 Animation/scroll-reveal non-goal respected — no keyframes or transition rules in the .loop* block; nothing animated to verify on the live page.
  7. baderdean commented on Oct 17, 2026

    @baderdean
    MemberAuthor

    E2E verification FAILED. A follow-up issue #112 has been opened in triage to fix the defect.

    Live URL

    https://ankaboot-source.github.io/boucle.dev/

    E2E trace

    <!-- boucle:verdict v=1 role=e2e sha=17323132fee3aa30addc42c620d3e0de6573d2ae -->
    VERDICT: FAIL
    - [x] 🔴 New `loop-states` content collection with a schema, one entry per state, registered in `src/content.config.ts` — verified in source: `loopStates` folder collection (9 entries, schema: order/label/description/type/typeLabel, type enum autonomous|human|terminal) + `loopStatesHeader`; schema validated by a fresh `npm run build`.
    - [x] 🔴 All nine states render in order with the autonomous/human/terminal distinction visible without reading the text — curl HTML + screenshots: cyan number badges/chips for autonomous, gold chips + "HUMAN DECIDES" typeLabel for spec-review/approval, muted struck-through chips for done/human; aria-hidden swatch legend.
    - [x] 🔴 At 390px the section is legible with no horizontal page scroll — headless-Firefox screenshot at 390px: vertical list with connector rail down the left edge; DOM scrollWidth 378 ≤ clientWidth 378 (full page) and 390/390 (isolated section), no clipping or overflow.
    - [x] 🔴 At 1440px the progression reads left-to-right without crowding — screenshot: 4-column grid, states 1–8 in order, escalation branch centred beneath.
    - [x] 🔴 Editable from `public/admin/config.yml` like the other collections — `loopStatesHeader` (file collection) and `loopStates` (folder collection, create: true) both registered.
    - [x] 🔴 `npm run build` passes — fresh run after clean `npm install`: build complete, exit 0, 1 page built.
    - [x] 🔴 Escalation state branches off the main path and survives the vertical collapse — mobile: own branch block below state 8 with join notch + "ESCALATION BRANCH — EXITS THE LOOP" tag; desktop: centred beneath the grid.
    - [ ] 🔴 Live page renders clean: a raw CSS comment, `/* ============ LOOP STATES ============ */` (src/pages/index.astro ~line 1828 — AFTER the closing `</style>` at line 1589, outside any tag), ships to production as visible text between `how-it-works` and the loop section. curl shows `</section>/* ============ LOOP STATES ============ */<section class="loop"` and screenshots at 390px and 1440px show `TES ============== */` rendered as page text at the top of the section. Fix: delete the stray comment line in the markup (the one at ~line 1041 inside the style block is fine and can stay).
    - [x] 🟡 Charter docs match production — DESIGN.md §Loop states documents exactly what shipped (collections, token-only colour coding, 1/2/4-column collapse, escalation branch, no scroll on mobile).
    - [x] 💭 Animation/scroll-reveal non-goal respected — no keyframes or transition rules in the `.loop*` block; nothing animated to verify on the live page.
    
    <!-- boucle:agent -->
    

    Closing this issue — work continues in #112.

  8. added a commit that references this issue on Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions