Skip to content
Resource
DocsTourSlicesBest PracticeAgentsInstall

Command Palette

Search for a command to run...

New
  • Changelog

Changelog

Release notes

Changelog

What changed in each rr release — page 10 of 25. Full prose history in CHANGELOG.md.

JUN302026
Featureslices@resumeJun 30, 2026

resume — new os slice: one-column CV renderer (profile injected)

Ported from the rahmanef-com web-OS as a brand-free, self-contained slice. A clean one-column résumé / CV: name, roles, location, contacts, summary, skills, experience and projects. The profile is injected via a single ResumeProfile seam (configureResume / useResumeProfile); unwired it renders a generic placeholder person so the catalog preview is fully populated with zero backend. Includes a 'Print / PDF' button (window.print()) with a print-friendly layout.

New slices

  • resume — one-column CV renderer, ResumeProfile host seam, generic placeholder profile, Print/PDF
JUN302026
Featureslices@start-hereJun 30, 2026

start-here — new os slice: guided onboarding tour (live-registry, drift-proof)

Ported from the rahmanef-com web-OS as a brand-free, self-contained slice. A guided 'Start Here' tour that lays the OS out as a path of stages, each stage opening real apps from the live registry — it reads the injected app catalog instead of a hardcoded list, so adding an app surfaces it automatically (in a stage if listed, else a final 'Everything else' bucket). The catalog, the open(id) callback, and the journey are injected via a StartHereAdapter (apps/open/stages); unwired it runs on an in-memory mock (a few generic apps + 3 stages) so the welcome tour renders fully alive with zero host.

New slices

  • start-here — guided OS onboarding tour, drift-proof live-registry path, StartHereAdapter host seam, in-memory mock
JUN302026
Featureslices@about-profileJun 30, 2026

about-profile — new os slice: macOS-style identity card (profile-injected)

Ported from the rahmanef-com web-OS as a brand-free, self-contained slice. A macOS 'About This Mac'-style identity card: avatar (or monogram fallback), name, roles, location, description, outbound links and an accordion FAQ. The whole card is driven by ONE injected AboutProfile via configureAbout; unwired it renders a generic mock person so it is fully populated with zero backend.

New slices

  • about-profile — identity card (avatar/monogram, roles, links, accordion FAQ), AboutProfile host seam via configureAbout, generic mock person
JUN302026
Featureslices@bookingJun 30, 2026

booking — new os slice: session request form + owner inbox (backend-injected)

Ported from the rahmanef-com web-OS as a brand-free, self-contained slice. One app that is both a public 'book a session' request form and the owner's triage inbox (flips on canManage). The backend is injected via a BookingAdapter (submit/list/setStatus/canManage); unwired it runs on an in-memory mock so the form + inbox are interactive with zero backend.

New slices

  • booking — public request form + owner inbox, BookingAdapter host seam, in-memory mock
JUN282026
Fixslices@file-explorer-tree-alignJun 28, 2026

file-explorer sidebar tree — left-align the folder/file rows (were centered)

The sidebar file-tree rows (Desktop, Documents, … and the files under them) rendered centered instead of flush-left like the Favorites 'Home' entry just above. Cause: the tree Node buttons (file-tree/dir.tsx) set `flex w-full items-center text-left` but never overrode shadcn Button's base `justify-center`, so the `[icon] name` group sat in the middle of the full-width row (`text-left` only aligns text inside the label, not the flex group). Added `justify-start` to both the file and folder Node buttons so they sit flush-left, matching the Favorites buttons that already had it. The main content/grid view was left untouched.

Fixes

  • file-explorer sidebar tree — folder/file rows now left-aligned (justify-start) instead of centered, matching the Favorites items
JUN282026
Improvementsite@perf-opt-sweepJun 28, 2026

Performance pass — lazy-load highlight.js in notion, index the audit-log-by-action query (rest already optimal)

Targeted perf sweep with the verifier inverted to REJECT premature/speculative optimization (no speculative memo, no 'could be faster' rewrites). The scout already showed the codebase follows its own rules — 0 bare .collect() in convex, 0 internal raw <a>, KaTeX already lazy — so only 2 concrete, structural wins survived verification; the other categories came back clean and were intentionally left alone. (1) notion-shell CodeBlock.tsx statically imported `highlight.js/lib/common` (~35 languages, ~100kB) at module top, so the highlighter JS shipped in the notion editor's initial bundle for EVERY page — including the majority with no code block. Now it loads lazily via dynamic import on the first code block, cached at module scope; until it resolves the block renders the same HTML-escaped plaintext it already used as the fallback, so SSR/first-paint output is unchanged (no hydration mismatch) and highlighting fills in client-side. The small CSS stays static. (2) convex/_shared/auditLogger_queries.ts getAuditLogsByAction did `.filter(workspaceId AND action)` over the UNBOUNDED activityEvents audit table — a full-table scan that grows with every event ever logged. Switched to `.withIndex("by_workspace", …)` (the same index the sibling getAuditLogsByWorkspace already uses one function up) and kept action as a post-index .filter — same most-recent-first result, but the scan is now scoped to the workspace partition. No schema migration (index already exists), no new dependency. Deliberately NOT changed (verified already-optimal, not worth touching): react-konva is core to the image-editor and only mounts when the editor is open; the ~5 raw <img> are all blob/object-URL/runtime sources where next/image does not apply; KaTeX is already lazy; no hot-render recompute worth memoizing. tsc + slices:check (70 ok) green.

Performance

  • notion-shell/CodeBlock — highlight.js (~100kB) now lazy-loads on the first code block instead of shipping in every notion page's bundle
  • convex/auditLogger — getAuditLogsByAction scoped to the by_workspace index instead of full-scanning the unbounded activityEvents table

Audited clean (left as-is)

  • image-editor konva (core, mounts only when editor opens), raw <img> (all blob/runtime sources), KaTeX (already lazy), hot-render recompute (none worth memoizing)
JUN282026
Fixsite@nonslice-defect-sweepJun 28, 2026

Defect sweep of the non-slice surfaces — packages/mcp, packages/cli, app server (convex copy-source came back clean)

30-unit multi-agent sweep (21 convex copy-source dirs + 5 cli units + 3 mcp units + the app server) — each unit found-then-adversarially-verified (default reject, fix must be minimal + gate-respecting). All 21 convex/features dirs came back CLEAN: last session's IDOR/null-throw fixes plus the new audit-convex-api-paths gate already locked that gate-invisible surface down. 7 real defects fixed elsewhere (6 verified-as-proposed + 1 whose proposed fix was wrong and got reworked from the verifier's corrected patch): (P1) MCP POST /api/oauth/token with a JSON body of literal `null` passed the SyntaxError-only try/catch then destructured null → unhandled TypeError that rejects before the per-request try in http-transport → unauth one-request server crash; fixed with `parsed || {}`. (P1) MCP /oauth/authorize redirect_uri with percent-encoded CR/LF passed validation because the WHATWG URL parser silently strips control chars, but the raw string kept its \r\n and blew up res.setHeader('Location', …) with ERR_INVALID_CHAR on the POST branch → unauth DoS; fixed by rejecting control chars (/[\x00-\x1f\x7f]/) before new URL(). (P2 ×2) MCP composeInit/composeAdd emitted request-controlled template/features/skills verbatim into the npx command strings the operator copy-pastes into a terminal — shell injection; now routed through the same sanitizeShellArg the sibling composeApp already used. (P2) CLI readStateFromRr lacked the Array.isArray guard its three sibling fields have, so a hand-edited rr.json with a non-array slices/features crashed `rr add` preflight + `rr compose` instead of the documented empty-state fallback. (P2) CLI listAllDNA had no try/catch around readDNA, so one corrupt or non-kebab-named .dna.json crashed all of `rr graph` / buildLineageGraph / the MCP lineage resources instead of being skipped. (P2) app/api/agent-stream returned a raw 500 on a malformed tool-role message (m.results undefined → .map throw); now guarded with Array.isArray. Each fix has a runnable behavioral check; tsc + slices:check green. CLI 1.14.2 + MCP 1.2.5.

Security

  • mcp/oauth-routes — `null` JSON token body no longer crashes the server (unauth DoS closed)
  • mcp/oauth-routes — CR/LF in redirect_uri rejected before new URL(), closing a setHeader ERR_INVALID_CHAR DoS
  • mcp/response-builders — composeInit + composeAdd now sanitize template/features/skills (no shell injection into copy-paste commands)

Fixes

  • cli/compose-state — malformed rr.json (non-array slices/features) no longer crashes `rr add` preflight
  • cli/dna — one corrupt/oddly-named .dna.json no longer crashes `rr graph` + lineage
  • app/agent-stream — malformed tool message returns cleanly instead of a raw 500
  • convex copy-source — all 21 feature dirs audited clean (no new fixes needed)
JUN282026
Improvementslices@ponytail-sweepJun 28, 2026

Ponytail dead-code sweep — the 37 slices the earlier dedup batches hadn't touched

Closed the gap left by the two prior dedup passes (batch-1 −636 across 20 slices, dead-code −217 across 14): 8 parallel scanners audited the remaining 37 slices for genuine within-slice over-engineering — dead internal symbols, unused exports not on the public entry, redundant wrappers, one-impl abstractions, speculative scaffolding. Copy-first discipline held: NO cross-slice dedup, and any export re-exported from a slice's public index/config (the product a consumer copies) was kept even when unused in-repo. Result: 32 slices already minimal (incl. notion's 10k-LOC tree, app-store, all 17 small slices), 5 had real cuts. Every cut grep-verified before applying — one finding was REJECTED on verification: browser's isUrlLike/normalizeUrl were flagged dead but toTarget() calls both (the agent misread 'called by' as 'replaced by'), so browser stayed untouched. Cuts: appshell chromeInsets() dead getter (setChromeInsets stays); reel-editor isXfadeSource() + tracksByKind() unused composition helpers; file-explorer mediaKind()+MediaKind type — a speculative media-viewer ext-mapper with zero callers (the VIDEO/AUDIO sets it used stay, they back the icon/color/route fns); admin 4 dead barrels (a types/index.ts re-export duplicating the public index, plus 3 empty `export {}` scaffolds) deleted, now-empty dirs removed. ~31 LOC + 4 files. tsc + slices:check (70 ok) green.

Cleanup

  • appshell — removed dead chromeInsets() getter
  • reel-editor — removed unused isXfadeSource() + tracksByKind() composition helpers
  • file-explorer — removed speculative mediaKind()/MediaKind (no callers)
  • admin — deleted 4 dead barrel files (redundant types re-export + 3 empty export{} scaffolds)
  • 32 of 37 audited slices were already minimal — no change; browser flagged-then-cleared on verification
JUN282026
Improvementsite@convex-api-path-gateJun 28, 2026

New CI gate — convex internal/api references must resolve (locks in the runtime-null-throw class)

Regression gate for the gate-invisible bug class found this session. convex/** is excluded from the root tsc, and audit-convex-features bans the plural FILE name (mutations.ts) but not a plural REFERENCE — so `internal.features.ai.mutations.logUsage` (plural) against the singular mutation.ts file resolved to undefined in the generated api object and threw 'Cannot read properties of undefined' at runtime, invisible to every gate. That shipped 3× (ai, bookings, newsletter) before being fixed. New audit-convex-api-paths.mjs walks convex/ and asserts every `internal.features.<path>.<fn>` / `api.features.<path>.<fn>` reference resolves to an existing convex/features/<path>.ts that exports <fn> — catching plural-vs-singular, wrong module/dir names, and renamed/removed exports. It skips the consumer-side `.slices.*` namespace (resolves only after consumer codegen, per Hard Rule 6). Wired into slices:check (so it runs in pre-commit + pre-push). Verified: passes clean on the current tree, and fails with the exact diagnostic when the historical `ai.mutations.logUsage` ref is injected.

Tooling

  • audit-convex-api-paths — fails CI on any convex internal./api.features.* ref that doesn't resolve to a real export (the plural-path runtime null-throw class)
JUN282026
Fixsite@app-server-huntJun 28, 2026

Live-site server surface — open redirect in proxy.ts closed; build-chat 500 on malformed input fixed

Security + correctness sweep of the deployed app's server surface (admin auth, the two LLM endpoints, external proxies, proxy.ts host rewriting, server actions), each finding adversarially verified — a speculative unsplash length-cap was correctly rejected (already rate-limited, hardcoded upstream host, percent-encoded query). 2 real bugs fixed: (1) SECURITY — proxy.ts built the external-demo redirect via new URL(request.nextUrl.pathname + search, external), putting the attacker-controlled path as the URL INPUT rather than mutating the trusted base. Empirically verified against the repo's Next 16.2.6: a request to a valid demo subdomain with path //evil.com/x yields nextUrl.pathname === '//evil.com/x' (Next does not normalize the leading //), and new URL('//evil.com/x', vercelOrigin) resolves to https://evil.com — a 307 OPEN REDIRECT off the allowlisted origin to any host (phishing / OAuth-token-leak). Now the dest is built from the trusted base first, then pathname/search assigned, so '//evil.com' collapses onto the allowlisted origin (verified: crafted // and backslash paths all stay on the Vercel host; normal paths preserved). (2) build-chat route did (body.messages ?? []).filter(...) before its try/catch — a non-array messages ({"messages":"x"}) passes the ?? guard but throws TypeError on .filter, returning a raw 500 instead of the clean 400 the surrounding validation produces; replaced with Array.isArray(...), matching the sibling agent-stream route. tsc + slices:check green.

Fixes

  • proxy.ts — open redirect closed: external-demo dest built from the trusted base, so a crafted //host path can't escape the allowlisted Vercel origin
  • build-chat — malformed messages (non-array) returns a clean 400 instead of an unhandled 500
NewerPage 10 / 25Older