You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
OSS→OHE Canvas gap inventory — 2026-11-11 03:00 UTC
Run resolution
Pinned OHE Canvas ref:v1.35.0 (enterprise/frontend/scripts/build-agent-canvas.sh:28). containers/app/Dockerfile has ARG AGENT_CANVAS_REF=main, which only the opt-in git source mode reads; the script default is canonical for the embedded build. docker-compose.yml:148 now pins agent-canvas:1.38.0 (enterprise#1312, enterprise#1313). The Helm chart image tag is 1.38.0 (values.yaml#L16). See gap:ohe-packaging/canvas-ref.
Current OSS main:7b5aa9eb6 (git describe --tags: v1.38.0-17-g7b5aa9eb6, 17 commits after the v1.38.0 release commit). It was e14b76cca in the previous run. There is no v1.39.0 tag and no open release PR yet.
Enterprise main:7fd5c6b (2026-11-11, enterprise#1331), 22 commits after the previous run's 6b3d21d: licensing, the legacy MCP library, the Super Admin starter modal, the rate-limit backend, two comment cleanups (enterprise#1246, enterprise#1331), the Compose pins (enterprise#1312, enterprise#1313), the 1.90.0 release and dependency bumps. Only the Compose pins touch a leaf (gap:ohe-packaging/canvas-ref). No commit touches frontend/src/routes/launch.tsx, the legacy secret form, conversation-card.tsx, the settings API or the feature-flag service, so every previous bump-only, not-OHE-gap and gate verdict stands. pyproject.toml pins the SDK at 1.60.1.
Range:v1.35.0..main, 157 commits: 45 shipped in v1.36.0 (#19306), 14 in v1.37.0 (#19402), 81 in v1.38.0 (#19419) and 17 unreleased after v1.38.0 (new since the previous run). This is a daily run (backfill: false), so the cloud capability scan covered only the files the new PRs touch. The K5 grep over the 17 new commits found no added kind === "cloud" or kind === "local" branch and no new getLockedCloudHost() gate, and no commit changes a K4 launch field or a K2 settings key. The own-copy test flagged seven touched files that also exist under enterprise/frontend/src (chat-input-actions.tsx, generic-event-message.tsx, hook-execution-event-message.tsx, conversation-websocket-context.tsx, websocket-provider-wrapper.tsx, file-diff-viewer.tsx, app-settings.tsx). All seven PRs are bump-only. The one new leaf, #19472, comes from the flag check.
Comparison: OSS PRs in the range, and cloud capability scan findings, that need a code change in OpenHands/enterprise beyond bumping AGENT_CANVAS_REF. 33 leaves: 22 need enterprise work (14 missing-integration and 8 unknown), 3 are flag-off and 8 are intentional-exclusion. 94 PRs are bump-only and 59 have nothing for OHE.
Typology source:fallback. Linear OSS-14542 has no typology artifact in its thread.
Reconciliation baseline:enterprise#1333 had no inventory comment yet (only a coordinator status comment), so this run used the latest inventory comment on saas-deploy#1847 as the baseline, read-only: 2026-11-10 09:09 UTC, pin v1.35.0. This comment is the first inventory on enterprise#1333; later runs edit it in place and use its body as the baseline.
Changes since the baseline: 1 new leaf, 0 resolved, 1 changed, 31 unchanged.
New (1):#19472, the automations dashboard "Service accounts" owner filter. It shows only when feature_flags.enable_service_accounts is true, and that flag defaults off. It joins the ENABLE_SERVICE_ACCOUNTS flag leaf. Flag-off leaves get no new issue by rule.
Changed (1):#18734: reported: ambiguous → already-reported (enterprise#1306 was filed in the previous run as a possible duplicate and carries the parity marker, so it is now an exact match) and worked: not-started → assigned (enterprise#1306 was assigned to juanmichelini on 2026-11-10 10:02 UTC). The leaf moves from reported: ambiguous to reported: already-reported.
Open PRs near a leaf that are not the same gap:enterprise#1270, enterprise#1293 (secret provenance; it does not mask the secret form), enterprise#1291, enterprise#1286, enterprise#1295 (ChatGPT Cloud OAuth MCP endpoint; not LLM subscription sign-in), enterprise#1161, enterprise#1332 (draft; organization skill precedence, not the Plugins or Apps page) and six new MCP, sandbox and Git PRs. Dependabot PRs and the draft enterprise#1305 touch no leaf path. enterprise#1246 merged; launch.tsx still returns no_plugins for a link without a plugin.
Filing (1f):filing-mode: file, filing-cap: 30, writes as openhands-agent. 0 issues filed, 0 labels added. 34 labeled issues loaded, any state; none is closed as a duplicate of a leaf. Every missing-integration and unknown leaf has an exact-match enterprise issue that carries oss-ohe-parity. The three flag-off leaves get no new issue by rule. No ohe-principles.md anchor was cited this run.
Credentials: reads (clones, gh queries) used GITHUB_TOKEN. Only the issue and this comment are written as openhands-agent.
Gap tree
missing-integration (14)
reported: already-reported (14)
worked: in-flight (6)
#16417 — LLM pre-save validation (src/api/profiles-service/profiles-service.api.ts, #L162 returns no verdict on cloud; shipped in v1.14.0). Key: gap:ohe-settings/control/settings/llm/pre-save-validation. Boundary: a validate endpoint next to the profile routes in openhands/app_server/settings/settings_router.py, plus a pre-save check on OHE's LLM page. Issue: enterprise#860. Evidence: open, approved enterprise#1234 adds POST /api/v1/settings/profiles/{name}/validate in settings_router.py and the pre-save check on OHE's LLM page.
#17869 — workspace file discovery settings are hidden on cloud (src/hooks/query/use-workspace-file-discovery.ts, #L22, S1; shipped in v1.25.0). Key: gap:canvas-cloud/workspace-file-discovery. Boundary: discovery options on the app-conversation files endpoint. Issue: enterprise#853. Evidence: open enterprise#1169 bounds the files proxy and adds persisted discovery options.
#18870 — mask secret values in the Settings forms (src/components/features/settings/secrets-settings/secret-form.tsx; shipped in v1.33.0). Boundary: OHE's own enterprise/frontend/src/components/features/settings/secrets-settings/secret-form.tsx, which is still a plain <textarea>. Issue: enterprise#1148. Evidence: open enterprise#1166 masks the value in secret-form.tsx and the service-account copy.
#19229 — open the VS Code URL with noopener, http(s) only (conversation-card.tsx, vscode-url-helper.ts; shipped in v1.35.0). Boundary: OHE's own conversation-card.tsx. Issue: enterprise#1149. Evidence: open, approved enterprise#1165 adds the noopener and http(s) check in conversation-card.tsx and vscode-url-helper.ts.
gap:ohe-launch/client-tools — the local launch registers canvas_ui, launch_child_conversation and request_secret for every OpenHands conversation (agent-server-adapter.ts#L1217). The cloud launch sends client_tools only in automation setup, and never sends request_secret (agent-server-conversation-service.api.ts#L638; also at the pin). Boundary: live secret attach for request_secret on cloud conversations (AppConversationStartRequest.client_tools exists). Issue: enterprise#761. Evidence: open enterprise#1167 forwards client_tools and adds live secret attach on AppConversationStartRequest.
worked: assigned (8)
#18436 — per-conversation Docker runtime and the Settings → Runtime page (src/routes/runtime-settings.tsx, src/api/agent-server-adapter.ts; shipped in v1.34.0, now behind the pin). The K4 runtime and container options are the same feature. Boundary: decide the OHE runtime default, then a route and page in enterprise/frontend/src/constants/settings-nav.tsx. Issue: enterprise#1147. Evidence: enterprise#1147 is assigned to juanmichelini (assigned 2026-11-06).
#18699 — automation-aware /launch install: mode=automation creates an automation through POST /api/automation/v1/plugin-spec (src/routes/launch.tsx, src/components/features/launch/plugin-launch-modal.tsx, src/api/automation-service/automation-service.api.ts; shipped in v1.38.0 #19419). OHE serves /launch from its own legacy route (frontend/src/routes.ts#L27), which has no mode handling: it starts a conversation with the plugin (launch.tsx#L150). The legacy frontend/ has no automation API client. A bump delivers the mode only at /canvas/launch. The sibling #18734 (message-only links) hits the same route. Boundary: forward /launch?…&mode=automation to /canvas/launch in enterprise/frontend/src/routes/launch.tsx (the alternative is a port into the legacy route). needs product decision: forward or port; the install needs manage_automations (owner and admin only). Issue: enterprise#1277. Evidence: enterprise#1277 is assigned to juanmichelini (assigned 2026-11-09 10:02 UTC); no open enterprise PR handles mode=automation. automation-safe: needs-human-decision.
#18734 — message-only /launch links: ?message=… with no plugin shows a confirmation modal and starts a conversation (src/routes/launch.tsx; shipped in v1.38.0 #19419). OHE serves /launch from its own legacy route (frontend/src/routes.ts#L28), which still returns no_plugins when no plugin is given, even with a message (launch.tsx#L82), so a message-only link shows an error. A bump delivers the feature only at /canvas/launch. Boundary: accept a message-only link in enterprise/frontend/src/routes/launch.tsx, or forward /launch to /canvas/launch together with #18699 (same route, same decision). needs product decision: forward or port. Scope: personal. Issue: enterprise#1306 (filed in the previous run as a possible duplicate of enterprise#1277; that issue covers mode=automation, not message-only links). Evidence: enterprise#1306 is assigned to juanmichelini (assigned 2026-11-10); no open PR. automation-safe: needs-human-decision. (changed: reported ambiguous → already-reported, worked not-started → assigned)
gap:canvas-cloud/apps — the Apps page is hidden and refused on cloud (extensions-navigation.tsx#L25, canvas-extensions.tsx#L54, S1; also at the pin). Boundary: an enterprise Canvas extensions store and API. needs product decision: beta and default off. Issue: enterprise#611. Evidence: enterprise#611 is assigned to juanmichelini (assigned 2026-11-06).
gap:canvas-cloud/plugins — the Plugins page is hidden on cloud: the catalog is empty and install, enable, uninstall and refresh throw (plugins-management-service.ts#L71, plugins-service.ts#L73, S1/S2; also at the pin). Enterprise has no plugin routes. Boundary: a per-user installed-plugin store and API. Issue: enterprise#865. Evidence: enterprise#865 is assigned to juanmichelini (assigned 2026-11-06).
gap:ohe-launch/workspace — the local launcher picks a workspace for a new conversation. The cloud launcher offers only a repository (home-chat-launcher.tsx#L87; also at the pin). AppConversationStartRequest has no workspace field, only sandbox_id. Boundary: a hosted workspace reuse choice on AppConversationStartRequest. needs product decision. Issue: enterprise#857. Evidence: enterprise#857 is assigned to juanmichelini (assigned 2026-11-06).
gap:ohe-launch/worktree — the local launch sets worktree and a workspace mode (new_worktree, docker_container) (agent-server-conversation-service.api.ts#L671, agent-server-adapter.ts#L1240; also at the pin). The cloud launch cannot carry either. Boundary: an isolation selection on AppConversationStartRequest. needs product decision. Issue: enterprise#851. Evidence: enterprise#851 is assigned to juanmichelini (assigned 2026-11-06).
gap:ohe-settings/control/settings/llm/subscription-sign-in — ChatGPT subscription sign-in on the LLM page talks only to the local agent server (llm-subscription-service.ts#L83, llm-settings.tsx#L438; introduced by 197588cc8, which is imported history with no PR in this repo). OHE's LLM page has no sign-in. Boundary: hosted subscription-auth ownership and storage. needs product decision. Issue: enterprise#861. Evidence: enterprise#861 is assigned to juanmichelini (assigned 2026-11-06).
unknown (8)
reported: already-reported (8)
worked: in-flight (4)
gap:canvas-cloud/file-transport — the cloud file read decodes content as UTF-8 and guesses binaries "fallibly" (use-workspace-file-content.ts#L214, S3; enterprise app_conversation_router.py#L1400 returns str and '' on errors). Boundary: a byte-preserving, MIME-aware /file response. Issue: enterprise#852. Evidence: open, approved enterprise#1233 adds GET /app-conversations/{id}/file/download, which returns the bytes unchanged with a MIME type and typed error codes.
gap:canvas-cloud/plan-file-path — the cloud plan read hardcodes /workspace/project/.agents_tmp/PLAN.md (agent-server-conversation-service.api.ts#L1046, S4; also at the pin). Boundary: report the planner artifact path in the app-conversation metadata. Issue: enterprise#849. Evidence: open enterprise#1168 adds a shared compute_plan_path() and exposes the artifact path through the app-conversation contract.
gap:canvas-cloud/secret-save — on cloud, one secret save is split across PUT /api/v1/secrets/{name} and POST /api/v1/secrets (secrets-service.api.ts#L63, S3; also at the pin). Boundary: an atomic rename-and-value secret mutation. Issue: enterprise#862. Evidence: open, approved enterprise#1231 lets PUT /api/v1/secrets/{name} take a value, so the rename and the value are written in one store() call.
gap:ohe-packaging/canvas-ref — the Canvas pins disagree. frontend/scripts/build-agent-canvas.sh (#L28) pins v1.35.0. docker-compose.yml (#L148) now pins 1.38.0 (enterprise#1312 and enterprise#1313, merged since the previous run; it was 1.37.0). The chart default image tag is 1.38.0 (agent-canvas/values.yaml#L16). A Replicated install serves /canvas from the chart image (replicated/openhands.yaml, agent-canvas.enabled: true), so it already carries every PR through v1.38.0. The Compose stack now matches the chart. The embedded build still carries v1.35.0. Boundary: decide which artifact each install mode serves and whether the embedded-build pin follows the chart. needs-live-validation: true. Issue: enterprise#856. Evidence: open enterprise#1262 (not a draft, now approved) cites the gap key and closes [OSS→OHE parity] Verify supported embedded Canvas build and packaging selection #856. It records and reports the served build and documents each install mode, but does not bump the embedded-build pin, so that decision is still open.
worked: assigned (4)
#16311 — the usage drawer's LLM credit balance is turned off on cloud (src/hooks/query/use-llm-balance.ts, #L22, S1; shipped in v1.13.0). Key: gap:canvas-cloud/llm-balance. Boundary: find out whether the sandbox agent server's /api/llm/balance already serves OHE (then the fix is in the Canvas only), or whether enterprise needs a route. Issue: enterprise#1164. Evidence: enterprise#1164 is assigned to juanmichelini (assigned 2026-11-06).
gap:canvas-cloud/mcp-server-mutations — on cloud, each MCP server add, edit and delete is a GET plus a full-catalog POST (settings-service.api.ts#L715, S3; also at the pin). Boundary: per-server MCP mutation routes in the settings API. Issue: enterprise#864. Evidence: enterprise#864 is assigned to juanmichelini (assigned 2026-11-06).
gap:canvas-cloud/mcp-stdio-probe — on cloud, the Test connection for STDIO servers is synthetic, and saving a STDIO server is skipped (custom-server-editor.tsx#L72, install-server-modal.tsx#L209, S2; also at the pin). Boundary: a sandbox-side probe capability in openhands/app_server/mcp/mcp_test_router.py. Issue: enterprise#864. Evidence: enterprise#864 is assigned to juanmichelini (assigned 2026-11-06).
gap:ohe-reimpl/memory-terminal-writes — enterprise's memory callback "only detects changes made via the file_editor tool" (memory_change_callback_processor.py#L8). The local agent also keeps memory that it writes from the terminal. Boundary: a PostToolUse hook or a session-end diff. Issue: enterprise#863. Evidence: enterprise#863 is assigned to juanmichelini (assigned 2026-11-06).
flag-off (3)
reported: new (3)
worked: not-started (3)
#17969 — Super Admin setup guide on enterprise backends (src/components/features/setup-guide/use-super-admin-setup-guide.ts, #L83; shipped in v1.26.0). Key: gap:ohe-flag/ENABLE_SUPER_ADMIN. The guide reads and writes /api/admin/setup-state, which enterprise mounts only when ENABLE_SUPER_ADMIN is set (saas_server.py#L226; _env_flag_enabled('ENABLE_SUPER_ADMIN') defaults off). The installer default is also off: super_admin_dashboard_enabled defaults to "0" (config.yaml#L1681). This is a rollout decision.
#19033 — run an automation as a service account (src/hooks/query/use-service-accounts.ts, #L27, S1: the service-account picker and the Run as control stay off unless feature_flags.enable_service_accounts is true; shipped in v1.36.0). Key: gap:ohe-flag/ENABLE_SERVICE_ACCOUNTS. Enterprise has the integration. GET /api/organizations/{org_id}/service-accounts takes limit and page_id and returns items and next_page_id (service_accounts.py#L183), each item has id, org_id, name and is_disabled (org_models.py#L589), owners and admins hold manage_service_accounts (authorization.py#L115), and the web client config carries the flag (default_web_client_config_injector.py#L266). The flag defaults off in code (feature_flag_service.py#L71), and the installer has no option for it (replicated/config.yaml and replicated/openhands.yaml do not mention it), so only a super admin who switches it on in the instance page (use-super-admin-mutations.ts#L207) gets the feature. The run-as route itself belongs to the automation service (its migration 036_add_automation_run_as.py), not to an enterprise route. This is a rollout decision. No issue tracks it: OSS #19291 is the closed Canvas request, and enterprise#1090 is a different gap (follow-up messages on service-account automation conversations).
#19472 — automations dashboard owner filter with a "Service accounts" option (src/routes/automations-list.tsx; unreleased, after v1.38.0). Key: gap:ohe-flag/ENABLE_SERVICE_ACCOUNTS. The option and the run_as=service filter show only when the cloud config reports isServiceAccountsEnabled, the same flag as the #19033 leaf above, so a bump alone leaves it hidden on OHE. The enterprise evidence is the one on that leaf. The run_as filter belongs to the automation service, not to an enterprise route. This is a rollout decision. No issue tracks it. (new)
intentional-exclusion (8)
reported: new (6)
worked: not-started (6)
gap:ohe-gate/acp-agent-settings-flag — enterprise/frontend/src/routes/agent-settings.tsx gates the ACP agent settings on enable_acp (supported: flag on).
gap:ohe-gate/automations-redirect — enterprise/frontend/src/routes/automations-redirect.tsx redirects /automations into the Canvas (partial: conditional).
gap:ohe-gate/automations-sidebar-flag — enterprise/frontend/src/components/features/sidebar/sidebar.tsx gates the automations nav entry on enable_automations (supported: flag on).
gap:ohe-gate/canvas-cross-app-redirect — enterprise/frontend/src/utils/cross-app-redirect.ts conditions the cross-app handoff (partial: conditional).
gap:ohe-gate/onboarding-flag — enterprise/frontend/src/components/features/guards/onboarding-guard.tsx gates onboarding on enable_onboarding (partial: conditional).
gap:ohe-gate/root-redirect — enterprise/frontend/src/routes/root-landing.tsx hard-redirects / to /canvas (location.replace).
reported: already-reported (2)
worked: not-started (1)
#17758 — gap:ohe-gate/acp-provider-allowlist — enterprise/openhands/app_server/acp_providers.py (#L18, SURFACED_ACP_PROVIDERS) offers only claude-code, codex and gemini-cli. The Canvas hides OpenCode and Pi on cloud to match (acp-providers.ts#L183; shipped in v1.27.0). The allowlist was decided in enterprise#315 (closed as completed).
worked: assigned (1)
gap:canvas-cloud/analytics-consent — on cloud the analytics switch is forced on and disabled (app-settings.tsx#L226, S1). OHE's own app settings page does the same with isSaasMode (app-settings.tsx#L270), so this is a hosted consent policy, not a missing integration. Issue: enterprise#858. Evidence: enterprise#858 is assigned to juanmichelini (assigned 2026-11-06).
Issues
Filed (0): none
Filed as possible duplicates (0): none this run. The one from the previous run, enterprise#1306 for #18734, is now linked below.
Not filed by rule: 8 intentional-exclusion leaves. 3 flag-off leaves (ENABLE_SUPER_ADMIN, and ENABLE_SERVICE_ACCOUNTS for #19033 and #19472): the rule never files a new issue for a flag, and no issue matches any of them exactly. 10 leaves are in flight as open PRs (enterprise#1165 to enterprise#1169, enterprise#1231 to enterprise#1234, and enterprise#1262); they already link their issues. Also not filed: the bump-only PRs and the ## Not OHE gaps entries.
Bump-only (94)
Bumping AGENT_CANVAS_REF delivers these PRs. No other enterprise change is needed. Open pin-bump PR: none (enterprise#1262 keeps the default at v1.35.0). A bump to v1.38.0 delivers the three shipped buckets today; the Helm chart image already runs 1.38.0 (see gap:ohe-packaging/canvas-ref). The unreleased bucket needs the OSS v1.39.0 tag first, which is an OSS release chore, not enterprise work.
Shipped in v1.36.0 (25):#17972 (tanstack deps), #17977 (monaco-editor 0.57.0), #19199 (react-router deps), #19297 (removes the automation-template integration notice; Canvas UI only), #19300 (template suggestion order; Canvas UI only), #19308 (axios 1.21.0), #19309 (httpxy 0.5.6), #19311, #19316 (the Stop button after an ACP reconnect; it follows the sandbox agent-server socket, no enterprise route), #19319 (collapsed script files in automation detail), #19323 (template card logo), #19335 (setup assistant names the event sources; the form tool reaches a cloud conversation only once enterprise forwards client_tools, which is the gap:ohe-launch/client-tools leaf, and the PR adds no request field), #19340 (Bitbucket Data Center and Azure DevOps repository picker in template setup; enterprise already reports the connection host in provider_tokens_set, settings_router.py#L282), #19342 (zustand 5.0.16), #19344 (ships the Data Center templates with extensions 0.39.0; a package bump), #19347 (template repos are sent only for providers the automation service clones; automation service capability, no enterprise route), #19349 (lists GitHub repositories directly when the token has no installations; existing endpoints), #19350 (Connect Git setup step; the git_provider field in /api/admin/setup-state landed with enterprise#1199), #19351 (no error toast when history ends with a hook event; Canvas event handling), #19352 (self-hosted GitHub templates guide to MCP or token setup; reads the existing secrets search), #19355 (Data Center templates use the repository picker, with extensions 0.40.0), #19358 (removes unused components and keys; no behavior change), #19370 (setup assistant stays on the form and saves drafts on cloud: uses tag merge-patch (app_conversation_models.py#L530) and the declared system_message_suffix; the form tool still needs the client_tools leaf), #19392, #19393 (@openhands/extensions 0.41.0)
Shipped in v1.38.0, a bump to v1.38.0 delivers them today (49):#16654 (@heroui/react 3.2.4, a Canvas build dependency), #17730 (Light+ and Solarized contrast pass; OHE's legacy frontend/ has no such themes), #18520, #18533 (budget meter fills; the cap comes from the sandbox agent-server conversation info (max_budget_per_run on the conversation URL), no enterprise route. OHE's own budget-display.tsx sits under the legacy /conversations/:id page, which server-generated links no longer target (they use /canvas/conversations/…)), #19228 (home route-at-start suppression moves from a store flag to a keyed module variable; the suppressRouterAtStart request field already existed, no new request field), #19262, #19307 (edit rights for org admins and owners; uses manage_automations, which enterprise defines (authorization.py#L112)), #19330 (export and import carry the script bundle; automation service API), #19384 (onboarding saves an ACP pick to its own profile; existing profile routes, names checked by the SDK pattern), #19397 (launch view keeps focus when the user navigated away; Canvas SPA only), #19407 (tanstack deps), #19408 (react-router deps), #19421 (prompt and plugin presets can run from an agent profile; the picker follows the automation service capability presetAgentProfiles, no enterprise route), #19437, #19438, #19445, #19446, #19447, #19451 (automation context for help chats; declared fields only; the form tool still needs the client_tools leaf), #19453 (executable plugin config in automation help; automation service plugin-spec API), #19454 (i18next group), #19455 (framer-motion 14.9.0), #19457 (vite 8.3.5, a build dependency of the Canvas bundle), #19458 (lucide-react 1.65.0), #19470 (OpenHands Enterprise license banner: it calls GET /api/license/status, which enterprise serves (license.py#L49) with every field the banner reads, delivered by enterprise#1241 and enterprise#1283), #19471 (hides the agent profile switch when a self-hosted instance turns Agent Profiles off; it reads feature_flags.enable_agent_profiles_page and deployment_mode, which enterprise's web client config already carries (default_web_client_config_injector.py#L262), and enterprise#1260 did the launch-side half; OHE's own chat-input-actions.tsx has no profile switch), #19478 (Bitbucket Data Center filter chip label; Canvas UI only), #19486, #19491, #19492 (the last three name Tailwind tokens for the file-drop art, markdown code padding and scroll fades; the CSS output is unchanged, so OHE's own drag-over.tsx, code.tsx, horizontal-scroll-fade.tsx and markdown-table-scroll.tsx need nothing), #19493 (spacing-scale aliases; no behavior change), #19501 (diff viewer releases editor models on teardown), #19506 (i18next group), #19508 (lucide-react 1.66.0), #19511 (posthog-js 1.444.0), #19518 (wide-table fades in message bubbles; Canvas CSS), #19530 (names existing background and on-accent colors; no behavior change), #19533 (names letter-spacing metrics; no behavior change), #19534 (names badge and inset-shadow recipes; no behavior change), #19536 (tanstack deps), #19537 (i18next group), #19538 (uuid 14.0.3), #19540 (react-syntax-highlighter 16.1.2), #19546 (the composer Stop interrupts the agent instead of pausing the Cloud sandbox: the Canvas calls the sandbox agent-server's /interrupt through conversationUrl, no enterprise route; OHE's legacy conversation-mutation-utils.ts already has both interruptV1Conversation and pauseV1ConversationSandbox), #19561 (context meters adopt the inline-style lint rule; no behavior change), #19566 (names commit viewer layout values; no behavior change), #19568 (reconciles the active LLM profile with the backend model; uses browser-side conversation metadata, no enterprise route), #19571 (names Files tab scroll and discovery height recipes; no behavior change), #19578 (names the shared dark Git control border; no behavior change)
Unreleased after v1.38.0, needs the OSS v1.39.0 tag, then the bump (11):#19290 (list memoization in the WebSocket provider wrapper), #19574 (chat sends over HTTP until the session socket is served; same send path as the closed-socket case), #19587 (@heroui/react), #19589 (react-icons), #19590 (mdast-util-from-markdown), #19595 (Paper theme; OHE's own app-settings.tsx has no theme picker), #19603 (resume timestamps read as UTC), #19619 (hides Stop hook feedback in the Canvas chat; OHE's hook-execution-event-message.tsx belongs to its own legacy conversation view, a separate implementation), #19623 (hover timestamp position), #19630 (Event Key dropdown), #19633 (shared agent-profile availability hook; OHE's own chat-input-actions.tsx has no profile switch)
#19329, #19321, #19275, #19341, #19385, #19264, #19448, #19439, #19484, #19529 — OSS build, CI and lint chores: the npm-publish timeout, Node 24.22.1 in OSS CI and the desktop bundle, the OSS Docker image liveness exit code, Stryker 10, the CI fix after the prettier and msw bumps, and five lint changes (the last three guard Tailwind arbitrary values, raw colors and recipe boundaries). Enterprise builds the Canvas with its own node:26.10.0 stage (Dockerfile#L27), so nothing changes for OHE.
#19426, #19428, #19564 — OSS test, CI and lint chores: an e2e wait fix, the Docker image smoke test that opens the Canvas in a browser, and a lint rule for Tailwind arbitrary values. #18975 and #16512 change only the OSS Docker image (workspaces on the persisted volume, a fail-fast check for unwritable bind mounts); enterprise builds its own image. Nothing ships in the bundle.
#19559, #19586, #19588, #19591, #19607: a docs map update, dev-dependency bumps (testing group, @eslint/js, electron-builder for the desktop app) and a dashboard test fixture. None changes the web bundle.
#17784, #18070, #19284 — local-machine behavior: workspace file listing and Planner paths on Windows local backends, and no agent-settings write for an ACP pick on local backends. #19388 raises the default local agent-server to 1.60.1 and the default local automation service to 1.30.1; those are local-stack defaults. #19572 does the same for v1.38.0: it raises the default local agent-server to 1.61.0 and the default local automation service to 1.31.0. Open enterprise#1291 bumps the enterprise SDK pin to 1.61.0 and open enterprise#1247 bumps it to 1.60.2; neither changes a leaf. Enterprise pins the SDK at 1.60.1 (pyproject.toml).
#19494 — resolved-thread banner above the composer (src/components/features/chat/resolved-conversation-banner.tsx; shipped in v1.38.0 #19419). It renders only when backend.kind === "local" and reads a resolved=user|auto conversation tag. The server half is the Agent Server projects API, software-agent-sdk#6602, which is still an open PR (checked 2026-11-10). No released openhands-agent-server can write the tag while that PR is open (the newest release is 1.61.0; enterprise still pins 1.60.1). A bump delivers a banner that cannot show on any enterprise backend, and there is no enterprise code to write until the SDK ships Projects. Revisit when software-agent-sdk#6602 merges: enterprise then needs to carry the runtime tag into its own conversation tags, which the Canvas comment says the app server does not do today.
Cloud agent-profile field gates (agentProfileSupportsSecretRefs, …Instructions, …Tools, …Skills, …Router in src/api/agent-profiles-service/profile-field-support.ts): these are Canvas-side gates on the Canvas /settings/agents page, which a locked-to-cloud Canvas does not route to. OHE's own agent profile form already edits secret refs, persona and suffix, tools, skills and MCP (agent-profile-form-state.ts). The open enterprise#1161 adds a Canvas agent-profile options endpoint.
agent_launch_additions on POST /api/v1/app-conversations: AppConversationStartRequest (#L347) drops it. The Canvas sends it only for the "run router at start" suffix, and enterprise adds that instruction itself (_maybe_append_route_at_start_instruction). Working cloud equivalent.
Agent context page: the SDK schema exposes only agent_context.load_memory there. OHE's page stores enable_memory_context and sets load_memory=True at launch (#L3523). Working cloud equivalent. The memory difference is the ohe-reimpl leaf.
Event search pagination fallback (src/api/event-service/event-service.api.ts): enterprise already accepts timestamp__gte, timestamp__lt, sort_order, page_id and exclude_full_state (event_router.py#L30). This is a stale Canvas workaround.
Conversation tag editing is local-only (allowEditTags in conversation-panel.tsx), but enterprise's PATCH accepts a tag merge patch (app_conversation_models.py#L530). Canvas-side gate.
Skill enablement: cloud uses disabled_skills as a deny-list, and the skills modal filters on the client (useSkillEnabledFilter). enabled_skills and default_profile_migrated are local-only. Working cloud equivalent.
ACP file credentials: the comment in acp-providers.ts says cloud cannot use them, but consumesFileCredentials is true on every backend (src/hooks/use-acp-credential-form.ts#L65), and enterprise binds CODEX_AUTH_JSON (codex_credential_binding.py). Stale comment.
ENABLE_ORG_MCP_SERVERS defaults off in code and in the installer, but it hides an OHE-only feature, not an integration of a Canvas feature. (ENABLE_SERVICE_ACCOUNTS moved to the tree as gap:ohe-flag/ENABLE_SERVICE_ACCOUNTS, because #19033 made a Canvas feature depend on it.)
Cloud-only features (public sharing, sandbox pause, start-task polling) and local-machine features (backend registry and health, the onboarding backend step, local git info, ACP host login status, Canvas update, Mars/DigitalOcean, automation telemetry-consent sync to the local automation service).
Carried over unchanged from the previous run, with the evidence given there: gap:ohe-settings/field/home_pinned_automations (pins are kept in localStorage on cloud), gap:ohe-settings/page/settings/meta-llm (OHE's org model router page), gap:ohe-settings/field/run_router_at_conversation_start (the org router envelope), and the flags ENABLE_MODEL_ROUTER, ENABLE_AGENT_PROFILES_PAGE and ENABLE_AGENT_CONTEXT_PAGE (the installer turns each on; enterprise#1176 also turns ENABLE_MODEL_ROUTER on in the SaaS server launch config).
Recall check
The scan found 16 of the 21 open, human-filed oss-ohe-parity issues on its own. This is the same result as the previous run: no new find and no new miss. The new leaf #19472 matches no open human-filed issue. The 6 open issues the skill filed (#1147, #1148, #1149, #1164, #1277, #1306) are left out of the count.
enterprise#74: a hole in the scan. The conversation skills endpoint does not apply disabled_skills, but the Canvas filters on the client. K3 compares field names, not server-side filtering, and the label bug is on OHE's own skills page.
enterprise#854: out of scope. It is a security check at the automation worker boundary, with no Canvas code difference.
enterprise#855: out of scope. It is about automation event integration identity in the automation service.
enterprise#859: a hole in the scan. K6 cleared ENABLE_MODEL_ROUTER because the installer turns it on, and the remaining org router adoption and launch-policy validation have no Canvas gate.
enterprise#868: out of scope. It covers automation-service start fields (hook_config, finish schema) and is parked. The Canvas launch does not set them.
This comment was created by an AI agent (OpenHands) via the daily OHE OSS gap discovery automation and is updated in place on every run.
Activity
openhands-agent commentedon Nov 11, 2026
dev-coordinator status
Inventory: #1333 (comment). 22 open gap issues with
oss-ohe-parity: 3 done, 18 blocked, 1 active (cap 8), 0 queued, 0 skipped.blockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setblockedlabel is setThis comment was posted by an AI agent (OpenHands dev-coordinator) on behalf of the user.
openhands-agent commentedon Nov 11, 2026
OSS→OHE Canvas gap inventory — 2026-11-11 03:00 UTC
Run resolution
v1.35.0(enterprise/frontend/scripts/build-agent-canvas.sh:28).containers/app/DockerfilehasARG AGENT_CANVAS_REF=main, which only the opt-ingitsource mode reads; the script default is canonical for the embedded build.docker-compose.yml:148now pinsagent-canvas:1.38.0(enterprise#1312, enterprise#1313). The Helm chart image tag is1.38.0(values.yaml#L16). Seegap:ohe-packaging/canvas-ref.7b5aa9eb6(git describe --tags:v1.38.0-17-g7b5aa9eb6, 17 commits after the v1.38.0 release commit). It wase14b76ccain the previous run. There is no v1.39.0 tag and no open release PR yet.7fd5c6b(2026-11-11, enterprise#1331), 22 commits after the previous run's6b3d21d: licensing, the legacy MCP library, the Super Admin starter modal, the rate-limit backend, two comment cleanups (enterprise#1246, enterprise#1331), the Compose pins (enterprise#1312, enterprise#1313), the 1.90.0 release and dependency bumps. Only the Compose pins touch a leaf (gap:ohe-packaging/canvas-ref). No commit touchesfrontend/src/routes/launch.tsx, the legacy secret form,conversation-card.tsx, the settings API or the feature-flag service, so every previous bump-only, not-OHE-gap and gate verdict stands.pyproject.tomlpins the SDK at1.60.1.v1.35.0..main, 157 commits: 45 shipped in v1.36.0 (#19306), 14 in v1.37.0 (#19402), 81 in v1.38.0 (#19419) and 17 unreleased after v1.38.0 (new since the previous run). This is a daily run (backfill: false), so the cloud capability scan covered only the files the new PRs touch. The K5 grep over the 17 new commits found no addedkind === "cloud"orkind === "local"branch and no newgetLockedCloudHost()gate, and no commit changes a K4 launch field or a K2 settings key. The own-copy test flagged seven touched files that also exist underenterprise/frontend/src(chat-input-actions.tsx,generic-event-message.tsx,hook-execution-event-message.tsx,conversation-websocket-context.tsx,websocket-provider-wrapper.tsx,file-diff-viewer.tsx,app-settings.tsx). All seven PRs are bump-only. The one new leaf, #19472, comes from the flag check.OpenHands/enterprisebeyond bumpingAGENT_CANVAS_REF. 33 leaves: 22 need enterprise work (14missing-integrationand 8unknown), 3 areflag-offand 8 areintentional-exclusion. 94 PRs are bump-only and 59 have nothing for OHE.fallback. Linear OSS-14542 has no typology artifact in its thread.OpenHands/enterprise#1333instead ofextensions-private#99. Nothing was posted on fix: Add anti-clickjacking security headers (X-Frame-Options / CSP frame-ancestors) #99 or onsaas-deploy#1847.enterprise#1333had no inventory comment yet (only a coordinator status comment), so this run used the latest inventory comment onsaas-deploy#1847as the baseline, read-only: 2026-11-10 09:09 UTC, pinv1.35.0. This comment is the first inventory onenterprise#1333; later runs edit it in place and use its body as the baseline.feature_flags.enable_service_accountsis true, and that flag defaults off. It joins theENABLE_SERVICE_ACCOUNTSflag leaf. Flag-off leaves get no new issue by rule.reported: ambiguous → already-reported(enterprise#1306 was filed in the previous run as a possible duplicate and carries the parity marker, so it is now an exact match) andworked: not-started → assigned(enterprise#1306 was assigned tojuanmichelinion 2026-11-10 10:02 UTC). The leaf moves fromreported: ambiguoustoreported: already-reported.AGENT_CANVAS_REF; enterprise#1262 keeps the default atv1.35.0.juanmichelinistill holds [RFC] Bring Agent Canvas Apps to Enterprise (as beta, default off) #611, [OSS→OHE parity] Decide and specify hosted worktree isolation selection #851, [OSS→OHE parity] Decide remote workspace reuse and isolation outcomes for Canvas #857, [OSS→OHE parity] Record hosted analytics consent policy and Canvas enforcement contract #858, [OSS→OHE parity] [Design/validation] Hosted subscription-auth ownership and lifecycle #861, [OSS→OHE parity] [Design/validation] Memory toggle, terminal checkpoints and two-tier durability #863, [OSS→OHE parity] Atomic hosted MCP mutations and truthful sandbox probe capabilities #864, [OSS→OHE parity] [Design/implementation] Durable tenant installed-plugin lifecycle #865, [OSS→OHE parity] Decide what OHE does with the Settings → Runtime default #1147 and [OSS→OHE parity] [Investigate] Show the LLM credit balance in the Canvas usage drawer #1164, plus [OSS→OHE parity] Handle automation-install /launch links (mode=automation) in OHE #1277 (assigned 2026-11-09). All are open. [OSS→OHE parity] Start a conversation from a message-only /launch link in OHE #1306 is now assigned too (see the changed leaf above).launch.tsxstill returnsno_pluginsfor a link without a plugin.filing-mode: file,filing-cap: 30, writes asopenhands-agent. 0 issues filed, 0 labels added. 34 labeled issues loaded, any state; none is closed as a duplicate of a leaf. Everymissing-integrationandunknownleaf has an exact-match enterprise issue that carriesoss-ohe-parity. The threeflag-offleaves get no new issue by rule. Noohe-principles.mdanchor was cited this run.ghqueries) usedGITHUB_TOKEN. Only the issue and this comment are written asopenhands-agent.Gap tree
missing-integration (14)
reported: already-reported (14)
worked: in-flight (6)
src/api/profiles-service/profiles-service.api.ts,#L162returns no verdict on cloud; shipped in v1.14.0). Key:gap:ohe-settings/control/settings/llm/pre-save-validation. Boundary: a validate endpoint next to the profile routes inopenhands/app_server/settings/settings_router.py, plus a pre-save check on OHE's LLM page. Issue: enterprise#860. Evidence: open, approved enterprise#1234 addsPOST /api/v1/settings/profiles/{name}/validateinsettings_router.pyand the pre-save check on OHE's LLM page.src/hooks/query/use-workspace-file-discovery.ts,#L22, S1; shipped in v1.25.0). Key:gap:canvas-cloud/workspace-file-discovery. Boundary: discovery options on the app-conversationfilesendpoint. Issue: enterprise#853. Evidence: open enterprise#1169 bounds the files proxy and adds persisted discovery options.src/components/features/settings/secrets-settings/secret-form.tsx; shipped in v1.33.0). Boundary: OHE's ownenterprise/frontend/src/components/features/settings/secrets-settings/secret-form.tsx, which is still a plain<textarea>. Issue: enterprise#1148. Evidence: open enterprise#1166 masks the value insecret-form.tsxand the service-account copy.noopener, http(s) only (conversation-card.tsx,vscode-url-helper.ts; shipped in v1.35.0). Boundary: OHE's ownconversation-card.tsx. Issue: enterprise#1149. Evidence: open, approved enterprise#1165 adds thenoopenerand http(s) check inconversation-card.tsxandvscode-url-helper.ts.gap:canvas-cloud/conversation-fork— Branch from here is refused on cloud (agent-server-conversation-service.api.ts#L1311,user-assistant-event-message.tsx#L73, S1; also at the pin). Boundary: an enterprise-managed fork endpoint under/api/v1/app-conversations. Issue: enterprise#850. Evidence: open, approved enterprise#1232 addsPOST /api/v1/app-conversations/{conversation_id}/fork(owner only, history copied into the app server).gap:ohe-launch/client-tools— the local launch registerscanvas_ui,launch_child_conversationandrequest_secretfor every OpenHands conversation (agent-server-adapter.ts#L1217). The cloud launch sendsclient_toolsonly in automation setup, and never sendsrequest_secret(agent-server-conversation-service.api.ts#L638; also at the pin). Boundary: live secret attach forrequest_secreton cloud conversations (AppConversationStartRequest.client_toolsexists). Issue: enterprise#761. Evidence: open enterprise#1167 forwardsclient_toolsand adds live secret attach onAppConversationStartRequest.worked: assigned (8)
src/routes/runtime-settings.tsx,src/api/agent-server-adapter.ts; shipped in v1.34.0, now behind the pin). The K4 runtime and container options are the same feature. Boundary: decide the OHE runtime default, then a route and page inenterprise/frontend/src/constants/settings-nav.tsx. Issue: enterprise#1147. Evidence: enterprise#1147 is assigned tojuanmichelini(assigned 2026-11-06)./launchinstall:mode=automationcreates an automation throughPOST /api/automation/v1/plugin-spec(src/routes/launch.tsx,src/components/features/launch/plugin-launch-modal.tsx,src/api/automation-service/automation-service.api.ts; shipped in v1.38.0 #19419). OHE serves/launchfrom its own legacy route (frontend/src/routes.ts#L27), which has nomodehandling: it starts a conversation with the plugin (launch.tsx#L150). The legacyfrontend/has no automation API client. A bump delivers the mode only at/canvas/launch. The sibling #18734 (message-only links) hits the same route. Boundary: forward/launch?…&mode=automationto/canvas/launchinenterprise/frontend/src/routes/launch.tsx(the alternative is a port into the legacy route).needs product decision: forward or port; the install needsmanage_automations(owner and admin only). Issue: enterprise#1277. Evidence: enterprise#1277 is assigned tojuanmichelini(assigned 2026-11-09 10:02 UTC); no open enterprise PR handlesmode=automation.automation-safe: needs-human-decision./launchlinks:?message=…with no plugin shows a confirmation modal and starts a conversation (src/routes/launch.tsx; shipped in v1.38.0 #19419). OHE serves/launchfrom its own legacy route (frontend/src/routes.ts#L28), which still returnsno_pluginswhen no plugin is given, even with amessage(launch.tsx#L82), so a message-only link shows an error. A bump delivers the feature only at/canvas/launch. Boundary: accept a message-only link inenterprise/frontend/src/routes/launch.tsx, or forward/launchto/canvas/launchtogether with #18699 (same route, same decision).needs product decision: forward or port. Scope: personal. Issue: enterprise#1306 (filed in the previous run as a possible duplicate of enterprise#1277; that issue coversmode=automation, not message-only links). Evidence: enterprise#1306 is assigned tojuanmichelini(assigned 2026-11-10); no open PR.automation-safe: needs-human-decision. (changed: reported ambiguous → already-reported, worked not-started → assigned)gap:canvas-cloud/apps— the Apps page is hidden and refused on cloud (extensions-navigation.tsx#L25,canvas-extensions.tsx#L54, S1; also at the pin). Boundary: an enterprise Canvas extensions store and API.needs product decision: beta and default off. Issue: enterprise#611. Evidence: enterprise#611 is assigned tojuanmichelini(assigned 2026-11-06).gap:canvas-cloud/plugins— the Plugins page is hidden on cloud: the catalog is empty and install, enable, uninstall and refresh throw (plugins-management-service.ts#L71,plugins-service.ts#L73, S1/S2; also at the pin). Enterprise has no plugin routes. Boundary: a per-user installed-plugin store and API. Issue: enterprise#865. Evidence: enterprise#865 is assigned tojuanmichelini(assigned 2026-11-06).gap:ohe-launch/workspace— the local launcher picks a workspace for a new conversation. The cloud launcher offers only a repository (home-chat-launcher.tsx#L87; also at the pin).AppConversationStartRequesthas no workspace field, onlysandbox_id. Boundary: a hosted workspace reuse choice onAppConversationStartRequest.needs product decision. Issue: enterprise#857. Evidence: enterprise#857 is assigned tojuanmichelini(assigned 2026-11-06).gap:ohe-launch/worktree— the local launch setsworktreeand a workspace mode (new_worktree,docker_container) (agent-server-conversation-service.api.ts#L671,agent-server-adapter.ts#L1240; also at the pin). The cloud launch cannot carry either. Boundary: an isolation selection onAppConversationStartRequest.needs product decision. Issue: enterprise#851. Evidence: enterprise#851 is assigned tojuanmichelini(assigned 2026-11-06).gap:ohe-settings/control/settings/llm/subscription-sign-in— ChatGPT subscription sign-in on the LLM page talks only to the local agent server (llm-subscription-service.ts#L83,llm-settings.tsx#L438; introduced by197588cc8, which is imported history with no PR in this repo). OHE's LLM page has no sign-in. Boundary: hosted subscription-auth ownership and storage.needs product decision. Issue: enterprise#861. Evidence: enterprise#861 is assigned tojuanmichelini(assigned 2026-11-06).unknown (8)
reported: already-reported (8)
worked: in-flight (4)
gap:canvas-cloud/file-transport— the cloud file read decodes content as UTF-8 and guesses binaries "fallibly" (use-workspace-file-content.ts#L214, S3; enterpriseapp_conversation_router.py#L1400returnsstrand''on errors). Boundary: a byte-preserving, MIME-aware/fileresponse. Issue: enterprise#852. Evidence: open, approved enterprise#1233 addsGET /app-conversations/{id}/file/download, which returns the bytes unchanged with a MIME type and typed error codes.gap:canvas-cloud/plan-file-path— the cloud plan read hardcodes/workspace/project/.agents_tmp/PLAN.md(agent-server-conversation-service.api.ts#L1046, S4; also at the pin). Boundary: report the planner artifact path in the app-conversation metadata. Issue: enterprise#849. Evidence: open enterprise#1168 adds a sharedcompute_plan_path()and exposes the artifact path through the app-conversation contract.gap:canvas-cloud/secret-save— on cloud, one secret save is split acrossPUT /api/v1/secrets/{name}andPOST /api/v1/secrets(secrets-service.api.ts#L63, S3; also at the pin). Boundary: an atomic rename-and-value secret mutation. Issue: enterprise#862. Evidence: open, approved enterprise#1231 letsPUT /api/v1/secrets/{name}take avalue, so the rename and the value are written in onestore()call.gap:ohe-packaging/canvas-ref— the Canvas pins disagree.frontend/scripts/build-agent-canvas.sh(#L28) pinsv1.35.0.docker-compose.yml(#L148) now pins1.38.0(enterprise#1312 and enterprise#1313, merged since the previous run; it was1.37.0). The chart default image tag is1.38.0(agent-canvas/values.yaml#L16). A Replicated install serves/canvasfrom the chart image (replicated/openhands.yaml,agent-canvas.enabled: true), so it already carries every PR through v1.38.0. The Compose stack now matches the chart. The embedded build still carries v1.35.0. Boundary: decide which artifact each install mode serves and whether the embedded-build pin follows the chart.needs-live-validation: true. Issue: enterprise#856. Evidence: open enterprise#1262 (not a draft, now approved) cites the gap key and closes [OSS→OHE parity] Verify supported embedded Canvas build and packaging selection #856. It records and reports the served build and documents each install mode, but does not bump the embedded-build pin, so that decision is still open.worked: assigned (4)
src/hooks/query/use-llm-balance.ts,#L22, S1; shipped in v1.13.0). Key:gap:canvas-cloud/llm-balance. Boundary: find out whether the sandbox agent server's/api/llm/balancealready serves OHE (then the fix is in the Canvas only), or whether enterprise needs a route. Issue: enterprise#1164. Evidence: enterprise#1164 is assigned tojuanmichelini(assigned 2026-11-06).gap:canvas-cloud/mcp-server-mutations— on cloud, each MCP server add, edit and delete is a GET plus a full-catalog POST (settings-service.api.ts#L715, S3; also at the pin). Boundary: per-server MCP mutation routes in the settings API. Issue: enterprise#864. Evidence: enterprise#864 is assigned tojuanmichelini(assigned 2026-11-06).gap:canvas-cloud/mcp-stdio-probe— on cloud, the Test connection for STDIO servers is synthetic, and saving a STDIO server is skipped (custom-server-editor.tsx#L72,install-server-modal.tsx#L209, S2; also at the pin). Boundary: a sandbox-side probe capability inopenhands/app_server/mcp/mcp_test_router.py. Issue: enterprise#864. Evidence: enterprise#864 is assigned tojuanmichelini(assigned 2026-11-06).gap:ohe-reimpl/memory-terminal-writes— enterprise's memory callback "only detects changes made via the file_editor tool" (memory_change_callback_processor.py#L8). The local agent also keeps memory that it writes from the terminal. Boundary: a PostToolUse hook or a session-end diff. Issue: enterprise#863. Evidence: enterprise#863 is assigned tojuanmichelini(assigned 2026-11-06).flag-off (3)
reported: new (3)
worked: not-started (3)
src/components/features/setup-guide/use-super-admin-setup-guide.ts,#L83; shipped in v1.26.0). Key:gap:ohe-flag/ENABLE_SUPER_ADMIN. The guide reads and writes/api/admin/setup-state, which enterprise mounts only whenENABLE_SUPER_ADMINis set (saas_server.py#L226;_env_flag_enabled('ENABLE_SUPER_ADMIN')defaults off). The installer default is also off:super_admin_dashboard_enableddefaults to"0"(config.yaml#L1681). This is a rollout decision.src/hooks/query/use-service-accounts.ts,#L27, S1: the service-account picker and the Run as control stay off unlessfeature_flags.enable_service_accountsis true; shipped in v1.36.0). Key:gap:ohe-flag/ENABLE_SERVICE_ACCOUNTS. Enterprise has the integration.GET /api/organizations/{org_id}/service-accountstakeslimitandpage_idand returnsitemsandnext_page_id(service_accounts.py#L183), each item hasid,org_id,nameandis_disabled(org_models.py#L589), owners and admins holdmanage_service_accounts(authorization.py#L115), and the web client config carries the flag (default_web_client_config_injector.py#L266). The flag defaults off in code (feature_flag_service.py#L71), and the installer has no option for it (replicated/config.yamlandreplicated/openhands.yamldo not mention it), so only a super admin who switches it on in the instance page (use-super-admin-mutations.ts#L207) gets the feature. Therun-asroute itself belongs to the automation service (its migration036_add_automation_run_as.py), not to an enterprise route. This is a rollout decision. No issue tracks it: OSS #19291 is the closed Canvas request, and enterprise#1090 is a different gap (follow-up messages on service-account automation conversations).src/routes/automations-list.tsx; unreleased, after v1.38.0). Key:gap:ohe-flag/ENABLE_SERVICE_ACCOUNTS. The option and therun_as=servicefilter show only when the cloud config reportsisServiceAccountsEnabled, the same flag as the #19033 leaf above, so a bump alone leaves it hidden on OHE. The enterprise evidence is the one on that leaf. Therun_asfilter belongs to the automation service, not to an enterprise route. This is a rollout decision. No issue tracks it. (new)intentional-exclusion (8)
reported: new (6)
worked: not-started (6)
gap:ohe-gate/acp-agent-settings-flag—enterprise/frontend/src/routes/agent-settings.tsxgates the ACP agent settings onenable_acp(supported: flag on).gap:ohe-gate/automations-redirect—enterprise/frontend/src/routes/automations-redirect.tsxredirects/automationsinto the Canvas (partial: conditional).gap:ohe-gate/automations-sidebar-flag—enterprise/frontend/src/components/features/sidebar/sidebar.tsxgates the automations nav entry onenable_automations(supported: flag on).gap:ohe-gate/canvas-cross-app-redirect—enterprise/frontend/src/utils/cross-app-redirect.tsconditions the cross-app handoff (partial: conditional).gap:ohe-gate/onboarding-flag—enterprise/frontend/src/components/features/guards/onboarding-guard.tsxgates onboarding onenable_onboarding(partial: conditional).gap:ohe-gate/root-redirect—enterprise/frontend/src/routes/root-landing.tsxhard-redirects/to/canvas(location.replace).reported: already-reported (2)
worked: not-started (1)
gap:ohe-gate/acp-provider-allowlist—enterprise/openhands/app_server/acp_providers.py(#L18,SURFACED_ACP_PROVIDERS) offers onlyclaude-code,codexandgemini-cli. The Canvas hides OpenCode and Pi on cloud to match (acp-providers.ts#L183; shipped in v1.27.0). The allowlist was decided in enterprise#315 (closed as completed).worked: assigned (1)
gap:canvas-cloud/analytics-consent— on cloud the analytics switch is forced on and disabled (app-settings.tsx#L226, S1). OHE's own app settings page does the same withisSaasMode(app-settings.tsx#L270), so this is a hosted consent policy, not a missing integration. Issue: enterprise#858. Evidence: enterprise#858 is assigned tojuanmichelini(assigned 2026-11-06).Issues
oss-ohe-parity): #16311 → enterprise#1164, #16417 → enterprise#860, #17869 → enterprise#853, #18436 → enterprise#1147, #18699 → enterprise#1277 (filed in the previous run, now linked; it hasoss-ohe-parity), #18734 → enterprise#1306 (filed in the previous run as a possible duplicate; now an exact marker match), #18870 → enterprise#1148, #19229 → enterprise#1149,canvas-cloud/apps→ enterprise#611,canvas-cloud/conversation-fork→ enterprise#850,canvas-cloud/file-transport→ enterprise#852,canvas-cloud/mcp-server-mutationsandcanvas-cloud/mcp-stdio-probe→ enterprise#864,canvas-cloud/plan-file-path→ enterprise#849,canvas-cloud/plugins→ enterprise#865,canvas-cloud/secret-save→ enterprise#862,ohe-launch/client-tools→ enterprise#761,ohe-launch/workspace→ enterprise#857,ohe-launch/worktree→ enterprise#851,ohe-packaging/canvas-ref→ enterprise#856 (a high match: it cites the same three packaging files; enterprise#1262 closes it),ohe-reimpl/memory-terminal-writes→ enterprise#863,ohe-settings/control/settings/llm/subscription-sign-in→ enterprise#861intentional-exclusionleaves. 3flag-offleaves (ENABLE_SUPER_ADMIN, andENABLE_SERVICE_ACCOUNTSfor #19033 and #19472): the rule never files a new issue for a flag, and no issue matches any of them exactly. 10 leaves are in flight as open PRs (enterprise#1165 to enterprise#1169, enterprise#1231 to enterprise#1234, and enterprise#1262); they already link their issues. Also not filed: the bump-only PRs and the## Not OHE gapsentries.Bump-only (94)
Bumping
AGENT_CANVAS_REFdelivers these PRs. No other enterprise change is needed. Open pin-bump PR: none (enterprise#1262 keeps the default atv1.35.0). A bump to v1.38.0 delivers the three shipped buckets today; the Helm chart image already runs1.38.0(seegap:ohe-packaging/canvas-ref). The unreleased bucket needs the OSS v1.39.0 tag first, which is an OSS release chore, not enterprise work.client_tools, which is thegap:ohe-launch/client-toolsleaf, and the PR adds no request field), #19340 (Bitbucket Data Center and Azure DevOps repository picker in template setup; enterprise already reports the connection host inprovider_tokens_set,settings_router.py#L282), #19342 (zustand 5.0.16), #19344 (ships the Data Center templates with extensions 0.39.0; a package bump), #19347 (templatereposare sent only for providers the automation service clones; automation service capability, no enterprise route), #19349 (lists GitHub repositories directly when the token has no installations; existing endpoints), #19350 (Connect Git setup step; thegit_providerfield in/api/admin/setup-statelanded with enterprise#1199), #19351 (no error toast when history ends with a hook event; Canvas event handling), #19352 (self-hosted GitHub templates guide to MCP or token setup; reads the existing secrets search), #19355 (Data Center templates use the repository picker, with extensions 0.40.0), #19358 (removes unused components and keys; no behavior change), #19370 (setup assistant stays on the form and saves drafts on cloud: uses tag merge-patch (app_conversation_models.py#L530) and the declaredsystem_message_suffix; the form tool still needs theclient_toolsleaf), #19392, #19393 (@openhands/extensions0.41.0)@heroui/react3.2.4, a Canvas build dependency), #17730 (Light+ and Solarized contrast pass; OHE's legacyfrontend/has no such themes), #18520, #18533 (budget meter fills; the cap comes from the sandbox agent-server conversation info (max_budget_per_runon the conversation URL), no enterprise route. OHE's ownbudget-display.tsxsits under the legacy/conversations/:idpage, which server-generated links no longer target (they use/canvas/conversations/…)), #19228 (home route-at-start suppression moves from a store flag to a keyed module variable; thesuppressRouterAtStartrequest field already existed, no new request field), #19262, #19307 (edit rights for org admins and owners; usesmanage_automations, which enterprise defines (authorization.py#L112)), #19330 (export and import carry the script bundle; automation service API), #19384 (onboarding saves an ACP pick to its own profile; existing profile routes, names checked by the SDK pattern), #19397 (launch view keeps focus when the user navigated away; Canvas SPA only), #19407 (tanstack deps), #19408 (react-router deps), #19421 (prompt and plugin presets can run from an agent profile; the picker follows the automation service capabilitypresetAgentProfiles, no enterprise route), #19437, #19438, #19445, #19446, #19447, #19451 (automation context for help chats; declared fields only; the form tool still needs theclient_toolsleaf), #19453 (executable plugin config in automation help; automation service plugin-spec API), #19454 (i18next group), #19455 (framer-motion 14.9.0), #19457 (vite 8.3.5, a build dependency of the Canvas bundle), #19458 (lucide-react 1.65.0), #19470 (OpenHands Enterprise license banner: it callsGET /api/license/status, which enterprise serves (license.py#L49) with every field the banner reads, delivered by enterprise#1241 and enterprise#1283), #19471 (hides the agent profile switch when a self-hosted instance turns Agent Profiles off; it readsfeature_flags.enable_agent_profiles_pageanddeployment_mode, which enterprise's web client config already carries (default_web_client_config_injector.py#L262), and enterprise#1260 did the launch-side half; OHE's ownchat-input-actions.tsxhas no profile switch), #19478 (Bitbucket Data Center filter chip label; Canvas UI only), #19486, #19491, #19492 (the last three name Tailwind tokens for the file-drop art, markdown code padding and scroll fades; the CSS output is unchanged, so OHE's owndrag-over.tsx,code.tsx,horizontal-scroll-fade.tsxandmarkdown-table-scroll.tsxneed nothing), #19493 (spacing-scale aliases; no behavior change), #19501 (diff viewer releases editor models on teardown), #19506 (i18next group), #19508 (lucide-react 1.66.0), #19511 (posthog-js 1.444.0), #19518 (wide-table fades in message bubbles; Canvas CSS), #19530 (names existing background and on-accent colors; no behavior change), #19533 (names letter-spacing metrics; no behavior change), #19534 (names badge and inset-shadow recipes; no behavior change), #19536 (tanstack deps), #19537 (i18next group), #19538 (uuid 14.0.3), #19540 (react-syntax-highlighter 16.1.2), #19546 (the composer Stop interrupts the agent instead of pausing the Cloud sandbox: the Canvas calls the sandbox agent-server's/interruptthroughconversationUrl, no enterprise route; OHE's legacyconversation-mutation-utils.tsalready has bothinterruptV1ConversationandpauseV1ConversationSandbox), #19561 (context meters adopt the inline-style lint rule; no behavior change), #19566 (names commit viewer layout values; no behavior change), #19568 (reconciles the active LLM profile with the backend model; uses browser-side conversation metadata, no enterprise route), #19571 (names Files tab scroll and discovery height recipes; no behavior change), #19578 (names the shared dark Git control border; no behavior change)@heroui/react), #19589 (react-icons), #19590 (mdast-util-from-markdown), #19595 (Paper theme; OHE's ownapp-settings.tsxhas no theme picker), #19603 (resume timestamps read as UTC), #19619 (hides Stop hook feedback in the Canvas chat; OHE'shook-execution-event-message.tsxbelongs to its own legacy conversation view, a separate implementation), #19623 (hover timestamp position), #19630 (Event Key dropdown), #19633 (shared agent-profile availability hook; OHE's ownchat-input-actions.tsxhas no profile switch)Not OHE gaps
docs(verify-openhands)feature-map edits under.agents/skills. Docs only; nothing ships in the bundle.node:26.10.0stage (Dockerfile#L27), so nothing changes for OHE.@eslint/js,electron-builderfor the desktop app) and a dashboard test fixture. None changes the web bundle.@types/node, eslint, testing group,globals,lint-staged,typescript7.0.2). #19541 raiseselectron, which only the OSS desktop app uses. They do not ship in the bundle.chore(main): releasePRs for v1.36.0, v1.37.0 and v1.38.0. Release chores, nothing for OHE to receive..pr/. Repository housekeeping.1.60.1(pyproject.toml).src/components/features/chat/resolved-conversation-banner.tsx; shipped in v1.38.0 #19419). It renders only whenbackend.kind === "local"and reads aresolved=user|autoconversation tag. The server half is the Agent Server projects API, software-agent-sdk#6602, which is still an open PR (checked 2026-11-10). No releasedopenhands-agent-servercan write the tag while that PR is open (the newest release is1.61.0; enterprise still pins1.60.1). A bump delivers a banner that cannot show on any enterprise backend, and there is no enterprise code to write until the SDK ships Projects. Revisit when software-agent-sdk#6602 merges: enterprise then needs to carry the runtime tag into its own conversation tags, which the Canvas comment says the app server does not do today.agentProfileSupportsSecretRefs,…Instructions,…Tools,…Skills,…Routerinsrc/api/agent-profiles-service/profile-field-support.ts): these are Canvas-side gates on the Canvas/settings/agentspage, which a locked-to-cloud Canvas does not route to. OHE's own agent profile form already edits secret refs, persona and suffix, tools, skills and MCP (agent-profile-form-state.ts). The open enterprise#1161 adds a Canvas agent-profile options endpoint.agent_launch_additionsonPOST /api/v1/app-conversations:AppConversationStartRequest(#L347) drops it. The Canvas sends it only for the "run router at start" suffix, and enterprise adds that instruction itself (_maybe_append_route_at_start_instruction). Working cloud equivalent.agent_context.load_memorythere. OHE's page storesenable_memory_contextand setsload_memory=Trueat launch (#L3523). Working cloud equivalent. The memory difference is theohe-reimplleaf.src/api/event-service/event-service.api.ts): enterprise already acceptstimestamp__gte,timestamp__lt,sort_order,page_idandexclude_full_state(event_router.py#L30). This is a stale Canvas workaround.allowEditTagsinconversation-panel.tsx), but enterprise's PATCH accepts a tag merge patch (app_conversation_models.py#L530). Canvas-side gate.disabled_skillsas a deny-list, and the skills modal filters on the client (useSkillEnabledFilter).enabled_skillsanddefault_profile_migratedare local-only. Working cloud equivalent.acp-providers.tssays cloud cannot use them, butconsumesFileCredentialsistrueon every backend (src/hooks/use-acp-credential-form.ts#L65), and enterprise bindsCODEX_AUTH_JSON(codex_credential_binding.py). Stale comment.ENABLE_ORG_MCP_SERVERSdefaults off in code and in the installer, but it hides an OHE-only feature, not an integration of a Canvas feature. (ENABLE_SERVICE_ACCOUNTSmoved to the tree asgap:ohe-flag/ENABLE_SERVICE_ACCOUNTS, because #19033 made a Canvas feature depend on it.)gap:ohe-settings/field/home_pinned_automations(pins are kept in localStorage on cloud),gap:ohe-settings/page/settings/meta-llm(OHE's org model router page),gap:ohe-settings/field/run_router_at_conversation_start(the org router envelope), and the flagsENABLE_MODEL_ROUTER,ENABLE_AGENT_PROFILES_PAGEandENABLE_AGENT_CONTEXT_PAGE(the installer turns each on; enterprise#1176 also turnsENABLE_MODEL_ROUTERon in the SaaS server launch config).Recall check
The scan found 16 of the 21 open, human-filed
oss-ohe-parityissues on its own. This is the same result as the previous run: no new find and no new miss. The new leaf #19472 matches no open human-filed issue. The 6 open issues the skill filed (#1147, #1148, #1149, #1164, #1277, #1306) are left out of the count.canvas-cloud/apps, Support client_tools forwarding and live secret attach for cloud conversations (request_secret) #761 ←ohe-launch/client-tools, [OSS→OHE parity] Resolve cwd and plan artifact consistently for grouped/provider workspaces #849 ←canvas-cloud/plan-file-path, [OSS→OHE parity] Managed event-index conversation forks through Enterprise lifecycle #850 ←canvas-cloud/conversation-fork, [OSS→OHE parity] Decide and specify hosted worktree isolation selection #851 ←ohe-launch/worktree, [OSS→OHE parity] Preserve file bytes, MIME and errors through tenant file transport #852 ←canvas-cloud/file-transport, [OSS→OHE parity] Bounded tenant file discovery options and truthful listing results #853 ← #17869, [OSS→OHE parity] Verify supported embedded Canvas build and packaging selection #856 ←ohe-packaging/canvas-ref, [OSS→OHE parity] Decide remote workspace reuse and isolation outcomes for Canvas #857 ←ohe-launch/workspace, [OSS→OHE parity] Record hosted analytics consent policy and Canvas enforcement contract #858 ←canvas-cloud/analytics-consent, [OSS→OHE parity] Bounded hosted pre-save LLM connection validation #860 ← #16417, [OSS→OHE parity] [Design/validation] Hosted subscription-auth ownership and lifecycle #861 ←llm/subscription-sign-in, [OSS→OHE parity] Atomic owned-secret mutation, overwrite consent and edit capabilities #862 ←canvas-cloud/secret-save, [OSS→OHE parity] [Design/validation] Memory toggle, terminal checkpoints and two-tier durability #863 ←ohe-reimpl/memory-terminal-writes, [OSS→OHE parity] Atomic hosted MCP mutations and truthful sandbox probe capabilities #864 ←canvas-cloud/mcp-server-mutationsandmcp-stdio-probe, [OSS→OHE parity] [Design/implementation] Durable tenant installed-plugin lifecycle #865 ←canvas-cloud/pluginsdisabled_skills, but the Canvas filters on the client. K3 compares field names, not server-side filtering, and the label bug is on OHE's own skills page.ENABLE_MODEL_ROUTERbecause the installer turns it on, and the remaining org router adoption and launch-policy validation have no Canvas gate.hook_config, finish schema) and is parked. The Canvas launch does not set them.This comment was created by an AI agent (OpenHands) via the daily OHE OSS gap discovery automation and is updated in place on every run.