Skip to content

ci: publish the results of the solves for the documentation (#314, phase B) - #419

Merged
ocots merged 1 commit into
mainfrom
feat/314-publish-results
Nov 7, 2026
Merged

ocots merged 1 commit into
mainfrom
feat/314-publish-results

Conversation

@ocots

@ocots ocots commented Nov 7, 2026

Copy link
Copy Markdown
Member

Part of #314, phase B of the plan. Stacked on #417 (phase A): the base of this pull request is its branch. Once #417 is merged, GitHub moves the base to main.

Conventions: ct-conventions v0.11.0, ct-agents v0.4.0.

What

The cron publish job now also writes, on the results branch, what the problem pages will draw (phase C). It extends tools/cron/report.py, which already publishes the reports; there is no second publisher. The output looks like this:

Path on results Content
manifest.json The last run of each scope: run, commit, date, platforms, problems.
problems/<problem>/result.json Every solve of the problem, all scopes: the columns of <report>-results.tsv, numbers as numbers, the problem's fingerprint included, plus the run, the commit and the paths below.
problems/<problem>/<scope>/<platform>/<modeling>/<configuration>.json The trajectory of a solve, converted from <report>-trajectories.toml (compact JSON).
env/<run id>/<platform>/<report>/ The environment of the solves: environment.toml, Project.toml, Manifest.toml, versioninfo.txt, status*.txt.

Choices

  • Merged per (scope, problem). A run replaces the entries of its own scope, and only for the problems it solved. A run restricted with problem=beam therefore leaves the other problems as they were, and a JuMP run leaves the OptimalControl entries alone. The plan said "per scope"; per (scope, problem) is what makes a partial run safe.
  • env/<run id>/, pruned. Each entry points to the environment of its own run. An environment is deleted once no entry refers to it, so the single-commit branch does not grow from run to run.
  • parse_results keeps every column of the .tsv, not only those of the report: result.json needs the grid, the scheme, the options and the fingerprint. The report reads its columns by name, so it is unchanged.
  • Workflow: the first report.py call takes --results-dir "$RESULTS_DIR", and the publish step stages the whole tree (git add --all) instead of cron/ alone. Python's tomllib reads the trajectories; it ships with Python ≥ 3.11, which ubuntu-latest has.
  • A problems input for a cron dispatched by hand (OptimalControl, OptimalControl scalarized, JuMP). The plan's check, "a cron on problem=beam", was not possible: a dispatch took no input and solved the whole catalogue. Now a restricted run solves only those problems and publishes their results and environments. It writes its report and its state aside, unpublished, and skips the issues: a run that solved only beam cannot say anything about the other problems, so it must not replace cron/<scope>.md, cron/state.json or the sections of the summary issues.
  • Documented in .github/workflows/README.md ("Results for the documentation"), next to the cron description that already exists, not in a new README.

Verification

  • python3 -m unittest discover -s tools/cron/test: 23 tests pass, 4 of them new.
    • A run writes the results, the typed numbers, the trajectory, the environment and the manifest.
    • Three runs (JuMP, then OptimalControl, then JuMP restricted to beam) replace only the entries of their scope and problems, and keep the environments still in use. A fourth run prunes the environments nothing refers to any more.
    • A solve without a trajectory or an environment is still published.
    • The file names of the configurations.
  • Run locally on real outputs: the reports of test: record the trajectories, the environment and the fingerprint of the solves (#314, phase A) #417 (beam, vanderpol, jackson, robot, glider, moonlander, OptimalControl and JuMP), arranged as the downloaded artifacts are. The tree above is produced; phase C builds the documentation from it.

Not done here: the check on GitHub ⛔

This step needs your go-ahead (human checkpoint of the plan). The real check is a run on GitHub: gh workflow run CronJuMP.yml --ref feat/314-publish-results -f problems=beam, then a look at problems/beam/ and env/ on the results branch. With problems set, the issues and the cron reports are not touched, but the run still writes to the results branch, so it waits for your decision. actionlint finds nothing in the modified workflows.

🤖 Generated with Claude Code

The publish job of the crons also writes, on the `results` branch, what the
problem pages draw (#314): `problems/<problem>/result.json` (every solve, all
scopes, from `<report>-results.tsv`), the trajectory of each solve as JSON,
`env/<run id>/<platform>/<report>/` (the environment of the solves) and
`manifest.json` (the last run of each scope). It extends
`tools/cron/report.py` (`--results-dir`): no second publisher.

A run replaces, for each problem it solved, the entries of its scope and
keeps the others; an environment is removed once no entry refers to it.

A convergence cron dispatched by hand takes a `problems` input: it solves
those problems only and publishes their results, and leaves the scope
report, the state and the issues as the last complete run left them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ocots ocots added the run ci github-runner Trigger the CI workflow on GitHub-hosted runners label Nov 7, 2026
Base automatically changed from feat/314-record-trajectories to main November 7, 2026 22:10
@ocots
ocots merged commit 1b4a393 into main Nov 7, 2026
20 checks passed
@ocots
ocots deleted the feat/314-publish-results branch November 7, 2026 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

run ci github-runner Trigger the CI workflow on GitHub-hosted runners

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant