---
name: catalyst-form-composer-auditor
description: >
  Compose and audit Aurora Catalyst detail/form components against a self-contained ruleset (see
  `references/catalyst-detail-form-rules.md`). Two modes: COMPOSE (generate form code from
  schema/brief) and AUDIT (evaluate an existing form via three parallel specialized judges — PRD
  Compliance, Domain Coherence, Visual & UX). Trigger: when user asks to compose, build, generate,
  audit, review, or evaluate a detail/form component; when editing `*-detail.component.ts` or
  `*-form.component.ts`; when user mentions `hlm-dialog`, `hlm-tabs`, `hlm-field` in a form context;
  when user says "componer form", "auditar form", "form composer", "form audit".
license: Apache-2.0
metadata:
  author: aurora
  version: '1.0'
---

## When to Use

- User asks to **compose** a new detail/form component from a schema, brief, or description
- User asks to **audit** an existing detail/form component (correctness, organization, UX)
- User is editing a `*-detail.component.ts`, `*-form.component.ts`, or dialog variant and wants
  validation against the PRD
- User mentions balancing form layout: dialog vs view, tabs vs groups, col-span tiers
- User wants to evaluate visual stress, field grouping, visual hierarchy, or UX on a form

---

## Two Modes

This skill has exactly two modes. Pick one based on the user's intent — never run both.

| Mode        | Trigger                              | Output                                                                    |
| ----------- | ------------------------------------ | ------------------------------------------------------------------------- |
| **COMPOSE** | "create/generate/compose form for X" | A complete Angular component (TS + inline template) following the PRD     |
| **AUDIT**   | "audit/review/evaluate this form"    | A verdict table with findings from 3 parallel judges + optional fix round |

If the user's intent is ambiguous, **STOP and ASK**: _"¿Querés que lo componga desde cero o que
audite uno existente?"_

---

## Ruleset Reference

The authoritative, self-contained ruleset lives at `./references/catalyst-detail-form-rules.md`
(inside this skill). Read it in full when any rule below is ambiguous for the case at hand. Below is
the **compact ruleset** — enough for 90% of decisions, and what gets injected into sub-agent
prompts.

> **Autonomy note**: this skill does NOT depend on any file outside its own directory. The ruleset
> was originally synthesized from the Aurora Catalyst CLI PRD, but the local resource is now the
> source of truth. If upstream conventions evolve, update `references/catalyst-detail-form-rules.md`
> AND the compact section below in lockstep.

### Module-level config (under `front`)

| Field               | Type                 | Default  | Effect                                     |
| ------------------- | -------------------- | -------- | ------------------------------------------ |
| `front.detailMode`  | `'dialog' \| 'view'` | `'view'` | Full page (view) or modal overlay (dialog) |
| `front.outlineIcon` | string               | —        | Header icon                                |
| `front.solidIcon`   | string               | —        | Header icon (solid variant)                |

### Property-level config (under `widget`)

| Field                         | Type    | Effect                                                                                              |
| ----------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| `widget.tab`            | string  | Tab id. Fields sharing `tab` render in the same tab panel. **View mode only.**                      |
| `widget.group`          | string  | Section id. Fields sharing `group` render under a common section title + separator. **Both modes.** |
| `widget.detailSort`     | number  | Ascending order within group. Default `Infinity`.                                                   |
| `widget.isDetailHidden` | boolean | Hides field from the form.                                                                          |
| `widget.type`           | string  | Relationship selector (`select`, `multiple-select`, `grid-select-element`, etc.)                    |

### Dispatch (2 levels)

```
for property in getFormDetailFieldsProperties(aggregateProperties):
  if property.widget?.type exists:
    -> partials/relationships/{type}-field.eta
  else:
    -> partials/fields/{property.type}-field.eta
```

### Grid tiers

| Field count | Dialog mode        | View mode                     |
| ----------- | ------------------ | ----------------------------- |
| ≤5          | `compact` (grid-2) | `compact` (grid-2 + max-w-lg) |
| 6–10        | `medium` (grid-6)  | `medium` (grid-6 + max-w-3xl) |
| >10         | `medium` (capped)  | `full` (grid-12, full width)  |

### Col-span proportions (AUTHORITATIVE)

Proportion per grid tier:

| Proportion | compact | medium | full |
| ---------- | ------- | ------ | ---- |
| third      | 1       | 2      | 4    |
| half       | 1       | 3      | 6    |
| twoThirds  | 1       | 4      | 8    |
| full       | 2       | 6      | 12   |

Length → proportion:

| Length    | Proportion |
| --------- | ---------- |
| undefined | full       |
| ≤30       | third      |
| ≤60       | half       |
| ≤90       | twoThirds  |
| >90       | full       |

Type → proportion:

| Type                           | Proportion                                         |
| ------------------------------ | -------------------------------------------------- |
| boolean, date, timestamp, enum | third                                              |
| password                       | half                                               |
| char                           | `lengthToProportion(length)`                       |
| varchar, int, smallint, bigint | `lengthToProportion(maxLength)`                    |
| decimal, float                 | `lengthToProportion(decimals[0])`                  |
| text                           | full                                               |
| id, relationship               | half (full if `widget.type` includes "grid") |

### Rendering hierarchy

```
Has any field with `tab`?
  YES → <hlm-tabs>
          for each unique tab:
            <hlm-tabs-content>
              Has any field in this tab with `group`?
                YES → for each unique group: <section + title> + <separator>
                NO  → flat fields
  NO  → Has any field with `group`?
          YES → for each unique group: <section + title> + <separator>
          NO  → flat fields
```

**Critical**: `tab` is **ignored in dialog mode** (too little space).

### Field partial contract

```html
<hlm-field class="{{ colSpan }}">
  <label
    hlmLabel
    for="{{ fieldId }}"
  >
    {{ label }}
  </label>
  <CONTROL
    formControlName="{{ fieldName }}"
    ...
  />
  <hlm-field-error>{{ signalForm.get('fieldName')?.errors | validationMessage }}</hlm-field-error>
</hlm-field>
```

### Exclusions (never rendered in forms)

- Timestamps: `createdAt`, `updatedAt`, `deletedAt`
- Internal: `rowId`, `meta` (jsonb)
- Hidden flag: `widget.isDetailHidden: true`
- Excluded types: non-enum `array`, `jsonb`
- Relationships: `one-to-many` (rendered elsewhere)
- `id`: included in FormGroup for submit, NOT rendered

### Ordering

1. Filter out hidden/excluded
2. Group by `tab` → tabs render in order of first field appearance
3. Within each tab, group by `group` → sections render in order of first field appearance
4. Within each group, sort by `detailSort` ascending (no-sort → Infinity → last)

### Prototype-specific adaptations

This skill runs inside `aurora-catalyst-prototype`. When composing or auditing here:

- No Transloco — use direct string labels (e.g., `"Name"` not `{{ t('iam.tag.Name') }}`)
- No codegen types — use `.types.ts` interfaces
- Signals + mock services instead of GraphQL composables
- Keep the PRD's **layout, composition, and FormGroup structure** identical (those are what migrate
  back to catalyst)

---

## MODE 1 — COMPOSE

### Protocol

1. **Resolve input**. Accept one of:
   - A `.aurora.yaml` schema excerpt
   - A TypeScript `.types.ts` interface
   - A free-form brief (list of fields + types + intent) If the input lacks field types or counts,
     STOP and ASK.

2. **Decide detail mode** if not explicit:
   - ≤5 fields without nested sections → suggest **dialog**
   - > 5 fields OR fields have `tab` → suggest **view**
   - Always confirm with user before generating.

3. **Delegate to executor sub-agent** (single delegation, fresh context) with the Executor Prompt
   below. Pass: schema/interface, detail mode, module name, and the compact PRD ruleset from this
   file.

4. **Review executor output inline** — do not re-delegate unless the output breaks the partial
   contract. Check: imports, OnPush, FormGroup validators, col-span classes, grid-cols classes,
   dispatch correctness.

5. **Hand to user** with a short summary of decisions taken (tier chosen, groups/tabs applied, any
   deviations).

### Executor Prompt Template

```
You are composing an Angular detail/form component for Aurora Catalyst prototype.

## Input
{paste schema / interface / brief}

## Detail Mode
{dialog | view}

## Module Name
{module-name}

## PRD Ruleset (compact)
{paste the "PRD Reference" section of this skill verbatim}

## Prototype Context
- Frontend-only prototype under aurora-catalyst-prototype
- No Transloco: use direct string labels
- Signals + mock services (no GraphQL)
- Spartan NG (Helm) components
- Standalone components, OnPush, inline template, tab indentation

## Your Task
1. Filter excluded properties
2. Sort by detailSort
3. Group by tab (if any) and by group (if any)
4. Determine grid tier from visible field count
5. For each field: calculate colSpan + pick the correct Spartan control
6. Generate the FormGroup with validators and pickModel defaults
7. Emit a complete standalone component (TypeScript + inline HTML template)

## Output Format
Return the component file content ready to write to disk. Include:
- Imports (grouped: Angular, router, ng-icons, Spartan, local)
- @Component decorator with OnPush + imports array
- Inline template using the field partial contract
- Class body: FormGroup signal, submit handler, cancel handler

Do NOT include Transloco directives, codegen imports, or GraphQL composables.

If any PRD rule is ambiguous for this input, emit a comment `<!-- TODO: ambiguity — {question} -->`
so the orchestrator can surface it to the user.
```

---

## MODE 2 — AUDIT

### Protocol

1. **Resolve target**. The user must point to one of:
   - A file path (`path/to/*-detail.component.ts`)
   - A snippet of code
   - A directory to audit every form in it (one audit per file) If unclear, STOP and ASK.

2. **Pre-analysis (orchestrator, inline)**. Read the target file and extract:
   - Field count (visible in form)
   - Detail mode (dialog / view)
   - Presence of tabs / groups
   - Field types present This summary is passed to all three judges as context.

3. **Launch 3 judges in parallel** via the `Agent` tool (`subagent_type: general-purpose`). All
   three in a single message (parallel tool calls). Each judge receives:
   - The target (file content + pre-analysis)
   - Its specialized prompt (below)
   - The compact PRD ruleset from this skill

4. **Wait for all 3 to complete.** Do not synthesize partial results.

5. **Synthesize verdict** (orchestrator, inline — NEVER delegate). Each judge is the **authority in
   its lens**. A finding reported by the PRD judge is a PRD issue; no cross-confirmation needed.
   Contradictions across lenses are rare — flag them if they appear.

6. **Present verdict table** to user (format below). Classify each finding by severity:
   - `CRITICAL` → breaks the PRD contract or produces a broken UI
   - `WARNING (real)` → creates real UX friction for a normal user
   - `WARNING (theoretical)` → contrived scenario only; INFO only, do NOT fix
   - `SUGGESTION` → non-blocking improvement

7. **Ask**: _"¿Arreglo los issues confirmados? / Fix confirmed issues?"_

8. **On user approval**, delegate a **Fix Agent** with the confirmed findings. Fix Agent runs alone
   (not parallel with judges). After it returns, re-launch **only the judges whose domain was
   touched**. If only PRD issues were fixed, re-run PRD judge. If visual layout was touched, re-run
   Visual & UX judge. This is different from judgment-day because judges are specialized — you don't
   need to re-judge a lens that wasn't affected.

9. **Iterate** max 2 fix rounds. After round 2, if issues remain, ASK the user before continuing.

### Judge 1 — PRD Compliance (objective)

Scope: everything **verifiable against the PRD**. Binary verdicts, no opinion.

```
You are an adversarial reviewer specialized in Aurora Catalyst PRD compliance.

## Target
{paste file path + full code + pre-analysis summary}

## PRD Ruleset (your only source of truth)
{paste the "PRD Reference" section of this skill verbatim}

## Your Lens — CHECK ONLY THESE
1. Dispatch: each field goes to the correct partial type
   (widget.type → relationship; else property.type → field)
2. Col-span: each field's col-span class matches calculateFieldColSpan(type, length, gridMode)
3. Grid tier: form grid-cols matches visible field count tier
   (≤5 compact, 6-10 medium, >10 full for view / medium-capped for dialog)
4. Validators: required iff !nullable; maxLength / minLength / length present when spec'd
5. pickModel defaults: initial FormGroup values match the PRD default table
6. Excluded properties: createdAt, updatedAt, deletedAt, rowId, meta, one-to-many, array (non-enum),
   jsonb, isDetailHidden — none of these should be rendered
7. id field: included in FormGroup for submit but NOT rendered in template
8. Ordering: fields sort by detailSort; tabs and groups in order of first field appearance
9. Partial contract: every field is `<hlm-field class="{colSpan}">` → `<label hlmLabel>` →
   CONTROL → `<hlm-field-error>`
10. Dialog-mode tabs: if detailMode is dialog and any field has `tab`, that's a violation
    (tabs are view-mode only)

## Return Format
Structured findings only. No praise. No approval.

Each finding:
- Severity: CRITICAL | WARNING (real) | WARNING (theoretical) | SUGGESTION
- File:Line (if applicable)
- Rule violated: cite the exact rule (e.g., "col-span proportion for varchar maxLength=20 → third → col-span-2 in medium, got col-span-4")
- Suggested fix: one-line intent

If no issues: `VERDICT: CLEAN — PRD compliance verified.`

End with: `Judge: PRD Compliance | Findings: {N}`
```

### Judge 2 — Domain Coherence (semantic)

Scope: do the groupings make **conceptual sense** given the field names and domain?

```
You are an adversarial reviewer specialized in semantic coherence of form field groupings.

## Target
{paste file path + full code + pre-analysis summary}

## PRD Ruleset (for organizational syntax only)
{paste the "PRD Reference" section of this skill verbatim}

## Your Lens — CHECK ONLY THESE
1. Do fields sharing the same `group` value belong conceptually together? Read field NAMES and
   types. Examples:
   - `name + email + phone` in `contact` → coherent ✓
   - `name + mealStart + password` in `config` → incoherent ✗ (unrelated concepts)
2. Do `tab` values separate genuinely distinct flows? A tab is justified only when fields
   represent a different user intent (e.g., "personal data" vs "security" vs "preferences").
   Decoration is not justification.
3. Is the `detailSort` order natural for filling? Typical rhythm:
   identification → descriptive → temporal → configuration → metadata.
4. Orphan fields: is there a field without `group` that clearly belongs with a grouped set?
5. Over-grouping: is there a group with only 1 field? That's over-structure — either merge or
   drop the group.
6. Under-grouping: is there a flat form with 8+ fields that clearly has subdomains? Propose
   groups.

## Return Format
Structured findings. Cite field names. Propose the corrected grouping when flagging.

Each finding:
- Severity: WARNING (real) | SUGGESTION (rarely CRITICAL — this lens is about quality, not correctness)
- Fields involved: (list)
- Issue: what's semantically off
- Proposed regrouping: concrete new group/tab assignment

If no issues: `VERDICT: CLEAN — Domain coherence verified.`

End with: `Judge: Domain Coherence | Findings: {N}`
```

### Judge 3 — Visual & Cognitive Load (perceptual)

Scope: how the form **feels** to complete.

```
You are an adversarial reviewer specialized in visual weight and cognitive load of forms.

## Target
{paste file path + full code + pre-analysis summary}

## PRD Ruleset (for layout choices)
{paste the "PRD Reference" section of this skill verbatim}

## Design System Reference
Also consult the layout-design-system skill (`.claude/skills/layout-design-system/SKILL.md`)
for spacing, density, and visual hierarchy rules.

## Your Lens — CHECK ONLY THESE
1. **Vertigo at the void**: a view-mode form with ≤3 visible fields feels empty and floating.
   → Propose dialog mode.
2. **Visual stress**: a flat form with 10+ fields without tabs/groups overwhelms.
   → Propose groups (if fields fall into subdomains) or tabs (if there are distinct flows).
3. **Grid tier mismatch**: the field count vs chosen tier — is the density right? A medium grid
   with 3 fields wastes space; a compact grid with 12 fields feels cramped.
4. **Visual weight balance**: does a `text` spanning full column sit next to 5 `boolean`
   switches? That descompensa the visual rhythm. Propose reordering or splitting.
5. **Prominence of critical fields**: is the primary identifier (name, title, code) visually
   prominent? Is it first, with proper emphasis? Required fields — are they visible at a glance?
6. **Emphasis proposals**: which components should be highlighted (full-width, top placement,
   visual separator above)? Propose concrete emphasis moves.
7. **Comprehension path**: can a first-time user fill this form top-to-bottom, left-to-right,
   without backtracking? Flag jarring jumps or unnatural orderings.

## Return Format
Structured findings. Focus on *felt* issues, not rule violations.

Each finding:
- Severity: WARNING (real) | SUGGESTION
- Issue: what feels off
- Perceptual reason: why it creates stress or confusion
- Concrete fix: reorder, regroup, change mode, change tier, emphasize field, etc.

If no issues: `VERDICT: CLEAN — Visual & cognitive load balanced.`

End with: `Judge: Visual & UX | Findings: {N}`
```

### Verdict Synthesis Format

```markdown
## Form Audit — {target path}

### Pre-analysis

- Detail mode: {dialog | view}
- Field count: {N} visible, {M} excluded
- Tabs: {list or "none"}
- Groups: {list or "none"}
- Grid tier: {compact | medium | full}

### Round {N} — Findings by Lens

#### PRD Compliance ({count})

| Severity | File:Line | Rule | Fix |
| -------- | --------- | ---- | --- |
| CRITICAL | ...       | ...  | ... |

#### Domain Coherence ({count})

| Severity | Fields          | Issue                             | Proposed regrouping            |
| -------- | --------------- | --------------------------------- | ------------------------------ |
| WARNING  | name, mealStart | Mixed concepts in `general` group | Split: `identity` + `schedule` |

#### Visual & UX ({count})

| Severity | Issue                 | Fix                   |
| -------- | --------------------- | --------------------- |
| WARNING  | 3 fields in view mode | Switch to dialog mode |

### Totals

- CRITICAL: {N}
- WARNING (real): {N}
- WARNING (theoretical): {N} — INFO only
- SUGGESTION: {N}

---

### ¿Arreglo los issues confirmados? / Fix confirmed issues?
```

### Fix Agent Prompt

```
You are a surgical fix agent for an Aurora Catalyst form component.

## Target File
{path}

## Confirmed Issues
{paste the findings table — only CRITICAL + WARNING (real)}

## PRD Ruleset
{paste the "PRD Reference" section of this skill verbatim}

## Instructions
- Fix ONLY the confirmed issues listed
- Do NOT refactor beyond what each fix requires
- If fixing a pattern in one place, search for the same pattern across the target file and fix
  all instances consistently (inconsistent fixes are the #1 cause of re-audit rounds)
- After each fix, note: file:line changed, what was done

## Return Format
## Fixes Applied
- {file:line} — {what was fixed} ({which lens it resolved: PRD | Domain | Visual})
```

---

## Blocking Rules (MANDATORY)

These override all other instructions. The orchestrator:

1. **MUST NOT** run both modes in the same turn — COMPOSE or AUDIT, never both.
2. **MUST NOT** review code itself in AUDIT mode — coordination only. The 3 judges do the work.
3. **MUST NOT** synthesize a verdict until all 3 judges return.
4. **MUST NOT** apply fixes without user approval.
5. **MUST NOT** re-run all 3 judges after a fix — only the ones whose lens was affected.
6. **MUST NOT** declare APPROVED until: round N judges return 0 CRITICAL + 0 WARNING (real).
7. **MUST NOT** iterate beyond 2 fix rounds without asking the user.
8. **MUST NOT** skip the pre-analysis step — judges rely on that context.

---

## Decision Tree

```
User request
│
├── "compose/build/create form for X"
│   └── MODE: COMPOSE
│       ├── Resolve input (schema | interface | brief)
│       ├── Decide / confirm detail mode
│       ├── Delegate Executor sub-agent
│       └── Review output inline + hand to user
│
├── "audit/review/evaluate this form"
│   └── MODE: AUDIT
│       ├── Resolve target (file path | snippet)
│       ├── Pre-analysis (inline)
│       ├── Launch 3 judges in parallel
│       ├── Synthesize verdict
│       ├── Present table + ASK
│       │   ├── User approves → delegate Fix Agent
│       │   │   └── Re-run affected judges only → iterate or APPROVE
│       │   └── User rejects → ESCALATED
│       └── (max 2 fix rounds before asking again)
│
└── Ambiguous
    └── STOP and ASK: "¿Componer o auditar?"
```

---

## Language

- **Spanish input → Rioplatense**: "Empecemos — ¿compose o audit?", "Los jueces están trabajando en
  paralelo...", "Arranco el juicio del form", "Los tres jueces terminaron", "¿Arreglo los issues
  confirmados?", "Aprobado ✓", "Necesita ajustes"
- **English input**: "Let's start — compose or audit?", "Judges are working in parallel...",
  "Starting form audit", "All three judges finished", "Fix confirmed issues?", "Approved ✓", "Needs
  work"

---

## Self-Check (before any terminal action)

Before saying "done" / "listo":

1. If in AUDIT mode: did all 3 judges return? Was the verdict presented to the user?
2. If fixes were applied: did the affected judges re-run and return CLEAN?
3. If in COMPOSE mode: did the executor return a complete component? Did you verify the partial
   contract, OnPush, imports order, and grid-cols class?
4. Did you run Prettier (or ask the user to) on any file written? (Per project CLAUDE.md.)
5. Did you save a session summary to engram if a non-trivial decision was made?

If any answer is "no" → go back and complete it.

---

## Commands

```bash
# No CLI commands — this is an orchestration protocol.
# Execution happens via Agent tool (subagent_type: general-purpose) + inline synthesis.
```

## Resources

- **Form composition ruleset**: `./references/catalyst-detail-form-rules.md` — self-contained,
  authoritative (inside this skill)
- **Layout design system**: `.claude/skills/layout-design-system/SKILL.md` — spacing and density
- **Spartan**: `.claude/skills/spartan/SKILL.md` — component catalog and forms rules
