# audit — Gap analysis: "Let it Snow" → FORGE (what has NOT been ported) **Date:** 2026-08-27 · Author: audit (read-only) · Scope: full parity sweep **Checklist source:** [FORGE-parity-spec.md](FORGE-parity-spec.md) (29 charts + PM-Insights + boards + data contract) **Compared against:** live FORGE code (`server/*.ts`, `client/src/**`, `extension/*`) and the initial app source (`/Users/dmytrotkachenko/WebstormProjects/Let It Snow/Let it Snow/*.js`, verified by grep — files are huge). Legend: ✅ done · 🟡 partial · ❌ missing. Value: **MH** must-have · **NTH** nice-to-have · **LOW**. --- ## 0. Executive summary FORGE has delivered a solid **read-only spine**: full data ingest (966 tickets + finance + jira + config), a server analytics engine, the **Overall** tab (~9 of 11 charts), the **Active** tab (5 of 6), the **6 SLA heatmaps** (charts 24–29), **PM Insights** (alert groups + waiting-PO + per-PM roll-up), a **6-column board** with list view + filtered Excel export, and **new** RBAC/Users/Tokens admin (beyond the original). What is **not** ported is roughly **half of the analytics surface and nearly all of the operator tooling**: - **PMs-KPI tab** is only the 6 heatmaps — charts **18–23** (workload, engagement + dual calendar heatmaps, missing-cost, awaiting-PO money, brand/market sub-cards) are **absent**, and the heatmaps have **no period/year granularity and no editable norms**. - **Board** is missing the 7th synthetic column, 13 of 16 card fields, all 14 sorts, all 6 group-by permutations, and ~9 of 11 filters (region, staleness, jira, requester, custom-label…). - **Whole features missing:** the standalone **Jira board**, the **Size CALC** estimator, the **finance view**, and the entire **options/config editor surface** (brand colours, norms, thresholds, card-field toggles, colleagues/region, currency, custom labels). - **Sync** is shallow: active-**RITM only**, 9 fields, **no SCTASK, no Jira, no closed, no finance, no statusDurations** collectors. - Overall/Active charts lack the **YoY pies (#5/#6)**, **CGO overlay**, **#/% toggle**, **Jira status durations (#17)**, and **time-in-status min/median/max (#15)**. Per the spec, **AI Advisor / at-risk, weather** are intentionally out of scope (confirmed below). --- ## 1. Overall analytics tab — `client/src/pages/Overview/index.tsx` + `server/analytics.ts:getOverview` | # | Item | Status | Note / where it lives | |---|---|:--:|---| | 1 | Opened per month | ✅ | `GroupedBars` — multi-year grouped, bars/line toggle, YoY badge. | | 2 | Closed per month | ✅ | `GroupedBars`, same. | | 3 | Revenue per month (cost/tickets, ±YoY) | ✅ | `GroupedBars` + Cost/Tickets toggle in Overview; GBP via fixed FX. | | 4 | Lifetime-at-close histogram + median/avg/closed tiles | ✅ | `BarList` 6 buckets + median tile. `avgDays`/`closed` computed server-side. | | 5 | **Opened YoY pie (fair/full)** | ❌ | No opened-YoY donut. Would live in Overview as a `DonutChart`; server has `openedByMonth` but no fair-window (same-day-of-year) series. **MH** | | 6 | **Closed YoY pie (fair/full)** | ❌ | Same — no closed-YoY donut / fair-vs-full comparison. **MH** | | 7 | By business unit (per-year, **brand drill**) | 🟡 | Flat `BarList` (`byBusinessUnit`), **no per-year split, no brand drill-down**. `server/analytics.ts:169`. **NTH** | | 8 | By requester (bars + YoY, **market drill**) | 🟡 | `ExpandBarList` drills requester→**brand** (spec wants →market), **no YoY**. `analytics.ts:170`. **NTH** | | 9 | Ticket-share donut (#/%, top 18 + Others) | 🟡 | `DonutChart` on `byRequesterShare` (full 966 dist — the REDO fix). **No #/% toggle, no top-18+Others rollup.** **NTH** | | 10 | By brand (per-year **segments**, market drill, YoY) | 🟡 | `ExpandBarList` brand→market counts only. **No per-year segments, no YoY, no size/status segmentation.** **NTH** | | 11 | By market | 🟡 | Flat `BarList`, top-20. No brand drill / segments. **LOW** | | — | Toggle: bars/line | ✅ | `GroupedBars` per-chart. | | — | Toggle: ±YoY | 🟡 | Shown as a computed badge, not a user toggle; only on the month `GroupedBars`. **LOW** | | — | Toggle: cost/tickets | 🟡 | Only on the Revenue chart; original applies it across money charts. **LOW** | | — | Toggle: #/% | ❌ | No percentage mode anywhere. **NTH** | | — | Growth badges | 🟡 | Only the month-total YoY badge; no per-series/per-requester growth. **LOW** | | — | **CGO overlay** | ❌ | Original overlays a "CGO" series per group (`dashboard.js` `CgoBars`/`CGO_REQUESTER`, toggle). Not in FORGE — needs a CGO flag on tickets + overlay in `GroupedBars`. **NTH** | **Bottom line:** the month/revenue/lifetime core is faithful; the **two YoY pies are missing outright**, and the by-dimension charts are **flat counts without the per-year segmentation, drill, and YoY** the original had. --- ## 2. Active tab — `client/src/pages/Active/index.tsx` (client-computed from active tickets) | # | Item | Status | Note / where it lives | |---|---|:--:|---| | 12 | Open-not-closed by month | ✅ | `TrendChart` area, `openedByMonth`. | | 13 | By status (kanban cats) | ✅ | `BarList` over `BOARD_COLUMNS`, state colours. | | 14 | Age histogram (0-50…200+ d) | ✅ | `BarList`, 5 buckets. | | 15 | **Time-in-status min/median/max** | 🟡 | Only **median** days-in-state per column (`Active/index.tsx:62`). No min/max grouped mini-bars. **NTH** | | 16 | By brand, **status-segmented** (market drill) | 🟡 | Flat `BarList` of active-by-brand. **No status segmentation, no market drill.** **NTH** | | 17 | **Jira status durations (workflow order)** | ❌ | Requires `statusDurations` from `jira_status_map` — **not ingested** (only `status`/`statusChangedAt`/`key` land in `jira` JSONB; see `scripts/dump-to-archives.mjs:36`). No chart. **MH** for Jira ops. | --- ## 3. PMs-KPI tab — `client/src/pages/SlaKpi/index.tsx` + `server/analytics.ts:getSlaHeatmaps` The whole tab is currently **only** the 6 SLA heatmaps. The original "PMs KPI" tab was 12 items (18–29). ### 3a. The 6 SLA heatmaps (24–29) — present but reduced | # | Item | Status | Note | |---|---|:--:|---| | 24 | On-Time Delivery heatmap | ✅ | `otd` metric, PM×size, on-time% vs `otd` norms. | | 25 | Avg days to close heatmap | ✅ | `avgclose` vs `avgdays`. | | 26 | Time to assign PM heatmap | ✅ | `assign` = `max(0, fulfillment→firstAssigned)` vs `asla`. | | 27 | Time to send preview heatmap | ✅ | `preview` = `toDoAt→inUatAt` vs `psla`. | | 28 | Avg TTFR heatmap | ✅ | `ttfr` = `ttfrMinutes/1440` vs `ttfr` norms (hrs). | | 29 | Avg PM response heatmap | ✅ | `cresp` = `clientRespMinutes/1440` vs `cresp` norms. | | — | **Current + previous year** side by side | ❌ | `getSlaHeatmaps` computes one all-time grid; original renders cur-yr + prev-yr heatmaps. **MH** | | — | **Period granularity (year / Q1-Q4 / month)** | ❌ | No period control at all. **MH** | | — | **Editable norms panels** | ❌ | Norms are read-only from `app_config`/`config.json`; original has inline norm editors (`buildNormsPanel` etc.) that persist. Needs a write endpoint + UI. **MH** | | — | Hidden PMs from `pm_kpi_settings` | ❌ | `getSlaHeatmaps:223` has a stubbed `hidden = new Set()` — never populated. **NTH** | ### 3b. Charts 18–23 — entirely missing | # | Item | Status | Note / where it'd live | |---|---|:--:|---| | 18 | **Workload by month** (revenue prev/cur yr, per-PM) | ❌ | New `GroupedBars`+per-PM series; new server agg (closed cost by PM×month). **MH** | | 19 | **PM Engagement** (backlog/Assist✓/Jira✓/Stale) + **dual daily-activity calendar heatmaps** | ❌ | Needs `CalendarHeatmap` component (GitHub-style) + activity/jira-movement ingest per day. Original: `EngagementKpi()` with PM-row accordion. **MH** | | 20 | **Missing final cost** (ranked PM bars + drill) | ❌ | `AssigneeBars` + list; server: closed rows where `finalCost` null, grouped by PM. Partial data exists. **MH** (margin-leak) | | 21 | **Awaiting PO** (ranked, Cost / Avg-d / Max-d, sortable) | 🟡 | Insights has a count + L1/L2/L3 + revenue, but **no per-PM Cost/Avg-days/Max-days sortable table**. **MH** | | 22 | No-cost by **brand / market** | ❌ | Two `BucketBars`. **NTH** | | 23 | Awaiting-PO by **brand / market** | ❌ | Two `BucketBars`. **NTH** | **Bottom line:** PMs-KPI is the **largest single gap** — 6 of 12 charts absent, and the 6 present ones lack year/period slicing and the editable norms that make them operational. --- ## 4. Board — `client/src/pages/Board/index.tsx`, `utils/board.ts`, `components/Board/BoardCard` | Item | Status | Note / where it lives | |---|:--:|---| | 7-state columns | 🟡 | **6 columns** built (`unassigned, open, hold, wip, replied, awaiting`; `board.ts:18`). **7th synthetic `Closed / Awaiting-PO` column is missing** (original `CLOSED / AWAITING PO – SYNTHETIC` overlay). **MH** | | Customer-replied pseudo-status | ✅ | `boardColumn`/`isAwaitingAgency` — WIP + last touch ∉ colleague roster. Faithful. | | Column SLA subtitles + per-column count | ✅ | `col.slaVerb(thr)` + count badge. | | Group-by (6 permutations of WIP·Replied·Awaiting) | ❌ | Column order is fixed; original has 6 orderings (`wip-agency-await` … `await-agency-wip`). **NTH** | | **16 toggleable card fields** (`card_fields`) | ❌ | `BoardCard` is a **fixed** layout showing ~8 fields (number, jira status, link, shortDesc, brand·market, assignee, in-state days, lifetime, last activity). **None toggleable.** Missing: description, raisedBy, dueDate, stateChanged, comments, createJira, jiraBar, teamsLink. Original fields: `cf-stateBadge/shortDesc/description/assignee/assignmentGroup/brandMarket/raisedBy/lifetime/dueDate/stateChanged/lastActivity/comments/createJira/showJiraStatus/showJiraBar/teamsChannelLink`. **NTH** | | Custom labels registry | ❌ | Original `custom_label` system (per-ticket labels + filter). Absent. **NTH** | | Staleness / PO / jira-stuck / missing-cost badges | ❌ | `BoardCard` has no badges beyond the jira-status chip. **NTH** | | **Sort (14 options)** | ❌ | No sort control. Original: `default, number, status-age-asc/desc, lifetime-asc/desc, jira-assignee, jira-status, brand, cost-asc/desc, due-asc/desc, analyzed`. **NTH** | | Filters: search / brand / market / assignee | ✅ | Present in the board header. | | Filters: **region EU/LATAM** sentinels | ❌ | `latamAssignees` is ingested (`config.json`) but the assignee dropdown has no EU/LATAM region grouping. **NTH** | | Filters: requester, custom-label, jira-assignee, jira-status | ❌ | None. **NTH** | | Filters: staleness (stale/updated/inactive/PO/jira-stuck/missing-cost), hide-empty, hide-cost | ❌ | Original `group-by` chips + status-label filters. Absent. **NTH** | | List view | ✅ | `TicketTable` toggle (fixed columns, not the same field set). | | Card click behaviour | 🟡 | Opens an in-app `TicketDetailModal` (+ a SNOW link icon). Original opens ServiceNow directly. Acceptable divergence. | | Filtered Excel export | ✅ | **New** — `utils/excel.utils.ts`, 17 cols, honours active filters. | | Azure DevOps focus board | ❌ | Out of scope per spec (§0). **LOW** | --- ## 5. PM Insights — `client/src/pages/Insights/index.tsx` + `server/insights.ts` | Item | Status | Note / where it lives | |---|:--:|---| | Alert groups (Unassigned, Open/Assigned, On-Hold, WIP-stalled, WIP-no-Jira, Customer-replied, Awaiting) | ✅ | `insights.ts` 9 groups; support rules `jiraBreached`/`clientOwed`/`isAwaitingAgency` ported. | | Informational groups (Lifetime ≥90d, Inactive requester) | ✅ | Present, excluded from Total Alerts. | | ∑ Total Alerts + Revenue-at-Risk | ✅ | Distinct-count reconciled (verifier-log). | | Waiting-PO count + revenue + **L1/L2/L3** | 🟡 | Counts + revenue present; **no per-level (L1/L2/L3) drill-down lists**. `insights.ts:140`. **NTH** | | PM-KPI table (# Tickets · $ Revenue · ⚠ Rev-at-Risk) | 🟡 | Table present; **not sortable**, and **hidden-PMs from `pm_kpi_settings` not honoured**. **NTH** | | **Excel export of the insights subtree** (PM→Size→Ticket) | ❌ | Original `xl-export.js` writes PM/Size/Ticket-grouped sheets. FORGE has board export only. **MH** | | **Region / PO / people filters** | ❌ | Original insights has EU/LATAM region + PO + people filters. Absent. **NTH** | | **Per-PM size stats** | ❌ | No size breakdown inside the PM roll-up. **NTH** | | **"Missing tickets" overlay** | ❌ | Original reconciliation overlay (tickets present in one source, absent in another). Absent. **LOW** | --- ## 6. Jira board page — **MISSING ENTIRELY** ❌ (MH for Jira ops, else NTH) Original `jira-board.html` + `jira-board.js` (2378 LOC): columns from `jira_board_state`, cards, RITM↔Jira link (`jira-ritm-link.js`), quick-filters, settings panel (board URL, scan controls, PO-cache clear), toasts, scan countdown. FORGE has **no route, no page, no `jira_board_state` ingest** (`dump-to-archives.mjs` only reads `jira_status_map`). Would live as `client/src/pages/JiraBoard/` + a `jira_board` archive/table + a `/api/jira/board` endpoint. --- ## 7. Sync / extension — `extension/background.js` (+ `popup.js`, `options.js`) FORGE's collector is **active-RITM only, shallow**. Original `background.js` (5219 LOC) is far deeper. | Aspect | Status | Note | |---|:--:|---| | SNOW active RITM scan | ✅ | `pageCollector` pages `sc_req_item`, `assignment_groupLIKEMarketing Web Presence`. | | Field depth | 🟡 | Only **9 fields** (number, short_desc, state, assigned_to, group, opened_at, due_date, updated_by, updated_on). No brand/market/BU/requester/cost/activity timeline/state-change history. Rich fields survive only from the **seed**, kept alive by COALESCE upsert. **MH** | | **SCTASK support** | ❌ | RITM-only. Original scans **SCTASK** too (`background.js` `sctask`/`SCTASK`). **NTH** | | **Closed-ticket collector** | ❌ | No closed scan; closed data is seed-only, goes stale. **MH** | | **Jira collector (+ statusDurations)** | ❌ | No Jira scanning; `jira_status_map`/`statusDurations`/`jira_board_state` never refreshed. **MH** | | **Finance xlsx scan** | ❌ | Original scans the SharePoint finance workbook (`finance_xlsx`); FORGE finance is a one-shot seed from the dump. **MH** | | Popup = RITM list + Jira tab | 🟡 | FORGE popup is **sync-only** (server URL + token + "Sync now"). Original popup is a RITM browser + Jira tab. **LOW** (by design — web app replaces it) | --- ## 8. Finance — `server/db.ts:applyFinance` + `scripts/dump-to-archives.mjs:106` | Item | Status | Note | |---|:--:|---| | Finance ingest (cost / currency / PO / invoiced) | ✅ | `finance.json` (860 rows) → fills `finalCost`/`poNumber`/`invoiced`, recomputes size. | | Milestone / PM / state columns | 🟡 | **Parsed into `finance.json`** (`milestone`, `pm`, `state`) **but never surfaced** — DB has no columns for them and no UI reads them. **NTH** | | **Finance view** (invoicing / milestone / filters) | ❌ | No finance page. PO/invoiced only appear as an Excel column + waiting-PO signal. **NTH** | --- ## 9. Size CALC tool — **MISSING ENTIRELY** ❌ (NTH) Original `size-calc.js` (692 LOC): a labor→size estimator (inputs by **role × hours × rate**, config `lis_size_calc_cfg`, `MATCH`/`composite` algorithms). FORGE has a server `sizeOf(cost)` helper (`db.ts:156`) that assigns sizes to tickets, but **no interactive estimator tool/page**. Would live as `client/src/pages/SizeCalc/` + a `lis_size_calc_cfg` config key. --- ## 10. Config / options editors — **MISSING ENTIRELY** ❌ (mixed) FORGE loads config **read-only** from `config.json`/`app_config` (seeded once). The original `options.html`/ `options.js` (629 LOC) is a rich settings surface with **no FORGE equivalent** (the FORGE Admin page is Users+Tokens only). Missing editors, each `GET /api/config` reads but nothing writes: | Setting (original id) | Status | Value | |---|:--:|---| | Brand colours editor (`brand_colors`, add/reset) | ❌ | **NTH** — 45 brands seeded, not editable in-app. | | SLA norms editors (otd/avgdays/asla/psla/ttfr/cresp) | ❌ | **MH** — required by §3a editable-norms gap. | | Insights thresholds editor (`insights_thresholds`) | ❌ | **NTH** | | Size cost-thresholds editor (`otd_cost_thresh`) | ❌ | **NTH** | | Card-field toggles (`cf-*`, 16) + mobile fields (`mf-*`) | ❌ | **NTH** — pairs with the board card-fields gap. | | Colleague names (`colleagueNames`) / LATAM assignees (`latamAssignees`) | ❌ | **NTH** — seeded, not editable. | | Display currency (`displayCurrency`) | ❌ | **LOW** — fixed GBP. | | Custom labels (`custom-labels`, clear-all) | ❌ | **NTH** | | SNOW field colours (`color-*`, 6) | ❌ | **LOW** — SNOW-page injection only, N/A to web app. | | Card layout breakpoints (`card_layout`) | ❌ | **LOW** | | Scan intervals / enables (analyticsIntervalHours, snRescanInterval, dashboardEnabled, jiraNotificationsEnabled, soundEnabled, analyzeButtonsEnabled) | ❌ | **LOW** — extension/SNOW-page behaviour. | | Teams bot (`teamsBotEnabled`, chat names) | ❌ | **LOW** — out of scope. | --- ## 11. Other | Item | Status | Note | |---|:--:|---| | AI Advisor / at-risk (`advisor-*.js`, `advisor-server/`) | ❌ (intended) | **Excluded per spec §1** ("user excluded AI"). Confirmed out of scope — do not port. | | Teams integration (`teamsChannelLink`, teams bot) | ❌ | Out of scope-ish. **LOW** | | Figma links (`figma-links.js`, 244 LOC) | ❌ | Optional per spec. **LOW** | | Weather | — (no gap) | Excluded per spec **and dead in the original** — manifest keeps open-meteo/nominatim host perms but no weather JS remains. Nothing to port. | | Docs page (`docs.html`/`docs.js`) | ❌ | In-app help. **LOW** | | Archive import / export | 🟡 | `scripts/dump-to-archives.mjs` + `npm run reseed` is a **manual CLI** path; no in-app import/export UI. **LOW** | | SCTASK support | ❌ | See §7 — RITM-only. **NTH** | | Extension popup RITM browser | 🟡 | See §7. **LOW** | | **New in FORGE (beyond original):** RBAC (4 roles), Users/Tokens Admin page, session auth, Postgres, server analytics engine | ✅ | Net-additive; no parity gap. | | Legacy/unrouted FORGE pages: `pages/Dashboard`, `pages/Stats` | — | `Dashboard` is unrouted (superseded by `Board`); `Stats` is a thin `/stats` count page. Housekeeping, not a gap. | --- ## 12. Recommended next phases (prioritized) **Phase A — PMs-KPI completion (highest value, biggest gap).** 1. Add **year/period granularity + current-vs-previous-year** to the 6 SLA heatmaps (`getSlaHeatmaps` + period control). *(MH)* 2. **Editable norms** — a `POST /api/config/norms` write path + inline norm panels (also unblocks the options editor). *(MH)* 3. Charts **18 (workload/month per-PM)**, **20 (missing final cost)**, **21 (awaiting-PO Cost/Avg/Max sortable)**. *(MH)* 4. Chart **19 engagement + `CalendarHeatmap`** (needs per-day activity/jira-movement ingest). *(MH, larger)* 5. Charts **22/23** brand-market sub-cards. *(NTH)* **Phase B — Overall/Active fidelity.** 6. **YoY pies #5/#6** (fair-window + full) as `DonutChart`s. *(MH)* 7. **#17 Jira status durations** (requires `statusDurations` ingest — see Phase D). *(MH)* 8. Per-year segmentation + drill + YoY on by-BU/by-brand/by-market/by-requester; **#15 min/median/max**; **#16 status-segmented brand**; **#/% toggle**; **CGO overlay**. *(NTH)* **Phase C — Board operability.** 9. **Sort (14)** + **group-by (6)** controls. *(NTH)* 10. **Toggleable card fields (16)** + badges (stale/PO/jira-stuck/missing-cost). *(NTH)* 11. Filters: region EU/LATAM, requester, jira-status/assignee, staleness, custom labels. *(NTH)* 12. **7th synthetic Closed/Awaiting-PO column.** *(MH)* **Phase D — Deeper sync (unblocks a lot above).** 13. Extend the collector: **richer RITM fields + closed scan + Jira (statusDurations, jira_board_state) + finance scan + SCTASK.** *(MH — currently rich data is seed-only and goes stale.)* **Phase E — Insights depth.** 14. **Excel export of the insights subtree** (PM→Size→Ticket); waiting-PO L1/L2/L3 drill; sortable PM table + hidden-PM support; region/PO/people filters. *(MH for export, else NTH.)* **Phase F — Standalone features.** 15. **Jira board page** (needs Phase D jira ingest). *(MH for Jira ops.)* 16. **Options/config editor** page (brand colours, thresholds, card fields, colleagues/region, currency, custom labels). *(NTH.)* 17. **Size CALC** estimator; **finance view** (milestone/invoicing — data already parsed). *(NTH.)* **Do not port:** AI Advisor/at-risk, weather (excluded); Teams/Figma/ADO board/docs page (low/optional). --- ## 13. Addendum — refinements from the source inventory (corroborated) A parallel deep read of the initial app's source confirmed the above and adds: - **Board columns:** the original renders **5 live columns** (Open/Assigned, On Hold, WIP, Customer-replied, Awaiting) **+ the synthetic Closed/Awaiting-PO** column; Unassigned is folded into Open/Assigned. FORGE builds 6 (splits Unassigned out) and still lacks the synthetic 7th — the §4 "7th column MH" gap stands. - **Per-chart Excel export:** in the original **every analytics chart** carries its own Excel button (`_xlData`/`_xlBtn` → `xl-export.js`). FORGE has **no per-chart export** — only the board export. Add as an **NTH** gap across Overall/Active/PMs-KPI. Insights groups also each export (see §5, MH). - **Missing-tickets overlay** lives on the **3 SLA/OTD charts** (OTD/AvgDays/Assign/Preview), grouping the timestamp-less tickets by current Jira status (reachedUat / beforeUat / noJira) — reclassify the §5 "missing-tickets overlay" as part of the **PMs-KPI SLA charts** (still ❌). - **Collector scope:** the original SN scan handles **RITM + SCTASK + INC** (not just RITM), computes per-ticket `statusDurations` from status-change history, and runs a **Jira scan as a tail after every SN scan**. FORGE's collector does none of this (§7) — add **INC** alongside the SCTASK gap. - **Threshold value drift:** FORGE `config.json` has `waitingPo3: 18` and `customerReplied: 1`, vs the original defaults `waitingPo3: 21` / `customerReplied: 3`. Minor, but reconcile when the norms/thresholds editor lands (§10). **LOW** - **Engagement KPI** reads the **live board** (not `ticketsMeta`), with twin Assist|Jira calendar heatmaps and a ~14-column sortable drill-down — confirms the §3b #19 scope (**MH**, larger build). - **Size CALC** uses 4 currencies (GBP/EUR/MXN + MXN·Brazil uplift ×1.111), roles DEV/CM/QA + auto-PM, PM-budget tiering (`pmThreshold`/`pmHi`/`pmLo`) — confirms §9. - **AI Advisor** is a full masked-digest + Node-bridge-to-Claude-CLI subsystem (`advisor-*.js` + `advisor-server/`) with the At-risk breach engine — **correctly excluded**, do not port. - **Archive import/export** exists as in-app **⬇ Archive / ⬇ Active** buttons in the original (FORGE has only the `dump-to-archives.mjs` CLI) — the §11 🟡 stands. None of these change the phase priorities; they sharpen scope for Phases A, D, and E. ## Next principal — sequence Phase A (PMs-KPI) as the next build; confirm which board/insights sub-items are in v1 scope.