Skip to content

Merge upstream PR #4604: Hermes-powered T3 Work - #103

Merged
Bl4ckBl1zZ merged 52 commits into
mainfrom
merge/pr-4604
Aug 2, 2026
Merged

Merge upstream PR #4604: Hermes-powered T3 Work#103
Bl4ckBl1zZ merged 52 commits into
mainfrom
merge/pr-4604

Conversation

@Bl4ckBl1zZ

Copy link
Copy Markdown
Owner

Merges pingdotgg/t3code#4604 (Hermes provider + T3 Work workspace, stacked on upstream #4400) into the fork while preserving all fork features.

Conflict resolution (54 files)

Policy: keep both feature sets — fork features (provider handoffs, queued turns, lifecycle timeline, diffstat-first tool rows, MCP liveness windows) plus the PR's Hermes/T3 Work additions.

Notable decisions:

  • Migrations renumbered: fork already had migration 044, so Hermes migrations shifted to 045–050 (ids, tests, and contiguity checks updated).
  • MCP credentials: Hermes-issued MCP credentials now honor the fork's 24h liveness window (refreshed on use) instead of upstream's valid-until-revoked semantics; upstream test adjusted.
  • EffectWorker: behavioral synthesis of the fork's requeue/settlement recovery with the PR's permanent-failure terminalization.
  • Hermes RPCs: added to the fork's RPC_REQUIRED_SCOPES (reads → orchestration-read, mutations → orchestration-operate).
  • New drivers (Hermes/HermesAcp/OpenClaw): added generateHandoffSummary stubs and widened driver envs for the fork's ACP adapter requirements.
  • Mobile: kept fork's in-list pending rows and voice combo button; upstream's header pending rows and plain start button dropped as superseded.
  • Web: kept fork's diffstat-first tool rows (upstream's success checkmark branch dropped by design); routeTree.gen.ts merged by hand — consider regenerating with the TanStack route generator.
  • Legacy importer: fork's evolved versions kept; upstream's transcript-time metadata backfill dropped (fork's reconcileShells covers it and fork tests forbid clobbering post-import renames).

Verification

  • pnpm -r typecheck clean across the repo
  • apps/server orchestration-v2 + mcp + persistence: 753 passed / 6 skipped
  • packages/client-runtime: 563 passed
  • mobile workspace/startTurn tests: 9 passed
  • apps/web typecheck + Sidebar/SettingsPanels logic tests passed during resolution

Worth a manual pass: work-workspace sidebar visuals, Hermes tool status indicators (running/stopped/failed only — no completed checkmark), work-mode composer labels.

🤖 Generated with Claude Code

juliusmarminge and others added 30 commits July 27, 2026 19:23
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…uses, path containment, draft clearing)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…search/inspect/reload)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… Hermes provider directory

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ateway lifecycle guards, cron/skills fail-closed, per-provider skills UI state)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…s_blocked skills error

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…e on factory failure during reconnect

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ing on socket close events

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…e_ids) so turns degrade instead of failing

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…avigation, control overlap, env scoping)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…rect resume for imported Hermes sessions

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…and transport cleanup

Imported Hermes sessions now rehydrate structured history into native T3
turn items: tool calls paired with results by call id, categorized into
command_execution/file_change/web_search/dynamic_tool presentations,
reasoning restored as activity, unmatched calls kept as cancelled, output
bounded with an explicit truncation marker, and malformed arguments parsed
safely. Transport framing on inherited user rows (sender prefixes, mirror
delivery, channel backfill, attachment envelopes) is cleaned up and
gateway-forged delegation/watch notifications are suppressed. A new
inherited_message_count boundary on the import ledger scopes all of this
to the inherited history only.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…e message dedup

Imported settled threads now settle with the upstream started_at (optional
settledAt on thread.settle) so sidebar rows stop labeling as "now".
Thread snapshots skip history rows whose content is already represented by
a live-streamed message, preventing duplicated assistant text when Hermes
history omits message ids.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- retry import hydration and log at error level so a transient gateway
  failure cannot silently leave a completed import without a transcript
- leave the inherited boundary unrecorded while history reads empty so a
  later full history still receives import normalization and rehydration
- resolve MEDIA output protocol inside rehydrated tool activities into
  durable attachment markers instead of leaving raw MEDIA: text
- historical settles stamp updatedAt from settledAt so imported threads
  keep sorting by when the work actually ended

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- close() rejects sent in-flight mutations with
  HermesGatewayMutationIndeterminateError instead of a connection error
- reconcileMutation only touches the local fence when the queried
  mutation id belongs to the fenced operation
- HermesCron reuses one shared gateway client per provider connection so
  operationId fences survive across cron calls; duplicate operation ids
  map to invalid_input and blocked writes map to indeterminate
- projectProvider projects success:false cron list responses as a
  provider error instead of a ready empty inventory
- HermesProviderDirectory applies assessHermesConnectionSecurity, so
  remote wss endpoints no longer receive the broad local gateway token,
  and an empty endpoint resolves to the default loopback endpoint

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- EffectWorker: verify lease ownership before projecting permanent
  failures and keep effects retryable when the terminal projection fails
- HermesHistoryNormalization: stop unquoted MEDIA paths from swallowing
  a second MEDIA directive on the same line
- HermesServeAdapterV2: bound oversized tool property names and redact
  standard Authorization schemes plus OAuth parameters
- HermesSessionCatalog: route discovery through the serve runtime's
  ensureReady so managed local Hermes instances are started first
- HermesServeRuntime: relaunch an owned unhealthy process instead of
  reporting endpoint_in_use for T3's own listener
- ThreadLaunchService: still generate thread titles when workspace
  preparation is skipped
- HermesDriver: resolve default-model capabilities from the active
  provider on duplicate model slugs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- SidebarV2: stay put instead of landing on the Code composer when the
  Work composer cannot open after a workspace switch
- SidebarV2: only blur the pin toggle on pointer activation so keyboard
  focus survives Enter/Space
- mobile: exclude Hermes threads from the Code workspace, matching web
  sidebar classification

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
maria-rcks and others added 14 commits July 27, 2026 21:43
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ture

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- EffectWorker: never re-execute permanently failed effects; persist a
  pending-terminalization marker so reclaims retry only the terminal
  projection
- HermesCron: close and evict stale gateway clients when a provider's
  connection identity (endpoint/token) changes
- HermesCron: only report duplicate-operation-id for actual duplicates
  via HermesGatewayDuplicateOperationIdError; map other configuration
  errors to a gateway diagnostic
- HermesDriver: omit the session catalog for disabled instances
- HermesServeRuntime: stop any lingering owned process before launching
  a replacement, even when the endpoint is unreachable
- sanitizeHermesToolValue: short-circuit object/array iteration when the
  size budget is exhausted

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… message snapshots, and route drafts on workspace switch

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…keep the index draft off the T3 Work backing project

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ort hydrate ledger, probe warnings, draft classification)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…classify Hermes Code threads

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…response placeholder with attachments

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… dedup by id and time proximity

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…amps are synthetic)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…nto committed entries

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Resolves 54 conflicted files, keeping both the fork's features (provider
handoffs, queued turns, lifecycle timeline, diffstat-first tool rows,
MCP liveness windows) and the PR's Hermes/T3 Work additions. Hermes
migrations renumbered 45-50 to avoid colliding with the fork's 044.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Add generateHandoffSummary stubs to Hermes/HermesAcp/OpenClaw drivers
- Widen HermesAcp/OpenClaw driver envs with BackgroundPolicy and
  ServerSettingsService required by the fork's ACP adapter
- Add Hermes RPC scope entries to RPC_REQUIRED_SCOPES
- Add fork-added fields to PR test fixtures (searchThreads, lastVisitedAt)
- Drop duplicated blocks left by the conflict resolution

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 236 files, which is 86 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to Pro+ to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 94d478f7-a89e-43c9-ae64-b7f0e301c4d4

📥 Commits

Reviewing files that changed from the base of the PR and between 90cf633 and e4b75ec.

⛔ Files ignored due to path filters (1)
  • apps/web/public/hermes-agent-logo.png is excluded by !**/*.png
📒 Files selected for processing (236)
  • apps/mobile/src/components/ProviderIcon.tsx
  • apps/mobile/src/features/home/HomeHeader.tsx
  • apps/mobile/src/features/home/HomeRouteScreen.tsx
  • apps/mobile/src/features/home/HomeScreen.tsx
  • apps/mobile/src/features/home/usePendingTaskListActions.ts
  • apps/mobile/src/features/threads/NewTaskDraftRouteScreen.tsx
  • apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
  • apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
  • apps/mobile/src/features/threads/new-task-flow-provider.tsx
  • apps/mobile/src/features/threads/sidebar-native-header-items.ts
  • apps/mobile/src/features/threads/thread-list-v2-items.tsx
  • apps/mobile/src/features/threads/use-project-actions.ts
  • apps/mobile/src/lib/mobileWorkspace.test.ts
  • apps/mobile/src/lib/mobileWorkspace.ts
  • apps/mobile/src/lib/projectThreadStartTurn.test.ts
  • apps/mobile/src/lib/projectThreadStartTurn.ts
  • apps/mobile/src/persistence/mobile-preferences.ts
  • apps/mobile/src/state/preferences.ts
  • apps/mobile/src/state/thread-outbox-model.ts
  • apps/mobile/src/state/use-thread-outbox-drain.ts
  • apps/server/src/assets/AssetAccess.test.ts
  • apps/server/src/assets/AssetAccess.ts
  • apps/server/src/attachmentStore.ts
  • apps/server/src/auth/RpcAuthorization.ts
  • apps/server/src/config.ts
  • apps/server/src/hermes/HermesConnectionSecurity.test.ts
  • apps/server/src/hermes/HermesConnectionSecurity.ts
  • apps/server/src/hermes/HermesCron.test.ts
  • apps/server/src/hermes/HermesCron.ts
  • apps/server/src/hermes/HermesGatewayClient.test.ts
  • apps/server/src/hermes/HermesGatewayClient.ts
  • apps/server/src/hermes/HermesHistoryNormalization.test.ts
  • apps/server/src/hermes/HermesHistoryNormalization.ts
  • apps/server/src/hermes/HermesImportHydration.test.ts
  • apps/server/src/hermes/HermesImportHydration.ts
  • apps/server/src/hermes/HermesOperational.test.ts
  • apps/server/src/hermes/HermesOperational.ts
  • apps/server/src/hermes/HermesProactiveEventRepository.test.ts
  • apps/server/src/hermes/HermesProactiveEventRepository.ts
  • apps/server/src/hermes/HermesProviderDirectory.test.ts
  • apps/server/src/hermes/HermesProviderDirectory.ts
  • apps/server/src/hermes/HermesServeRuntime.test.ts
  • apps/server/src/hermes/HermesServeRuntime.ts
  • apps/server/src/hermes/HermesSessionBindingRepository.test.ts
  • apps/server/src/hermes/HermesSessionBindingRepository.ts
  • apps/server/src/hermes/HermesSessionCatalog.test.ts
  • apps/server/src/hermes/HermesSessionCatalog.ts
  • apps/server/src/hermes/HermesSessionImportService.test.ts
  • apps/server/src/hermes/HermesSessionImportService.ts
  • apps/server/src/hermes/HermesSkills.test.ts
  • apps/server/src/hermes/HermesSkills.ts
  • apps/server/src/http.ts
  • apps/server/src/mcp/McpHttpServer.test.ts
  • apps/server/src/mcp/McpHttpServer.ts
  • apps/server/src/mcp/McpInvocationContext.test.ts
  • apps/server/src/mcp/McpInvocationContext.ts
  • apps/server/src/mcp/McpProviderSession.ts
  • apps/server/src/mcp/McpSessionRegistry.test.ts
  • apps/server/src/mcp/McpSessionRegistry.testkit.ts
  • apps/server/src/mcp/McpSessionRegistry.ts
  • apps/server/src/mcp/OrchestratorMcpToolkit.integration.test.ts
  • apps/server/src/mcp/PreviewAutomationBroker.test.ts
  • apps/server/src/mcp/WorktreeMcpService.test.ts
  • apps/server/src/mcp/toolkits/preview/handlers.ts
  • apps/server/src/mcp/toolkits/preview/tools.ts
  • apps/server/src/mcp/toolkits/worktree/registration.test.ts
  • apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.ts
  • apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.testkit.ts
  • apps/server/src/orchestration-v2/Adapters/CursorAdapterV2.testkit.ts
  • apps/server/src/orchestration-v2/Adapters/HermesAcpAdapterV2.test.ts
  • apps/server/src/orchestration-v2/Adapters/HermesAcpAdapterV2.ts
  • apps/server/src/orchestration-v2/Adapters/HermesServeAdapterV2.test.ts
  • apps/server/src/orchestration-v2/Adapters/HermesServeAdapterV2.ts
  • apps/server/src/orchestration-v2/Adapters/OpenClawAdapterV2.test.ts
  • apps/server/src/orchestration-v2/Adapters/OpenClawAdapterV2.ts
  • apps/server/src/orchestration-v2/EffectOutbox.ts
  • apps/server/src/orchestration-v2/EffectWorker.test.ts
  • apps/server/src/orchestration-v2/EffectWorker.ts
  • apps/server/src/orchestration-v2/FoundationPersistence.test.ts
  • apps/server/src/orchestration-v2/Orchestrator.migration.test.ts
  • apps/server/src/orchestration-v2/Orchestrator.ts
  • apps/server/src/orchestration-v2/ProjectionStore.test.ts
  • apps/server/src/orchestration-v2/ProjectionStore.ts
  • apps/server/src/orchestration-v2/ProviderAdapter.ts
  • apps/server/src/orchestration-v2/ProviderEventIngestor.ts
  • apps/server/src/orchestration-v2/ProviderSessionManager.test.ts
  • apps/server/src/orchestration-v2/ProviderSessionManager.ts
  • apps/server/src/orchestration-v2/ProviderTurnStartService.test.ts
  • apps/server/src/orchestration-v2/ProviderTurnStartService.ts
  • apps/server/src/orchestration-v2/RunExecutionService.test.ts
  • apps/server/src/orchestration-v2/RunExecutionService.ts
  • apps/server/src/orchestration-v2/ThreadLaunchService.test.ts
  • apps/server/src/orchestration-v2/ThreadLaunchService.ts
  • apps/server/src/orchestration-v2/builtInProviderAdapterDrivers.ts
  • apps/server/src/orchestration-v2/runtimeLayer.test.ts
  • apps/server/src/orchestration-v2/testkit/ProviderReplayHarness.ts
  • apps/server/src/orchestration/decider.settled.test.ts
  • apps/server/src/orchestration/decider.ts
  • apps/server/src/persistence/Migrations.ts
  • apps/server/src/persistence/Migrations/036_037_OrchestrationV2.test.ts
  • apps/server/src/persistence/Migrations/045_HermesSessionBindings.test.ts
  • apps/server/src/persistence/Migrations/045_HermesSessionBindings.ts
  • apps/server/src/persistence/Migrations/046_HermesProactiveEvents.ts
  • apps/server/src/persistence/Migrations/047_HermesTitleBranchLineage.ts
  • apps/server/src/persistence/Migrations/048_HermesSessionImports.test.ts
  • apps/server/src/persistence/Migrations/048_HermesSessionImports.ts
  • apps/server/src/persistence/Migrations/049_HermesImportProjectScope.test.ts
  • apps/server/src/persistence/Migrations/049_HermesImportProjectScope.ts
  • apps/server/src/persistence/Migrations/050_HermesImportInheritedBoundary.ts
  • apps/server/src/provider/Drivers/HermesAcpDriver.test.ts
  • apps/server/src/provider/Drivers/HermesAcpDriver.ts
  • apps/server/src/provider/Drivers/HermesDriver.test.ts
  • apps/server/src/provider/Drivers/HermesDriver.ts
  • apps/server/src/provider/Drivers/OpenClawDriver.test.ts
  • apps/server/src/provider/Drivers/OpenClawDriver.ts
  • apps/server/src/provider/Layers/HermesAcpProvider.test.ts
  • apps/server/src/provider/Layers/HermesAcpProvider.ts
  • apps/server/src/provider/Layers/OpenClawProvider.test.ts
  • apps/server/src/provider/Layers/OpenClawProvider.ts
  • apps/server/src/provider/Layers/ProviderInstanceRegistryHydration.test.ts
  • apps/server/src/provider/Layers/ProviderInstanceRegistryHydration.ts
  • apps/server/src/provider/Layers/ProviderInstanceRegistryLive.test.ts
  • apps/server/src/provider/Layers/ProviderRegistry.test.ts
  • apps/server/src/provider/ProviderDriver.ts
  • apps/server/src/provider/acp/HermesAcpSupport.test.ts
  • apps/server/src/provider/acp/HermesAcpSupport.ts
  • apps/server/src/provider/acp/OpenClawSupport.test.ts
  • apps/server/src/provider/acp/OpenClawSupport.ts
  • apps/server/src/provider/builtInDrivers.ts
  • apps/server/src/server.ts
  • apps/server/src/ws.ts
  • apps/web/src/components/ChatMarkdown.tsx
  • apps/web/src/components/ChatView.logic.test.ts
  • apps/web/src/components/ChatView.logic.ts
  • apps/web/src/components/ChatView.tsx
  • apps/web/src/components/CommandPalette.tsx
  • apps/web/src/components/HermesImportOnboarding.logic.test.ts
  • apps/web/src/components/HermesImportOnboarding.logic.ts
  • apps/web/src/components/HermesImportOnboarding.tsx
  • apps/web/src/components/Icons.tsx
  • apps/web/src/components/Sidebar.logic.test.ts
  • apps/web/src/components/Sidebar.logic.ts
  • apps/web/src/components/SidebarV2.tsx
  • apps/web/src/components/chat/ChatComposer.tsx
  • apps/web/src/components/chat/DraftHeroHeadline.tsx
  • apps/web/src/components/chat/ExpandedImageDialog.test.tsx
  • apps/web/src/components/chat/ExpandedImageDialog.tsx
  • apps/web/src/components/chat/MarkdownMedia.test.ts
  • apps/web/src/components/chat/MarkdownMedia.tsx
  • apps/web/src/components/chat/MessagesTimeline.logic.test.ts
  • apps/web/src/components/chat/MessagesTimeline.logic.ts
  • apps/web/src/components/chat/MessagesTimeline.test.tsx
  • apps/web/src/components/chat/MessagesTimeline.tsx
  • apps/web/src/components/chat/ThreadDetailsPanel.test.tsx
  • apps/web/src/components/chat/ThreadDetailsPanel.tsx
  • apps/web/src/components/chat/ThreadErrorBanner.tsx
  • apps/web/src/components/chat/composerAttachmentValidation.test.ts
  • apps/web/src/components/chat/composerAttachmentValidation.ts
  • apps/web/src/components/chat/providerErrorPresentation.test.ts
  • apps/web/src/components/chat/providerErrorPresentation.ts
  • apps/web/src/components/chat/providerIconUtils.test.ts
  • apps/web/src/components/chat/providerIconUtils.ts
  • apps/web/src/components/settings/AddProviderInstanceDialog.tsx
  • apps/web/src/components/settings/HermesCronSettings.tsx
  • apps/web/src/components/settings/HermesSkillsSettings.logic.test.ts
  • apps/web/src/components/settings/HermesSkillsSettings.logic.ts
  • apps/web/src/components/settings/HermesSkillsSettings.tsx
  • apps/web/src/components/settings/ProviderInstanceCard.comingSoon.test.tsx
  • apps/web/src/components/settings/ProviderInstanceCard.tsx
  • apps/web/src/components/settings/ProviderModelsSection.tsx
  • apps/web/src/components/settings/ProviderSettingsForm.test.ts
  • apps/web/src/components/settings/SettingsPanels.logic.test.ts
  • apps/web/src/components/settings/SettingsPanels.logic.ts
  • apps/web/src/components/settings/SettingsPanels.tsx
  • apps/web/src/components/settings/SettingsSidebarNav.tsx
  • apps/web/src/components/settings/providerDriverMeta.ts
  • apps/web/src/components/sidebar/SidebarChrome.tsx
  • apps/web/src/composerDraftStore.ts
  • apps/web/src/hooks/useHandleNewThread.ts
  • apps/web/src/index.css
  • apps/web/src/lib/messageReply.test.ts
  • apps/web/src/lib/messageReply.ts
  • apps/web/src/routeTree.gen.ts
  • apps/web/src/routes/-settings.hermes-cron.test.ts
  • apps/web/src/routes/_chat.index.tsx
  • apps/web/src/routes/settings.hermes-cron.tsx
  • apps/web/src/routes/settings.hermes-skills.tsx
  • apps/web/src/routes/settings.providers.tsx
  • apps/web/src/session-logic.test.ts
  • apps/web/src/session-logic.ts
  • apps/web/src/state/hermes.ts
  • apps/web/src/t3WorkProject.test.ts
  • apps/web/src/t3WorkProject.ts
  • apps/web/src/t3WorkProjectCreate.ts
  • apps/web/src/types.ts
  • docs/internals/hermes-conformance.md
  • docs/user/hermes-acp.md
  • docs/user/hermes-conformance-evidence.template.md
  • package.json
  • packages/client-runtime/package.json
  • packages/client-runtime/src/operations/commands.test.ts
  • packages/client-runtime/src/operations/commands.ts
  • packages/client-runtime/src/state/hermes.ts
  • packages/client-runtime/src/state/models.ts
  • packages/client-runtime/src/state/orchestrationV2Projection.test.ts
  • packages/client-runtime/src/state/orchestrationV2Projection.ts
  • packages/client-runtime/src/state/server.ts
  • packages/client-runtime/src/state/threadWorkflows.ts
  • packages/contracts/src/assets.ts
  • packages/contracts/src/chatAttachment.ts
  • packages/contracts/src/fixtures/hermesGateway.sanitized.json
  • packages/contracts/src/hermesGateway.test.ts
  • packages/contracts/src/hermesGateway.ts
  • packages/contracts/src/hermesProactive.test.ts
  • packages/contracts/src/hermesProactive.ts
  • packages/contracts/src/hermesSessions.test.ts
  • packages/contracts/src/hermesSessions.ts
  • packages/contracts/src/hermesSkills.ts
  • packages/contracts/src/index.ts
  • packages/contracts/src/model.ts
  • packages/contracts/src/orchestration.ts
  • packages/contracts/src/orchestrationV2.ts
  • packages/contracts/src/preview.test.ts
  • packages/contracts/src/previewAutomation.ts
  • packages/contracts/src/rpc.ts
  • packages/contracts/src/server.ts
  • packages/contracts/src/settings.test.ts
  • packages/contracts/src/settings.ts
  • packages/shared/src/filePreview.test.ts
  • packages/shared/src/filePreview.ts
  • scripts/dev-runner.test.ts
  • scripts/dev-runner.ts
  • scripts/fixtures/hermes-conformance/README.md
  • scripts/hermes-conformance.ts
  • scripts/lib/hermes-conformance.test.ts
  • scripts/lib/hermes-conformance.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Comment @coderabbitai help to get the list of available commands.

github-actions Bot and others added 7 commits August 2, 2026 14:47
Server/Hermes: close browser-artifact file handles, derive asset MIME type,
bound the gateway mutations map, fix resetHistory ordering, recognize IPv6
and 127.0.0.0/8 loopback endpoints, guard empty unsettled-create intents,
refresh driver checkedAt, trim skill reload operation ids.

Orchestration: keep imported thread timestamps off wall-clock, include
titleRevision/titleOrigin/pinned fields in threadShellFromProjection, fix
failure-item ordinal scale, reject prepareWorkspace:false with worktree
strategy, clamp future settledAt to now (with regression test).

Web/contracts: extract T3 Work backing-project creation, tighten attachment
and Hermes session schemas, per-skill reload state, playsInline video.

Docs: move hermes-conformance to docs/internals, fix command examples,
kill the spawned child on Windows cleanup.

Also fixes stale upstream migration bounds in Hermes tests (Hermes
migrations are 045-050 on this branch), which were failing 7 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Tighten IsoDateTime in hermesProactive: require full ISO 8601 date-time
  grammar and reject impossible calendar dates instead of trusting
  Date.parse, which accepts date-only and non-ISO values.
- Make a failed T3 Work backing-project preparation recoverable: the
  failure toast now offers 'Try again', which clears the guard and
  re-runs preparation instead of requiring a reload.
- Restore the 'Tool call completed' accessible label on the (visually
  empty) indicator slot, keeping the fork's diffstat-first row design
  while preserving screen-reader parity.
- Update the coming-soon provider test for the now provider-agnostic copy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Bound ISO timezone offsets in the pattern (rejecting +99:99) and reject
  second 60 outright rather than implying leap-second support these
  gateway event timestamps do not have.
- Give the completed tool-call indicator role=img so its accessible name
  is actually exposed; ARIA ignores aria-label on role-less elements.
- Add contract tests covering ten timestamp forms Date.parse accepts but
  the contract must reject, plus valid offset/leap-day round-trips.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Critical:
- Fence the proactive outbox lease before writing projections: an expired
  or reclaimed lease could double-deliver a notification. Delivery now
  commits via a conditional UPDATE and bails when no row matches.
- Route Hermes media attachments to the ChatAttachment type implied by
  their MIME instead of hard-coding 'file', which produced rows the
  contract rejects at persistence (e.g. .svg as image/svg+xml).

Gateway/runtime: bound the sessionSequences map, send connection (not
indeterminate) errors for unsent mutations, decouple fast-config reads
from the models.inventory capability, and stop late probe socket errors
from surfacing as uncaught exceptions.

Cron: fail mutations the gateway reports unsuccessful instead of
reporting them applied, prune and close cached clients on shutdown and
provider removal, and stop the durable-cursor diagnostic firing with no
executions.

History/proactive: order media by source offset across both MEDIA passes,
expand ~/ on Windows, decode stored capability JSON through the error
channel, and give the test helper isolated profile keys.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Return lease_not_held instead of unsettled_prompt when a binding lease
  was lost: the zero-row insert is ambiguous, so re-check the fence.
- Stop resetHistory skipping threads moved by provider.switch. The
  history id query is already scoped to provider instance, profile and
  project, so the extra providerInstanceId equality added no isolation
  while orphaning ledger rows the scoped clear still deleted.
- Replace the per-session import lookup in discover with one scoped
  listSessionImports query (was up to 10k queries per discovery).
- Report negotiated 'unsupported' protocol reasons instead of an empty
  missing-capability list, and distinguish sessions filtered out by
  transport/age from ids the profile never returned.
- Reject non-positive started_at epochs so imports cannot backdate to 1970.
- Isolate the binding test database per case and scan SQLite sidecars in
  the private-prompt assertion.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- failPermanently ignored the committed flag from writeIfRunCurrent, so a
  guarded write rejected as stale reported success and the worker never
  retried. It now fails, which routes into the fork's pending-
  terminalization requeue path rather than silently completing.
- Drop the superseded liveSessionId mapping when a binding resumes with a
  fresh Hermes session id; late events were routing to a discarded state.
- Stop handleToolOutputRisk mutating tool.output: repeated risk events
  nested wrappers and a later tool.complete discarded the annotation.
  Risk details now live in dedicated ActiveHermesTool fields.
- Clear or finalize the active turn on every startTurn failure, not only
  when the provider turn was never created.
- Allow pinned + workInboxRole 'main' against a settled or snoozed
  thread: the same command unsettles it, so the guard rejected a
  combination the client dispatches as one command.
- Skip hydration for archived or deleted threads before opening a
  provider session, matching startNextQueuedRun.
- Suppress empty assistant_message projections, and pass mutationOptions
  so attachment mutations carry wire-level mutation ids.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Bl4ckBl1zZ

Copy link
Copy Markdown
Owner Author

CodeRabbit review loop — 7 rounds

Merged latest main into the branch, then ran CodeRabbit repeatedly, fixing findings between rounds.

97 findings triaged — 74 fixed, 23 disproved as stale or wrong.

Round Scope Findings Fixed Disproved
1 full branch 42 33 9
2 round-1 fixes 2 2 0
3 round-2 fixes 3 3 0
4 server/src/hermes sweep 34 (2 critical) 24 10
5 round-4 fixes 0
6 orchestration-v2 sweep 16 12 4
7 round-6 fixes 0

Reviews of the fixes converged to zero twice, while each new directory sweep kept finding real issues in the PR's own code — the full-branch review timed out server-side, so directory-scoped sweeps were used to reach the code it never examined.

Most significant fixes

  • Proactive outbox double-delivery (critical) — delivery selected a row and wrote projections without fencing the lease, so an expired or reclaimed lease could deliver a notification twice. Now commits via a conditional UPDATE and bails when no row matches.
  • Attachment persistence (critical) — media was hard-coded to type: "file", but the ChatAttachment contract rejects image/*, video/* and application/pdf on that branch, so .svg produced rows that fail schema validation at persistence. Now routed by MIME, with a contract round-trip test.
  • failPermanently phantom success — the terminal write ignored writeIfRunCurrent's committed flag, so a write rejected as stale reported success and the worker never retried. Now fails, routing into the fork's pending-terminalization requeue path. New dedicated test file.
  • resetHistory orphaning — the redundant providerInstanceId equality check (the id query is already scoped to provider + profile + project) skipped threads moved by provider.switch while the scoped clear still deleted their ledger rows.
  • Stale live-session routingresumeBinding never dropped the superseded statesByLiveSession key, so late gateway events routed to a discarded state.
  • Tool output risk annotationhandleToolOutputRisk mutated tool.output in place, so repeated risk events nested wrappers and a later tool.complete discarded the annotation entirely.
  • Plus: unbounded map growth in the gateway client and event sequences, N+1 in session discovery (up to 10k queries), cron mutations reporting gateway rejections as applied, IPv6/loopback endpoint detection, ISO timestamp validation, and a Tool call completed a11y label that ARIA was ignoring on a role-less element.

Notable rejections

Several findings were disproved rather than applied — applying them would have caused regressions:

  • Adding job_id to cron mutations would have broken them; the gateway addresses jobs by name (verified against the conformance script).
  • The token-in-URL concern conflated T3's own auth flow with the Hermes gateway's; the endpoint is loopback-only by policy.
  • Rotating MCP credentials for already-attached threads would break live provider processes that bake the credential in at openSession.
  • Several "missing migration" findings were stale — Hermes migrations are renumbered 045–050 on this branch.

Verification

pnpm -r typecheck clean · server 2270 · web 1893 · client-runtime 563 · contracts 283 — all passing.

Outstanding

  • A sweep of apps/web/src/components could not complete — the CodeRabbit account hit its rate limit after seven rounds. Worth running once the quota resets.
  • Scope-wide "single Main thread" uniqueness is still unenforced in the per-thread reducer (the importer enforces it via a unique index). Flagged as architectural rather than patched.

🤖 Generated with Claude Code

- Revoke optimistic message preview URLs and clear the handoff map when a
  Hermes timeline is cleared, on both the draft and server-clear paths;
  blob URLs leaked and stale optimistic bubbles could re-render.
- Derive isHermesConversation from the active thread's runtime provider
  rather than the composer selection, so opening the handoff or model
  picker no longer flips Hermes-only behaviour before the handoff runs.
- Only intercept bare /new and /reset: the previous pattern accepted
  trailing text and silently discarded it.
- Report every attachment rejection including capacity, instead of
  stopping at the first, and only preventDefault on paste when at least
  one clipboard file is accepted so text still lands in the composer.
- Reject '.' and '..' as attachment names.
- Download cross-origin images through an object URL so the chat document
  cannot navigate away, and give the image-preview backdrop an accessible
  name distinct from the close button.
- Wrap disabled sidebar tooltip triggers so their tooltips can open in
  exactly the disabled states they explain.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Bl4ckBl1zZ
Bl4ckBl1zZ merged commit 657476c into main Aug 2, 2026
3 of 8 checks passed
@Bl4ckBl1zZ
Bl4ckBl1zZ deleted the merge/pr-4604 branch August 4, 2026 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants