viepilot 2.45.5 → 2.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,79 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.47.0] - 2026-05-06
11
+
12
+ ### Added
13
+ - **ENH-081** Brownfield Scan Trace Log — `BROWNFIELD-TRACE.md` real-time trace artifact
14
+ (`workflows/crystallize.md`). Before any signal category scanning begins, crystallize now
15
+ writes `.viepilot/BROWNFIELD-TRACE.md` to disk with all 13 categories pre-populated as
16
+ `planned`. Full feature set:
17
+ - **Trace initialization + resume detection**: on session start, checks for existing trace;
18
+ if `Status: scan_complete` → AUQ offers skip re-scan or re-scan from scratch; if trace is
19
+ mid-scan (interrupted) → AUQ offers resume from the last completed signal category
20
+ - **Per-Category Update Protocol (ENH-081)**: on category start → row moves to `scanning`;
21
+ on completion → row moves to `done`/`assumed`/`skipped` with file count, signals found,
22
+ start time, and duration; `## Files Read Log` appended with `[x]` (read) / `[ ]` (not found)
23
+ per file probed
24
+ - **Coverage gate (ENH-081)**: before presenting Scan Report, counts remaining `planned` rows;
25
+ non-blocking warning if any categories were not executed; sets `Status: scan_complete` in
26
+ trace header after gate passes
27
+ - **Gap Filling Log (ENH-081)**: each user response during Step 0-B-ii gap-filling is
28
+ immediately appended to `## Gap Filling Log` — no batching
29
+ - **Step Completion tracking**: `## Step Completion` rows updated after Step 0-C (Brainstorm
30
+ Stub) and Step 0-D (UI Workspace, 3 cases: done / skipped / N/A)
31
+
32
+ ## [2.46.1] - 2026-05-06
33
+
34
+ ### Fixed
35
+ - **ENH-080** Upgrade re-scan (ENH-067 Step 0-B) now detects Signal Category 13 gap for
36
+ projects crystallized before v2.46.0:
37
+ - Delta computation table extended with `v2.46.0` row: detection field `ui_signals_imported`
38
+ absent from HANDOFF.json; trigger re-check prevents false-positive for backend-only projects
39
+ (no CSS, no Tailwind, no UI component files)
40
+ - Step 0-D now persists `ui_signals_imported: true/false` + `ui_signals_imported_at`/
41
+ `ui_signals_skipped_at` to `HANDOFF.json` after workspace generation or skip — marks gap
42
+ as "evaluated"; prevents re-asking on every crystallize run; `--upgrade` forces re-evaluation
43
+ - Patch mode handler added: re-runs Signal Cat 13 (Sub-scans A/B/C) + Step 0-D when UI gap
44
+ detected; AUQ gate preserved; no brainstorm supplement check (reads codebase directly)
45
+
46
+ ## [2.46.0] - 2026-04-27
47
+
48
+ ### Added
49
+ - **ENH-079** Signal Category 13 — UI/Design System Signals in brownfield scanner
50
+ (`workflows/crystallize.md`). When an existing project has a real UI layer, the
51
+ brownfield scan now reverse-engineers it into a complete `.viepilot/ui-direction/`
52
+ workspace automatically:
53
+ - Sub-scan A: CSS custom properties (`--color-*`, `--font-*`, `--spacing-*`, `--radius-*`),
54
+ Tailwind config (`theme.extend.colors`, `fontFamily`, `spacing`, `borderRadius`),
55
+ SCSS variables, design token JSON files → Design.MD v1 `design.md`
56
+ - Sub-scan B: Page/route inventory for 8 framework types (Next.js App Router, Next.js Pages
57
+ Router, React Router, Vue Router, Angular, Nuxt 3, SvelteKit, plain HTML) →
58
+ `index.html` hub + `pages/{slug}.html` stubs per discovered route
59
+ - Sub-scan C: Component inventory via file glob + UI library detection from `package.json`
60
+ (shadcn/ui, Material UI, Chakra UI, Ant Design, Headless UI, Bootstrap, Radix) →
61
+ `notes.md ## components_inventory`
62
+ - AUQ gate: "Generate ui-direction workspace?" before reverse-engineering (skippable)
63
+ - Scan Report `ui_signals` field: `triggered`, `workspace_generated`, `ui_tokens`,
64
+ `ui_pages`, `ui_components`
65
+ - `notes.md` front matter: `reverse_engineered: true` flag — distinguishes auto-generated
66
+ sessions from manually crafted brainstorm sessions
67
+ - `workflows/brainstorm.md` Step 3C: imports Signal 13 data when brownfield stub contains
68
+ `ui_signals`; handles 3 cases (workspace generated / data present / not triggered);
69
+ offers on-demand workspace generation via AUQ
70
+
71
+ ## [2.45.6] - 2026-04-27
72
+
73
+ ### Fixed
74
+ - **BUG-026**: `vp-brainstorm` internal session sub-commands (`/save`, `/research-ui`,
75
+ `/review-arch`, `/sync-ui`) conflicted with Claude Code's `/` command prefix —
76
+ typed as slash commands they were intercepted as unknown skill invocations.
77
+ Fix: removed all slash sub-command documentation; replaced with proactive AUQ
78
+ triggers that fire on intent detection (multi-language save signals: "save",
79
+ "done", "xong", "lưu"; UI walkthrough offered on research intent; arch review
80
+ offered on review intent). Consistent behavior across ALL adapters — no
81
+ adapter-specific typing rules (BUG-026)
82
+
10
83
  ## [2.45.5] - 2026-04-27
11
84
 
12
85
  ### Enhanced
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viepilot",
3
- "version": "2.45.5",
3
+ "version": "2.47.0",
4
4
  "description": "**Autonomous Vibe Coding Framework / Bộ khung phát triển tự động có kiểm soát**",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -63,6 +63,19 @@ Prompt user conversationally with numbered list options.
63
63
 
64
64
  ## C. Tool Usage
65
65
  Use Cursor tools: `Shell`, `ReadFile`, `Glob`, `rg`, `ApplyPatch`, `WebSearch`, `WebFetch`, `Subagent`
66
+
67
+ ## D. Session Actions — Proactive AUQ Triggers (BUG-026)
68
+ **No slash sub-commands.** All session actions are triggered proactively by the AI via
69
+ `AskUserQuestion` at the right moment — no user typing required.
70
+
71
+ | Action | Trigger condition | AUQ prompt |
72
+ |--------|-------------------|------------|
73
+ | **Save + crystallize handoff** | User signals done: "save", "done", "xong", "lưu", "finished", "ready", "crystallize", or equivalent intent | "Save session and prepare for /vp-crystallize?" |
74
+ | **UX walkthrough** | In UI session AND user mentions "research", "test", "UX", "walkthrough" — OR ≥1 UI signals accumulated | "Run UX walkthrough (3-phase simulate + research + update HTML)?" |
75
+ | **Architecture review** | User asks "review decisions", "check arch", "summarize choices", or equivalent intent | "Generate architecture review summary table?" |
76
+ | **Sync UI → Arch** | After arch update when UI workspace also active | "Sync architecture changes to UI Direction workspace?" |
77
+
78
+ **Why:** In Claude Code terminal, any `/command` is intercepted by the shell as a skill invocation. Using proactive AUQ triggers works identically on ALL adapters — no adapter-specific typing rules needed.
66
79
  </cursor_skill_adapter>
67
80
  <scope_policy>
68
81
  ## ViePilot Namespace Guard (BUG-004)
@@ -90,15 +103,15 @@ Supports:
90
103
  - UI Direction mode: create/update HTML prototype + notes under `.viepilot/ui-direction/{session-id}/` — supports **multi-page** (`pages/{slug}.html` + hub `index.html`) and the **`## Pages inventory`** hook in `notes.md` when `pages/` exists (FEAT-007)
91
104
  - **Phase assignment (ENH-030):** in every session, features/capabilities are assigned directly to Phase 1, Phase 2, Phase 3... — no MVP/Post-MVP/Future tiers. Session file stores assignments in the `## Phases` section.
92
105
  - **Project meta intake (FEAT-009):** after **scope locked**, **before** `Completed` / `/end`, if `.viepilot/META.md` (`viepilot_profile_id`) is missing — run **sequential** Q&A with proposals; read/write `~/.viepilot/profile-map.md`; create `~/.viepilot/profiles/<slug>.md` + binding per **`docs/dev/global-profiles.md`**. If a profile is already bound — skip intake by default (ask if change needed).
93
- - **UX walkthrough (FEAT-010 + ENH-019 + ENH-020):** in **`--ui`** mode, command **`/research-ui`** or **`/research ui`** runs 3 phases simulates **end-user** (with **content stress pass** + **stress recipes by archetype** → **Stress findings**) → **UX designer + web research** → update `index.html` / `pages/*.html` / `style.css` and write **`## UX walkthrough log`** in `notes.md` (sync hub + **Pages inventory** for multi-page).
94
- - **Background UI extraction (ENH-026 + ENH-060):** automatically detects UI signal keywords in every brainstorm session (no `--ui` flag required). **Auto-suggests itself (ENH-060):** if the initial message contains ≥1 UI keyword, shows a proactive 🎨 banner immediately — mirrors Architect Design Mode's 🏗️ proactive activation. Accumulation starts at ≥1 signal (was ≥3); surfaces for confirmation when topic ends, `/save`, or **≥2 unique signals** accumulated (was ≥5) — does not interrupt the main conversation.
95
- - **Idea → Architecture breakdown loop (ENH-061):** structured 8-step flow from free idea collection → scope lock → **Feature → Coverage mapping** (maps each Phase 1 feature to an architect page + UI screen, outputs `## Coverage` matrix in `notes.md`) → Architect Design → **`arch_to_ui_sync`** reverse sync (surfaces UI implications of architectural decisions; `/sync-ui` command) → UI Direction → **completeness gate** (CHECK 4: warns if any Phase 1 feature has no coverage in either mode, non-blocking). See `Recommended Breakdown Ordering` section in `workflows/brainstorm.md`.
106
+ - **UX walkthrough (FEAT-010 + ENH-019 + ENH-020):** in **`--ui`** mode, proactively offered via AUQ when user mentions "research", "test UX", "walkthrough" — or when ≥1 UI signals accumulated. Runs 3 phases: simulates **end-user** (with **content stress pass** + **stress recipes by archetype** → **Stress findings**) → **UX designer + web research** → update `index.html` / `pages/*.html` / `style.css` and write **`## UX walkthrough log`** in `notes.md` (sync hub + **Pages inventory** for multi-page).
107
+ - **Background UI extraction (ENH-026 + ENH-060):** automatically detects UI signal keywords in every brainstorm session (no `--ui` flag required). **Auto-suggests itself (ENH-060):** if the initial message contains ≥1 UI keyword, shows a proactive 🎨 banner immediately — mirrors Architect Design Mode's 🏗️ proactive activation. Accumulation starts at ≥1 signal (was ≥3); surfaces for confirmation when topic ends, user signals done, or **≥2 unique signals** accumulated (was ≥5) — does not interrupt the main conversation.
108
+ - **Idea → Architecture breakdown loop (ENH-061):** structured 8-step flow from free idea collection → scope lock → **Feature → Coverage mapping** (maps each Phase 1 feature to an architect page + UI screen, outputs `## Coverage` matrix in `notes.md`) → Architect Design → **`arch_to_ui_sync`** reverse sync (surfaces UI implications of architectural decisions; proactively offered via AUQ after arch updates) → UI Direction → **completeness gate** (CHECK 4: warns if any Phase 1 feature has no coverage in either mode, non-blocking). See `Recommended Breakdown Ordering` section in `workflows/brainstorm.md`.
96
109
  - **Unified workspace mode selection (BUG-018):** after scope lock, before any design workspace is created, an AUQ prompt offers: Both / Architect only / UI Direction only / Neither. Architect auto-activate heuristic is deferred until after this selection; suppressed if user selects "Neither" or "UI Direction only".
97
110
  - **Admin & Governance coverage (ENH-063):** Topic 6 in brainstorm template; proactive 🔐 heuristic fires on admin/governance keywords; admin coverage gate before /save for multi-user/SaaS/compliance projects; `admin.html` added to Architect workspace when applicable; `notes.md ## admin` YAML exported via crystallize.
98
111
  - **Content Management coverage (ENH-065):** Topic 7 in brainstorm template; proactive 🗂️ heuristic fires on content-type/media/SEO keywords; content coverage gate before /save for projects with content layer; `content.html` added to Architect workspace; `notes.md ## content` YAML exported via crystallize.
99
112
  - **Admin Entity Management coverage (ENH-068):** Topic 7 in brainstorm template; proactive 🗄️ heuristic fires on CRUD/entity/admin panel keywords; entity management coverage gate before /save for projects with DB entities (cross-references ERD); `entity-mgmt.html` added to Architect workspace; `notes.md ## entity_mgmt` YAML exported via crystallize.
100
113
  - **User Data Management coverage (ENH-066):** Topic 9 in brainstorm template; proactive 👤 heuristic fires on user-account/privacy/auth keywords; user data coverage gate before /save for B2C/SaaS/GDPR projects; `user-data.html` added to Architect workspace; `notes.md ## user_data` YAML exported via crystallize.
101
- - **Architect Design Mode (FEAT-011):** `/vp-brainstorm --architect` or auto-activate when ≥3 components/services detected; generate HTML workspace (architecture, data-flow, decisions, tech-stack, tech-notes, feature-map) with Mermaid diagrams; incremental update per decision; `/review-arch` command; machine-readable `notes.md` YAML schema.
114
+ - **Architect Design Mode (FEAT-011):** `/vp-brainstorm --architect` or auto-activate when ≥3 components/services detected; generate HTML workspace (architecture, data-flow, decisions, tech-stack, tech-notes, feature-map) with Mermaid diagrams; incremental update per decision; architecture review offered via AUQ when user asks to review decisions; machine-readable `notes.md` YAML schema.
102
115
  - **ERD page (ENH-027):** Architect workspace includes `erd.html` — Mermaid `erDiagram`, entity list table, relationship summary; triggered by DB/entity/table/relationship keywords; notes.md `## erd` YAML section exported to ARCHITECTURE.md `## Database Schema` via crystallize Step 1D.
103
116
  - **User Use Cases page (ENH-028):** Architect workspace includes `user-use-cases.html` — actor/use-case diagram (Mermaid flowchart), use case table; triggered by user/role/actor/story keywords; notes.md `## use_cases` YAML section exported to PROJECT-CONTEXT.md `## User Stories & Use Cases` via crystallize Step 1D.
104
117
  - **C4Context/Sequence/Deployment/APIs pages (ENH-029, 12-page workspace):** Architect workspace expanded to 12 pages — `sequence-diagram.html` (per-scenario sequenceDiagram), `deployment.html` (infra graph + environments + CI/CD pipeline), `apis.html` (endpoint tables with HTTP method badges); page boundary rules table; trigger keywords for sequence/deploy/API; notes.md `## apis` YAML section; deployment+APIs exported to ARCHITECTURE.md via crystallize Step 1D (sequence excluded — scenario docs are not architecture artifacts).
@@ -334,6 +334,70 @@ Store the pending gap list. Re-surface the same AUQ at `/save` before writing th
334
334
  Proceed normally. Do **not** set `upgrade_supplement_version` — gap will re-surface on next open.
335
335
  </step>
336
336
 
337
+ <step name="brownfield_ui_signal_import">
338
+ ### Step 3C: Brownfield UI Signal Import (ENH-079)
339
+
340
+ **Trigger:** When the loaded session is a brownfield import stub (contains `session-brownfield-import.md` or `IS_BROWNFIELD=true`) AND the session's embedded Scan Report contains a `ui_signals` field.
341
+
342
+ **Check:** Read session file for `ui_signals` YAML block under `## Scan Report`.
343
+
344
+ ---
345
+
346
+ **Case 1 — workspace already generated** (`ui_signals.workspace_generated: true`):
347
+
348
+ Display notice (no AUQ required):
349
+ ```
350
+ UI workspace already generated at .viepilot/ui-direction/{session-id}/
351
+ Open index.html to review {ui_pages.count} pages and {ui_components.total} components.
352
+ ```
353
+ Continue brainstorm normally. Do not re-generate workspace.
354
+
355
+ ---
356
+
357
+ **Case 2 — Signal 13 data present, workspace NOT yet generated** (`ui_signals.triggered: true`, `workspace_generated: false` or absent):
358
+
359
+ Import into session notes.md:
360
+ - `ui_pages.routes[]` → populate `## pages_inventory` section
361
+ - `ui_components` data → populate `## components_inventory` section
362
+ - `ui_tokens` summary → populate `## design_tokens` section
363
+ - Set notes.md front matter: `reverse_engineered: true`
364
+
365
+ Display import summary:
366
+ ```
367
+ Imported Signal 13 data: {ui_pages.count} pages, {ui_components.total} components,
368
+ {ui_tokens.detected} tokens detected ({ui_tokens.assumed} assumed).
369
+ ```
370
+
371
+ **Claude Code (terminal) — REQUIRED:** Offer workspace generation via AUQ:
372
+ - question: "Signal 13 data imported. Generate full ui-direction workspace now?"
373
+ - header: "UI Workspace"
374
+ - options:
375
+ a. "Yes — generate workspace (Recommended)" → run workspace generation (Step 0-D logic from crystallize.md)
376
+ b. "Continue brainstorm first" → proceed; workspace generation remains available
377
+
378
+ **Text fallback:**
379
+ ```
380
+ Signal 13 data imported.
381
+ 1. Generate ui-direction workspace now (Recommended)
382
+ 2. Continue brainstorm first
383
+ ```
384
+
385
+ ---
386
+
387
+ **Case 3 — `ui_signals` not present** (Signal 13 not triggered for this project):
388
+
389
+ Skip this step entirely. Proceed to Step 4 normally.
390
+
391
+ ---
392
+
393
+ **Reverse-engineered workspace handling:**
394
+
395
+ When `notes.md` front matter contains `reverse_engineered: true`:
396
+ - Display "(Reverse-engineered)" badge in session header instead of standard brainstorm banner
397
+ - Skip "missing brainstorm" warnings in vp-audit and vp-crystallize
398
+ - Do not treat session as an incomplete brainstorm — it is a valid documentation artifact
399
+ </step>
400
+
337
401
  <step name="brainstorm_mode">
338
402
  ## 4. Brainstorm Mode
339
403
 
@@ -1178,7 +1242,7 @@ When the user mentions: `user story`, `use case`, `actor`, `persona`, `as a user
1178
1242
 
1179
1243
  1. After each **major decision** (tech stack, service boundary, data model) → update the related HTML section + update `notes.md`.
1180
1244
  2. When the user **changes a decision** → **incremental update**: only edit the related section; keep all other sections unchanged. Add `data-updated="true"` attribute + class `.updated` CSS highlight (yellow left border + "updated" badge) to the changed element.
1181
- 3. **`/review-arch`** command ViePilot outputs a summary table of all `decisions` (from `notes.md`) + list of `open_questions` with status; ask the user to confirm before continuing.
1245
+ 3. **Architecture review trigger** when user asks to review decisions ("review", "check architecture", "summarize choices", "what did we decide", or equivalent intent): ViePilot proactively outputs a summary table of all `decisions` (from `notes.md`) + list of `open_questions` with status, then asks the user to confirm before continuing. **Claude Code (terminal) — REQUIRED:** use `AskUserQuestion` to offer the review; text fallback on other adapters.
1182
1246
 
1183
1247
  #### Incremental update rule
1184
1248
 
@@ -1457,8 +1521,8 @@ This mirrors **Architect Design Mode** which proactively banners when system arc
1457
1521
 
1458
1522
  #### Surface triggers (when to ask the user)
1459
1523
  Display a confirmation dialogue when any of the following conditions occur:
1460
- - (a) **Topic ends** — user types `/topic` to switch to a new topic or says "next"
1461
- - (b) **User types `/save` or `/review`**
1524
+ - (a) **Topic ends** — user says "next", "next topic", or switches subject
1525
+ - (b) **User signals session end** — says "save", "done", "xong", "finished", "ready", "crystallize", "ready for crystallize", or equivalent intent in any language
1462
1526
  - (c) **≥2 unique signals accumulated** in the buffer
1463
1527
 
1464
1528
  #### Confirmation dialogue template
@@ -1490,12 +1554,16 @@ mkdir -p .viepilot/ui-direction/{session-id}
1490
1554
 
1491
1555
  ### UI Direction — UX walkthrough & upgrade (FEAT-010)
1492
1556
 
1493
- When inside **`/vp-brainstorm --ui`** or a `.viepilot/ui-direction/{session-id}/` already exists for the current session, the user can invoke:
1557
+ When inside **`/vp-brainstorm --ui`** or a `.viepilot/ui-direction/{session-id}/` already exists for the current session, the UX walkthrough pipeline is **proactively triggered via AUQ** (BUG-026) when:
1558
+ - User mentions "research", "test", "UX review", "walkthrough", "simulate user", or equivalent intent
1559
+ - OR: ≥1 UI signal accumulated AND user signals topic end
1494
1560
 
1495
- - **`/research-ui`**runs the full pipeline below
1496
- - **`/research ui`** **alias** of `/research-ui` (space after `research`; does not conflict with `/research {free topic}`)
1561
+ **Claude Code (terminal) REQUIRED:** Call `AskUserQuestion`:
1562
+ - question: "Run UX walkthrough? (3-phase: simulate user UX research update HTML)"
1563
+ - header: "UX Walkthrough"
1564
+ - options: [{ label: "Yes — run full walkthrough (Recommended)", description: "Simulate end-user + content stress + research + update prototype" }, { label: "Skip for now", description: "Continue brainstorm; offer again at session end" }]
1497
1565
 
1498
- The user can include one line of context (e.g., product name **Trips**, persona, priority flow) — entered in the same message as the command.
1566
+ The user can include one line of context (e.g., product name, persona, priority flow) — in the same message or as a follow-up after selecting "Yes".
1499
1567
 
1500
1568
  Apply **the phases sequentially** (assistant does not skip a phase unless the user explicitly says “phase 1 only”):
1501
1569
 
@@ -1623,6 +1691,23 @@ After intake is **completed** or a **valid skip** (META already has profile) →
1623
1691
  <step name="save_session">
1624
1692
  ## 6. Save Session
1625
1693
 
1694
+ ### Save Trigger (BUG-026)
1695
+
1696
+ The save step fires when the AI detects session-end intent — **no slash command required**.
1697
+
1698
+ **Save intent signals** (any language):
1699
+ - "save", "done", "finished", "ready", "crystallize", "ready for crystallize", "let's save", "that's it", "wrap up"
1700
+ - Equivalent phrases in the session language (e.g. "xong", "luu", or any clear session-end signal)
1701
+ - Or: conversation reaches natural end (all topics covered, no new questions)
1702
+
1703
+ **Claude Code (terminal) — REQUIRED:** Call `AskUserQuestion`:
1704
+ - question: "Save session and prepare for /vp-crystallize?"
1705
+ - header: "Save Session"
1706
+ - options: [{ label: "Save + prepare for crystallize (Recommended)", description: "Write session file, then offer /vp-crystallize handoff" }, { label: "Continue brainstorming", description: "Not done yet — keep going" }]
1707
+
1708
+ On "Save + prepare": proceed to Pre-Save validation below, then write file, then offer crystallize handoff.
1709
+ On "Continue brainstorming": resume conversation.
1710
+
1626
1711
  ### Pre-Save Phase Assignment Validation (ENH-052)
1627
1712
 
1628
1713
  Before writing the session file, validate phase assignment completeness:
@@ -1648,7 +1733,7 @@ CHECK 4 (ENH-061): If both Architect workspace AND UI Direction workspace are ac
1648
1733
  1. Assign all features to phases (## Phases section)
1649
1734
  2. Ensure Phase 1 has at least one feature
1650
1735
 
1651
- Return to the conversation to assign phases, then /save again.
1736
+ Return to the conversation to assign phases, then signal done when ready (e.g. "save" or "xong").
1652
1737
  ```
1653
1738
  - If scope is **not** locked (exploratory session — no feature assignments):
1654
1739
  → **Allow save** with `Status: In Progress` and add advisory note to session file:
@@ -1660,7 +1745,7 @@ CHECK 4 (ENH-061): If both Architect workspace AND UI Direction workspace are ac
1660
1745
  ```
1661
1746
  ⚠️ Coverage gap detected — these Phase 1 features have no Architect or UI coverage:
1662
1747
  - {feature name}
1663
- Consider running /sync-ui or adding these features to a workspace before /vp-crystallize.
1748
+ Consider asking to sync UI or adding these features to a workspace before /vp-crystallize.
1664
1749
  Proceed with save? (yes / skip coverage for now)
1665
1750
  ```
1666
1751
  - If brownfield stub session (`IS_BROWNFIELD=true`): **skip this gate** — brownfield stubs intentionally have no phases.
@@ -54,10 +54,15 @@ If `~/.viepilot/config.json` is absent, use defaults (en/en) — do not fail.
54
54
  | v2.32.0 | `## Admin & Governance` in PROJECT-CONTEXT.md | section absent AND `admin_imported` not in HANDOFF.json |
55
55
  | v2.33.0 | `## Content Management` in PROJECT-CONTEXT.md | section absent AND `content_imported` not in HANDOFF.json |
56
56
  | v2.34.0 | `## User Data Management` in PROJECT-CONTEXT.md | section absent AND `user_data_imported` not in HANDOFF.json |
57
+ | v2.46.0 | UI/Design scan not run (Signal Cat 13) | `ui_signals_imported` absent from HANDOFF.json AND any UI trigger condition met: `.css`/`.scss` files > 5 OR `tailwind.config.js`/`tailwind.config.ts` exists OR component files (`.jsx/.tsx/.vue/.svelte`) > 10 |
57
58
 
58
59
  Cross-check: confirm section is actually absent from current `PROJECT-CONTEXT.md` before listing
59
60
  as a gap — avoids false positives for projects that have the content already.
60
61
 
62
+ UI trigger re-check note: backend-only projects (no CSS, no Tailwind, no UI components) must
63
+ NOT see "UI scan gap" — the trigger condition re-check prevents false-positive upgrade noise
64
+ for CLI tools, data pipelines, and other non-UI projects.
65
+
61
66
  ### Upgrade menu
62
67
 
63
68
  **Claude Code (terminal) — REQUIRED:**
@@ -89,6 +94,10 @@ For each missing section, run only the corresponding Step 1D export item:
89
94
  - `## Admin & Governance` → Step 1D item 7 (ENH-063)
90
95
  - `## Content Management` → Step 1D item 8 (ENH-065)
91
96
  - `## User Data Management` → Step 1D item 9 (ENH-066)
97
+ - UI/Design scan (v2.46.0, ENH-079) → Re-run Signal Category 13 (Sub-scans A/B/C) then
98
+ proceed through Step 0-D (AUQ gate + workspace generation). AUQ gate is preserved — user
99
+ can still choose to skip. No brainstorm supplement check required (reads codebase directly).
100
+ After gate: writes `ui_signals_imported` to HANDOFF.json per Task 121.2 spec.
92
101
 
93
102
  For each item:
94
103
  1. Check if architect `notes.md` has the corresponding YAML section (`## admin`, `## content`,
@@ -269,7 +278,92 @@ When brownfield was triggered automatically (not via `--brownfield`), present th
269
278
  > - "Cancel" / "3" → exit without changes
270
279
 
271
280
  **When brownfield mode is active:**
272
- 1. Run the full 12-category codebase scanner (Signal Categories 1–12 below).
281
+
282
+ ### Brownfield Scan Trace — Initialization (ENH-081)
283
+
284
+ **Before running any signal category**, initialize the scan trace:
285
+
286
+ 1. Check if `.viepilot/BROWNFIELD-TRACE.md` exists.
287
+
288
+ 2. **If exists AND `Status: scan_complete`** — prior scan completed. Offer resume via AUQ:
289
+ ```
290
+ question: "Prior scan found (completed {date}). Re-scan or resume from gap-filling?"
291
+ header: "Brownfield Trace"
292
+ options:
293
+ a. "Resume — skip re-scan, go to gap-filling (Recommended)"
294
+ b. "Re-scan from scratch — overwrite trace"
295
+ ```
296
+ - On "Resume": skip to Interactive Gap-Filling (Step 0-B-ii), using data from prior trace.
297
+ - On "Re-scan": delete trace, continue to step 4 below.
298
+
299
+ 3. **If exists AND `Status: scanning`** — prior scan was interrupted. Read which category row
300
+ last shows `scanning` → identify interrupted category N. Offer via AUQ:
301
+ ```
302
+ question: "Prior scan interrupted at Signal Cat {N} — {Category Name}. How to proceed?"
303
+ header: "Interrupted Scan"
304
+ options:
305
+ a. "Resume from Signal Cat {N} (Recommended)"
306
+ b. "Re-scan from scratch"
307
+ ```
308
+ - On "Resume from Cat N": skip completed categories (1 through N-1), restart from Cat N.
309
+ - On "Re-scan": overwrite trace, continue to step 4 below.
310
+
311
+ 4. **If not exists (or user chose "Re-scan"):** create `.viepilot/BROWNFIELD-TRACE.md`:
312
+
313
+ ```markdown
314
+ # Brownfield Scan Trace
315
+
316
+ <!-- Generated by vp-crystallize --brownfield v{crystallize_version} -->
317
+
318
+ ## Session Info
319
+ - **Started**: {ISO-8601 timestamp}
320
+ - **Project**: {project_name or "unknown (pre-scan)"}
321
+ - **crystallize_version**: {semver}
322
+ - **Status**: scanning
323
+
324
+ ## Signal Coverage
325
+
326
+ | # | Category | Status | Files Checked | Signals Found | Started | Duration |
327
+ |---|----------|--------|---------------|---------------|---------|----------|
328
+ | 1 | Build Manifest & Package Identity | planned | — | — | — | — |
329
+ | 2 | Framework & Library Detection | planned | — | — | — | — |
330
+ | 3 | Architecture Layer Inference | planned | — | — | — | — |
331
+ | 4 | Database Schema Signals | planned | — | — | — | — |
332
+ | 5 | API Contract Files | planned | — | — | — | — |
333
+ | 6 | Infrastructure & Deployment Config | planned | — | — | — | — |
334
+ | 7 | Environment & Configuration Shape | planned | — | — | — | — |
335
+ | 8 | Test Coverage Signals | planned | — | — | — | — |
336
+ | 9 | Code Quality & Tooling | planned | — | — | — | — |
337
+ | 10 | Documentation Files | planned | — | — | — | — |
338
+ | 11 | Git History & Version Signals | planned | — | — | — | — |
339
+ | 12 | File Extension Language Survey | planned | — | — | — | — |
340
+ | 13 | UI/Design System Signals | planned | — | — | — | — |
341
+
342
+ ## Files Read Log
343
+
344
+ (Populated during scanning — one subsection per signal category)
345
+
346
+ ## Gap Filling Log
347
+
348
+ | Field | Status | Source | Value |
349
+ |-------|--------|--------|-------|
350
+
351
+ (Populated during interactive gap-filling — Step 0-B-ii)
352
+
353
+ ## Step Completion
354
+
355
+ | Step | Status | Completed At | Notes |
356
+ |------|--------|-------------|-------|
357
+ | 0-B Scanner | in_progress | {timestamp} | — |
358
+ | 0-C Brainstorm Stub | pending | — | — |
359
+ | 0-D UI Workspace | pending | — | N/A if not triggered |
360
+ ```
361
+
362
+ **Write this file to disk immediately** — before any signal category scanning begins.
363
+
364
+ ---
365
+
366
+ 1. Run the full 13-category codebase scanner (Signal Categories 1–13 below).
273
367
  2. Produce a structured **Scan Report** (see schema at end of this step).
274
368
  3. Classify every field as DETECTED / ASSUMED / MISSING per Gap Detection Rules.
275
369
  4. Present Scan Report summary to user; interactively fill every MISSING MUST-DETECT field.
@@ -676,6 +770,179 @@ Rule: `secondary_languages[]` = languages with ≥5 files that are not `primary_
676
770
 
677
771
  ---
678
772
 
773
+ ### Signal Category 13 — UI/Design System Signals
774
+
775
+ **Trigger condition (ANY of):**
776
+ - `.css` or `.scss` files > 5 in the project
777
+ - `tailwind.config.js` or `tailwind.config.ts` exists
778
+ - Component files (`.jsx`, `.tsx`, `.vue`, `.svelte`) > 10
779
+ - Route config files detected (see Sub-scan B sources below)
780
+
781
+ **Runs after:** Signal Category 12.
782
+ **Output stored in:** `ui_signals` Scan Report field.
783
+
784
+ ---
785
+
786
+ #### Sub-scan A — Design Token Extraction
787
+
788
+ **Sources (priority order):**
789
+
790
+ 1. `tailwind.config.js` / `tailwind.config.ts`
791
+ - Extract: `theme.extend.colors`, `theme.colors`, `theme.fontFamily`, `theme.spacing`, `theme.borderRadius`
792
+
793
+ 2. CSS custom properties in `*.css` / `globals.css` / `variables.css` / `_variables.scss`
794
+ - `--color-*`, `--primary-*`, `--bg-*`, `--text-*` → TOKEN_MAP.colors
795
+ - `--font-*`, `--text-size-*` → TOKEN_MAP.typography
796
+ - `--spacing-*`, `--gap-*`, `--padding-*` → TOKEN_MAP.spacing
797
+ - `--radius-*`, `--rounded-*` → TOKEN_MAP.rounded
798
+
799
+ 3. SCSS variables: `$color-primary`, `$font-size-base`, `$spacing-unit`, etc.
800
+
801
+ 4. Design token JSON files: `tokens.json`, `design-tokens.json`, `theme.json`
802
+
803
+ **Output:** Populate TOKEN_MAP for workspace generation step.
804
+ - ASSUMED prefix for any token not found in any source.
805
+ - Track `source_files[]` — list of all files scanned.
806
+
807
+ **Scan Report field:** `ui_tokens: { detected: N, assumed: M, source_files: [] }`
808
+
809
+ ---
810
+
811
+ #### Sub-scan B — Page/Route Inventory
812
+
813
+ | Framework | Detection method | Route extraction |
814
+ |-----------|-----------------|-----------------|
815
+ | Next.js 13+ App Router | `app/` directory with `page.tsx` or `page.jsx` | Directory structure → route paths |
816
+ | Next.js Pages Router | `pages/` directory (exclude `api/` and `_` prefixes) | Directory structure → route paths |
817
+ | React Router | `src/routes/*.{jsx,tsx}`, `src/App.{jsx,tsx}` | Parse `<Route path="...">` attrs |
818
+ | Vue Router | `src/router/index.{js,ts}` | Parse `routes: [{ path, component }]` |
819
+ | Angular | `src/app/app-routing.module.ts` | Parse `Routes` array |
820
+ | Nuxt 3 | `pages/` directory | Directory structure → route paths |
821
+ | Plain HTML | `*.html` at root, `src/`, `public/` | File names → page names |
822
+ | SvelteKit | `src/routes/+page.svelte` | Directory structure |
823
+
824
+ **Scan Report field:** `ui_pages: { count: N, routes: [], framework: string }`
825
+
826
+ Framework values: `"next-app"` | `"next-pages"` | `"react-router"` | `"vue-router"` | `"angular"` | `"nuxt3"` | `"sveltekit"` | `"html"` | `"unknown"`
827
+
828
+ ---
829
+
830
+ #### Sub-scan C — Component Inventory
831
+
832
+ **Sources:**
833
+
834
+ 1. Component file globs:
835
+ - `src/components/**/*.{jsx,tsx,vue,svelte}`
836
+ - `components/**/*.{jsx,tsx,vue}`
837
+ - `app/components/**/*`
838
+
839
+ 2. UI library detection from `package.json` dependencies:
840
+ - `@mui/material` → Material UI
841
+ - `@chakra-ui/react` → Chakra UI
842
+ - `@shadcn/ui` or `components/ui/` directory → shadcn/ui
843
+ - `antd` → Ant Design
844
+ - `@headlessui/react` → Headless UI
845
+ - `react-bootstrap` → Bootstrap
846
+ - `@radix-ui/*` → Radix primitives
847
+
848
+ 3. Common component pattern detection (by filename):
849
+ - Button, Modal, Dialog, Card, Form, Input, Select, Table, Navbar, Sidebar, Footer, Header
850
+
851
+ **Scan Report field:**
852
+ ```yaml
853
+ ui_components:
854
+ total: N
855
+ ui_library: string # "shadcn/ui" | "Material UI" | "Chakra UI" | "Ant Design" | "Headless UI" | "Bootstrap" | "Radix" | "none"
856
+ categories:
857
+ layout: N
858
+ forms: N
859
+ navigation: N
860
+ data-display: N
861
+ feedback: N
862
+ ```
863
+
864
+ ---
865
+
866
+ ### Brownfield Scan Trace — Per-Category Update Protocol (ENH-081)
867
+
868
+ For each signal category (1–13), apply this update protocol to `BROWNFIELD-TRACE.md`:
869
+
870
+ #### On category start
871
+
872
+ Update the category's row in `## Signal Coverage`:
873
+ - Status: `scanning`
874
+ - Started: current ISO timestamp (time portion only: `HH:MM:SS`)
875
+
876
+ #### On category complete
877
+
878
+ Update the category's row:
879
+ - **Status**: one of:
880
+ - `done` — evidence found, DETECTED tier (high confidence)
881
+ - `assumed` — evidence found, ASSUMED tier (low confidence / indirect signal)
882
+ - `skipped` — no relevant files found; category not applicable to this project
883
+ - **Files Checked**: integer count of files actually read
884
+ - **Signals Found**: comma-separated key results (e.g. `react, next.js`), or `none`
885
+ - **Duration**: elapsed seconds since category started (e.g. `3s`)
886
+
887
+ Append a new subsection to `## Files Read Log`:
888
+
889
+ ```markdown
890
+ ### Signal {N} — {Category Name}
891
+
892
+ - [x] {relative/path/to/file} → {signal or "none found"}
893
+ - [x] {another/file.json} → {result summary}
894
+ - [ ] {expected/missing.yaml} → not present
895
+ ```
896
+
897
+ Legend:
898
+ - `[x]` = file was read (exists on disk and was examined)
899
+ - `[ ]` = file was expected per workflow probe list but not found on disk
900
+
901
+ **Skipped category** (no files probed): append instead:
902
+ ```markdown
903
+ ### Signal {N} — {Category Name}
904
+
905
+ (No files probed — category not applicable to this project)
906
+ ```
907
+
908
+ #### Status transitions
909
+
910
+ Flow: `planned → scanning → done` (full evidence) | `scanning → assumed` (low confidence) | `scanning → skipped` (no files)
911
+
912
+ ```
913
+ planned → scanning (category starts)
914
+ scanning → done (evidence found — DETECTED)
915
+ scanning → assumed (evidence found — ASSUMED, low confidence)
916
+ scanning → skipped (no matching files found)
917
+ ```
918
+
919
+ #### Example — Signal Category 5 (API Contract Files)
920
+
921
+ Row after completion:
922
+ ```
923
+ | 5 | API Contract Files | done | 3 | openapi.yaml, swagger.json (REST) | 14:23:05 | 2s |
924
+ ```
925
+
926
+ Files Read Log append:
927
+ ```markdown
928
+ ### Signal 5 — API Contract Files
929
+
930
+ - [x] openapi.yaml → REST (OpenAPI 3.0)
931
+ - [x] swagger.json → REST (Swagger 2.0)
932
+ - [ ] graphql/schema.graphql → not present
933
+ - [x] src/routes/index.ts → REST route patterns detected
934
+ ```
935
+
936
+ #### Signal Category 13 special format
937
+
938
+ Signal Category 13 (UI/Design) Signals Found field format:
939
+ ```
940
+ tailwind ({N} colors), {M} routes ({framework}), {K} components ({ui_library})
941
+ ```
942
+ Example: `tailwind (12 colors), 8 routes (next-app), 24 components (shadcn/ui)`
943
+
944
+ ---
945
+
679
946
  ### Scan Report Schema (finalized)
680
947
 
681
948
  After running all 12 signal categories, produce this structured Scan Report:
@@ -741,6 +1008,26 @@ top_contributors: []
741
1008
  docs_extracted: [] # { file, summary, key_facts[] }
742
1009
  language_distribution: {} # { ts: 142, java: 38, ... }
743
1010
  open_questions: [] # root-level open questions (includes rollup from modules)
1011
+ ui_signals: # present only when Signal Category 13 triggered
1012
+ triggered: bool
1013
+ workspace_generated: bool # true after workspace generation step completes
1014
+ ui_tokens:
1015
+ detected: N # tokens extracted from sources
1016
+ assumed: M # tokens filled with ASSUMED values
1017
+ source_files: [] # files scanned (tailwind.config.js, globals.css, etc.)
1018
+ ui_pages:
1019
+ count: N
1020
+ routes: [] # [ { path, name, source_file } ]
1021
+ framework: string # "next-app" | "next-pages" | "react-router" | "vue-router" | "angular" | "nuxt3" | "sveltekit" | "html" | "unknown"
1022
+ ui_components:
1023
+ total: N
1024
+ ui_library: string # "shadcn/ui" | "Material UI" | "Chakra UI" | "Ant Design" | "Headless UI" | "Bootstrap" | "Radix" | "none"
1025
+ categories:
1026
+ layout: N
1027
+ forms: N
1028
+ navigation: N
1029
+ data-display: N
1030
+ feedback: N
744
1031
  ```
745
1032
 
746
1033
  ---
@@ -829,6 +1116,19 @@ Root gap tier: MISSING (worst across modules)
829
1116
 
830
1117
  After scanner completes:
831
1118
 
1119
+ **Coverage gate (ENH-081):** Before presenting the Scan Report, verify the trace:
1120
+
1121
+ 1. Read `## Signal Coverage` table from `.viepilot/BROWNFIELD-TRACE.md`.
1122
+ 2. Count rows still showing `planned` (never executed).
1123
+ 3. If any `planned` rows found: display warning (non-blocking):
1124
+ ```
1125
+ ⚠️ Coverage incomplete — {N} signal categories not executed:
1126
+ - Signal Cat {N}: {Category Name}
1127
+ Proceeding with partial Scan Report. Uncovered gap fields will be MISSING.
1128
+ ```
1129
+ 4. Update trace `## Session Info` → `Status: scan_complete`.
1130
+ 5. Update `## Step Completion` row "0-B Scanner" → `done` + current timestamp.
1131
+
832
1132
  1. Display Scan Report summary table to user (field | value | status).
833
1133
  2. **Per-module MISSING fields** — for each module with `gap_tier: MISSING`, pause and ask per field:
834
1134
  ```
@@ -843,6 +1143,14 @@ After scanner completes:
843
1143
  5. Capture all user responses; update Scan Report fields accordingly.
844
1144
  6. All remaining unresolved items → `open_questions[]` (roll up per-module `open_questions[]` into root).
845
1145
 
1146
+ **Gap Filling Log (ENH-081):** For each field where the user provides or confirms a value, append a row to `## Gap Filling Log` in `.viepilot/BROWNFIELD-TRACE.md`. Write after each user response — do not batch:
1147
+
1148
+ | Field | Status | Source | Value |
1149
+ |-------|--------|--------|-------|
1150
+ | {field_name} | MISSING → user-filled | user input | {value} |
1151
+ | {field_name} | ASSUMED → accepted | user accept | {assumed_value} |
1152
+ | {field_name} | DETECTED → user-confirmed | user confirm | {value} |
1153
+
846
1154
  ---
847
1155
 
848
1156
  ### Brownfield Brainstorm Stub Generation (Step 0-C)
@@ -869,6 +1177,120 @@ After gap-filling is complete, write:
869
1177
 
870
1178
  **Purpose:** This stub allows `vp-audit` and other ViePilot tools to not error on missing brainstorm session files. The presence of `session-brownfield-import.md` is treated as a valid brownfield import.
871
1179
 
1180
+ **Trace update (ENH-081):** Update `.viepilot/BROWNFIELD-TRACE.md` `## Step Completion` row
1181
+ "0-C Brainstorm Stub" → `done` + current timestamp + `stub: docs/brainstorm/session-brownfield-import.md`.
1182
+
1183
+ ---
1184
+
1185
+ ### UI Workspace Generation Gate (Step 0-D)
1186
+
1187
+ **Condition:** Run only when `ui_signals.triggered: true` in the Scan Report.
1188
+
1189
+ #### AUQ Gate — Brownfield UI Reverse-Engineering
1190
+
1191
+ **Claude Code (terminal) — REQUIRED:** Call AskUserQuestion:
1192
+ - question: "UI signals detected — generate ui-direction workspace from existing code?"
1193
+ - header: "Brownfield UI Reverse-Engineering"
1194
+ - options:
1195
+ a. "Yes — generate now (Recommended)" → proceed to workspace generation below
1196
+ b. "Skip — I will create ui-direction manually" → set `ui_signals.workspace_generated: false`; add note to `open_questions[]`; write to `.viepilot/HANDOFF.json`: `{ "ui_signals_imported": false, "ui_signals_skipped_at": "{ISO-8601 timestamp}" }` (merge — do not overwrite unrelated fields); continue
1197
+
1198
+ **Text fallback (non-terminal adapters):**
1199
+ ```
1200
+ UI signals detected. Options:
1201
+ 1. Yes — generate ui-direction workspace now (Recommended)
1202
+ 2. Skip — create ui-direction manually later
1203
+ ```
1204
+
1205
+ #### Workspace Generation
1206
+
1207
+ When user selects "Yes — generate now":
1208
+
1209
+ Generate session ID: `brownfield-{YYYY-MM-DD}` (or reuse existing if re-running).
1210
+
1211
+ Create artifacts under `.viepilot/ui-direction/{session-id}/`:
1212
+
1213
+ **`design.md`** (Design.MD v1 format):
1214
+ - Populate colors, typography, spacing, rounded from TOKEN_MAP (Sub-scan A)
1215
+ - Prefix ASSUMED for any token not extracted from source
1216
+ - Add `## Source` section listing all scanned files and extraction method
1217
+
1218
+ **`notes.md`**:
1219
+ ```markdown
1220
+ ---
1221
+ reverse_engineered: true
1222
+ source_project: {project_name}
1223
+ scan_date: {ISO date}
1224
+ signal_category: 13
1225
+ ---
1226
+
1227
+ ## pages_inventory
1228
+
1229
+ | Route | Page Name | Source File | Status |
1230
+ |-------|-----------|-------------|--------|
1231
+ {one row per route from ui_pages.routes[]}
1232
+
1233
+ ## components_inventory
1234
+
1235
+ | Component | Type | File | UI Library |
1236
+ |-----------|------|------|------------|
1237
+ {one row per component from ui_components scan}
1238
+
1239
+ ## design_tokens
1240
+
1241
+ - Detected: {ui_tokens.detected} tokens
1242
+ - Assumed: {ui_tokens.assumed} tokens
1243
+ - Sources: {ui_tokens.source_files[]}
1244
+ ```
1245
+
1246
+ **`index.html`** hub page:
1247
+ - Header: project name + UI library badge (if `ui_library != "none"`)
1248
+ - Table of contents: one link per page stub
1249
+ - Each entry: route path + source file reference
1250
+
1251
+ **`pages/{slug}.html`** stubs — one per discovered route:
1252
+ - Page title (from route name) + route path
1253
+ - "Reverse-engineered from: {source file}"
1254
+ - Component list (if detectable via import analysis)
1255
+ - Placeholder section for handover notes
1256
+
1257
+ **Generated artifact tree:**
1258
+ ```
1259
+ .viepilot/ui-direction/
1260
+ brownfield-{YYYY-MM-DD}/
1261
+ design.md ← design tokens (Design.MD v1)
1262
+ notes.md ← pages_inventory + components_inventory + design_tokens
1263
+ index.html ← hub page with all discovered pages linked
1264
+ pages/
1265
+ {slug}.html ← one per discovered route/page
1266
+ ```
1267
+
1268
+ After generation: set `ui_signals.workspace_generated: true` in Scan Report.
1269
+
1270
+ Also write to `.viepilot/HANDOFF.json` (merge — do not overwrite unrelated fields):
1271
+ ```json
1272
+ {
1273
+ "ui_signals_imported": true,
1274
+ "ui_signals_imported_at": "{ISO-8601 timestamp}",
1275
+ "ui_signals_version": "2.46.0"
1276
+ }
1277
+ ```
1278
+ This flag is used by Step 0-B upgrade re-scan (ENH-080) to detect whether Signal Cat 13 has
1279
+ been run for this project. A future `--upgrade` re-run can force re-evaluation by re-running
1280
+ Signal Cat 13 even when `ui_signals_imported: true` is present.
1281
+
1282
+ **Reverse-engineered workspace notice:** The workspace is a documentation approximation
1283
+ from static code analysis — not a pixel-perfect rendering. `pages/*.html` stubs describe
1284
+ what exists based on file structure and imports. The `reverse_engineered: true` flag allows
1285
+ downstream tools (`vp-audit`, `vp-crystallize`) to adjust expectations (e.g., skip
1286
+ "missing brainstorm" warnings).
1287
+
1288
+ **Trace update (ENH-081):** Update `.viepilot/BROWNFIELD-TRACE.md` `## Step Completion` row
1289
+ "0-D UI Workspace":
1290
+ - If workspace generated: `done` + timestamp + `workspace: .viepilot/ui-direction/{session-id}/`
1291
+ - If user skipped AUQ: `skipped` + timestamp + `reason: user skipped`
1292
+ - If Signal Category 13 did not trigger: `N/A` (update row to `N/A` + timestamp)
1293
+
872
1294
  ---
873
1295
 
874
1296
  ### Safety Rules