Tropical Update Publisher Functional Master List
Tropical Update Publisher Functional Master List
Legend:
- Existing implemented features are listed normally with
Status: UNTESTED. - Features implemented in code but not described in
project-spec.mdare tagged[UNDOCUMENTED]. - Features required by the spec but not implemented, or only represented by placeholders/stubs, are tagged
[MISSING]and useStatus: MISSING.
Implementation baseline observed in this codebase:
- Main-process foundations are substantial: config loading, first-run gating, Word COM document creation, storm-folder services, quick-browse services, file copy, git publish/status, logging, CSP, crash guard, and a broad preload API.
- Renderer coverage is still skeletal: routed shell chrome, theme handling, first-run path modal, a polished
.docxdrop zone, git status footer, and placeholder pages for most spec views. - Phase 2/NHC/AI/email/dashboard functionality is typed and routed through stub IPC channels, but not implemented.
This flattened list records the latest known status and evidence exactly once per feature ID.
F001 — npm run dev Development Launch Path
- Category: CLI
- Spec Reference: Section 2.1, Section 31.2
- What it should do (end-user perspective): Let a developer build the Electron main/preload bundles, start the Vite renderer on
localhost:5173, and open the desktop app in development mode. - How to test it (step-by-step as a human user):
- Open the tool directory in a terminal.
- Run
npm run dev. - Wait for Vite and Electron to start.
- Confirm the app window loads from the dev server without opening a browser manually.
- Code path:
package.jsondev->vite.config.ts->src/main/index.ts->src/main/window/createMainWindow.ts - Dependencies: None
- Test data needed: Installed Node.js, npm, and project dependencies
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.json,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.stdout.log,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png
F002 — npm start Packaged-Style Local Launch Path
- Category: CLI
- Spec Reference: Section 2.1
- What it should do (end-user perspective): Build the Electron main/preload code and start Electron against the compiled main entrypoint.
- How to test it (step-by-step as a human user):
- Open the tool directory in a terminal.
- Run
npm start. - Confirm
dist/main/main/index.jsis built first. - Confirm Electron launches the app window.
- Code path:
package.jsonstart->tsconfig.main.json/tsconfig.preload.json->src/main/index.ts - Dependencies: F001
- Test data needed: Installed Node.js, npm, and project dependencies
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-start-after-path-fix.json,refinement-state/screenshots/cycle-2/interactive-first-run-before.png,refinement-state/screenshots/cycle-2/interactive-after-continue.png
F003 — npm run build / npm run build:win Packaging Workflow
- Category: CLI
- Spec Reference: Section 16, Section 31.2
- What it should do (end-user perspective): Build the renderer and main bundles, then package a Windows installer through
electron-builder. - How to test it (step-by-step as a human user):
- Run
npm run build. - Run
npm run build:win. - Confirm
electron-builderstarts with the NSIS Windows target. - Confirm output artifacts are written successfully.
- Run
- Code path:
package.jsonbuild/build:win->vite.config.ts->tsc->electron-builderbuildblock inpackage.json - Dependencies: F001
- Test data needed: Windows host with Electron build prerequisites
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-run-build-final.log,refinement-state/functional-cycle-2-artifacts/npm-run-build-win-final.log,release/Tropical Update Publisher Setup 1.0.0.exe
F004 — npm test, npm run lint, And npm run typecheck
- Category: CLI
- Spec Reference: Section 27.1, Section 27.4
- What it should do (end-user perspective): Provide repository-level verification commands for unit/component tests, ESLint, and TypeScript checking.
- How to test it (step-by-step as a human user):
- Run
npm test. - Run
npm run lint. - Run
npm run typecheck. - Confirm each command invokes the expected toolchain without additional manual setup.
- Run
- Code path:
package.jsonscripts ->vitest.config.ts->.eslintrc.cjs->tsconfig.*.json - Dependencies: F001
- Test data needed: Installed project dependencies
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-run-typecheck-final.log,refinement-state/functional-cycle-2-artifacts/npm-run-lint-final.log,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-1.log,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-2.log,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/functional-cycle-2-artifacts/vitest-shadcn-smoke-final.log
F005 — Electron Main Boot Sequence
- Category: Backend
- Spec Reference: Section 1, Section 2.2, Section 28.5, Section 29.1, Section 29.3
- What it should do (end-user perspective): Start exactly one app instance, initialize logging/crash guards/CSP, enforce the first-run gate, and open the main app window securely.
- How to test it (step-by-step as a human user):
- Launch the app through a supported entrypoint.
- Confirm only one instance remains running.
- Confirm the main window opens with the expected title and size constraints.
- Confirm the app still starts even if the renderer bundle or dev server is missing, falling back gracefully.
- Code path:
src/main/index.ts->src/main/app/crashGuard.ts->src/main/app/lifecycle.ts->src/main/security/csp.ts->src/main/window/createMainWindow.ts - Dependencies: None
- Test data needed: Windows desktop environment
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-first-run-before.png,refinement-state/screenshots/cycle-2/interactive-after-continue.png,%APPDATA%/tropical-update-publisher/config.json
F006 — First-Run Gate Window Launch
- Category: UI
- Spec Reference: Section 19 R5, Section 23.10
- What it should do (end-user perspective): Block normal app launch until a valid tropical updates folder path is configured, showing a dedicated first-run window.
- How to test it (step-by-step as a human user):
- Start the app with no saved config or with an invalid tropical path.
- Confirm the first-run window opens instead of the main app shell.
- Confirm the renderer loads the
#first-runsurface. - Confirm closing the first-run window aborts launch.
- Code path:
src/main/index.ts->src/main/services/firstRun/FirstRunGate.ts->src/main/window/createMainWindow.ts->src/renderer/main.tsx->src/renderer/features/first-run/FirstRunModal.tsx - Dependencies: F005
- Test data needed: Missing or invalid
userData/config.json - Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-first-run-before.png,refinement-state/screenshots/cycle-2/interactive-after-continue.png,%APPDATA%/tropical-update-publisher/config.json
F007 — Windows Installer Configuration
- Category: Config
- Spec Reference: Section 16, Section 28.3
- What it should do (end-user perspective): Package the app as an NSIS Windows installer with configurable install directory and app metadata.
- How to test it (step-by-step as a human user):
- Open
package.json. - Confirm the Electron Builder
buildblock targetsnsis. - Confirm
oneClick: falseandallowToChangeInstallationDirectory: true. - Confirm app metadata such as
appIdandproductNameare set.
- Open
- Code path:
package.jsonbuildblock - Dependencies: F003
- Test data needed: None
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-run-build-win-final.log,release/Tropical Update Publisher Setup 1.0.0.exe
F008 — launcher.bat, launcher.vbs, And Desktop Shortcut Launchers
- Category: CLI
- Spec Reference: Section 2.1, Section 21
- What it should do (end-user perspective): Provide Windows wrapper launchers and shortcut files so the app can be started outside npm commands.
- How to test it (step-by-step as a human user):
- Look for
launcher.bat,launcher.vbs, and shortcut/bootstrap files in the repo. - Run each launcher path from Windows Explorer.
- Confirm the app opens without a visible console when appropriate.
- Confirm the desktop shortcut points to the expected launcher.
- Look for
- Code path:
launcher.bat->npm start;launcher.vbs->launcher.bat(hidden window style 0, non-blocking);create-shortcut.ps1->WScript.Shell->Tropical Update Uploader.lnkon Desktop withTargetPath = launcher.vbs - Dependencies: F005
- Test data needed: Windows shell/Explorer
- Status: PASS
- Evidence:
refinement-state/functional-verify-5-artifacts/launchers-isolated.log(3/3 tests PASS intests/shared/launchers.test.ts),refinement-state/test-fixtures/cycle-5-verify/launchers-smoke.json(allStructuralChecksPass: true— bat callsnpm start, vbs runs bat hidden withshell.Run ..., 0, False, ps1 writesTropical Update Uploader.lnkto Desktop viaWScript.Shell),refinement-state/refinement-functional-fixes-5.md(fix landing notes)
F009 — Required App Assets (WMB_Logo.png, icon.ico, Asset Docs)
- Category: Integration
- Spec Reference: Section 15, Section 2.2, Section 16
- What it should do (end-user perspective): Supply the header logo and installer/window icon assets expected by the spec and packaging config.
- How to test it (step-by-step as a human user):
- Look for an
assets/directory. - Confirm
WMB_Logo.png,icon.ico, and asset documentation exist. - Launch the app and inspect the title bar/taskbar icon.
- Build the installer and confirm the icon is embedded.
- Look for an
- Code path:
assets/WMB_Logo.png+assets/icon.ico+assets/README.mdgenerated byscripts/generate-assets.mjs;vite.config.tspublicDir: 'assets'ships the logo todist/renderer/;src/main/window/createMainWindow.tsreadsassets/icon.ico;package.json > build.win.iconreferences the same file for NSIS. - Dependencies: F005, F007
- Test data needed: Asset files
- Status: PASS
- Evidence:
tests/shared/assets.test.ts(6/6 PASS — PNG signature, ICO type=1, README inventory, package.json pin, vite publicDir, main icon path);refinement-state/refinement-functional-fixes-9.md
2. Core Navigation
F010 — Routed App Shell
- Category: UI
- Spec Reference: Section 23.3
- What it should do (end-user perspective): Present a persistent sidebar, top bar, routed content area, and footer so the app behaves like a desktop dashboard instead of a single long page.
- How to test it (step-by-step as a human user):
- Launch the main app surface.
- Confirm the sidebar, top bar, main route area, and footer render together.
- Click through the available routes.
- Confirm unknown hashes redirect back to Publish.
- Code path:
src/renderer/App.tsx->src/renderer/layout/AppShell.tsx->react-router-domHashRouter - Dependencies: F005
- Test data needed: None
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F011 — Sidebar Navigation And Collapse Toggle
- Category: UI
- Spec Reference: Section 23.3
- What it should do (end-user perspective): Let the user switch between top-level views and collapse the sidebar to icon-only mode.
- How to test it (step-by-step as a human user):
- Open the app shell.
- Click each sidebar item.
- Toggle the collapse button.
- Confirm active route highlighting and badge placeholders remain visible.
- Code path:
src/renderer/layout/AppShell.tsx->src/renderer/layout/Sidebar.tsx->src/renderer/stores/useSidebarStore.ts->src/renderer/routes/navConfig.ts - Dependencies: F010
- Test data needed: None
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F012 — Top Bar Branding, Search Affordance, And Theme Button
- Category: UI
- Spec Reference: Section 23.3, Section 23.8
- What it should do (end-user perspective): Show app identity, expose a centered command-palette affordance, and let the user toggle light/dark theme from the header.
- How to test it (step-by-step as a human user):
- Open the main app shell.
- Inspect the branding, search button, and theme toggle.
- Click the search button.
- Confirm it advertises the shortcut but does not yet open a functional palette.
- Code path:
src/renderer/layout/TopBar.tsx->src/renderer/layout/topBarModel.ts->src/renderer/components/ThemeToggle.tsx - Dependencies: F010
- Test data needed: None
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F013 — Theme Toggle Persistence
- Category: UI
- Spec Reference: Section 23.2, Section 23.3
- What it should do (end-user perspective): Flip between light and dark themes and remember the selected theme across renderer reloads.
- How to test it (step-by-step as a human user):
- Click the theme toggle in the top bar.
- Confirm the
darkclass on<html>changes. - Reload the renderer.
- Confirm the theme is restored from local storage.
- Code path:
src/renderer/components/ThemeToggle.tsx->src/renderer/theme/uiTheme.ts->src/renderer/theme/bootstrapRendererChrome.ts - Dependencies: F012
- Test data needed: Browser/Electron local storage
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F014 — Footer Status Bar With Git Branch Query
- Category: UI
- Spec Reference: Section 23.3, Section 14
- What it should do (end-user perspective): Show the current git branch and placeholder status chips for monitor, AI backend, last push, storms, and network; surface a retryable error banner if git status fails.
- How to test it (step-by-step as a human user):
- Open the main app shell.
- Inspect the footer segments.
- Trigger a git-status failure.
- Confirm the error banner appears with a retry button and branch text changes accordingly.
- Code path:
src/renderer/layout/StatusBar.tsx->src/renderer/hooks/useGitStatus.ts->src/renderer/api/ipcClient.ts->src/main/ipc/handlers/gitGetStatusHandlers.ts - Dependencies: F010, F029
- Test data needed: Git repo and optional non-repo scenario
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F015 — Route Fade Transitions And Reduced-Motion Respect
- Category: UI
- Spec Reference: Section 23.4, Section 23.6
- What it should do (end-user perspective): Animate route changes with a short cross-fade unless reduced-motion is preferred.
- How to test it (step-by-step as a human user):
- Navigate between top-level routes.
- Observe the fade transition timing.
- Enable reduced-motion preference.
- Confirm route changes stop animating.
- Code path:
src/renderer/layout/AppShell.tsx->src/renderer/motion/RouteTransitionLayout.tsx->src/renderer/motion/presets.ts - Dependencies: F010
- Test data needed: Optional OS reduced-motion preference
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F016 — Drafts Route Placeholder
- Category: UI
- Spec Reference: Section 23.3, Section 20.4
- What it should do (end-user perspective): Provide a dedicated Drafts route, currently with placeholder copy explaining that pending AI drafts will appear there later.
- How to test it (step-by-step as a human user):
- Navigate to Drafts.
- Confirm the route renders successfully.
- Confirm the title reads
Drafts. - Confirm the body text is placeholder-only.
- Code path:
src/renderer/routes/Placeholders.tsxDraftsPlaceholder - Dependencies: F010
- Test data needed: None
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F017 — Storms Route Placeholder
- Category: UI
- Spec Reference: Section 23.3, Section 20.4
- What it should do (end-user perspective): Provide a dedicated Storms route, currently with placeholder copy for future active-storm cards.
- How to test it (step-by-step as a human user):
- Navigate to Storms.
- Confirm the route renders successfully.
- Confirm the title reads
Storms. - Confirm the body text is placeholder-only.
- Code path:
src/renderer/routes/Placeholders.tsxStormsPlaceholder - Dependencies: F010
- Test data needed: None
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F018 — History Route Placeholder
- Category: UI
- Spec Reference: Section 23.3, Section 24.4
- What it should do (end-user perspective): Provide a dedicated History route, currently with placeholder copy for future publish/archive history.
- How to test it (step-by-step as a human user):
- Navigate to History.
- Confirm the route renders successfully.
- Confirm the title reads
History. - Confirm the body text is placeholder-only.
- Code path:
src/renderer/routes/Placeholders.tsxHistoryPlaceholder - Dependencies: F010
- Test data needed: None
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F019 — Monitor Route Placeholder
- Category: UI
- Spec Reference: Section 20.1, Section 23.3
- What it should do (end-user perspective): Provide a dedicated Monitor route, currently with placeholder copy for future NHC monitor status and alerts.
- How to test it (step-by-step as a human user):
- Navigate to Monitor.
- Confirm the route renders successfully.
- Confirm the title reads
Monitor. - Confirm the body text is placeholder-only.
- Code path:
src/renderer/routes/Placeholders.tsxMonitorPlaceholder - Dependencies: F010
- Test data needed: None
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F020 — Settings Route Placeholder
- Category: UI
- Spec Reference: Section 23.3, Section 20.5
- What it should do (end-user perspective): Provide a Settings route, currently with placeholder copy and sample staggered cards rather than a working settings form.
- How to test it (step-by-step as a human user):
- Navigate to Settings.
- Confirm the route renders successfully.
- Confirm the title reads
Settings. - Confirm the list items are demo content only.
- Code path:
src/renderer/routes/Placeholders.tsxSettingsPlaceholder - Dependencies: F010
- Test data needed: None
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
3. Primary Workflow
F021 — Publish View Surface
- Category: UI
- Spec Reference: Section 6.4, Section 23.3
- What it should do (end-user perspective): Present the current Publish route with the drop zone, temporary queue preview, git summary, and sample controls.
- How to test it (step-by-step as a human user):
- Navigate to Publish.
- Confirm the page heading and drop zone appear.
- Confirm a temporary queue preview area appears after adding files.
- Confirm the page is still a scaffold rather than the full spec workflow.
- Code path:
src/renderer/routes/Placeholders.tsxPublishPlaceholder - Dependencies: F010
- Test data needed: One or more
.docxfiles - Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-run-dev-after-optimize-fix.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F022 — Drag-And-Drop .docx Enqueue
- Category: UI
- Spec Reference: Section 6.4, Section 7.7
- What it should do (end-user perspective): Let the user drag Word documents into the drop zone, resolve absolute file paths synchronously through preload, and enqueue them into the current preview list.
- How to test it (step-by-step as a human user):
- Drag one or more
.docxfiles onto the drop zone. - Confirm the zone enters its active visual state.
- Drop the files.
- Confirm their absolute paths appear in the preview queue.
- Drag one or more
- Code path:
src/renderer/features/publish/DropZone.tsx->window.dragDrop.getPathsForFiles/getFilePaths->src/preload/index.ts - Dependencies: F021
- Test data needed: Valid non-empty
.docxfiles - Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F023 — Browse .docx Picker From Publish View
- Category: UI
- Spec Reference: Section 6.4, Section 7.2
- What it should do (end-user perspective): Open a native file picker for Word documents and enqueue the selected paths into the current preview list.
- How to test it (step-by-step as a human user):
- Open the Publish route.
- Click
Browse for .docx. - Select one or more
.docxfiles from the dialog. - Confirm the selected paths appear in the preview queue.
- Code path:
src/renderer/features/publish/DropZone.tsx->window.api.dialogOpenDocx->src/main/ipc/router.tsdialog handler - Dependencies: F021
- Test data needed: Valid non-empty
.docxfiles - Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F024 — Drop Zone Validation, Error States, And Max-5 Cap
- Category: Error Handling
- Spec Reference: Section 6.4
- What it should do (end-user perspective): Reject non-
.docxfiles, zero-byte.docxfiles, path-resolution failures, and more than five files in one gesture with a clear visual and spoken error. - How to test it (step-by-step as a human user):
- Drop a
.pdf, a zero-byte.docx, and a set larger than five files in separate attempts. - Confirm the zone shakes and turns error-colored.
- Confirm an alert message appears and is announced.
- Confirm nothing is added to the queue when validation fails.
- Drop a
- Code path:
src/renderer/features/publish/DropZone.tsx->src/renderer/features/publish/dropZoneModel.ts->src/preload/index.ts - Dependencies: F022, F023
- Test data needed:
.pdf, zero-byte.docx, more than five.docxfiles - Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F025 — [UNDOCUMENTED] Publish Queue Preview List
- Category: UI
- Spec Reference: UNDOCUMENTED (not found in project-spec.md)
- What it should do (end-user perspective): Show a temporary unordered preview of absolute file paths added through the current drop zone implementation.
- How to test it (step-by-step as a human user):
- Add one or more
.docxfiles through drop or browse. - Confirm a
Queued paths (preview)card appears. - Confirm each path is displayed in insertion order.
- Confirm there are no remove/edit/reorder controls.
- Add one or more
- Code path:
src/renderer/routes/Placeholders.tsxlocalqueuedDocxPathsstate - Dependencies: F022, F023
- Test data needed: Valid
.docxfiles - Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F026 — Publish View Git Status Summary
- Category: UI
- Spec Reference: Section 14
- What it should do (end-user perspective): Show branch/cleanliness text and a manual refresh control directly within the Publish route.
- How to test it (step-by-step as a human user):
- Open Publish.
- Wait for git status to load.
- Confirm branch and clean/dirty text appear.
- Click
Refreshand confirm the query reruns.
- Code path:
src/renderer/routes/Placeholders.tsxGitStatusSummaryLine->src/renderer/hooks/useGitStatus.ts - Dependencies: F029
- Test data needed: Git repo with clean and dirty states
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F027 — [UNDOCUMENTED] Publish Timeout Unknown-State Banner
- Category: Error Handling
- Spec Reference: UNDOCUMENTED (not found in project-spec.md)
- What it should do (end-user perspective): Warn the user that a publish request timed out at the renderer boundary and let them refresh git status, open the repo folder, or dismiss the banner.
- How to test it (step-by-step as a human user):
- Force
git:publishto hang past the renderer timeout. - Open Publish.
- Confirm the warning banner appears.
- Confirm the
Refresh git status,Open repo folder, andDismisscontrols work.
- Force
- Code path:
src/renderer/hooks/useGitPublish.ts->src/renderer/components/PublishUnknownStateBanner.tsx->window.api.configGetPublic/shellOpenPath - Dependencies: F029, F067, F068
- Test data needed: Mock or stalled
git:publishinvocation - Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F028 — File Copy To Incoming Posts With Per-File Metadata
- Category: Backend
- Spec Reference: Section 7.2, Section 11, Section 19 R2
- What it should do (end-user perspective): Copy each selected
.docxinto the configured incoming posts directory and, when a per-file YouTube ID is supplied, write a sibling.meta.jsonfile containing that specificyoutube_id. - How to test it (step-by-step as a human user):
- Call the file-copy path with one or more
.docxfiles and optional YouTube IDs. - Confirm the files are copied into the incoming posts folder.
- Confirm overwritten files are flagged in the result.
- Confirm each non-empty YouTube ID produces a matching
{stem}.meta.json.
- Call the file-copy path with one or more
- Code path:
window.api.copyFiles->src/main/ipc/handlers/fileCopyHandlers.ts->src/main/services/publish/FileCopyService.ts - Dependencies: F052, F057
- Test data needed: Source
.docxfiles and sample YouTube IDs - Status: PASS
- Evidence:
refinement-state/test-fixtures/file-copy-result.json,refinement-state/test-fixtures/file-copy-overwrite-result.json,refinement-state/test-fixtures/file-copy-batch-result.json,refinement-state/test-fixtures/cycle-5/file-copy-perfile-yt-result.json(cycle 5: 3 files with 2 distinct YouTube IDs + 1 without —meta_written_flags: [true, true, false],distinct_youtube_ids: true)
F029 — Git Publish Workflow
- Category: Backend
- Spec Reference: Section 8, Section 19 R1
- What it should do (end-user perspective): Publish copied files to the configured git branch using repo validation, optional stash/branch switching, pull, stage, commit, push, and restore logic.
- How to test it (step-by-step as a human user):
- Prepare the repo on the target branch and on a non-target branch with local changes.
- Invoke publish with one or more copied files and a commit message.
- Confirm the app stages both
.docxand available.meta.jsonsidecars. - Confirm the branch comes from config and original state is restored after push.
- Code path:
window.api.gitPublish->src/main/ipc/handlers/gitPublishHandlers.ts->src/main/services/git/PublishService.ts->src/main/services/git/GitService.ts - Dependencies: F028, F056, F057
- Test data needed: Git repo, copied target files, commit message
- Status: PASS
- Evidence:
refinement-state/test-fixtures/cycle-2/publish-e2e-result.json
F030 — File Queue Rows, Parsed Metadata, And Row Actions
- Category: UI
- Spec Reference: Section 6.6, Section 12, Section 19 R2, Section 23.5
- What it should do (end-user perspective): Show validated queue rows with parsed title/date/time, legacy conversion badges, per-file YouTube inputs, remove buttons, batch selection, drag handles, and clear-all controls.
- How to test it (step-by-step as a human user):
- Add valid, invalid, and legacy-format files to the Publish queue.
- Confirm each row shows the correct validation state and metadata.
- Edit/remove/reorder files from the queue.
- Confirm per-file YouTube inputs are available.
- Code path:
src/renderer/features/publish/queueRowModel.ts(purecreateQueueRow,addPathsdedup §12,applyYouTubeUrl/applyGlobalYouTubeUrl,removeRowById,clearAllRows) +src/renderer/stores/usePublishQueueStore.ts(Zustand store) +src/renderer/features/publish/FileList.tsx(valid/invalid row UI, per-row YouTube input, Remove + Clear All buttons) rendered viasrc/renderer/routes/Placeholders.tsxPublishPlaceholder. - Dependencies: F022, F023, F036, F037
- Test data needed: Valid, invalid, and legacy-format
.docxfilenames - Status: PASS
- Evidence:
tests/renderer/queueRowModel.test.ts(17 tests) +tests/renderer/usePublishQueueStore.test.ts(8 tests) +tests/renderer/fileList.test.tsx(6 tests) PASS in full-suite run (659/659 across 66 files,refinement-state/refinement-functional-fixes-10.md). Covers NEW/OLD format, dedup §12, converted badge, Clear All, per-row remove, per-row YouTube validation.
F031 — Commit Message Input And Upload Button State Machine
- Category: UI
- Spec Reference: Section 6.7
- What it should do (end-user perspective): Let the user edit the commit message, see auto-populated default text, and run upload only when queue/content state is valid.
- How to test it (step-by-step as a human user):
- Add files to the queue.
- Confirm the commit message input auto-populates.
- Clear the message and confirm upload disables.
- Start an upload and confirm button text/state updates.
- Code path:
src/renderer/features/publish/commitMessageModel.ts(puredefaultCommitMessageFor,uploadButtonLabel,isUploadEnabled) +src/renderer/features/publish/CommitMessage.tsx(Input + Upload button, invokesuseGitPublish, logs start/success/failure into the store) + commitMessageTouched flag inusePublishQueueStore(auto-populate stops after user edits). - Dependencies: F030, F029
- Test data needed: One or more queued files
- Status: PASS
- Evidence:
tests/renderer/commitMessageModel.test.ts(12 tests) +tests/renderer/commitMessage.test.tsx(4 tests) PASS in full-suite run (659/659 across 66 files,refinement-state/refinement-functional-fixes-10.md). Covers singular/plural copy, button labels (“Publishing…”, “Upload 1 File”, “Upload N Files”), disable gates (empty queue, blank commit msg, publishing, YouTube error), successfulgitPublishinvocation with descriptors.
F032 — YouTube URL UI
- Category: UI
- Spec Reference: Section 6.5, Section 11, Section 19 R2
- What it should do (end-user perspective): Let the user enter either a global YouTube URL or per-file URLs, validate them live, and map them to per-file
youtube_idvalues on publish. - How to test it (step-by-step as a human user):
- Queue multiple files.
- Enter valid and invalid YouTube URLs.
- Confirm live validation state and extracted IDs are shown.
- Publish and confirm each sidecar gets the expected
youtube_id.
- Code path:
src/renderer/features/publish/YouTubeSection.tsx(global input with live ✓/✗ chip + 11-char video ID preview using sharedvalidateYouTubeUrl) + per-row override input inFileList.tsx+applyGlobalYouTubeUrl/applyYouTubeUrlinqueueRowModel.ts; storesetGlobalYouTubeUrlre-applies to all rows and inherits URL on new enqueues (§11). - Dependencies: F028, F030
- Test data needed: Sample YouTube URLs for multiple files
- Status: PASS
- Evidence:
tests/renderer/youTubeSection.test.tsx(4 tests) + per-row coverage intests/renderer/fileList.test.tsx(“typing an invalid per-row YouTube URL marks the input aria-invalid”) + store coverage intests/renderer/usePublishQueueStore.test.ts(“setGlobalYouTubeUrl re-applies to all existing rows” / “newly enqueued rows inherit the current global YouTube URL”) PASS in full-suite run. Extracted ID verified againstCommitMessageupload path carryingyoutubeIdintoPublishFileDescriptor.
F033 — Status Log UI And Live Git Log Stream
- Category: UI
- Spec Reference: Section 6.8, Section 7.4, Section 13
- What it should do (end-user perspective): Show a scrolling timestamped status log with up to 50 entries and real-time git publish messages from an IPC subscription.
- How to test it (step-by-step as a human user):
- Start the app and open the Publish workflow.
- Trigger a publish or other logged action.
- Confirm status entries append in real time with icons and timestamps.
- Confirm the list trims to the newest 50 entries.
- Code path:
src/preload/index.ts(gitStreamSubscribenow wiresipcRenderer.on('git:log', …)returning an unsubscribe — previously threwNOT_IMPLEMENTED) +src/renderer/hooks/useGitLogStream.ts(installs subscriber, pushes into store) +src/renderer/features/publish/statusLogModel.ts(pureappendLogEntrywith 50-entry FIFO,iconForLevel, en-US 12hformatEntryTimestamp) +src/renderer/features/publish/StatusLog.tsx(ordered list with icons + timestamps + Clear + auto-scroll). Main side already emitswebContents.send('git:log', …)insrc/main/ipc/handlers/gitPublishHandlers.ts. - Dependencies: F029
- Test data needed: Publish activity generating logs
- Status: PASS
- Evidence:
tests/renderer/statusLogModel.test.ts(7 tests) +tests/renderer/statusLog.test.tsx(4 tests) PASS in full-suite run. Covers icon mapping (• ✓ ⚠ ✗), 50-entry FIFO trim, en-US 12-hour timestamp format, empty-state copy, Clear button, and livegitStreamSubscribecallback forwarding into the store viauseGitLogStream. Preload fix verified bytests/renderer/statusLog.test.tsx“installs the gitStreamSubscribe listener on mount and forwards events” which asserts the subscribe mock is called exactly once and payloads reach the visible log.
F034 — Publish Footer Destination Path
- Category: UI
- Spec Reference: Section 6.9
- What it should do (end-user perspective): Show the full destination path where published files are copied.
- How to test it (step-by-step as a human user):
- Open the Publish view.
- Confirm a footer text shows the full incoming path.
- Change config if supported.
- Confirm the displayed path updates.
- Code path:
src/renderer/features/publish/PublishFooter.tsx(TanStackuseQuery→config:getPublicviainvokeWithTimeout) rendered bysrc/renderer/routes/Placeholders.tsxPublishPlaceholder; IPC chainwindow.api.configGetPublic→src/preload/index.ts→src/main/ipc/router.ts(CONFIG_GET_PUBLIC) →src/main/services/config/ConfigService.ts. - Dependencies: F068
- Test data needed: Loaded public config snapshot
- Status: PASS
- Evidence:
tests/renderer/publishFooter.test.tsx4/4 PASS (happy path rendersFiles are copied to {fullIncomingPath}, loading state, structured IPC failure surface, footer landmark + polite live region) inrefinement-state/refinement-functional-fixes-7.mdfull-suite run (578/578 PASS across 56 files). Renderer wiring confirmed viagrep -n PublishFooter src/renderer/routes/Placeholders.tsx→ import at line 33 +<PublishFooter />render at line 193 insidePublishPlaceholder.
F035 — Existing Incoming Files Listing
- Category: API
- Spec Reference: Section 7.2
- What it should do (end-user perspective): Let the renderer ask for the current
.docxfiles already present in the incoming posts directory. - How to test it (step-by-step as a human user):
- Ensure incoming posts contains one or more
.docxfiles. - Call the incoming-files listing API.
- Confirm the returned names match the folder contents.
- Confirm non-
.docxfiles are excluded.
- Ensure incoming posts contains one or more
- Code path:
window.api.filesListIncoming->src/preload/index.ts->src/main/ipc/router.ts(FILES_LIST_INCOMING) ->src/main/ipc/handlers/incomingFilesHandlers.ts->src/main/services/publish/IncomingFilesService.ts - Dependencies: F052
- Test data needed: Sample
.docxfiles in the incoming posts folder - Status: PASS
- Evidence:
refinement-state/functional-verify-4-artifacts/test-run-1.log(tests/main/incomingFilesService.test.ts7/7,tests/main/ipcRouter.test.ts27/27),refinement-state/test-fixtures/cycle-4-verify/incoming-files-smoke.json(happy + ENOENT + EACCES),refinement-state/test-fixtures/cycle-5/incoming-files-smoke.json(cycle 5: happy + ENOENT + empty-dir + EACCES →FILES_LIST_INCOMING_IO_ERROR; length-boundary.docx→reject vsz.docx→accept reconfirmed)
4. Secondary Features By Spec Section Order
F036 — New Filename Validation
- Category: Backend
- Spec Reference: Section 5.1
- What it should do (end-user perspective): Accept valid
YYYY-MM-DD[-TIME]-Slug.docxfilenames, reject invalid dates/extensions/slugs, and preserve storm-type and storm-ID parsing. - How to test it (step-by-step as a human user):
- Validate a set of correctly formatted NEW filenames.
- Validate malformed dates, bad extensions, and short/oversized slugs.
- Confirm results distinguish success from failure codes.
- Confirm storm type and
94L/09Ltokens are parsed when present.
- Code path:
src/shared/validation/FileValidator.tsparseNewFormat/validateDocxFilename - Dependencies: None
- Test data needed: Valid and invalid NEW-format basenames
- Status: PASS
- Evidence:
refinement-state/test-fixtures/file-validator-result.json,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-5/file-validator-smoke.json(cycle 5: 22 cases — 11 valid incl. boundary years 2020/2100, months Jan/Dec, 94L/94l case; 11 rejection incl. year 2019/2101, day 00/32, month 0/13, Feb 30, short slug, bad ext, path separator, empty)
F037 — Legacy Filename Auto-Conversion
- Category: Backend
- Spec Reference: Section 5.2
- What it should do (end-user perspective): Accept old
Name_Time_M-D-YY.docxfilenames, convert them into NEW format, and reject legacy names that convert into invalid NEW-format results. - How to test it (step-by-step as a human user):
- Validate a set of legacy-format filenames.
- Confirm the converted basename matches the expected NEW name.
- Confirm invalid converted dates fail.
- Confirm original legacy data is retained in the parsed result.
- Code path:
src/shared/validation/FileValidator.tsconvertOldToNew/parseOldFormat/validateDocxFilename - Dependencies: F036
- Test data needed: Legacy
.docxbasenames - Status: PASS
- Evidence:
refinement-state/test-fixtures/file-validator-result.json,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-5/file-validator-smoke.json(cycle 5:Imelda_12pm_9-29-25.docxandHelene_4pm_10-15-24.docxboth validate asok: truevia legacy→NEW conversion)
F038 — Filename Display Formatting With Configurable Timezone
- Category: Config
- Spec Reference: Section 5.4, Section 19 R4
- What it should do (end-user perspective): Format validated filenames into display-friendly title/date/time strings and append a configurable timezone label instead of hardcoded
ET. - How to test it (step-by-step as a human user):
- Parse a valid NEW-format filename.
- Confirm the title converts hyphens into capitalized words.
- Confirm storm IDs remain uppercase.
- Confirm the timezone label changes when
timezoneLabelchanges.
- Code path:
src/shared/validation/FileValidator.tsparseFilename->src/shared/config/ConfigSchema.tstimezoneLabel - Dependencies: F036, F057
- Test data needed: Valid NEW-format basenames and alternate timezone labels
- Status: PASS
- Evidence:
refinement-state/test-fixtures/file-validator-result.json,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-5/file-validator-smoke.json(cycle 5: 7 timezone labels —ET,CT,UTC,PT,GMT,MT,AKT— all render as suffix on12:00 PM <TZ>; Invest storm-ID casing normalization94l→Invest 94Lconfirmed)
F039 — Document Creator Renderer Section
- Category: UI
- Spec Reference: Section 6.2, Section 5.3
- What it should do (end-user perspective): Provide the full create-document form with date, time, storm selection, storm creation fields, update type, live filename preview, create/open button, and add-to-queue button.
- How to test it (step-by-step as a human user):
- Open the Create New Briefing Document section.
- Change date, time, storm, and type inputs.
- Confirm the filename preview updates live and validates.
- Create the document and add it to the queue.
- Code path:
src/renderer/features/doc-creator/DocCreator.tsx+docCreatorModel.ts+useDocCreatorFocusStore.tsmounted onPublishPlaceholder(src/renderer/routes/Placeholders.tsx); Ctrl+N (useAppShortcuts.ts) and command palette (CommandPalette.tsx) both route to the section viauseDocCreatorFocusStore.requestFocus() - Dependencies: F040, F041
- Test data needed: Year, storm ID, storm name/type combinations
- Status: PASS
- Evidence:
tests/renderer/docCreatorModel.test.ts(28 pure-model cases: filename grammar §5.3, storm folder §10, readiness §6.2),tests/renderer/docCreator.test.tsx(8 RTL cases: rendering, live preview, create + queue flow, DOC_EXISTS rejection, Ctrl+N focus bus), cycle-12 full suite 795/795 passing (refinement-functional-fixes-12.md)
F040 — Word COM Document Creation IPC
- Category: Backend
- Spec Reference: Section 7.5, Section 9
- What it should do (end-user perspective): Create a blank
.docxat the target tropical-updates folder through PowerShell Word COM automation, then open the file in the default.docxhandler. - How to test it (step-by-step as a human user):
- Call
doc:createwith a valid filename/year/folder. - Confirm the destination folder is created if missing.
- Confirm Word creates the
.docx. - Confirm Windows opens the file after creation.
- Call
- Code path:
window.api.docCreate->src/main/ipc/handlers/docHandlers.ts->src/main/services/word/WordDocumentService.ts - Dependencies: F036, F046
- Test data needed: Valid NEW-format filename, year, optional storm folder, installed Word
- Status: PASS
- Evidence:
refinement-state/test-fixtures/cycle-2/word-create-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F041 — Storm Folder Creation IPC
- Category: Backend
- Spec Reference: Section 7.5
- What it should do (end-user perspective): Create a storm folder under the configured tropical updates root for the given year and folder basename.
- How to test it (step-by-step as a human user):
- Call
storm:createFolderwith a year and folder name. - Confirm the year/storm path is created.
- Repeat the call with an existing folder.
- Confirm duplicate creation fails cleanly.
- Call
- Code path:
window.api.stormCreateFolder->src/main/ipc/handlers/stormFolderHandlers.ts->src/main/services/storms/StormFolderService.ts - Dependencies: F052, F057
- Test data needed: Writable tropical root, year, storm folder name
- Status: PASS
- Evidence:
refinement-state/test-fixtures/storm-folder-result.json,refinement-state/test-fixtures/storm-folder-retry-result.json,refinement-state/test-fixtures/storm-folder-errors-result.json,refinement-state/test-fixtures/storm-sync-mixed-result.json,refinement-state/test-fixtures/quick-browse-result.json,refinement-state/test-fixtures/quick-browse-base-path-result.json,refinement-state/test-fixtures/quick-browse-invalid-base-path-result.json
F042 — Single Storm Folder Rename IPC
- Category: Backend
- Spec Reference: Section 7.5, Section 10
- What it should do (end-user perspective): Inspect the
.docxfiles inside one storm folder, infer the correct target name, and rename the folder using the spec retry rules when Word locks are encountered. - How to test it (step-by-step as a human user):
- Prepare a storm folder with valid
.docxfiles. - Call
storm:updateFolderName. - Confirm the target folder name matches the filename evidence.
- Confirm lock retries and
pendingRenamebehavior appear on repeated lock failures.
- Prepare a storm folder with valid
- Code path:
window.api.stormUpdateFolderName->src/main/ipc/handlers/stormFolderHandlers.ts->src/main/services/storms/StormFolderService.ts - Dependencies: F044
- Test data needed: Storm folder with valid
.docxfiles and optional file lock scenario - Status: PASS
- Evidence:
refinement-state/test-fixtures/storm-folder-result.json,refinement-state/test-fixtures/storm-folder-retry-result.json,refinement-state/test-fixtures/storm-folder-errors-result.json,refinement-state/test-fixtures/storm-sync-mixed-result.json,refinement-state/test-fixtures/quick-browse-result.json,refinement-state/test-fixtures/quick-browse-base-path-result.json,refinement-state/test-fixtures/quick-browse-invalid-base-path-result.json
F043 — Bulk Storm Folder Sync IPC
- Category: Backend
- Spec Reference: Section 7.5, Section 10
- What it should do (end-user perspective): Walk every storm folder within a year, rename what should change, skip what is already correct, and report failures without aborting the whole year.
- How to test it (step-by-step as a human user):
- Prepare a year folder with multiple storm folders.
- Call
storm:syncAllFolderNames. - Confirm renamed, skipped, and failed rows are all reported.
- Confirm the overall success flag is false when any operation fails.
- Code path:
window.api.stormSyncAllFolderNames->src/main/ipc/handlers/stormFolderHandlers.ts->src/main/services/storms/StormFolderService.ts - Dependencies: F044
- Test data needed: Year folder containing multiple storm folders with varied contents
- Status: PASS
- Evidence:
refinement-state/test-fixtures/storm-folder-result.json,refinement-state/test-fixtures/storm-folder-retry-result.json,refinement-state/test-fixtures/storm-folder-errors-result.json,refinement-state/test-fixtures/storm-sync-mixed-result.json,refinement-state/test-fixtures/quick-browse-result.json,refinement-state/test-fixtures/quick-browse-base-path-result.json,refinement-state/test-fixtures/quick-browse-invalid-base-path-result.json
F044 — Storm Folder Naming Rules Engine
- Category: Backend
- Spec Reference: Section 4.1, Section 10, Section 19 R3
- What it should do (end-user perspective): Determine folder basenames using the runtime priority
Named Storm > TD > PTC > Invest, with tie-break and consensus rule IDs for diagnostics. - How to test it (step-by-step as a human user):
- Feed the engine named-storm, TD, PTC, and invest filename combinations.
- Confirm named storms beat TD, TD beats PTC, and PTC beats invest.
- Confirm same-tier ties use filename ordering or consensus rules.
- Confirm validation errors fire for empty candidates or mixed storm IDs.
- Code path:
src/main/services/storms/StormFolderService.ts->src/main/services/storms/determineFolderName.ts->src/shared/constants/stormFolderRules.ts - Dependencies: F036, F037
- Test data needed: Representative
.docxbasename sets for each storm-classification scenario - Status: PASS
- Evidence:
refinement-state/test-fixtures/storm-folder-result.json,refinement-state/test-fixtures/storm-folder-retry-result.json,refinement-state/test-fixtures/storm-folder-errors-result.json,refinement-state/test-fixtures/storm-sync-mixed-result.json,refinement-state/test-fixtures/quick-browse-result.json,refinement-state/test-fixtures/quick-browse-base-path-result.json,refinement-state/test-fixtures/quick-browse-invalid-base-path-result.json,refinement-state/test-fixtures/cycle-5/folder-name-smoke.json(cycle 5: 12 cases — full priority matrixNamed > TD > PTC > Investwith every ordered pair including newnamed-beats-invest-only)
F045 — [MISSING] Quick Browse Renderer Section
- Category: UI
- Spec Reference: Section 6.3
- What it should do (end-user perspective): Show year and storm selectors, refresh/sync buttons, a file checklist, and an
Add Selectedaction for browsing the tropical updates folder from the app UI. - How to test it (step-by-step as a human user):
- Open the Quick Browse section.
- Select a year and storm.
- Refresh the storm file list and sync folders.
- Add selected files to the upload queue.
- Code path: MISSING — browse services and IPC exist, but no renderer UI consumes them
- Dependencies: F046, F047, F048, F049
- Test data needed: Tropical updates directory with year/storm/docx content
- Status: MISSING
- Evidence:
F046 — Quick Browse Base Path Lookup
- Category: API
- Spec Reference: Section 7.6
- What it should do (end-user perspective): Return the resolved tropical updates root path so the renderer can display or seed browse flows.
- How to test it (step-by-step as a human user):
- Configure a valid tropical updates path.
- Call the base-path API.
- Confirm the returned path is absolute and normalized.
- Confirm invalid or missing config causes a structured error.
- Code path:
window.api.browseGetBasePath->src/main/ipc/handlers/browseHandlers.ts->src/main/services/browse/QuickBrowseService.ts - Dependencies: F052, F057
- Test data needed: Valid and invalid tropical path configurations
- Status: PASS
- Evidence:
refinement-state/test-fixtures/storm-folder-result.json,refinement-state/test-fixtures/storm-folder-retry-result.json,refinement-state/test-fixtures/storm-folder-errors-result.json,refinement-state/test-fixtures/storm-sync-mixed-result.json,refinement-state/test-fixtures/quick-browse-result.json,refinement-state/test-fixtures/quick-browse-base-path-result.json,refinement-state/test-fixtures/quick-browse-invalid-base-path-result.json
F047 — Quick Browse Year Listing
- Category: API
- Spec Reference: Section 6.3, Section 7.6
- What it should do (end-user perspective): Return all four-digit season folders under the tropical updates root, sorted newest-first.
- How to test it (step-by-step as a human user):
- Prepare multiple year directories under the tropical root.
- Call the year-list API.
- Confirm only
YYYYdirectory names are returned. - Confirm the list is sorted descending.
- Code path:
window.api.browseListYears->src/main/ipc/handlers/browseHandlers.ts->src/main/services/browse/QuickBrowseService.ts - Dependencies: F046
- Test data needed: Multiple year folders, plus non-year directories to exclude
- Status: PASS
- Evidence:
refinement-state/test-fixtures/storm-folder-result.json,refinement-state/test-fixtures/storm-folder-retry-result.json,refinement-state/test-fixtures/storm-folder-errors-result.json,refinement-state/test-fixtures/storm-sync-mixed-result.json,refinement-state/test-fixtures/quick-browse-result.json,refinement-state/test-fixtures/quick-browse-base-path-result.json,refinement-state/test-fixtures/quick-browse-invalid-base-path-result.json
F048 — Quick Browse Storm Listing
- Category: API
- Spec Reference: Section 6.3, Section 7.6
- What it should do (end-user perspective): Return storm folders for a selected year with parsed
folder,id,name, anddisplayNamevalues sorted by numeric storm ID. - How to test it (step-by-step as a human user):
- Prepare a year folder with invest, TD/PTC, and named-storm subfolders.
- Call the storm-list API for that year.
- Confirm each row includes the expected parsed display fields.
- Confirm sort order follows the storm number rather than raw string order.
- Code path:
window.api.browseListStorms->src/main/ipc/handlers/browseHandlers.ts->src/main/services/browse/QuickBrowseService.ts - Dependencies: F047
- Test data needed: Mixed storm folder names such as
94L,07L_TD7,09L_Imelda - Status: PASS
- Evidence:
refinement-state/test-fixtures/storm-folder-result.json,refinement-state/test-fixtures/storm-folder-retry-result.json,refinement-state/test-fixtures/storm-folder-errors-result.json,refinement-state/test-fixtures/storm-sync-mixed-result.json,refinement-state/test-fixtures/quick-browse-result.json,refinement-state/test-fixtures/quick-browse-base-path-result.json,refinement-state/test-fixtures/quick-browse-invalid-base-path-result.json
F049 — Quick Browse Storm File Listing
- Category: API
- Spec Reference: Section 6.3, Section 7.6
- What it should do (end-user perspective): Return
.docxfiles within a selected storm folder, including path, size, and modified timestamp sorted newest-first. - How to test it (step-by-step as a human user):
- Prepare a storm folder with several
.docxfiles and non-.docxfiles. - Call the file-list API.
- Confirm only
.docxfiles are returned. - Confirm they are sorted by modified time descending.
- Prepare a storm folder with several
- Code path:
window.api.browseListStormFiles->src/main/ipc/handlers/browseHandlers.ts->src/main/services/browse/QuickBrowseService.ts - Dependencies: F048
- Test data needed: Storm folder with
.docxand non-.docxfiles - Status: PASS
- Evidence:
refinement-state/test-fixtures/storm-folder-result.json,refinement-state/test-fixtures/storm-folder-retry-result.json,refinement-state/test-fixtures/storm-folder-errors-result.json,refinement-state/test-fixtures/storm-sync-mixed-result.json,refinement-state/test-fixtures/quick-browse-result.json,refinement-state/test-fixtures/quick-browse-base-path-result.json,refinement-state/test-fixtures/quick-browse-invalid-base-path-result.json
F050 — Header Logo And Git Status Indicator
- Category: UI
- Spec Reference: Section 6.1, Section 14, Section 15
- What it should do (end-user perspective): Show the WxManBran logo and a colored git status indicator in the header, including the uncommitted-changes warning text.
- How to test it (step-by-step as a human user):
- Open the app header.
- Confirm the logo image is displayed.
- Confirm a colored dot and branch text appear in the header.
- Dirty the repo and confirm the warning text updates.
- Code path:
src/renderer/layout/TopBar.tsx(logo<img src="./WMB_Logo.png">+computeHeaderGitIndicatorsection) ->src/renderer/layout/headerGitIndicatorModel.ts(§14 color ladder: connected/warning/error/loading) ->src/renderer/hooks/useGitStatus.ts->git:getStatusIPC. - Dependencies: F009, F014
- Test data needed: Clean and dirty repo states
- Status: PASS
- Evidence:
tests/renderer/topBar.test.tsx(7/7 PASS — logo alt text, green/yellow/red dot variants per spec §14, command-button + theme-toggle regression);tests/renderer/headerGitIndicatorModel.test.ts(9/9 PASS — model cases for clean/dirty/error/loading/detached);refinement-state/refinement-functional-fixes-9.md
F051 — Application Menu
- Category: UI
- Spec Reference: Section 19 R5
- What it should do (end-user perspective): Provide File/Edit application menus and eventually let the user open Settings from the menu.
- How to test it (step-by-step as a human user):
- Launch the app on Windows.
- Open the application menu.
- Confirm
FileandEditmenus exist. - Confirm
Settingsis present but currently disabled.
- Code path:
src/main/index.ts->src/main/menu/appMenu.ts - Dependencies: F005
- Test data needed: Running Electron app
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F052 — Repo/Incoming/Tropical Path Resolution
- Category: Config
- Spec Reference: Section 3, Section 4.2, Section 19 R5
- What it should do (end-user perspective): Derive the repo root, incoming posts directory, full incoming path, and tropical updates path from app paths and config values.
- How to test it (step-by-step as a human user):
- Inspect or call into the path service with default config.
- Confirm repo root resolves two levels above the tool directory.
- Confirm incoming posts normalizes to POSIX-style
incoming/posts. - Confirm
%USERPROFILE%expansion works for the tropical path.
- Code path:
src/main/services/paths/PathService.ts - Dependencies: None
- Test data needed: Different incoming path strings and tropical path templates
- Status: PASS
- Evidence:
refinement-state/screenshots/cycle-2/interactive-after-continue.png,refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F053 — Config Load, Save, Atomic Write, And Migration
- Category: Config
- Spec Reference: Section 19 R5, Section 30.1, Section 30.2
- What it should do (end-user perspective): Persist app configuration in
userData/config.json, validate it through the shared schema, write atomically, and run versioned migrations with backups when schema versions change. - How to test it (step-by-step as a human user):
- Launch the app with no config file and confirm defaults load.
- Save a modified config and confirm
config.jsonis written atomically. - Corrupt the file and confirm load fails with a structured config error.
- Create an older schema version and confirm migration/backups run.
- Code path:
src/main/services/config/ConfigService.ts->src/shared/config/ConfigSchema.ts - Dependencies: F057, F058, F059, F060
- Test data needed: Missing, valid, corrupt, and out-of-date config files
- Status: PASS
- Evidence:
refinement-state/functional-verify-3-artifacts/f053-migration-chain-20260408-182821.log
F054 — First-Run Path Submission And Validation
- Category: Config
- Spec Reference: Section 19 R5, Section 23.10
- What it should do (end-user perspective): Validate that the configured tropical updates path is absolute, exists, is a directory, and is writable before saving it and unblocking the app.
- How to test it (step-by-step as a human user):
- Open the first-run window.
- Submit an empty, relative, missing, non-directory, and unwritable path in separate attempts.
- Confirm each invalid path shows a structured error.
- Submit a valid path and confirm the gate resolves.
- Code path:
src/main/services/firstRun/FirstRunGate.ts->window.api.firstRunGetState/firstRunSubmitPath->src/renderer/features/first-run/FirstRunModal.tsx - Dependencies: F053
- Test data needed: Multiple path scenarios on disk
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F055 — Settings Read API
- Category: API
- Spec Reference: Section 20.7, Section 28.1, Section 30.1
- What it should do (end-user perspective): Return the current config snapshot to the renderer, optionally filtered by top-level keys, while redacting the stored Discord webhook value.
- How to test it (step-by-step as a human user):
- Save a populated config.
- Call
settings:getwith and without akeysfilter. - Confirm
schemaVersionis always included. - Confirm a non-empty Discord webhook is returned as
[REDACTED].
- Code path:
window.api.settingsGet->src/main/ipc/handlers/settingsHandlers.ts->src/main/services/config/ConfigService.ts - Dependencies: F053
- Test data needed: Populated config with multiple top-level keys
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F056 — Settings Update API With Optimistic Locking
- Category: API
- Spec Reference: Section 20.7, Section 28.1, Section 30.2
- What it should do (end-user perspective): Accept a patch plus
expectedSchemaVersion, merge it into the current config, reject stale updates, validate the result, save it, and append a settings audit line. - How to test it (step-by-step as a human user):
- Load settings to capture the current
schemaVersion. - Send a valid patch with the matching version.
- Confirm the config saves successfully.
- Retry with a stale version or invalid field and confirm a structured error is returned.
- Load settings to capture the current
- Code path:
window.api.settingsUpdate->src/main/ipc/handlers/settingsHandlers.ts->src/main/services/config/ConfigService.ts->src/main/services/audit/writeAuditLine.ts - Dependencies: F053, F055
- Test data needed: Valid config patches and stale-version scenarios
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F057 — Config Schema: Core Publish Settings
- Category: Config
- Spec Reference: Section 19 R1, Section 19 R4, Section 19 R5, Section 20.5, Section 30.1
- What it should do (end-user perspective): Persist the core settings the implemented app already uses:
schemaVersion,tropicalUpdatesPath,timezoneLabel,branch,incomingPostsPath, andonboardingComplete. - How to test it (step-by-step as a human user):
- Load a minimal config object.
- Confirm defaults are applied.
- Change each core value through settings or config load/save tests.
- Confirm downstream services consume the updated values.
- Code path:
src/shared/config/ConfigSchema.ts->src/main/services/config/ConfigService.ts->PathService/PublishService/FirstRunGate - Dependencies: F053
- Test data needed: Config JSON with partial and full core settings
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F058 — Config Schema: Review And Draft Settings
- Category: Config
- Spec Reference: Section 20.3, Section 20.5
- What it should do (end-user perspective): Persist review/draft-related settings already defined in the schema:
approvalMode,reviewerEmail,senderEmail,senderProvider,imapInbox,maxRevisionCycles,reviewTimeoutHours,draftBackend, andbackendModels. - How to test it (step-by-step as a human user):
- Load a config with review/draft keys omitted.
- Confirm defaults are applied.
- Save custom values for each field.
- Confirm they round-trip through
settings:getandsettings:update.
- Code path:
src/shared/config/ConfigSchema.ts->src/main/ipc/handlers/settingsHandlers.ts - Dependencies: F053, F055, F056
- Test data needed: Config JSON variations covering each field
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F059 — Config Schema: Monitor And Dashboard Settings
- Category: Config
- Spec Reference: Section 20.1, Section 20.4, Section 20.5
- What it should do (end-user perspective): Persist monitor and dashboard preferences already defined in schema:
nhcMonitor.enabled,pollIntervalMinutes,enabledProducts,manuallyWatchedStorms,excludedStorms,dashboard.sections, anddashboard.sectionOrder. - How to test it (step-by-step as a human user):
- Load config with monitor/dashboard keys omitted.
- Confirm defaults are applied.
- Save custom product arrays and dashboard section orders.
- Confirm values round-trip through settings APIs.
- Code path:
src/shared/config/ConfigSchema.ts->src/main/ipc/handlers/settingsHandlers.ts - Dependencies: F053, F055, F056
- Test data needed: Config JSON variations covering monitor and dashboard fields
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F060 — Config Schema: Intelligence, QoL, And Advanced Settings
- Category: Config
- Spec Reference: Section 24.2, Section 24.6, Section 29.1, Section 31.4
- What it should do (end-user perspective): Persist additional settings already modeled in schema:
aiCostLimits,publishing.autoCommitMessage,publishing.scheduleEnabled,social.discord,liveSiteCheck,updateCheck.manifestUrl,queue.autoSave,developer.showDraftPrompts,houseStyleRules, andlogging.level. - How to test it (step-by-step as a human user):
- Load config with these fields omitted and inspect defaults.
- Save custom values for each group.
- Read them back through
settings:get. - Confirm secret-like keys are still blocked from config JSON.
- Code path:
src/shared/config/ConfigSchema.ts->src/main/services/config/ConfigService.ts - Dependencies: F053, F055, F056
- Test data needed: Config JSON variations for advanced fields
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F061 — OS Credential Vault Integration
- Category: Integration
- Spec Reference: Section 28.1
- What it should do (end-user perspective): Store and retrieve secrets from Windows Credential Manager through
keytarusing the app’s fixed service name instead of saving passwords/tokens in config JSON. - How to test it (step-by-step as a human user):
- Save a credential for a supported account key.
- Read it back.
- Delete it.
- Confirm empty accounts, empty passwords, and vault failures map to structured errors.
- Code path:
src/main/services/security/CredentialVault.ts - Dependencies: None
- Test data needed: Sample SMTP/IMAP/OAuth/GitHub/Anthropic account identifiers
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F062 — Content Security Policy Enforcement
- Category: Backend
- Spec Reference: Section 1 Rule 6, Section 28.2
- What it should do (end-user perspective): Inject a baseline CSP into renderer responses, with extra dev-only relaxations for Vite HMR and no Node access in the renderer.
- How to test it (step-by-step as a human user):
- Launch the app in production mode.
- Inspect response headers for the renderer.
- Confirm the baseline CSP is present.
- Launch in development mode and confirm HMR-specific directives are added.
- Code path:
src/main/security/csp.ts->src/main/index.ts - Dependencies: F005
- Test data needed: Development and production app launches
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F063 — Main Log File Rotation
- Category: Backend
- Spec Reference: Section 29.1
- What it should do (end-user perspective): Write the main process log to
userData/logs/main.logand rotate it with a five-file, five-megabyte policy. - How to test it (step-by-step as a human user):
- Start the app.
- Generate enough logs to exceed the size threshold.
- Confirm
main.log.1throughmain.log.5are created as needed. - Confirm file logging falls back cleanly on directory/rotation failures.
- Code path:
src/main/logging/logger.ts - Dependencies: F005
- Test data needed: Writable
userDatapath and enough log output to rotate - Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F064 — Crash Guard And Previous-Crash Marker
- Category: Error Handling
- Spec Reference: Section 29.3
- What it should do (end-user perspective): Catch uncaught exceptions and unhandled rejections, log them, and write a
PREVIOUS_CRASHmarker for future recovery handling. - How to test it (step-by-step as a human user):
- Launch the app in development mode.
- Trigger an uncaught exception or unhandled rejection.
- Confirm the failure is logged.
- Confirm
PREVIOUS_CRASHappears underuserData.
- Code path:
src/main/app/crashGuard.ts->src/main/index.ts - Dependencies: F005
- Test data needed: Controlled crash or rejection scenario
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F065 — Audit Log Append Helper
- Category: Backend
- Spec Reference: Section 29.4
- What it should do (end-user perspective): Append one JSON-lines audit record into
userData/logs/audit.logwithout crashing the process if the write fails. - How to test it (step-by-step as a human user):
- Trigger an action that writes an audit record.
- Open
userData/logs/audit.log. - Confirm a single JSON object line was appended.
- Confirm audit write failures are logged but non-fatal.
- Code path:
src/main/services/audit/writeAuditLine.ts - Dependencies: F053 or any caller using audit append
- Test data needed: A caller that emits an audit event
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F066 — Publish History Append
- Category: Backend
- Spec Reference: Section 24.6, Section 30.1
- What it should do (end-user perspective): Append a JSON-lines record of each successful publish to a user-data history file.
- How to test it (step-by-step as a human user):
- Complete a successful publish.
- Open the publish-history file.
- Confirm a new line contains timestamp, branch, and commit.
- Confirm failed publishes do not append success records.
- Code path:
src/main/services/git/PublishService.ts->src/main/services/publish/PublishHistoryService.ts - Dependencies: F029
- Test data needed: Successful publish scenario
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F067 — [UNDOCUMENTED] shell:openPath Utility
- Category: API
- Spec Reference: UNDOCUMENTED (not found in project-spec.md)
- What it should do (end-user perspective): Let renderer code request that an absolute filesystem path be opened by the OS shell, returning a structured success/error result instead of throwing raw platform errors.
- How to test it (step-by-step as a human user):
- Call the utility with a valid absolute path.
- Confirm the target opens.
- Call it with an empty, relative, or invalid path.
- Confirm a structured error result is returned.
- Code path:
window.api.shellOpenPath->src/main/ipc/handlers/utilityHandlers.ts - Dependencies: None
- Test data needed: Valid absolute directory/file path plus invalid path examples
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F068 — [UNDOCUMENTED] config:getPublic Utility
- Category: API
- Spec Reference: UNDOCUMENTED (not found in project-spec.md)
- What it should do (end-user perspective): Return the repo path, incoming posts path, full incoming path, tropical path, timezone label, and branch in one renderer-safe public snapshot.
- How to test it (step-by-step as a human user):
- Save a populated config.
- Call the public-config API.
- Confirm only non-secret values are returned.
- Confirm the incoming path is fully resolved.
- Code path:
window.api.configGetPublic->src/main/ipc/handlers/utilityHandlers.ts->PathService - Dependencies: F052, F053
- Test data needed: Populated config
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log,refinement-state/verification-cycle-2-artifacts/verify-regression-slice.log,refinement-state/verification-cycle-2-artifacts/npm-run-build-verify.log
F069 — [UNDOCUMENTED] paths:resolve Utility IPC
- Category: API
- Spec Reference: UNDOCUMENTED (not found in project-spec.md)
- What it should do (end-user perspective): Resolve a requested incoming filename into both absolute filesystem and git-relative target paths.
- How to test it (step-by-step as a human user):
- Call the path-resolution API with a sample incoming filename.
- Confirm the returned absolute and git-relative paths are correct.
- Call the API with malformed input.
- Confirm it rejects cleanly.
- Code path:
src/preload/index.tspathsResolve->src/main/ipc/handlers/utilityHandlers.ts->src/main/ipc/router.ts - Dependencies: F052, F068
- Test data needed: Sample incoming basenames
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log
F070 — Onboarding Completion IPC
- Category: API
- Spec Reference: Section 23.10
- What it should do (end-user perspective): Persist onboarding completion state after the renderer submits the user’s completed first-launch answers.
- How to test it (step-by-step as a human user):
- Call
onboardingCompletewith a completed answers payload. - Confirm
config.jsonis saved withonboardingComplete: true. - Reload first-run state or restart the app.
- Confirm onboarding no longer reports as needed and an audit line is appended.
- Call
- Code path:
src/preload/index.tsonboardingComplete->src/main/ipc/handlers/utilityHandlers.ts->src/main/ipc/router.ts - Dependencies: F054
- Test data needed: Completed onboarding answers payload
- Status: PASS
- Evidence:
refinement-state/verification-cycle-2-artifacts/verify-fixes-suite.log
5. Error Handling And Recovery
F071 — Drop Zone Bridge Failure Handling
- Category: Error Handling
- Spec Reference: Section 6.4, Section 23.11
- What it should do (end-user perspective): Surface clear errors if the preload drag-drop bridge or browse dialog bridge is unavailable or rejects a request.
- How to test it (step-by-step as a human user):
- Simulate a missing
window.dragDroporwindow.api. - Attempt to drop or browse files.
- Confirm an error toast and/or inline alert appears.
- Confirm the app does not silently swallow the failure.
- Simulate a missing
- Code path:
src/renderer/features/publish/DropZone.tsx->src/renderer/api/ipcClient.ts - Dependencies: F022, F023
- Test data needed: Missing bridge or rejected dialog invocation
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F072 — File Copy Error Mapping And Batch Abort
- Category: Error Handling
- Spec Reference: Section 7.2, Section 29.2
- What it should do (end-user perspective): Map filesystem failures into stable
FILE_COPY_*codes, stop the batch at the first failing file, and mark remaining items as aborted. - How to test it (step-by-step as a human user):
- Invoke the file-copy path with multiple files.
- Force an
ENOENT,EACCES,ENOSPC, or bad-destination case on one item. - Confirm the failing row gets the correct code and user summary.
- Confirm later rows are returned as
FILE_COPY_BATCH_ABORTED.
- Code path:
src/main/services/publish/FileCopyService.ts - Dependencies: F028
- Test data needed: Missing file, locked destination, full disk simulation, malformed destination
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F073 — Git Status Error Mapping
- Category: Error Handling
- Spec Reference: Section 14, Section 29.2
- What it should do (end-user perspective): Translate status failures into structured
GIT_NOT_A_REPOandGIT_STATUS_FAILEDerrors instead of rawsimple-gitexceptions. - How to test it (step-by-step as a human user):
- Call git status in a valid repo.
- Call git status in a non-repo directory.
- Simulate a missing
gitbinary. - Confirm the structured error code/message matches the expected branch-indicator behavior.
- Code path:
src/main/ipc/handlers/gitGetStatusHandlers.ts->src/main/services/git/GitService.ts->src/main/services/git/gitStatusMapper.ts - Dependencies: F014
- Test data needed: Valid repo, non-repo, and missing-git scenarios
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F074 — [UNDOCUMENTED] Duplicate Publish Guard
- Category: Error Handling
- Spec Reference: UNDOCUMENTED (not found in project-spec.md)
- What it should do (end-user perspective): Reject a second publish request while one publish is already in flight.
- How to test it (step-by-step as a human user):
- Start a long-running publish.
- Trigger a second publish request before the first completes.
- Confirm the second request returns a duplicate-submit warning.
- Confirm the first publish continues normally.
- Code path:
src/main/services/git/PublishService.tsinFlightguard - Dependencies: F029
- Test data needed: Two overlapping publish attempts
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F075 — [UNDOCUMENTED] Pre-Existing Staged-Changes Conflict Guard
- Category: Error Handling
- Spec Reference: UNDOCUMENTED (not found in project-spec.md)
- What it should do (end-user perspective): Refuse to publish if unrelated files are already staged in git on the target branch.
- How to test it (step-by-step as a human user):
- Stage unrelated repo files manually.
- Run publish for tropical update files.
- Confirm publish stops before mutating git history.
- Confirm the user-facing error explains that other staged changes must be resolved first.
- Code path:
src/main/services/git/PublishService.tsfindUnexpectedPreStagedPaths - Dependencies: F029
- Test data needed: Target branch with unrelated staged files
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F076 — Publish No-Changes Exit
- Category: Error Handling
- Spec Reference: Section 8
- What it should do (end-user perspective): Exit the publish workflow cleanly when staging produces no cached changes to commit.
- How to test it (step-by-step as a human user):
- Copy files that already match repo contents.
- Trigger publish.
- Confirm publish returns success with a
No changes to commitwarning. - Confirm stash/branch state is restored if branch switching occurred.
- Code path:
src/main/services/git/PublishService.tsPUBLISH_NO_CHANGES - Dependencies: F029
- Test data needed: Repo where target files are unchanged
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F077 — Publish Remote/Auth/Conflict/Push-Rejected Recovery
- Category: Error Handling
- Spec Reference: Section 8, Section 29.2
- What it should do (end-user perspective): Surface structured user messages for pull conflicts, auth failures, remote outages, checkout/stash failures, and push rejection while attempting to restore the original working state.
- How to test it (step-by-step as a human user):
- Trigger each publish failure mode in isolation.
- Confirm a structured error code/user message is returned.
- Confirm branch/stash restoration is attempted after the failure.
- Confirm restore failures are logged without masking the original problem.
- Code path:
src/main/services/git/PublishService.ts->src/main/services/git/GitService.ts - Dependencies: F029
- Test data needed: Auth failure, pull conflict, remote outage, push reject, stash conflict scenarios
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F078 — Document Creation Validation And Word Failure Mapping
- Category: Error Handling
- Spec Reference: Section 9, Section 29.2
- What it should do (end-user perspective): Reject invalid document-create requests before Word runs, and map Word/PowerShell failures into stable
DOC_EXISTS,WORD_TIMEOUT,WORD_NOT_INSTALLED, andWORD_COM_FAILUREresults. - How to test it (step-by-step as a human user):
- Call
doc:createwith invalid body shapes and unsafe paths. - Call it with an existing destination file.
- Simulate missing Word and script timeout cases.
- Confirm each case returns the expected code and message.
- Call
- Code path:
src/main/ipc/handlers/docHandlers.ts->src/main/services/word/WordDocumentService.ts - Dependencies: F040
- Test data needed: Invalid requests, existing file, missing Word, long path, locked folder
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F079 — Storm Folder Validation And Rename Exhaustion
- Category: Error Handling
- Spec Reference: Section 10, Section 29.2
- What it should do (end-user perspective): Reject unsafe year/folder inputs, target collisions, missing folders, and repeated lock failures with structured storm-folder error codes and
pendingRenamedata. - How to test it (step-by-step as a human user):
- Call storm-folder APIs with invalid years and basenames.
- Prepare target-exists and folder-missing scenarios.
- Force repeated
EBUSY,EPERM, orEACCESrename failures. - Confirm
pendingRenameis returned after retries exhaust.
- Code path:
src/main/services/storms/StormFolderService.ts->src/main/ipc/handlers/stormFolderHandlers.ts - Dependencies: F041, F042, F043
- Test data needed: Invalid input values and lock-conflict scenarios
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F080 — First-Run Invalid State And Abort Handling
- Category: Error Handling
- Spec Reference: Section 19 R5, Section 23.10, Section 29.2
- What it should do (end-user perspective): Reject malformed first-run IPC payloads, show inline path errors, and quit the app if the blocking first-run window is dismissed before setup completes.
- How to test it (step-by-step as a human user):
- Launch the first-run gate.
- Submit invalid request bodies or paths.
- Confirm inline error copy appears.
- Close the window before success and confirm the app quits.
- Code path:
src/main/services/firstRun/FirstRunGate.ts->src/renderer/features/first-run/FirstRunModal.tsx - Dependencies: F054
- Test data needed: Invalid path values and early window close
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F081 — Global Renderer IPC Failure Toasts
- Category: Error Handling
- Spec Reference: Section 23.11
- What it should do (end-user perspective): Show deduplicated global error toasts for query/mutation failures, provide user-friendly copy, and offer a
Copy detailsaction. - How to test it (step-by-step as a human user):
- Force an IPC query failure.
- Confirm a global error toast appears.
- Click
Copy details. - Confirm repeat failures within the dedupe window do not spam the UI.
- Code path:
src/renderer/api/ipcClient.ts->src/renderer/components/ui/sonner.tsx - Dependencies: F014 or any failing query/mutation
- Test data needed: Controlled IPC failures
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
F082 — [UNDOCUMENTED] NOT_IMPLEMENTED Stub Behavior For Unwired IPC
- Category: API
- Spec Reference: UNDOCUMENTED (not found in project-spec.md)
- What it should do (end-user perspective): Reject calls to unwired IPC channels with a stable
{ code: 'NOT_IMPLEMENTED', channel }payload instead of an opaque Electron error string. - How to test it (step-by-step as a human user):
- Call a known stubbed channel such as
paths:resolveornhc:getMonitorStatus. - Confirm the promise rejects with
NOT_IMPLEMENTED. - Call
gitStreamSubscribe. - Confirm the synchronous preload method throws a matching structured error.
- Call a known stubbed channel such as
- Code path:
src/main/ipc/router.tsstub registration ->src/preload/index.ts->src/shared/ipc/invokeErrors.ts - Dependencies: None
- Test data needed: Calls to stubbed channels
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/test-fixtures/cycle-2/publish-e2e-result.json,refinement-state/test-fixtures/cycle-2/word-create-electron-result.json
6. Keyboard Shortcuts, Accessibility, And Polish
F083 — First-Run Accessibility Baseline
- Category: UI
- Spec Reference: Section 23.6, Section 23.10
- What it should do (end-user perspective): Keep the first-run window keyboard reachable with clearly labeled controls, 44px touch targets, and inline error announcements.
- How to test it (step-by-step as a human user):
- Open the first-run window.
- Navigate the controls by keyboard only.
- Trigger a validation error.
- Confirm focus order, sizing, and alert text remain usable.
- Code path:
src/renderer/features/first-run/FirstRunModal.tsx->src/renderer/components/ui/button.tsx->src/renderer/components/ui/input.tsx - Dependencies: F006
- Test data needed: Invalid and valid path values
- Status: PASS
- Evidence:
refinement-state/functional-verify-3-artifacts/f083-invalid-path-a11y-20260408-182834.log
F084 — Sidebar, Button, Dialog, And Input Accessibility/Polish
- Category: UI
- Spec Reference: Section 23.4, Section 23.5, Section 23.6
- What it should do (end-user perspective): Provide accessible buttons, dialogs, and sidebar navigation with focus rings, minimum touch targets, and sensible ARIA labels.
- How to test it (step-by-step as a human user):
- Navigate the app shell with Tab.
- Open the sample dialog on Publish.
- Confirm focus is trapped and close controls are labeled.
- Confirm icon-only buttons expose accessible names.
- Code path:
src/renderer/layout/Sidebar.tsx->src/renderer/components/ui/button.tsx->src/renderer/components/ui/dialog.tsx->src/renderer/components/ui/input.tsx - Dependencies: F010, F021
- Test data needed: Running renderer
- Status: PASS
- Evidence:
refinement-state/functional-verify-4-artifacts/test-run-1.log,test-run-2.log,test-run-3.log(3/3 full-suite runs 564/564 PASS, zero flakes),refinement-state/functional-verify-4-artifacts/shadcn-smoke-isolated.log(16/16 isolated PASS),refinement-state/screenshots/cycle-2/interactive-after-continue.png. Cycle-4 flake resolved by switching dialog tests touserEvent.setup({ delay: null })+openDialogReliablyhelper and raising renderer projecttestTimeoutto 20000ms (seerefinement-functional-fixes-4.md). Cycle 5 restability:refinement-state/functional-cycle-5-artifacts/test-run-1.log/test-run-2.log/test-run-3.logall 564/564 PASS,shadcn-smoke-isolated.log16/16 PASS.
F085 — Footer Live Regions And Error Banner Accessibility
- Category: UI
- Spec Reference: Section 23.6
- What it should do (end-user perspective): Announce status-bar summaries politely and announce git-status failures assertively with a visible retry path.
- How to test it (step-by-step as a human user):
- Open the app with a working git repo.
- Inspect the hidden live-region summary.
- Force a git-status failure.
- Confirm the error banner uses
role="alert"and the retry action remains keyboard accessible.
- Code path:
src/renderer/layout/StatusBar.tsx->src/renderer/layout/statusBarModel.ts - Dependencies: F014
- Test data needed: Successful and failing git-status scenarios
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/screenshots/cycle-2/interactive-after-continue.png
F086 — Drop Zone Motion And Accessibility
- Category: UI
- Spec Reference: Section 23.4, Section 23.5, Section 23.6
- What it should do (end-user perspective): Give the drop zone active/success/error motion feedback while exposing
aria-invalid,role="alert", and polite live previews of filenames. - How to test it (step-by-step as a human user):
- Drag files over the zone.
- Confirm filename preview text is announced.
- Trigger success and error paths.
- Confirm motion reduces or disappears when reduced-motion is preferred.
- Code path:
src/renderer/features/publish/DropZone.tsx->src/renderer/motion/presets.ts->src/renderer/styles/globals.css - Dependencies: F022, F024
- Test data needed: Valid and invalid file drops, reduced-motion preference
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log,refinement-state/screenshots/cycle-2/interactive-after-continue.png
F087 — Functional Command Palette
- Category: Keyboard Shortcut
- Spec Reference: Section 23.8
- What it should do (end-user perspective): Open a searchable command launcher with navigation and action commands when the user presses
Ctrl+K/Cmd+K. - How to test it (step-by-step as a human user):
- Press
Ctrl+Kor click the search affordance. - Confirm a palette opens.
- Search for a route or command.
- Execute it entirely by keyboard.
- Press
- Code path:
src/renderer/features/command-palette/CommandPalette.tsx(shadcn Dialog + combobox input + listbox) ->commandPaletteModel.ts(pure filter + recency helpers) ->commandRegistry.ts(14 navigation/action/theme commands) ->src/renderer/stores/useCommandPaletteStore.ts(open/query/highlight/recent state) -> mounted insrc/renderer/layout/AppShell.tsx - Dependencies: F012
- Test data needed: Searchable commands and route/action registry
- Status: PASS
- Evidence:
tests/renderer/commandPalette.test.tsx,tests/renderer/commandPaletteModel.test.ts,tests/renderer/useCommandPaletteStore.test.ts(all green in cycle-11 fixes pass),refinement-state/refinement-functional-fixes-11.md
F088 — Keyboard Shortcut Wiring
- Category: Keyboard Shortcut
- Spec Reference: Section 23.7
- What it should do (end-user perspective): Implement the documented shortcuts:
Ctrl/Cmd+K,P,D,S,H,,,Enter,Del,A,Esc,N,R,/, andShift+Dcombinations as described in the spec. - How to test it (step-by-step as a human user):
- Open the app shell.
- Press each documented shortcut in context.
- Confirm the expected route/action/theme/sidebar behavior fires.
- Confirm shortcuts are documented in Settings.
- Code path:
src/renderer/hooks/keyboardShortcutModel.ts(pure key/modifier helpers, editable-target policy, Apple detection) ->src/renderer/hooks/useAppShortcuts.ts(single window-levelkeydownlistener, 14 bindings matching §23.7 table) -> installed fromsrc/renderer/layout/AppShell.tsx - Dependencies: F010, F087
- Test data needed: Running renderer with functional route/action handlers
- Status: PASS
- Evidence:
tests/renderer/keyboardShortcutModel.test.ts(20/20 PASS),tests/renderer/useAppShortcuts.test.tsx(9/9 PASS),refinement-state/refinement-functional-fixes-11.md
F089 — Context Menus
- Category: UI
- Spec Reference: Section 23.12
- What it should do (end-user perspective): Show right-click menus on queue files, storm cards, drafts, and published items with the actions listed in the spec.
- How to test it (step-by-step as a human user):
- Right-click each supported entity type.
- Confirm the expected menu opens.
- Choose one action from each menu.
- Confirm the target action fires correctly.
- Code path:
src/renderer/components/ContextMenu.tsx(reusable primitive with keyboard nav + viewport clamping) ->src/renderer/features/publish/queueRowContextMenu.ts(spec §23.12 queue-row items: Remove / Preview in Word / Copy filename / Edit YouTube URL / Move to top) -> consumed bysrc/renderer/features/publish/FileList.tsxonContextMenu handler; storm/draft/history surfaces will consume the same primitive when those routes land (F103, F108). - Dependencies: F030, F103, F108
- Test data needed: Queue items, storm cards, drafts, and published items
- Status: PASS
- Evidence:
tests/renderer/contextMenu.test.tsx,tests/renderer/queueRowContextMenu.test.ts(all green in cycle-11 fixes pass); storm/draft/history consumers deferred to their owning features (F103 Draft Queue, F108 Publish History Dashboard) — primitive + queue-row surface satisfy the spec §23.12 clause that exists today (queued file right-click menu).
F090 — Designed Empty States
- Category: UI
- Spec Reference: Section 23.9
- What it should do (end-user perspective): Show polished empty states for Publish, Drafts, Storms, and History instead of generic placeholder text.
- How to test it (step-by-step as a human user):
- Open each major route with no data.
- Confirm a dedicated empty-state design appears.
- Confirm the copy matches the spec for that route.
- Confirm each empty state includes the intended CTA or guidance.
- Code path:
src/renderer/components/EmptyState.tsx(reusable primitive) ->src/renderer/routes/Placeholders.tsx(DraftsPlaceholder,StormsPlaceholder,HistoryPlaceholderconsumers); Publish view’s illustration+CTA is provided bysrc/renderer/features/publish/DropZone.tsx(§8A) as spec §23.9 requires. - Dependencies: F021, F016, F017, F018
- Test data needed: Empty data state for each route
- Status: PASS
- Evidence:
tests/renderer/emptyState.test.tsx(7/7 PASS — EmptyState primitive + three route consumers assert spec §23.9 copy verbatim),refinement-state/refinement-functional-fixes-6.md(fix landing notes)
F091 — [UNDOCUMENTED] Default Dark Theme In Local Storage
- Category: UI
- Spec Reference: UNDOCUMENTED (not found in project-spec.md)
- What it should do (end-user perspective): Default the renderer to dark theme when no prior choice is stored, then persist the choice under
tup:ui-theme-v1. - How to test it (step-by-step as a human user):
- Clear local storage.
- Load the renderer.
- Confirm dark theme is applied.
- Toggle to light and confirm the storage key is written.
- Code path:
src/renderer/theme/uiTheme.ts->src/renderer/theme/bootstrapRendererChrome.ts - Dependencies: F013
- Test data needed: Empty local storage
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
F092 — [UNDOCUMENTED] Ephemeral Sidebar Collapse State
- Category: UI
- Spec Reference: UNDOCUMENTED (not found in project-spec.md)
- What it should do (end-user perspective): Keep sidebar collapse state only for the current renderer session without persisting it to local storage or config.
- How to test it (step-by-step as a human user):
- Collapse the sidebar.
- Navigate between routes.
- Confirm the sidebar stays collapsed during the session.
- Reload the renderer and confirm it resets to expanded.
- Code path:
src/renderer/stores/useSidebarStore.ts - Dependencies: F011
- Test data needed: None
- Status: PASS
- Evidence:
refinement-state/functional-cycle-2-artifacts/npm-test-final-rerun-3.log
7. Phase 2 / Advanced Feature Gaps
F093 — [MISSING] NHC Monitor Scheduler
- Category: Backend
- Spec Reference: Section 20.1
- What it should do (end-user perspective): Run a background service that polls NHC on the configured cadence with backoff and rate limits.
- How to test it (step-by-step as a human user):
- Enable monitoring.
- Leave the app open through multiple poll intervals.
- Confirm monitor cycles run on schedule and back off on failures.
- Confirm pause/resume controls affect the scheduler.
- Code path: MISSING — no main-process monitor service or timers exist
- Dependencies: F059
- Test data needed: Reachable NHC endpoints or mocks
- Status: MISSING
- Evidence:
F094 — [MISSING] NHC Product Fetchers And HTTP Rules
- Category: Integration
- Spec Reference: Section 20.1
- What it should do (end-user perspective): Fetch TCPAT, TCMAT, TCDAT, TCUAT, WTNT/WOCA, graphics, active-storm JSON, and RSS with the configured headers, timeout, cache, and rate-limit behavior.
- How to test it (step-by-step as a human user):
- Start the NHC monitor.
- Confirm each enabled product type can be fetched.
- Inspect request headers, timeout behavior, and one-request-per-endpoint-per-minute enforcement.
- Confirm failures back off instead of flooding requests.
- Code path: MISSING — no HTTP client or NHC fetch modules exist
- Dependencies: F093
- Test data needed: Mock or live NHC responses
- Status: MISSING
- Evidence:
F095 — [MISSING] Change Detection, Fingerprints, And Active-Storm State
- Category: Backend
- Spec Reference: Section 20.1, Section 30.1, Section 30.3
- What it should do (end-user perspective): Fingerprint fetched NHC products, detect advisory changes, and persist active-storm state across restarts.
- How to test it (step-by-step as a human user):
- Fetch a storm product set twice.
- Confirm unchanged content does not trigger a draft.
- Change the source body and confirm a new fingerprint/event is recorded.
- Restart the app and confirm active-storm state resumes.
- Code path: MISSING — no fingerprint or active-storm persistence files are produced by current code
- Dependencies: F093, F094
- Test data needed: Stable and changed NHC payload samples
- Status: MISSING
- Evidence:
F096 — [MISSING] Monitor Override UI And Persistence
- Category: UI
- Spec Reference: Section 20.1, Section 20.4, Section 20.5
- What it should do (end-user perspective): Let the user manually watch invests and exclude storms from monitor tracking, with those overrides persisted to config/state.
- How to test it (step-by-step as a human user):
- Open the monitor or settings UI.
- Add a manual storm watch and an exclusion.
- Restart the app.
- Confirm the overrides persist and affect monitor behavior.
- Code path: MISSING — config fields exist, but no UI or runtime behavior consumes them
- Dependencies: F059, F093
- Test data needed: Example manual watch/exclusion storm IDs
- Status: MISSING
- Evidence:
F097 — [MISSING] AI Backend Execution Switching
- Category: Integration
- Spec Reference: Section 20.2, Section 20.5
- What it should do (end-user perspective): Run the configured Claude/Cursor/Codex backend using the exact CLI conventions and let the next draft switch backends when settings change.
- How to test it (step-by-step as a human user):
- Configure each AI backend in turn.
- Trigger a draft job.
- Confirm the expected CLI command is executed.
- Confirm changing settings affects the next draft without restart.
- Code path: MISSING — no AI executor or
ai:testBackendmain handler exists - Dependencies: F058, F100
- Test data needed: Working AI CLI installations and a sample draft job
- Status: MISSING
- Evidence:
F098 — [MISSING] Prompt Assembly From House Style, Templates, Examples, And NHC Sources
- Category: Backend
- Spec Reference: Section 20.2, Section 26
- What it should do (end-user perspective): Assemble draft prompts from the house style guide, Word templates, recent briefings, raw NHC products, and revision instructions using the exact template structure defined by the spec.
- How to test it (step-by-step as a human user):
- Prepare a storm with source advisories and recent briefings.
- Trigger draft generation.
- Inspect the generated prompt file.
- Confirm the required sections appear in the specified order.
- Code path: MISSING — no prompt-assembly or document-ingestion modules exist
- Dependencies: F094, F097
- Test data needed: House style markdown, templates, recent
.docxfiles, NHC source text - Status: MISSING
- Evidence:
F099 — [MISSING] AI Draft Output Files And .draft-meta.json
- Category: Backend
- Spec Reference: Section 20.2
- What it should do (end-user perspective): Write AI-generated draft
.docxfiles into the storm folder and persist a.draft-meta.jsonsidecar with backend, advisory, timestamp, and review metadata. - How to test it (step-by-step as a human user):
- Trigger a successful draft generation.
- Confirm a
.docxis written into the storm folder. - Confirm filename collision logic uses
-ai-draftwhen needed. - Confirm the
.draft-meta.jsonsidecar is written beside the draft.
- Code path: MISSING — no draft writer or sidecar generator exists
- Dependencies: F097, F098
- Test data needed: Draftable storm/advisory inputs
- Status: MISSING
- Evidence:
F100 — [MISSING] Review Modes, Dashboard Review, And Email Approval Flow
- Category: Integration
- Spec Reference: Section 20.3
- What it should do (end-user perspective): Support
review,auto-publish, anddashboard-onlyapproval modes; send draft emails; accept YES/NO/CANCEL responses; and publish or revise accordingly. - How to test it (step-by-step as a human user):
- Configure each approval mode.
- Trigger a draft.
- Confirm the expected email or dashboard behavior occurs.
- Confirm YES publishes, NO revises, and CANCEL stops the draft.
- Code path: MISSING — no SMTP/IMAP services, dashboard review UI, or approval-state runtime exists
- Dependencies: F097, F098, F099
- Test data needed: Reviewer mailbox, SMTP/IMAP credentials, sample draft
- Status: MISSING
- Evidence:
F101 — [MISSING] Revision Loop, Resume, Archive, And Timeout Handling
- Category: Backend
- Spec Reference: Section 20.3, Section 30.1
- What it should do (end-user perspective): Persist draft queue state, resume unfinished work on restart, archive terminal drafts, and auto-cancel stale drafts.
- How to test it (step-by-step as a human user):
- Start a draft and stop the app mid-flow.
- Restart the app.
- Confirm the draft resumes from the correct phase.
- Confirm old drafts are archived or auto-cancelled per the spec.
- Code path: MISSING — no
draft-queue.json, draft-history, or resume engine exists - Dependencies: F100
- Test data needed: Interrupted and aged draft jobs
- Status: MISSING
- Evidence:
F102 — [MISSING] AI Cost Cap Enforcement
- Category: Config
- Spec Reference: Section 20.3, Section 20.5
- What it should do (end-user perspective): Track token/dollar usage against daily and weekly caps, finish in-flight drafts, block new ones, and surface a warning banner.
- How to test it (step-by-step as a human user):
- Configure strict cost caps.
- Run draft jobs until the limit is reached.
- Confirm in-flight jobs finish but new jobs are blocked.
- Confirm the warning state clears after the reset boundary.
- Code path: MISSING — schema fields exist, but no runtime accounting or UI exists
- Dependencies: F058, F097
- Test data needed: Draft jobs with mocked token/cost accounting
- Status: MISSING
- Evidence:
F103 — [MISSING] Rich Dashboard Sections And Layout Preferences
- Category: UI
- Spec Reference: Section 20.4, Section 23.3
- What it should do (end-user perspective): Render the spec dashboard sections (
Active Storms,Pending Drafts,Draft Pipeline,Publish History,NHC Status,Alerts,Revisions,AI Stats,Quick Actions) and let the user show/hide/reorder them. - How to test it (step-by-step as a human user):
- Open the dashboard views.
- Confirm each section exists.
- Hide, show, and reorder sections.
- Restart the app and confirm preferences persist.
- Code path: MISSING — only placeholder routes and schema defaults exist
- Dependencies: F059, F093, F100
- Test data needed: Dashboard data for each section plus saved layout preferences
- Status: MISSING
- Evidence:
F104 — [MISSING] Phase 2 IPC Implementations
- Category: API
- Spec Reference: Section 20.7
- What it should do (end-user perspective): Implement the unwired Phase 2 IPC endpoints:
nhc:*,draft:*,email:testConnection,ai:testBackend,audit:export, andapp:getDiagnostics. - How to test it (step-by-step as a human user):
- Call each advertised Phase 2 API from the renderer.
- Confirm it reaches a real main-process handler.
- Confirm fulfilled payloads match the shared types.
- Confirm failures use structured error shapes instead of
NOT_IMPLEMENTED.
- Code path:
src/preload/index.tsexposes these methods ->src/main/ipc/router.tscurrently registers stub handlers only - Dependencies: F093, F097, F100, F101
- Test data needed: Calls for each advertised IPC method
- Status: MISSING
- Evidence:
F105 — [MISSING] Publishing Intelligence Features
- Category: Backend
- Spec Reference: Section 24.2
- What it should do (end-user perspective): Generate smart commit messages, schedule publishes, verify live-site availability after push, and support publish-time intelligence rather than only manual fixed commit text.
- How to test it (step-by-step as a human user):
- Queue a publishable update.
- Confirm the commit message auto-generates from parsed metadata.
- Schedule a delayed publish and wait for the scheduled time.
- Confirm the app verifies the site went live after push.
- Code path: MISSING — config fields mention some advanced publishing options, but runtime publish logic only accepts a provided commit message and immediate push
- Dependencies: F029, F060
- Test data needed: Parsed tropical update metadata and a live-site check target
- Status: MISSING
- Evidence:
F106 — [MISSING] Multi-Destination And Social Publishing
- Category: Integration
- Spec Reference: Section 24.2
- What it should do (end-user perspective): Publish the same update to the main WxManBran site and optional external destinations such as Discord/social surfaces.
- How to test it (step-by-step as a human user):
- Configure one or more secondary destinations.
- Publish an update.
- Confirm the site publish still succeeds.
- Confirm each enabled secondary destination also receives its post.
- Code path: MISSING — schema includes
social.discord, but there is no runtime delivery service or UI - Dependencies: F029, F060
- Test data needed: Destination credentials/webhooks and a publishable update
- Status: MISSING
- Evidence:
F107 — [MISSING] Content Quality And Sanity Checks
- Category: Backend
- Spec Reference: Section 20.8, Section 24.3, Section 26.4
- What it should do (end-user perspective): Check AI-generated content for readability, terminology consistency, numeric mismatches, grammar, and excessive duplication before publish.
- How to test it (step-by-step as a human user):
- Generate or prepare a draft with known quality issues.
- Run the quality-check pipeline.
- Confirm each issue type is flagged.
- Confirm auto-publish is blocked on numeric mismatches or
[NEEDS REVIEW]conditions.
- Code path: MISSING — no draft-analysis or number-sanity modules exist
- Dependencies: F098, F099, F100
- Test data needed: AI draft text plus NHC source material with intentional mismatches
- Status: MISSING
- Evidence:
F108 — [MISSING] Historical/Season Features
- Category: UI
- Spec Reference: Section 24.4
- What it should do (end-user perspective): Provide a season archive browser, storm timeline, annual report generation, and template-evolution tracking.
- How to test it (step-by-step as a human user):
- Open the History/Archive views.
- Browse past seasons and storm timelines.
- Generate an annual report.
- Inspect template evolution comparisons.
- Code path: MISSING — no archive/timeline/report modules or route implementations exist
- Dependencies: F018, F066
- Test data needed: Historical publish and storm data
- Status: MISSING
- Evidence:
F109 — [MISSING] Notifications And Alerts
- Category: Integration
- Spec Reference: Section 24.5
- What it should do (end-user perspective): Deliver desktop notifications, optional sounds, do-not-disturb handling, and possibly mobile notifications for key monitor/draft/publish events.
- How to test it (step-by-step as a human user):
- Enable notifications.
- Trigger draft-ready, publish-success, and monitor-error events.
- Confirm the correct alerts are delivered.
- Confirm DND rules suppress only the appropriate events.
- Code path: MISSING — no notification or sound services exist
- Dependencies: F093, F100
- Test data needed: Triggerable app events
- Status: MISSING
- Evidence:
F110 — [MISSING] Quality-Of-Life Workflow Features
- Category: UI
- Spec Reference: Section 24.6, Section 31.4
- What it should do (end-user perspective): Restore queue state after crash, undo the last publish, warn on template diffs, support offline mode, export config backups, and check for updates.
- How to test it (step-by-step as a human user):
- Build queue state and crash/restart the app.
- Publish once and invoke undo.
- Work offline and then reconnect.
- Export config and confirm the update-check path runs once per day.
- Code path: MISSING — config fields exist for some advanced options, but no runtime/UI implementations exist
- Dependencies: F021, F029, F060
- Test data needed: Queue state, git history, offline simulation, update manifest endpoint
- Status: MISSING
- Evidence:
F111 — [MISSING] Audit And Compliance Enhancements
- Category: Backend
- Spec Reference: Section 24.7, Section 29.4
- What it should do (end-user perspective): Preserve source attribution, draft fingerprints, revision diffs, and long-lived audit/compliance history beyond the current minimal audit helper.
- How to test it (step-by-step as a human user):
- Generate and publish a draft.
- Inspect audit/compliance records.
- Confirm source attribution and fingerprint metadata are retained.
- Confirm prior draft revisions remain viewable for the retention window.
- Code path: MISSING — only a minimal audit-log append helper and publish-history append helper exist
- Dependencies: F065, F066, F099, F101
- Test data needed: Draft and publish lifecycle events
- Status: MISSING
- Evidence: