docs: add specification, reference docs, workplan, and agent guidance

Adds all Phase 0 content that was created but never committed:
- CLAUDE.md and SCOPE.md — agent and developer orientation
- specs/TailwindForInteractionHubs_v0.2.md — IHF Tailwind coding guide
- docs/ — five IHP v1.5 reference guides (overview, data, controllers, realtime, ihf-mapping)
- workplans/IHUB-WP-0001 — Phase 1 implementation plan (12 tasks, state-hub synced)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-27 02:07:13 +01:00
parent 75b88ee760
commit 8b6ce5bbc8
9 changed files with 2181 additions and 0 deletions

View File

@@ -0,0 +1,289 @@
# Tailwind for Interaction Hubs
**Agentic Coding Best-Practice Guide**
*For building governed, observable, antifragile hub interfaces with Tailwind + IHP*
**Version:** 0.2 (Agent-Optimized)
**Status:** Production-Ready Reference
**Audience:** Human developers **and** coding agents (LLMs)
**Framework:** IHP (Integrated Haskell Platform) + Interaction Hub Framework (IHF) layer
**Date:** March 2026
---
## 0. Quick-Start for Coding Agents (READ THIS FIRST)
When you receive a UI task for an Interaction Hub:
1. **Semantic first** — Never start with classes. Ask: “What IHF primitive/widget does this map to?”
2. **Import hierarchy** — Always `import Web.View.IHF.Primitives`, `Web.View.IHF.Widgets`, `Web.View.IHF.Classes`.
3. **Use wrappers** — Render via `widgetFrame`, `signalBadge`, `hubActionButton`, etc.
4. **Token roles only** — Reference `surfaceBase`, `signalSuccess`, `focusRing` (defined in `Theme.hs`).
5. **No raw soup** — If you see >8 utility classes in one element, extract to a helper.
6. **Document for reproducibility** — Every new primitive gets Haddock + example HSX.
This guide is your single source of truth. Follow it → zero drift.
---
## 1. Purpose
This guide makes **Tailwind the shared visual grammar** for all Interaction Hubs built on IHP + IHF, while keeping the **IHF semantic model** (Widget, Panel, SignalBadge, etc.) as the architectural control point.
It guarantees:
- Perfect visual coherence across hubs
- Zero CSS entropy
- Agent-reproducible styling (no folklore)
- Governed evolution via semantic contracts
- Full compatibility with IHPs server-rendered HSX, partial updates, and future islands
**Tailwind is the substrate. IHF widgets are the product.**
---
## 2. Core Principle (Agent Rule #1)
```hs
-- ALWAYS do this
widgetFrame widget content
-- NEVER do this
<div class="rounded-xl border border-slate-700 bg-slate-900/80 px-4 py-3 shadow-sm ...">
```
**Architecture layers (enforced order):**
1. **IHF Semantic Model** (`Widget`, `HubPanel`, `CommentThread`…)
2. **Visual Primitive Contracts** (`Primitives.hs`)
3. **Tailwind Token Application** (centralized in `Classes.hs` + `tailwind.config.js`)
4. **Screen Composition**
---
## 3. IHP + Tailwind Setup (Mandatory Baseline)
Follow the official IHP Tailwind guide, then apply these IHF extensions:
### Required Files (exact locations)
```text
Project Root
├── tailwind/
│ ├── tailwind.config.js ← extend with IHF tokens
│ └── app.css
├── Web/View/IHF/
│ ├── Theme.hs ← semantic roles
│ ├── Tokens.hs ← spacing/radius/shadow maps
│ ├── Classes.hs ← reusable class builders
│ ├── Primitives.hs ← surface, panel, badge, button…
│ ├── Widgets.hs ← widgetFrame, inspectorPanel…
│ ├── Patterns.hs ← triageDashboard, decisionBoard…
│ ├── AnnotationUI.hs
│ └── GovernanceUI.hs
├── Web/View/CustomCSSFramework.hs ← IHP component override (required for JIT)
└── Config/Config.hs ← option customTailwind
```
**Key tailwind.config.js snippet (add to IHF theme):**
```js
theme: {
extend: {
colors: {
surfaceBase: "hsl(var(--surface-base))",
signalSuccess: "hsl(var(--signal-success))",
// … all roles from Theme.hs
},
spacing: { /* baseline rhythm */ },
}
}
```
**CustomCSSFramework.hs** must expose `customTailwind` with Tailwind classes for all IHP form/button/flash helpers.
---
## 4. Recommended Layer Model (Agent Reference)
| Layer | Name | Lives In | Example Functions | Purpose |
|-------|-----------------------------|-------------------|---------------------------------------|---------|
| A | Semantic Interaction | Widgets.hs / Types | `widgetFrame`, `commentRail` | What it *is* |
| B | Visual Primitive | Primitives.hs | `panel`, `signalBadge`, `actionButton` | Reusable building blocks |
| C | Tailwind Utility Application| Classes.hs | `panelClasses`, `badgeVariant` | Actual classes |
| D | Screen Composition | Patterns.hs | `triageDashboard` | Workflow views |
---
## 5. Golden Rules for Agents
- **Rule 1**: Every visual element must have a named Haskell wrapper (no raw `<div class="…">` longer than one line).
- **Rule 2**: All color/spacing decisions go through `Theme.hs` roles.
- **Rule 3**: Variant logic must be exhaustive and named (`primary | ghost | danger`).
- **Rule 4**: Commentability is first-class — every widget primitive exposes `commentable :: Bool`.
- **Rule 5**: Before writing any new class string, check `Classes.hs`. If missing, add it there with documentation.
---
## 6. Visual Language & Tokens (Copy-Paste Ready)
### 6.1 Color Roles (Theme.hs)
```hs
surfaceBase, surfaceRaised, surfaceMuted,
borderSubtle, borderStrong,
textPrimary, textSecondary, textMuted,
signalInfo, signalSuccess, signalWarning, signalDanger,
focusRing, commentAccent, policyAccent, outcomeAccent
```
Map these to CSS variables in `tailwind/app.css` `@layer base`.
### 6.2 Spacing Rhythm (Tokens.hs)
```hs
space1, space2, space3, space4, space6, space8, space12, space16
```
Use only these. Arbitrary values are forbidden.
### 6.3 Radius & Shadow
```hs
roundedPanel = "rounded-xl"
roundedBadge = "rounded-lg"
shadowLight = "shadow-sm"
```
---
## 7. Core Primitives (Primitives.hs — Starter Template)
```hs
-- Example: panel
panel :: [Attribute] -> Html -> Html
panel attrs content = div!
( [ class_ (panelClasses <> " " <> unwords (map renderAttr attrs))
, role_ "region"
] )
content
panelClasses :: Text
panelClasses = "bg-surfaceBase border border-borderSubtle rounded-xl shadow-sm px-4 py-3"
-- Example: signalBadge
signalBadge :: SignalStatus -> Html
signalBadge status = span!
[ class_ (badgeVariant status) ]
[ text (statusLabel status) ]
```
All primitives follow this exact signature pattern.
---
## 8. Widget-Centered Rules (IHF Core)
Every `Widget` **must** render via `widgetFrame`:
```hs
widgetFrame :: Widget -> (Widget -> Html) -> Html
widgetFrame w inner = div!
[ class_ widgetFrameClasses
, dataAttribute "widget-id" (widgetId w)
, dataAttribute "commentable" (show $ isCommentable w)
] $ do
widgetHeader w
inner w
widgetFooter w
```
State cues (inspectable, commentable, in-flight) use **one** consistent visual language (header accent + badge + subtle background shift).
---
## 9. Agent-Friendly Practices
### 9.1 Component Creation Protocol (Mandatory)
When creating a new primitive:
1. Add to `Primitives.hs` with full Haddock:
```hs
{-# LANGUAGE OverloadedStrings #-}
-- | A governed action button. Variants map to IHF policy levels.
actionButton :: ActionVariant -> Text -> Html
```
2. Define variant type in `Types.hs`.
3. Implement class builder in `Classes.hs`.
4. Add example usage in `docs/Examples.hs`.
5. Update `Short Operational Checklist` (section 26).
### 9.2 Prompt Template for Future Agents
> “Generate an IHF widget for X using only primitives from Web.View.IHF. Use semantic roles from Theme.hs. No raw Tailwind soup. Include comment affordance.”
---
## 10. Anti-Patterns (Hard-Coded Agent Rejection Rules)
- Utility soup longer than 6 classes
- Screen-local button/panel/badge reinvention
- Literal color names in component signatures
- Mixed density without system-level justification
- Styling logic inside business controllers
- Any custom CSS outside `tailwind/app.css` `@layer components`
---
## 11. Forms, Tables, Annotations, Governance (IHF-Specific)
- **Forms**: Use `styledFormGroupClass` from `CustomCSSFramework.hs` + `fieldWithPolicyNote`.
- **Tables**: Standardized `sortableTable` in `Patterns.hs` with actor/timestamp/state columns.
- **Annotations**: First-class `annotationThread` + triage variants (`open | reviewed | policySensitive`).
- **Governance**: `decisionBanner`, `policyScopeBadge`, `traceabilityChain` — all with built-in comment hooks.
---
## 12. File & Module Organization (Exact)
See section 3. All IHF UI lives under `Web/View/IHF/`.
Import graph is strict: `Patterns.hs` → `Widgets.hs` → `Primitives.hs` → `Classes.hs` → `Theme.hs`.
---
## 13. Rollout Phases & Minimum Standard
**Phase 1 (MVP)**: Theme + Tokens + Primitives (panel, button, badge, widgetFrame)
**Phase 2**: AnnotationUI + GovernanceUI
**Phase 3**: Hub-specific accents + adaptive patterns
**Every new component** must ship with:
- Purpose
- Type signature
- Allowed variants
- Accessibility notes
- Commentability behavior
- Example HSX
---
## 14. Short Operational Checklist (Agent + Human Merge Gate)
Before any PR/merge:
- [ ] Semantic name used
- [ ] Imported only from IHF modules
- [ ] Classes composed via `Classes.hs`
- [ ] State signaling matches existing system
- [ ] Focus + contrast + color+icon rule satisfied
- [ ] Comment affordance present where applicable
- [ ] No custom CSS added
- [ ] Agent reproduction test passed (copy-paste into new context works)
---
## 15. Motto
**“Use Tailwind for expression. Let IHF widgets define meaning.”**
This guide is the contract between humans and agents. Follow it and Interaction Hubs stay coherent, evolvable, and antifragile forever.