# Round-2 Verifier Report — commits 72fedf7 + 0ffd938 **Verifier:** fresh-context, 2026-06-12. HEAD at verification time = `0ffd938` (working tree matches the commits under review; only untracked `judging/crops/`, `judging/round2/`). ## VERDICT: PASS All changes trace to judge complaints or the mission. No new dependencies, no flags/shims, no unrelated refactoring. All four gates green on a fresh run, including the marketplace-sync suite the commit message flagged as flaky. Security posture of the new chat-markdown renderer is sound and test-locked. Three minor, non-blocking notes below. --- ## 1. Scope tracing (every hunk → complaint or mission) ### 72fedf7 (42 files, +1251/−202) | Change | Traces to | |---|---| | `LoginBriefing.tsx` — `lastActive` from workspace store (`ws.lastActive`) not `ctx.lastActive`; honest empty-workspace nudge | Recency contradiction ("active yesterday" vs "away 10 days") — machine cron writes no longer count as user activity | | `briefing-highlights.ts` — dedup by normalized first line, keep higher-importance then earliest timestamp | Same memory shown twice with two different ages | | `AppShell.tsx` — LoginBriefing gated to `/home`; `OnboardingTooltips suppressed={ov.showGlobalSearch}` | Modal overlaying Memory/Skills; Ctrl+K tip painting over the open palette | | `home.ts` — `SUGGESTION_MAX_IDLE_DAYS = 30` filter on suggested actions | Stale test prompts recommended as today's actions | | `workspace-context.ts` — `SYSTEM_JOB_TYPES` filter on `buildUpcomingSchedules` | "Up next" showing the janitor's calendar (verified: "Marketplace sync" and "Index reconciliation" both run as `job_type='memory_consolidation'` per `setup-crons.ts:22,29`, so the filter catches every item the judges named) | | `render-markdown.ts` + `TextBlock.tsx` — `renderChatMarkdown` | Literal `## DECISION 1` / `**bold**` noise in chat | | `login-briefing-brag.ts` — "people, projects & things it knows" | entities/relations jargon | | `ChatApp.tsx` / `AgentDetail.tsx` — Ask first / Trusted / Autopilot **display labels only**; internal `'normal'|'trusted'|'yolo'` values untouched | YOLO jargon — explicitly *not* a compat shim | | `dock-tiers.ts` `description` + `AppShell` HintTooltip | Opaque nav labels ("Waggle Dance", "MCP Hub") | | `activity-labels.ts` (new, 37 lines + test) | `tool_result: create_skill` machine vocabulary in the activity rail | | `WorkspaceDesktopApp.tsx` — humanize summaries, "1 memory"/"1 session" plurals | Jargon + grammar complaints | | `AgentsApp.tsx` — empty state lists built-in workspace assistants | "No agents yet" while an agent demonstrably worked (contradiction) | | `EvolutionTab.tsx` — default filter `'all'` + plain-language primer | Agent-evolution invisibility | | `AutomationCenterApp.tsx` — Next-up / Recent-results overview panels | Three stat tiles over a void; no answer to "what runs next / how did it go" | | `skills.ts` + `types.ts` — absent provenance ⇒ `'built-in'` | Unfalsifiable provenance badge (stock skills attributed to the user) | | `identity.ts` — merge-on-update | Partial identity write wiping stored fields | | `profile.ts` — `deleteByContentPrefix('User identity: ')` before re-create | Profile-frame duplication root cause | | `monthly-assessment.ts` — frames stamped source `'system'` | Provenance lie (agent report stamped user_stated) | | `ImportStep.tsx` hints, `onboarding-profile.ts` greeting preview | Onboarding export how-tos + "real greeting preview" complaints | | `HomeCockpit.tsx` `upNext ?? []` | Boundary hardening for an absent field (system-boundary validation — in-spec) | | `judging/*.md` (5 judge verdicts, round1-fixes, verifier report) | Mission evidence artifacts, not code | | Test updates (`phase3b/3c` MemoryRouter wrap, copy assertions) | Direct consequence of `useNavigate` in the new AgentsApp empty state | ### 0ffd938 (14 files) - `truncateHighlight` strips `**`/`#`/`` ` `` tokens — highlights render as text nodes, so raw markdown showed literally (judge complaint). - `notes/judge-round1-patterns.md` + 13 recaptured screenshots — evidence, in-mission. ### Negative checks - **No new dependencies:** `git diff 72fedf7~1 0ffd938 --stat -- '**/package.json' package.json package-lock.json bun.lock` → empty. `renderChatMarkdown` is hand-rolled (~40 lines) instead of pulling a markdown lib — consistent with the no-new-deps constraint. - **No flags/shims:** the only new props/params (`suppressed`, injectable `now` for test determinism) are direct fix mechanics. Autonomy rename is display-only. - **No unrelated refactoring:** the `escapeHtml`/`applyInline` extraction in render-markdown.ts is the minimal factoring required for `renderChatMarkdown` to reuse the escape-first pipeline; `buildProfilePreview` rewrite *is* the greeting-preview complaint. ## 2. Special-attention items ### renderChatMarkdown security posture — SOUND - **Escape-first confirmed:** both renderers run `escapeHtml()` (escapes `&`, `<`, `>`, `"`) over the *entire input* before any tag is emitted; block parsing in `renderChatMarkdown` operates on already-escaped lines and routes all inline content through `applyInline(escaped)`. - **Href allowlist confirmed:** only `^https?:\/\//i` becomes ``; anything else (javascript:, data:, vbscript:) renders as inert `label (url)` text. - **Tests lock the defenses** (`apps/web/src/lib/render-markdown.test.ts`, read in full): raw `