Classic confinement request for cortex-ide

Hi,

I’d like to request classic confinement for cortex-ide (name already registered to my account).

What it is: Cortex is an AI-native desktop IDE — a code editor with an integrated terminal, git workflow, language servers, semantic code search, and an AI agent that edits files and runs commands on the user’s behalf. It is built with PyQt6 + Qt WebEngine and currently ships as .deb and .rpm from https://cortex-ide.app/

Why strict confinement does not work

Cortex is a development tool in the same category as the already-classic code, pycharm-*, intellij-idea-* and sublime-text snaps, and it needs classic for the same reasons:

  1. It executes the user’s own toolchains. The agent and the build/run features invoke whatever the developer has installed — git, bash, python, node, make, project-local virtualenvs and node_modules binaries. These are arbitrary executables at arbitrary paths on the host; they cannot be enumerated ahead of time or bundled.

  2. It opens arbitrary project directories. Developers keep code outside $HOME — on secondary drives, mounted volumes, /srv, /opt, network shares. The home interface covers only $HOME, and removable-media only /media, so neither is sufficient for an editor that must open any path the user chooses.

  3. It provides a real PTY terminal. src/ui/components/xterm_terminal.py allocates a POSIX pty and runs the user’s login shell, which then runs anything the user types — the same unrestricted execution a terminal emulator needs.

  4. It runs language servers and MCP tool servers as child processes. pyright, typescript-language-server, bash-language-server, plus user-configured MCP servers, are spawned as subprocesses and must see the same filesystem the user’s project lives on.

Under strict confinement the editor could not open most users’ code, the terminal could not run their tools, and the agent could not perform the file and command operations that are the product’s core function.

Packaging notes

  • Base: core26, grade: stable, confinement: classic
  • Single amd64 build; payload is a self-contained PyInstaller bundle installed to $SNAP/opt/cortex
  • The bundle ships its own Qt/Chromium libraries and resolves them via PyInstaller’s $ORIGIN mechanism, so the part is deliberately built without enable-patchelf (injecting an RPATH into the base snap’s lib dir breaks PyInstaller’s bootstrap)
  • Verified installing and running from a local --dangerous --classic install on Ubuntu 26.04

Happy to answer any questions or make changes the review needs.

Thanks!

Please see the template for classic requests here:

You should also read:

https://snapcraft.io/docs/reference/administration/reviewing-classic-confinement-snaps/

name: cortex-ide

description: Cortex is an AI-native desktop IDE — a code editor with an integrated terminal, git workflow, language servers, semantic code search, and an AI agent that edits files and runs commands on the developer’s behalf. It is built with PyQt6 + Qt WebEngine and already ships as .deb and .rpm from

https://cortex-ide.app/

snapcraft: Not publicly available (private source). The full snapcraft.yaml is inlined at the bottom of this post.

upstream: PRIVATE

upstream-relation: I am the author and sole publisher of Cortex. The snap is built from the same source tree and the same PyInstaller payload as the official .deb/.rpm releases on cortex-ide.app.

supported-category: IDEs, and “AI agent/assistant that runs arbitrary user-directed code and needs to reach files and programs that aren’t known at build time” — Cortex is both: an IDE whose central feature is an AI agent that runs user-directed code.

reasoning:

Mapping to the criteria in the review process doc:

  1. Running arbitrary commands (listed criterion: “running arbitrary command, esp if user-configurable such as a developer tool”). The agent and the run/build features invoke whatever the developer has installed — git, bash, python, node, make, project-local virtualenvs and node_modules binaries. Which binaries these are is decided by the user’s project and machine, not by us, so they are unknown at build time and cannot be bundled or enumerated.

  2. Access to files and programs on the host outside the snap’s runtime (listed criterion: “access to files on the host outside the snap’s runtime”). The agent reads and edits the toolchains and interpreters it drives — resolving the active Python interpreter, reading installed package metadata, following imports into site-packages under /usr — to produce correct edits and diagnostics.

  3. A real PTY terminal. src/ui/components/xterm_terminal.py allocates a POSIX pty and runs the user’s login shell, which then runs anything the user types — the same unrestricted execution the “terminal emulators, multiplexers and shells” category covers.

  4. Language servers and MCP tool servers as child processes. pyright, typescript-language-server, bash-language-server and user-configured MCP servers are spawned as subprocesses and must resolve the same interpreters and toolchains as point 1.

To be explicit about the “unsupported” list: this request is not about difficulty making strict work, and not about avoiding snap size — the snap already bundles its own Qt/Chromium runtime. It is about executing user-designated programs that cannot be known at build time.

  • I understand that strict confinement is generally preferred over classic.
  • I’ve tried the existing interfaces to make the snap work under strict confinement.

Packaging notes

  • base: core26, grade: stable, confinement: classic, amd64 only
  • Payload is a self-contained PyInstaller onedir installed to $SNAP/opt/cortex
  • The part is deliberately built without enable-patchelf: the injected RPATH=/snap/core26/current/lib/x86_64-linux-gnu overrides PyInstaller’s $ORIGIN-relative resolution and breaks its bootstrap
  • Verified working from a local --dangerous --classic install on Ubuntu 26.04
  • Revision 1 is uploaded and currently held in manual review

snapcraft.yaml

name: cortex-ide
title: Cortex
base: core26
version: '3.0.22'
summary: AI-powered desktop coding IDE
description: |
  Cortex is an AI-native desktop code editor and IDE. It opens your local
  projects, edits files, runs terminal commands, indexes and searches your
  codebase, and drives an agentic coding loop with multi-provider LLM
  routing (bring your own API key). Includes an integrated terminal,
  Monaco and native editors, git workflow, semantic search and MCP tools.

grade: stable
confinement: classic
website: https://cortex-ide.app/
contact: https://cortex-ide.app/
icon: snap/gui/cortex-ide.png

platforms:
  amd64:

apps:
  cortex-ide:
    command: bin/cortex-ide
    desktop: share/applications/cortex-ide.desktop

parts:
  desktop-entry:
    plugin: dump
    source: gui
    organize:
      cortex-ide.desktop: share/applications/cortex-ide.desktop
      cortex-ide.png: share/icons/hicolor/256x256/apps/cortex-ide.png

  cortex:
    plugin: dump
    source: payload
    # NO enable-patchelf. snapcraft's classic patching injects
    #   RPATH=/snap/core26/current/lib/x86_64-linux-gnu
    # into every ELF, which overrides PyInstaller's own $ORIGIN-relative
    # resolution — the bootstrap then cannot find its bundled libs and dies
    # with "Failed to execute script 'main'". The payload is self-contained
    # and already resolves its own libraries, so it must be shipped unpatched.
    organize:
      '*': opt/cortex/

  launcher:
    plugin: nil
    after: [cortex]
    override-build: |
      set -eux
      install -d -m 0755 "$CRAFT_PART_INSTALL/bin"
      cat > "$CRAFT_PART_INSTALL/bin/cortex-ide" <<'SH'
      #!/bin/sh
      # Mirrors build/linux/launcher.sh: the app resolves resources relative to
      # its own directory, so cd there before exec.
      APP_DIR="$SNAP/opt/cortex"
      cd "$APP_DIR" || exit 1
      exec "$APP_DIR/Cortex" "$@"
      SH
      chmod 0755 "$CRAFT_PART_INSTALL/bin/cortex-ide"

This request has been added to the queue for review by the @reviewers team.