Skip to content

Governed Generation — Nav Rename and Dropdown Consolidation

Ticket: PHON-41 (parent: PHON-4 — Governed Generation UI polish) Branch: feature/phon-41-governed-gen-nav-layout (from develop) Date: 2026-04-18 Status: Spec for review

Problem

The Governed Generation tool has two user-facing naming and layout issues:

  1. Wrong framing in the tool nav. The tool appears in the main navigation as Constrained Generation (packages/web/frontend/src/App_new.tsx, id: 'constrainedGeneration', title: 'Constrained Generation'). The rest of the codebase — component name (GovernedGenerationTool), package names, CLAUDE.md, memory, Confluence KB — uses Governed Generation. The nav label is the lone holdout. It is also conceptually wrong: the governors govern the constraints the user chooses — governor > constraints.
  2. Five flat top-level accordions inside the tool, with mixed axes. The current sections (Phoneme Exclusion, Phoneme Inclusion, Psycholinguistic Bounds, Word List Boost, Contrastive Pairs) interleave three BAN/BOOST pairings and one relational section. Users must visually re-group as they compose constraints.

Design

1. Tool nav renaming (packages/web/frontend/src/App_new.tsx)

  • title: 'Constrained Generation''Governed Generation'
  • description: 'Constrained content generation …''Governed content generation with phonological targets, psycholinguistic bounds, and compliance analysis.'
  • id: 'constrainedGeneration''governedGeneration'
  • Matching key in TOOL_COMPONENTS updated to governedGeneration

The id rename is safe: it has only two internal consumers (TOOL_DEFINITIONS and TOOL_COMPONENTS), no URL routing, no analytics keying, no deep-link callers.

2. Accordion consolidation (5 → 3)

Collapse by domain, preserving platform-wide BAN/BOOST language:

New accordion Replaces Mode toggle Source component
Phonemes Phoneme Exclusion + Phoneme Inclusion BAN \| BOOST PhonemeConstraints.tsx (already hosts both)
Psycholinguistics Psycholinguistic Bounds + Word List Boost BAN \| BOOST New PsycholinguisticsSection.tsx (merges BoundsSection.tsx and WordListBoostSection.tsx)
Contrastive Sets Contrastive Pairs MINPAIR \| MAXOPP ContrastiveSection.tsx (rename toggle labels only)

Inside each accordion:

  • Mode toggle at top (ToggleButtonGroup, exclusive). Controls which form is shown for adding new entries. Does not hide existing entries.
  • Only the "add new" form at the top of the accordion swaps with the toggle. Existing entries keep their per-entry displays and inline controls (e.g., BOOST phoneme's coverage slider, BOUND_BOOST property's range + coverage) regardless of toggle state — all entries remain editable and deletable at all times.
  • Both chip lists render below the add form, always visible, color-coded consistent with current palette:
  • BAN chips: color="error" (red, outlined)
  • BOOST chips: color="success" (green, outlined)
  • Accordion-header summary chip shows both counts side-by-side when either is non-zero — e.g., 2 BAN · 3 BOOST. When both are zero, no chip is rendered. The chip's numbers update live as entries are added/removed.

3. Toggle labels

Short, all-caps, parallel across all three accordions:

  • BAN | BOOST (Phonemes, Psycholinguistics)
  • MINPAIR | MAXOPP (Contrastive Sets — currently Minimal Pair / Maximal Opposition)

4. State and behavior

  • Toggle state: component-local useState. Resets on tool unmount.
  • Default mode: BAN / MINPAIR.
  • Not persisted to the constraint store. The store already tracks entry types per-entry (exclude, include, bound, bound_boost, contrastive) — the toggle is a UI affordance for "what am I adding next?", not a semantic state.

5. Accordion helper copy

Each accordion keeps a single caption line under the toggle that adapts to mode. Reuses copy from the retired components verbatim:

  • Phonemes / BAN: "Block phonemes from appearing in generated output."
  • Phonemes / BOOST: "Encourage phonemes in generated output. Set a coverage target — e.g., 20% means roughly 1 in 5 content words will contain the phoneme. The system self-regulates across the output."
  • Psycholinguistics / BAN: "Exclude words outside property thresholds. Function words (the, a, is, etc.) are always allowed."
  • Psycholinguistics / BOOST: "Encourage words that meet psycholinguistic criteria. Set a coverage target for how many content words should come from the boosted list."
  • Contrastive Sets: existing caption unchanged.

Files

Modified:

  • packages/web/frontend/src/App_new.tsx — nav rename (id, title, description, TOOL_COMPONENTS key).
  • packages/web/frontend/src/components/tools/GovernedGenerationTool/index.tsx — replace <BoundsSection /> + <WordListBoostSection /> with <PsycholinguisticsSection />; reorder so the three accordions render as Phonemes, Psycholinguistics, Contrastive Sets.
  • packages/web/frontend/src/components/tools/GovernedGenerationTool/PhonemeConstraints.tsx — convert from two sibling accordions (ExclusionSection + InclusionSection) to a single accordion with a BAN | BOOST toggle and both chip lists always visible. Header summary chip shows combined ban/boost count.
  • packages/web/frontend/src/components/tools/GovernedGenerationTool/ContrastiveSection.tsx — toggle labels only: Minimal PairMINPAIR, Maximal OppositionMAXOPP.

New:

  • packages/web/frontend/src/components/tools/GovernedGenerationTool/PsycholinguisticsSection.tsx — merges the behavior of BoundsSection.tsx and WordListBoostSection.tsx into a single accordion with a BAN | BOOST toggle.

Retired:

  • packages/web/frontend/src/components/tools/GovernedGenerationTool/BoundsSection.tsx — delete.
  • packages/web/frontend/src/components/tools/GovernedGenerationTool/WordListBoostSection.tsx — delete.

Unchanged:

  • Constraint store (store/constraintStore.ts), store schema, compiler (lib/constraintCompiler.ts), generation API client, output feed, compliance visualization, server-status chip, ActiveConstraints, backend, Workers API.

Out of scope

  • No changes to constraint semantics or the API contract.
  • No new sub-header layer above the three accordions.
  • No change to ActiveConstraints chip summary or OutputFeed.
  • No relocation of the server-status chip.
  • No icon changes.
  • No changes to the TermsOfService, App_new.tsx line-16 comment ("Governed Generation (coming soon)" — stale but unrelated), or other documentation outside this tool. A separate pass can clean those up.

Verification

  • Visual check in the browser (dev server on http://localhost:3000/): tool nav shows "Governed Generation"; three accordions appear in order Phonemes, Psycholinguistics, Contrastive Sets; each toggle swaps the form; both chip lists stay visible; count summary reflects both modes.
  • Frontend type check passes (npm run build or tsc --noEmit in packages/web/frontend).
  • Existing Vitest suite under packages/web/workers untouched (this is a frontend-only change; no API changes).

Follow-ups (separate tickets if surfaced)

  • App_new.tsx line-16 comment // - Governed Generation (coming soon) is stale; not strictly in-scope but trivial to tidy alongside.
  • PHON-41 ticket wording mentions "5 top-level dropdowns" — update to "3 top-level dropdowns, consolidated from 5" after merge.