# Deferred Work

## Deferred from: code review of 1-1-module-scaffold-cicd-pipeline-and-design-token-system (2026-05-21)

- [ ] Vulnerable dependency CVE-2023-43645 — flat-cache-4.0.1 (needs verification)
- [ ] Version conflicts — Multiple versions: make-dir (5.7.2, 6.3.1, 7.8.0), debug (4.4.3, 3.2.7) (npm resolution, pre-existing)

## Deferred from: Group 6 (Tests) - 2026-05-21

- [ ] MAX_PAYLOAD_BYTES size boundary test — Story 1.2+ SocketHandler responsibility (EC-001)
- [ ] Multi-track stream test — Story 1.2+ WebRTC surface (EC-010)
- [ ] Invalid snapshot fixtures (wrong version, null version) — Story 1.3+ StateStore (EC-012)
- [ ] Circular reference in gameWebrtc handling — Story 1.2+ WebRTC probe (EC-020)

## Deferred from: Group 7 (CI/CD & i18n) - 2026-05-21

- [ ] Missing failure notifications — Story 1.2+ (EC-002)
- [ ] Missing build artifact upload — Story 1.2+ (EC-006)
- [ ] No Node.js matrix testing — Story 1.2+ (EC-004)
- [ ] Missing concurrency control — Story 1.2+ (EC-008)
- [ ] Missing i18n schema validation — Story 1.2+ (EC-I18N-003)
- [ ] ubuntu-latest not pinned — Story 1.2+ (EC-003)
- [ ] Missing coverage upload — Story 1.2+ (EC-005)

## Deferred from: code review of 1-4-core-logic-scryingpoolcontroller-and-visibilitymanager (2026-05-22)

- [ ] Memory leak in _revisions Map — No cleanup of old/disconnected userIds from _revisions Map; grows unbounded over time. [ScryingPoolController.js:31]
- [ ] No listener cleanup — Socket and Hooks listeners registered in init() are never unregistered; potential memory leak on module reload. [ScryingPoolController.js:35-41, VisibilityManager.js:33-38]

## Deferred from: code review of 1-5-gm-control-ui-scryingpoolstrip-actionpopover-and-av-tile-integration (2026-05-22)

- [ ] Echo accepts non-finite revisions — No validation that `revision` is finite; accepts `NaN`, `Infinity`. [ScryingPoolController.js:164]
- [ ] No validation revision is number — `revision ?? 0` doesn't validate `revision` is a number type. [ScryingPoolController.js:164]

## Deferred from: code review of 2-1-notificationbus-and-notification-verbosity (2026-05-22)

- [ ] VisibilityManager only handles binary states — T-09 handles hidden/offline/cam-lost/ghost as "disable", else as "enable". States like self-muted, reconnecting fall through incorrectly. Pre-existing issue, not introduced in this story. [VisibilityManager.js:84-90]
- [ ] No handling of `setMatrix` hook events — setMatrix emits without userId; bulk state changes won't trigger notifications. Pre-existing architectural limitation. [NotificationBus.js, StateStore.js:139]
- [ ] ScryingPoolController cleanup only on userConnected hook — Disconnect detection limited to userConnected event. Other disconnect scenarios may leak entries. Pre-existing. [ScryingPoolController.js:46-49]
- [ ] Hook data property mismatch with `setMatrix` — setMatrix emits `{ matrix, timestamp, revision }` without userId; incompatible with NotificationBus expectations. Pre-existing. [StateStore.js:139, NotificationBus.js]

## Deferred from: code review of 2-2-directors-board-core-layout-and-participant-toggle (2026-05-23)

- [ ] No Error Handling in _savePosition — `game.user?.setFlag(...)` called without try/catch. Pre-existing pattern in codebase (same as ScryingPoolStrip). Not introduced by Story 2.2. [DirectorsBoard.js:160-167]
- [ ] CSS Includes sp-state-pending Class — Defines `sp-state-pending` class but Story 2.2 only specifies 8 states. Relates to StateStore/VisibilityManager from Epic 1, not introduced by this story. [_participant-card.less:18]

## Deferred from: code review of 2-3-directors-board-bulk-actions-spotlight-and-keyboard-shortcuts (2026-05-23)

- [x] buildCardContext defaults null state to active [ParticipantCard.js:48] — RESOLVED: ParticipantCard.js deleted in code review fix. Functionality moved to boardUtils.js.

## Deferred from: code review of 4-1-player-privacy-panel-and-automation-opt-ins (2026-05-25)

- Reaction Cam and HP-Reactive Cam Styling automation triggers not implemented — These are Future Epic 5+ features. The privacy panel infrastructure (this story) enables them, but the actual automation trigger code is not part of Story 4.1.

## Deferred from: code review of 4-2-custom-portrait-fallback (2026-05-26)

- [x] PortraitFallbackHandler not imported anywhere — RESOLVED: Wired up in module.js, passed to RoleRenderer and PlayerPrivacyPanel
- [x] RoleRenderer doesn't use PortraitFallbackHandler — RESOLVED: Integrated in _applyAVTileState() for CAMERA_ABSENT states
- [x] PrivacyPanel has no portrait UI — RESOLVED: Added portrait section with file picker, preview, choose/remove buttons
- [ ] 5MB MAX_PORTRAIT_SIZE vs ~50KB Foundry flag limit — documented design limitation; flag limit is server-dependent and can't be changed in code
- [ ] No magic-byte file content validation — spec mentions "MIME type AND file content" but only format/MIME check implemented; enhancement for future
- [ ] No animated-vs-static GIF distinction — FR-26 requires static GIF only but MIME-type alone can't distinguish; requires binary GIF parsing

## Deferred from: code review of 3-3-preset-import-and-export (2026-05-26)

- [ ] Replace mode rollback can fail partially leaving corrupted state — Browser env lacks transaction support; existing error reporting is reasonable but state can be partially deleted/restored when both delete and rollback fail. [`src/core/PresetImportExportManager.js:434-448`]
