Skip to content

Give code cells the Quarto 1 execute environment (QUARTO_EXECUTE_INFO and friends) - #1161

Merged
cscheid merged 2 commits into
mainfrom
feature/issue-1131
Nov 11, 2026
Merged

cscheid merged 2 commits into
mainfrom
feature/issue-1131

Conversation

@cscheid

@cscheid cscheid commented Nov 10, 2026

Copy link
Copy Markdown
Member

Closes #1131.

Code cells now see the environment Quarto 1 gives them:

  • QUARTO_PROJECT_ROOT, QUARTO_DOCUMENT_PATH, QUARTO_DOCUMENT_FILE
  • QUARTO_EXECUTE_INFO: path to a JSON file with document-path and the resolved six-bin format (identifier, execute, render, pandoc, language, metadata), including format.render.brand.{light,dark}
  • QUARTO_FIG_WIDTH, QUARTO_FIG_HEIGHT, QUARTO_FIG_DPI, QUARTO_FIG_FORMAT

Design

q2 never mutates its own process environment. The values are computed once per document in EngineExecutionStage (ExecutionContext.execute_env) and each engine delivers them:

  • knitr: Command::envs on the per-document R process.
  • Jupyter: kernels are shared by every document of a project (sessions keyed by kernel and directory), so spawn-time env cannot carry per-document values. A silent execute_request (store_history: false, silent: true) sets them inside the kernel before the document's first cell, for Python, R and Julia kernels. This is how Quarto 1 already sets QUARTO_FIG_*.
  • The execute-info file is written into the document's temp dir, only when code runs.

engine/execute_info.rs ports Q1's metadataAsFormat. Its key lists are tested against ts-packages/quarto-api/src/config/index.ts, so the file and the Node engine host can't drift apart. quarto-sass gains resolve_brand_modes, which returns the dark half only when the brand defines dark values.

Cost

Measured with the new QUARTO_PERF_STATS=1 gauge (perf.execute-info), debug build:

Project Bytes Build + write
claude-notes website 6,359 0.24 ms
docs website 19,406 0.35 ms
Quarto 1, lone document 6,513

The cost is per document that executes code, small next to starting an engine. Most of the docs size is the website sidebar config, which Quarto 1 includes too.

Differences from Quarto 1

These are listed in the new docs page docs/guides/authoring/execution-context.qmd:

  • brand.dark is present whenever the brand defines dark values.
  • Each brand mode has data and brandDir, not Q1's whole internal Brand object.
  • QUARTO_FIG_* report q2's figure defaults (png, 96 dpi), not Q1's HTML retina.
  • The julia and marimo engines don't receive the variables yet (bd-x3h4zjhl).

Tests

  • Unit tests in engine/execute_info.rs: partition, key-list parity, fig env, paths, brand, per-language setup code with escaping.
  • quarto-sass brand-mode tests.
  • execute_env_cli_e2e: drives q2 render with a knitr document in a subdirectory with a light/dark brand, and two Jupyter documents on one shared kernel, each seeing its own document. Skips without R+knitr or a python3 kernel.
  • cargo nextest run -p quarto-core -p quarto-sass -p quarto-brand -p quarto: 9,152 of 9,153 pass. The one failure is capture_classifies_pieces, which also fails on main with newer rlang (bd-54odm3rz).
  • Clippy with -D warnings, cargo xtask lint, and npm run build:wasm pass.
  • The Windows cross-check is not possible for these crates (C build scripts). The new code uses no platform-specific APIs.

No snapshot files changed.

Found along the way (separate strands, not fixed here)

  • bd-i7yz08uh (P1): parallel project renders interleave cells of different documents on one shared Jupyter kernel. Reproduced with QUARTO_JOBS=2. The new Jupyter test runs with QUARTO_JOBS=1 until it is fixed.
  • bd-08hfh3ut (P1): a project-level brand: resolves against the document directory once code runs, for a document in a subdirectory. This is pre-existing on main.

Triage record: claude-notes/issue-reports/1131/triage.md. Plan and measurements: claude-notes/plans/2026-11-10-execute-environment.md.

🤖 Generated with Claude Code

cscheid and others added 2 commits November 10, 2026 08:36
…O for code cells (bd-8fmuyh4d)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Code cells now see QUARTO_PROJECT_ROOT, QUARTO_DOCUMENT_PATH,
QUARTO_DOCUMENT_FILE, QUARTO_EXECUTE_INFO and QUARTO_FIG_*, as in
Quarto 1. q2 never mutates its own process environment: the values are
computed once per document in EngineExecutionStage and delivered per
engine.

- engine/execute_info.rs: a port of Q1's metadataAsFormat into the
  six-bin format (key lists tested against ts-packages/quarto-api), the
  `language` bin from the resolved quarto.language table, execute
  visibility and figure defaults, and format.render.brand.{light,dark}.
- The JSON file is written into the document's temp dir only when code
  runs. QUARTO_PERF_STATS=1 prints a perf.execute-info gauge.
- knitr: Command::envs on the per-document R process.
- Jupyter: kernels are shared across a project's documents, so a silent
  setup request sets the values inside the kernel (Python, R, Julia)
  before the document's first cell.
- quarto-sass: resolve_brand_modes returns the dark half only when the
  brand defines dark values.
- Docs: guides/authoring/execution-context.qmd.

Measured: 6.4 KB / 0.24 ms on claude-notes, 19.4 KB / 0.35 ms on docs
(mostly the website sidebar config). Details in
claude-notes/plans/2026-11-10-execute-environment.md.

No snapshot files changed.

Found while implementing: bd-i7yz08uh (parallel renders interleave
cells across documents on a shared kernel), bd-08hfh3ut (project brand
path resolves against the document dir after engine execution),
bd-x3h4zjhl (TS engines follow-up).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@posit-snyk-bot

posit-snyk-bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cscheid

cscheid commented Nov 10, 2026

Copy link
Copy Markdown
Member Author

We're going to merge this to increase Quarto 1 compatibility, but I'll note for the record that this is a feature we probably will deprecate in the future (we want to minimize our dependence on filesystems for access to information because of a variety of reasons).

@cscheid
cscheid merged commit 78b4863 into main Nov 11, 2026
17 checks passed
@cscheid
cscheid deleted the feature/issue-1131 branch November 11, 2026 15:12
@mcanouil

mcanouil commented Nov 11, 2026 •

Copy link
Copy Markdown

We're going to merge this to increase Quarto 1 compatibility, but I'll note for the record that this is a feature we probably will deprecate in the future (we want to minimize our dependence on filesystems for access to information because of a variety of reasons).

FWIW, I might be the only one using that feature at the moment, mostly to gain access to metadata otherwise not available to code cells / engines, e.g., brand.yml and project options.

edit: it seems plotnine (Python), flextable (R) are using it.
It is also in the Quarto book.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Code cells get none of the Quarto 1 execute variables, including QUARTO_EXECUTE_INFO

3 participants