Mark Phase 409 complete and document perf, agentctl, and release gates.

Update PLATFORM_ROADMAP, LOGGING, AGENTCTL, ARCHITECTURE, and
AUTOMATED_TESTING with Phase 409 verification guidance.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-06-02 16:41:50 -04:00
co-authored by Cursor
parent 99d1312ecc
commit 9558ed28b8
5 changed files with 42 additions and 49 deletions
+2
View File
@@ -169,6 +169,8 @@ JSON with a `steps` array:
| `ipc` | `{ "type": "...", ... }` | Same as `agentctl ipc` |
| `wait` | view match object + `timeoutMs` | Poll `view` until `matchView` passes |
| `waitMetrics` | view match object + `timeoutMs` | Alias of `wait` for diagnostics counters (`viewBuildStats`, `workerPoll`, `meshStatusSummary`, …) |
**Phase 409:** Headless `runSteps` appends a final `{ perfSummary, waitDiagnostics }` entry. Wait timeouts include `formatWaitTimeoutError` snapshots (`pollDbReadBudget`, `viewIntegrity`, final `workerPoll`). Verify coalesced pushes with `waitMetrics: { workerPoll: { tier: 'active' } }` after `renderer-poll-hints` / focus changes. Bundle: `npm run test:phase409-agentctl`.
| `press` | chord string e.g. `"Meta+Shift+C"` | Attached renderer only; headless records `skipped: true` |
| `waitEvent` | sidecar matcher + `timeoutMs` | Poll sidecar events; optional `toastIncludes` matches `ui-toast` when `PEARCORD_AGENTCTL_TOAST=1` |
| `waitLogContains` | `{ "messageIncludes" \| "contains" \| "regex", "lines"?, "timeoutMs"? }` | Poll `pearcord.log` until a structured log line matches |
+1 -1
View File
@@ -58,7 +58,7 @@ The worker sidecar (`apps/pearcord/index.js`) is the sole publisher of renderer
1. **Boot**`sendBoot()` emits a lightweight `boot` payload (`bootSnapshot: true`) without duplicating a full `state` push.
2. **Hydration** — First accepted `ui-ready` triggers `pushState({ bootHydrate: true })` once; duplicates are ignored (`uiReadyHandled`).
3. **Poll loop**`scheduleStatePoll()` issues light `view({ light: true })` on an adaptive interval (active / loading / idle).
3. **Poll loop**`scheduleStatePoll()` issues light `view({ light: true })` on an adaptive interval (`computeAdaptiveStatePollMs`: focus, unread, typing, modal, mesh-quiet multiplier). Renderer sends `renderer-poll-hints` and `renderer-focus` IPC so the worker does not poll at full rate while typing or unfocused.
4. **Event batching** — Platform emits many events (`message`, `reaction`, `presence`, …). Handlers call `requestEventPushState()` which coalesces into a single `setTimeout` flush (~16ms) before `pushState`, with optional `{ structural: true }` for heavy slices.
5. **Guards**`voice-media` events are ignored when not in a voice session; push burst clamp + shallow hash suppress redundant IPC.
+12
View File
@@ -576,6 +576,18 @@ caches stay consistent across guild/message/invite.
`scripts/test-pear-boot.sh` runs dev for ~22s. Requires Pear runtime installed (display optional for headless in some setups).
## Known perf anti-patterns (Phase 409)
| Anti-pattern | Symptom | Fix |
|--------------|---------|-----|
| Duplicate `discovery.list` in one frame | Extra list spans, cache churn | `discovery-frame-dedupe` (same animation frame) |
| Heavy full `view()` on poll | `poll-path db read budget exceeded` | Keep poll light; avoid N+1 DB in `view.light` paths |
| Synchronous message list repaint | Jank under load | `measureRenderBudget` / `renderMessagesBody` |
| Toast spam | Stacked toasts | `toast-queue` dedupe window |
| Discovery publish while offline-only | Unwanted public listing | `discoveryLocalOnly` user pref |
Release gate before tag: `npm run test:phase409-release-gates` (includes `test:boot-warn-allowlist-phase408`).
## When to run
- After every change to `modules/pearcord-platform`, `pearcord-guild`, or `apps/pearcord/index.js`
+10
View File
@@ -2,6 +2,16 @@
Pearcord uses the **`pearcord-log`** module for structured diagnostics across the worker, platform, UI flow, and companion.
## Phase 409 worker signals (v0.8.639)
| Signal | Meaning |
|--------|---------|
| `poll-path db read budget exceeded` | Light `view()` exceeded `PEARCORD_POLL_DB_READ_BUDGET_PER_SEC` (default 120 reads/s) — reduce poll-path DB work or raise budget |
| `renderer focus changed` | `renderer-focus` IPC toggled window focus; worker recomputes adaptive poll tier |
| `discovery.publish skipped — local-only mode` | User pref `discoveryLocalOnly` blocked mesh listing publish |
Adaptive poll uses `pearcord-platform/state-poll-adaptive` with floor/ceiling (`PEARCORD_STATE_POLL_FLOOR_MS`, `PEARCORD_STATE_POLL_CEIL_MS`) and renderer hints (`renderer-poll-hints`: composer typing, modal open). Mesh quiet mode multiplies poll interval via `guildSyncHealthRail.meshQuietPollMultiplier`.
## Quick reference
| Surface | Scope | Notes |
+17 -48
View File
@@ -5,8 +5,8 @@ Focused roadmap of unfinished items extracted from `PLATFORM_ROADMAP_v0.1-v0.8.6
**Legend:** `[ ]` not started
**Legend:** `[SKIP]` skip for now
Unfinished items tracked: **185**
Skipped items tracked: **9**
Unfinished items tracked: **149**
Skipped items tracked: **10**
---
@@ -24,14 +24,25 @@ Skipped items tracked: **9**
Primary in-flight work. Move completed items to `[x]` and add a changelog line.
### Phase 409 — stability confirmation & perf hardening (in progress)
Near-term focus after Phase 408 completion. See **Next** section for the full P409 checklist (perf, networking, data integrity, UX, agentctl, docs, release gates).
_No active phase — complete backlog `[ ]` items before opening a new 50-item phase._
---
## Completed (recent)
### Phase 409 — stability confirmation & perf hardening (complete)
- [x] **P409-0912 Perf:** Adaptive poll floor/ceiling (`state-poll-adaptive`, `renderer-poll-hints` IPC), discovery.list same-frame dedupe, renderer frame-budget instrumentation, poll-path DB read budget warnings.
- [x] **P409-1316 Networking:** joinMesh ETA in `guildSyncHealthRail`, mesh jitter/quiet mode (`mesh-guild-backoff`), topic merge counters (`topic-merge-counters`).
- [x] **P409-1720 Data integrity:** Cross-ref audit, stale draft prune, pin body fallback, `userPrefsChecksum` (`view-integrity-phase409`).
- [x] **P409-2124 UX:** Header title shimmer, keyboard/pointer focus-ring tokens, channel-switch load smoke, toast queue dedupe/collapse.
- [x] **P409-2528 A11y:** State refresh `aria-live`, politeness smokes, keyboard modal smoke, high-contrast sidebar smoke.
- [x] **P409-2932 Security:** Diagnostics redaction, deep-link query allowlist, hardened attachment filenames, `discoveryLocalOnly` pref.
- [SKIP] **P409-33 Agentctl:** Manual checkpoint — duplicate of P410-33 (`manualCheckpoint` in scenario DSL).
- [x] **P409-3436 Agentctl:** Keyboard/topic smokes (existing), perf summary (`perf-summary.js`), wait retry diagnostics (`wait-diagnostics.js`).
- [x] **P409-4244 Testing/voice:** Channel-switch load smoke, voice roster speak throttle, stream cadence downgrade hints.
- [x] **P409-4550 Docs/release:** LOGGING/AGENTCTL/ARCHITECTURE/AUTOMATED_TESTING updates; bundle `npm run test:phase409-release-gates`.
### Phase 408 — Discord parity hardening (complete)
- [x] **P408-3442** Voice stream freeze + packet-loss hints, message outbox retry states, inline edit UX, spoiler first-use hint, folder badge motion class, guild drag ghost + insertion rail, activity normalization (buttons/timestamps), presence stale reaper.
@@ -280,49 +291,6 @@ Near-term queued phases after current in-flight work.
---
## Phase 409 — stability confirmation & perf hardening (new)
- [ ] **P409-09 Perf:** Add adaptive state poll floor/ceiling based on renderer focus + active typing + modal state.
- [ ] **P409-10 Perf:** Add `discovery.list` call dedupe window to avoid repeated cache hits in same frame.
- [ ] **P409-11 Perf:** Add renderer frame-budget instrumentation for heavy chat render paths (message list + sidebars).
- [ ] **P409-12 Perf:** Add warning budget for repeated poll-path DB reads per second.
- [ ] **P409-13 Networking:** Improve joinMesh bounded retry messaging with next-attempt ETA in view model.
- [ ] **P409-14 Networking:** Add jittered reconnect backoff by guild to avoid synchronized mesh retry bursts.
- [ ] **P409-15 Networking:** Add per-guild mesh “quiet mode” when no peers are present to reduce unnecessary sync attempts.
- [ ] **P409-16 Networking:** Add conflict-safe merge counters for concurrent channel/topic edits from multiple peers.
- [ ] **P409-17 Data integrity:** Add invariant checks for message/reaction cross-references before sending state to renderer.
- [ ] **P409-18 Data integrity:** Add stale draft cleanup for channels deleted or permissions-revoked mid-session.
- [ ] **P409-19 Data integrity:** Add safe fallback when pinned message points to missing message body.
- [ ] **P409-20 Data integrity:** Add checksum marker on settings snapshots to detect partial write corruption.
- [ ] **P409-21 UX parity:** Add Discord-like header/title loading shimmer while guild/channel data transitions.
- [ ] **P409-22 UX parity:** Add nuanced focus-ring color transitions matching Discord for keyboard vs pointer focus origin.
- [ ] **P409-23 UX parity:** Add channel list interaction latency budget test for hover/select under high message volume.
- [ ] **P409-24 UX parity:** Add polished toasts queueing behavior with collapse + dedupe similar to Discord timing.
- [ ] **P409-25 Accessibility:** Add SR announcements for coalesced state refresh outcomes when relevant UI sections change.
- [ ] **P409-26 Accessibility:** Validate `aria-live` politeness levels across discovery, notifications, and topic popovers.
- [ ] **P409-27 Accessibility:** Add keyboard-only smoke for modal open/close/focus-return across core dialogs.
- [ ] **P409-28 Accessibility:** Add high-contrast theme regression pass for all sidebar and popover controls.
- [ ] **P409-29 Security/privacy:** Add redaction pass for token-like strings in exported diagnostics bundles.
- [ ] **P409-30 Security/privacy:** Add strict allowlist for deep-link command names and query keys.
- [ ] **P409-31 Security/privacy:** Add attachment filename sanitizer hardening for unsafe Unicode + control chars.
- [ ] **P409-32 Security/privacy:** Add optional local-only mode that blocks discovery listing publish.
- [ ] **P409-33 Agentctl:** Add explicit “manual step checkpoint” primitive for human-in-the-loop scenario validation.
- [ ] **P409-34 Agentctl:** Add keyboard chord simulation coverage for topic popover and composer formatting hotkeys.
- [ ] **P409-35 Agentctl:** Add scenario result summary block for perf counters (state pushes, deduped polls, mesh retries).
- [ ] **P409-36 Agentctl:** Add retry diagnostics for flaky waits (`wait` reason telemetry and final-state snapshot).
- [ ] **P409-42 Testing:** Add integration smoke for channel switch under load with stable focus and no message jump regressions.
- [ ] **P409-43 Voice/media:** Add voice roster render throttling when many speaking-state toggles arrive rapidly.
- [ ] **P409-44 Voice/media:** Add screen-share tile quality downgrade hints when capture frame cadence drops.
- [ ] **P409-45 Docs:** Update `LOGGING.md` with new worker startup/idempotency signals and troubleshooting guidance.
- [ ] **P409-46 Docs:** Update `AGENTCTL.md` with manual validation workflows and state-coalescing verification steps.
- [ ] **P409-47 Docs:** Update `ARCHITECTURE.md` state-flow section to describe coalesced sidecar-to-renderer updates.
- [ ] **P409-48 Docs:** Add “Known perf anti-patterns” appendix to `AUTOMATED_TESTING.md`.
- [ ] **P409-49 Release:** Require one agentctl onboarding/manual scenario + one focused smoke bundle before every tag.
- [ ] **P409-50 Release:** Require post-boot log scan gate ensuring no new WARN signatures beyond approved allowlist.
---
---
### Phase 658 — DM threads & forum DM bridge (v0.8.636)
@@ -528,6 +496,7 @@ For deferred items, use `[SKIP]` and include a brief reason inline.
## Changelog
- 2026-06-02 - Completed Phase 409 (P409-0950, P409-33 [SKIP]): adaptive poll + renderer hints, discovery frame dedupe, view integrity/draft prune/pin fallback, mesh quiet/ETA, toast queue, header shimmer, diagnostics redaction, `discoveryLocalOnly`, agentctl perf/wait diagnostics; bundle `npm run test:phase409-release-gates`.
- 2026-06-02 - Phase 408 voice/messaging/presence tail (P408-3442): `stream-tile-health.js`, `message-outbox.js`, `message-inline-edit.js`, `composer-spoiler-hint.js`, `guild-drag-ghost.js`, `refreshScreenSharePreview` + `restart-screen-share` IPC, presence `reapStalePeers`, activity buttons/timestamps; bundle `npm run test:phase408-voice-messaging-parity`.
- 2026-06-02 - Phase 408 reliability/security/docs (P408-1520, P408-33, P408-4350): `guild-sync-replay.js`, mark-read fanout queue, attachment metadata audit, automation payload guard, device-pair at-rest passphrase, voice reconnect elapsed UI, `log:triage`, bundles `test:phase408-reliability-security` + `test:phase408-release-gates`.
- 2026-06-02 - Phase 408 mesh/API/agentctl (P408-1011, P408-1314, P408-17, P408-2128): `mesh-peer-quality.js`, `meshStatusSummary` + `platformCapabilities` + `ipcContractVersion` in view, channel meta validators, `export-channel-topic-preview` IPC, agentctl `waitMetrics`/`press`/`toastIncludes` matchers + `runChannelTopicExportJourney`, bundle `npm run test:phase408-mesh-agentctl`.