Skip to content

Verso upstreaming dashboard with graph visualisation - #10

Merged
chrisflav merged 8 commits into
chrisflav:masterfrom
chrisflav-agents:upstreaming-dashboard
Jun 29, 2026
Merged

Verso upstreaming dashboard with graph visualisation#10
chrisflav merged 8 commits into
chrisflav:masterfrom
chrisflav-agents:upstreaming-dashboard

Conversation

@chrisflav

Copy link
Copy Markdown
Owner

Adds a Verso "upstreaming dashboard" that renders the staging dependency graph as a published site, following the integration pattern of chrisflav/proetale. Builds on the toolkit merged in #9.

Design

verso-blueprint is pinned to Lean v4.31.0 (no v4.32 branch), and proetale's path = ".." dependency forces a shared toolchain. Since the main library tracks mathlib master (v4.32.0-rc1), a path-dependency would clash. So the dashboard is a self-contained dashboard/ Lake package with its own lean-toolchain (v4.31.0) that does not depend on MathlibStaging. The graph flows through generated data instead:

  • New lake exe upstream viz --decls --format verso emits the staging graph as a Verso chapter (dashboard/UpstreamingBlueprint/Chapters/Graph.lean): one :::definition node per declaration, with {uses …} dependency edges.
  • Blueprint.lean includes that chapter plus {blueprint_graph} / {blueprint_summary}.

Serendipitously, Verso's automatic ready/blocked status (and its blue/amber colours) coincides with our model: a node with no staging dependencies is ready (directly upstreamable); one that depends on other staging declarations is blocked.

CI / Pages

.github/workflows/verso-blueprint.yml is dual-toolchain: it generates the chapter with the v4.32 toolchain, then builds the site with the v4.31 toolchain, and publishes to the gh-pages branch under dashboard/ (via JamesIves/github-pages-deploy-action, so it coexists with the existing docgen output).

Verification

Verified locally end-to-end: verso-blueprint builds, and the site generates to dashboard/_out/site/html-multi/ with the real graph — 24 declaration nodes, 62 edges; the two ready nodes are exactly the depth-0 directly-upstreamable declarations from upstream report --max-depth 0.

Caveats

  • The CI/Pages job runs on GitHub and hasn't been exercised there yet; the repo's Pages source may need to point at the gh-pages branch for dashboard/ to serve.
  • A custom "pending" (@[upstreamed]) status colour isn't expressible through Verso's (closed, env-computed) status enum; pending PRs are shown in the node body text rather than as a distinct colour.

🤖 Generated with Claude Code

First component of the upstreaming toolkit. `lake exe upstream report` ranks
MathlibStaging units — whole files or individual declarations (`--decls`) — by
how ready they are to upstream to mathlib, over the staging-internal dependency
graph (edges to mathlib/Lean are ignored as already-upstream):

* depth — longest path to a leaf; depth 0 = directly upstreamable;
* deps — number of transitive staging dependencies.

Filter with `--max-depth N` (e.g. `--max-depth 0` for the worklist) and
`--max-deps N`; `--json` for machine output. Reuses import-graph for env loading
and the declaration/module APIs.

Declaration nodes are source-written decls only (compiler machinery filtered via
`isGenerated`); a structure's constructor dependencies are folded into the type
node so its true dependencies are counted.
`@[upstreamed N]` tags a staging declaration as being upstreamed in mathlib pull
request `N`. `lake exe upstream check` collects the tags, queries the merge
status of each PR via `gh api graphql` (Bors-aware: a Bors-merged PR shows as
CLOSED with `[Merged by Bors]`), and reports which declarations are in merged
PRs and so can be removed from staging (exiting non-zero so CI can flag cleanup).

Module-system notes:
* The attribute registration must be `meta` to be active during elaboration, but
  the standalone exe must read the tags from non-`meta` runtime code. So the
  env-extension + reader live in a non-`meta` `Meta.UpstreamedExt`, and the
  `meta` attribute in `Meta.Upstreamed` writes to it via a `meta import`.
* `withImportModules` loads with `loadExts := false`, so it does not initialize
  env extensions; `check` uses `importModules (loadExts := true)` with
  `importAll` to load the (private) extension entries.
`lake exe upstream viz [--decls] [--format json|dot] [--out FILE]` emits the
staging dependency graph for visualisation:

* JSON — a versioned record (nodes with upstreaming status + presentation
  colours, edges, module groups), modelled on verso-blueprint's `GraphData`
  with semantics (`status`) separated from presentation (`visual`); consumed by
  the Verso blueprint renderer (M4).
* DOT — Graphviz, nodes coloured by status (verified it renders).

Node status: `upstreamable` (depth 0), `pending` (`@[upstreamed]`, read with
`loadExts`), or `blocked`. Refactored the analysis into shared `stagingFileGraph`
/ `stagingDeclGraph` / `rowsOf` builders used by both `report` and `viz`.
… M4/M5)

A `blueprint-verso/` sub-package renders the staging dependency graph as a Verso
blueprint site, following the integration pattern of chrisflav/proetale.

* It is a self-contained Lake package with its own `lean-toolchain` (v4.31.0, the
  latest verso-blueprint supports). It does NOT depend on `MathlibStaging` via
  `path = ".."`, because the main library tracks mathlib master (v4.32.0-rc1) and
  the toolchains would clash. Instead, `lake exe upstream viz --decls --format
  verso` (new) generates the graph as a Verso chapter (`Chapters/Graph.lean`).
* Each declaration becomes a `:::definition` node with `{uses …}` edges. Verso's
  automatic ready/blocked status — and its blue/amber colours — coincide with our
  upstreaming model: a node with no staging dependencies is *ready* (directly
  upstreamable), one that depends on other staging declarations is *blocked*.
* `.github/workflows/verso-blueprint.yml` builds the site in CI (generate the
  chapter with the v4.32 toolchain, then build the site with the v4.31 toolchain)
  and publishes it to the `gh-pages` branch under `dashboard/`.

Verified locally: the site builds to `_out/site/html-multi`, with the real graph
(24 declaration nodes, 62 edges); the two ready nodes are exactly the depth-0
directly-upstreamable declarations from `upstream report --max-depth 0`.
Purely a rename of the Verso dashboard sub-package directory and its references
(`.gitignore`, the CI workflow paths, and the `upstream viz --out` target).
GitHub Pages allows only one deployment per repository, so the API docs and the
Verso dashboard must share it. Consolidate into `pages.yml` (renamed from
`dashboard.yml`): on push to master it builds the API docs (`docgen-action` with
`deploy: false`) and the dashboard, assembles one site (docs at `/docs`,
dashboard at `/dashboard`, with a small landing page), and deploys once via the
native GitHub Actions Pages flow (`upload-pages-artifact` + `deploy-pages`).

`lean_action_ci.yml` no longer runs docgen or holds the Pages permissions; it is
now CI checks only (build, mirror_imports, lint).
@chrisflav
chrisflav merged commit c813747 into chrisflav:master Jun 29, 2026
1 check passed
chrisflav added a commit that referenced this pull request Jun 29, 2026
Fixes the GitHub Pages deployment added in #10, which failed on
`master`.

## Two bugs
1. **`lake: No such file or directory`** — `pages.yml` installed elan
*after* the docs step, but docgen-action's build script invokes
`~/.elan/bin/lake` directly. Install elan first.
2. **`409 Conflict` on the `github-pages` artifact** — docgen-action@v1
runs `upload-pages-artifact` on *every push* regardless of its `deploy`
input (only its `deploy-pages` step honours the flag). So the workflow's
own `upload-pages-artifact` was a second `github-pages` artifact and
collided.

## Fix
Since GitHub Pages allows only one deployment per repo and docgen-action
insists on uploading its `docs/` directory, let docgen own the single
upload + deploy instead of deploying separately. The workflow now:

1. builds the dashboard (chapter with Lean v4.32.0-rc1, Verso site with
v4.31.0),
2. drops it into docgen's output dir (`docs/dashboard`) and adds a
landing `docs/index.html`,
3. runs `docgen-action` (`build-page: false`), which builds the API docs
into `docs/docs` and uploads + deploys the whole `docs/` tree.

Resulting site: landing page at `/`, API docs at `/docs`, dashboard at
`/dashboard`.

(docgen's `build_docs.sh` only does `mkdir -p docs` + `cp … docs/docs`,
no `rm`, so the pre-placed dashboard survives.)

## Before merging
This branch is set up so the site can be deployed and tested from it.
Remove the temporary bits before/after merge:
- [ ] remove `fix-pages-deploy` from the `push:` trigger in `pages.yml`;
- [ ] remove the `fix-pages-deploy` branch from the `github-pages`
environment's deployment-branch policies.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.

1 participant