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
A GitHub Project for the control-toolbox ecosystem
Why a GitHub Project, and why now
Issues, discussions, and pull requests are the right unit of work at the individual
repository level. They are permanent, searchable, and well-integrated with code
review. The case for a GitHub Project is not that they are insufficient — it is that
the control-toolbox ecosystem has outgrown single-repository coordination.
With eight or more CTX packages in separate repositories, several pain points
have no natural home in any one repo's issue tracker:
Cross-repo release visibility. The question "what is still open for the v2.1
release of OptimalControl?" spans CTBase, CTModels, CTDirect, CTFlows, CTSolvers, and the root package simultaneously. Answering it today means opening
eight browser tabs and reconstructing the picture mentally. A GitHub Project answers
it in a single table view, filtered by milestone label.
The cascade problem. A breaking change in CTBase requires a coordinated sequence
of beta registrations and compat updates across every downstream package. That
sequence is a single logical task — but it has no representation as such in any
individual repo. A project item can track the cascade as a unit, with linked PRs from
multiple repos showing their joint status.
Onboarding and external visibility. New contributors (PhD students, collaborators
on CONV or related initiatives) should be able to understand what is in flight without
navigating eight repositories. A project board or roadmap view gives them that
overview in one place. It is also useful when reporting progress to funding
stakeholders who should not need to read GitHub issue trackers.
What it does not replace
A GitHub Project is a view layer on top of existing issues and PRs — it adds no new
data, only organisation. Discussions and bug reports continue to live in the individual
repository closest to the relevant code. Issues filed there are the source of truth;
the project board reflects them. Free-form "note" cards with no corresponding issue
are explicitly avoided: if something deserves a card, it deserves a proper issue first.
Scope: narrow and release-focused
The zombie risk is real and worth naming precisely. A team of five people doing
research-driven development has no designated project manager. Keeping a board current
requires curation discipline that is orthogonal to doing the actual work, and in
practice that discipline erodes within weeks: cards stop moving, stale items accumulate,
and the board becomes a liability — a misleading picture that is worse than no picture
at all. Several well-intentioned GitHub Projects in comparable research-software
ecosystems have died this way.
The mitigation is not better discipline — it is removing the need for discipline
entirely. The scope is kept to the absolute minimum: one project, used solely as
a cross-repo release dashboard. Feature ideas, bug reports, and design discussions
live in individual repository issues and never touch the board. An item enters the
project only when it receives a concrete release milestone label, and from that point
it moves between columns automatically via GitHub Actions (see below) — no human
ever drags a card. The board has four columns: Planned — In progress — In review —
Done. If the automation is set up correctly, the only way the board goes stale is if
the underlying issues and PRs go stale, which is a different and pre-existing problem.
GitHub automation
The objective is a board that stays current without any manual curation. GitHub
provides two complementary mechanisms: built-in project automation rules for
simple state transitions, and GitHub Actions calling the Projects v2 GraphQL API
for anything that involves events in other repositories or external systems such as ct-registry.
These rules require no code and handle the common transitions inside a single
repository:
Trigger
Action
Issue or PR opened
Set status → Planned
PR merged
Set status → Done
Issue closed
Archive item
Item re-opened
Set status → In progress
Enable these for all source types (issues and PRs, all repositories linked to the
project).
Custom Actions workflows
For everything involving ct-registry, cross-repo events, or custom project fields,
GitHub Actions workflows call the Projects v2 GraphQL API via octokit/graphql-action. The workflows below are defined once in CTActions and
referenced as reusable workflows by each CTX repository, so maintenance is
centralised.
Workflow A — add to project on milestone label
Fires in any CTX repo when an issue or PR receives a label matching a release
milestone (e.g., v2.1). Adds the item to the project and sets the Package custom
field to the source repository name.
Workflow B — beta registration updates project field
Fires on every push to ct-registry (i.e., every LocalRegistry.register() call).
Parses which package and version were registered, finds the corresponding project item
by label, updates the Beta version field, and moves the item to In review.
# Lives in ct-registryname: Sync beta to projecton:
push:
branches: [master]paths: ['packages/**']jobs:
sync:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4with:
fetch-depth: 2
- name: Detect new registrationid: detectrun: | changed=$(git diff --name-only HEAD~1 HEAD) pkg=$(echo "$changed" | grep Versions.toml | head -1 | cut -d/ -f2) echo "pkg=$pkg" >> $GITHUB_OUTPUT
- name: Update Beta version field and move to In reviewuses: octokit/graphql-action@v2# query: find item by label matching $pkg and milestone,# update Beta version field, set status to In reviewenv:
GITHUB_TOKEN: ${{ secrets.PROJECT_TOKEN }}
Workflow C — nightly CI result on project items
After CTDev's nightly integration suite completes, updates a Nightly CI custom
field on every active project item (pass ✓ / fail ✗ with a link to the run). The
result is visible directly in the project table without opening a separate Actions tab.
# Lives in CTDevname: Nightly project syncon:
workflow_run:
workflows: ["Nightly integration"]types: [completed]jobs:
update-project:
runs-on: ubuntu-lateststeps:
- name: Set CI status on all In-progress itemsuses: octokit/graphql-action@v2with:
query: | # 1. Query all project items with status In progress or In review # 2. For each, update Nightly CI field to pass/fail # with link to ${{ github.event.workflow_run.html_url }}env:
GITHUB_TOKEN: ${{ secrets.PROJECT_TOKEN }}
Workflow D — cascade notification on PR merge
When a PR tagged for a release is merged in any CTX repo, the workflow reads dependency_order.toml from CTDev to identify which downstream package can now
proceed, and posts a notification comment on that package's tracking issue. This
makes the cascade visible and actionable without anyone needing to monitor the
upstream repo manually.
The board stays current with no manual curation. The only human action required is
filing issues, opening PRs, and applying milestone labels — all of which happen
naturally as part of normal development.
Conclusion
A single GitHub Project, scoped to release milestones and populated automatically,
gives the control-toolbox ecosystem one missing piece: a cross-repo view of what is
in flight. Its value is not in replacing issues or PRs — it is in making the release cascade visible as a unit, across eight repositories, without manual
aggregation. GitHub Actions keep the board current at zero curation cost: items enter
on labeling, advance on beta registration, and close on PR merge. Claude Code agents
handle the tasks that require judgment — opening the chain of compat PRs triggered by
a base-package change, diagnosing a nightly failure across logs and recent commits,
and producing a release readiness report on demand. The result is a lightweight,
mostly automated coordination layer that stays out of the way during normal development
and becomes useful precisely when a release is being prepared.
Appendix: AI agent automation with Claude Code
GitHub automation handles deterministic, event-shaped transitions. Tasks that require
reading and reasoning across multiple files, repositories, or log outputs belong to
an AI agent. Claude Code can be invoked as a GitHub Actions step via anthropics/claude-code-action, with access to the repository filesystem, shell
commands, Julia scripts, and the GitHub API.
The boundary is approximately: anything deterministic → GitHub workflow; anything requiring judgment across multiple sources → Claude Code agent. The two
layers compose naturally: a workflow detects an event and hands structured context to
an agent when the response requires reasoning.
Agent task 1 — cascade compat PR opener
Trigger: push to ct-registry registering a new beta of any CTX package.
What the agent does: reads dependency_order.toml, walks all downstream packages
in topological order, reads each Project.toml, computes the correct new compat
bound, and opens a PR in each affected repository updating the [compat] entry.
Links the PRs together in a summary comment. This replaces the six-step manual
cascade that is the main source of coordination errors.
- uses: anthropics/claude-code-action@betawith:
prompt: | Package ${{ steps.detect.outputs.pkg }} version ${{ steps.detect.outputs.version }} was just registered to ct-registry. 1. Read CTDev/release/dependency_order.toml. Identify all packages that directly or transitively depend on ${{ steps.detect.outputs.pkg }}. 2. For each downstream package in dependency order: a. Read its Project.toml [compat] section. b. If ${{ steps.detect.outputs.version }} is not covered, compute the correct new upper bound (same major, increment minor by one). c. Open a PR against that repository updating the compat entry. d. Apply the label "${{ steps.detect.outputs.milestone }}" to the PR. 3. Post a summary comment on the ct-registry commit listing all opened PRs and their dependency order.allowed_tools: "Bash,GitHub"env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Agent task 2 — nightly failure diagnosis
Trigger: CTDev's nightly integration workflow completes with a failure.
What the agent does: reads the test output, correlates the failure with recent
commits to ct-registry, identifies the responsible package and likely cause
(missing compat bound, breaking change without version bump, flaky test), and posts
a diagnostic comment on the relevant package's most recent PR or issue. If the fix
is mechanical, it opens a correction PR directly.
- uses: anthropics/claude-code-action@betawith:
prompt: | The nightly integration suite has failed. Logs are in ./integration-logs/. The current Manifest.toml of the integration environment is in ./Manifest.toml. 1. Identify which test(s) failed and extract the minimal error message. 2. List recent commits to ct-registry (last 48 h) for new registrations. 3. Correlate the failure with any interface changes in those registrations. 4. Identify the responsible package and the most likely cause. 5. Post a comment on the most recent open PR or issue in that repository explaining the failure and the likely fix. 6. If the fix is a missing compat bound, open a correction PR directly.allowed_tools: "Bash,GitHub"env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Agent task 3 — release readiness report
Trigger: manual dispatch when preparing a release, or scheduled weekly.
What the agent does: surveys all open issues and PRs tagged with the current
release milestone across all CTX repos, checks their CI status, verifies that the
current beta combination on ct-registry is mutually consistent (no missing compat
entries, nightly suite green), and posts a structured readiness report on the release
tracking issue. Replaces a manual survey of eight repositories.
- uses: anthropics/claude-code-action@betawith:
prompt: | Prepare a release readiness report for milestone ${{ inputs.milestone }}. 1. List all CTX repositories from CTDev/release/dependency_order.toml. 2. For each, find all open issues and PRs labeled "${{ inputs.milestone }}". Check their CI status and any blocking dependencies. 3. Verify that all expected beta versions are registered on ct-registry and that their compat entries are mutually consistent. 4. Check CTDev's most recent nightly run result. 5. Produce a structured markdown report: - Overall status: ready / blocked / incomplete - Per-package table: open items, CI status, beta version registered - Blocking issues that must be resolved before General registration 6. Post this report as a comment on the release tracking issue in control-toolbox/OptimalControl.jl.allowed_tools: "Bash,GitHub"env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Agent task 4 — issue triage
Trigger: a new issue is opened by an external contributor (first-time or outside
the core team).
What the agent does: reads the issue, applies appropriate labels, determines
whether it belongs in the current repository or should be redirected to another CTX
package, checks for duplicates, and posts an initial response. For bug reports it
sketches a minimal reproducer request or points to the relevant source file.
- uses: anthropics/claude-code-action@betawith:
prompt: | A new issue has been opened in ${{ github.repository }}: Title: ${{ github.event.issue.title }} Body: ${{ github.event.issue.body }} 1. Apply appropriate labels from: bug, enhancement, question, documentation, good-first-issue. 2. Determine whether this issue belongs here or in another CTX package (CTBase, CTDirect, CTFlows, CTParser, CTModels, CTSolvers). If elsewhere, say so clearly and suggest transferring. 3. Search open and closed issues for duplicates; link any found. 4. Post a helpful initial comment: acknowledge the issue, request any missing information (reproduction script, Julia version, full error message), and note any obvious relationship to known issues or recent changes.allowed_tools: "Bash,GitHub"env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Division of labour between the two automation layers
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
@ocots @PierreMartinon @gergaud
A GitHub Project for the control-toolbox ecosystem
Why a GitHub Project, and why now
Issues, discussions, and pull requests are the right unit of work at the individual
repository level. They are permanent, searchable, and well-integrated with code
review. The case for a GitHub Project is not that they are insufficient — it is that
the control-toolbox ecosystem has outgrown single-repository coordination.
With eight or more
CTXpackages in separate repositories, several pain pointshave no natural home in any one repo's issue tracker:
Cross-repo release visibility. The question "what is still open for the v2.1
release of OptimalControl?" spans
CTBase,CTModels,CTDirect,CTFlows,CTSolvers, and the root package simultaneously. Answering it today means openingeight browser tabs and reconstructing the picture mentally. A GitHub Project answers
it in a single table view, filtered by milestone label.
The cascade problem. A breaking change in
CTBaserequires a coordinated sequenceof beta registrations and compat updates across every downstream package. That
sequence is a single logical task — but it has no representation as such in any
individual repo. A project item can track the cascade as a unit, with linked PRs from
multiple repos showing their joint status.
Onboarding and external visibility. New contributors (PhD students, collaborators
on CONV or related initiatives) should be able to understand what is in flight without
navigating eight repositories. A project board or roadmap view gives them that
overview in one place. It is also useful when reporting progress to funding
stakeholders who should not need to read GitHub issue trackers.
What it does not replace
A GitHub Project is a view layer on top of existing issues and PRs — it adds no new
data, only organisation. Discussions and bug reports continue to live in the individual
repository closest to the relevant code. Issues filed there are the source of truth;
the project board reflects them. Free-form "note" cards with no corresponding issue
are explicitly avoided: if something deserves a card, it deserves a proper issue first.
Scope: narrow and release-focused
The zombie risk is real and worth naming precisely. A team of five people doing
research-driven development has no designated project manager. Keeping a board current
requires curation discipline that is orthogonal to doing the actual work, and in
practice that discipline erodes within weeks: cards stop moving, stale items accumulate,
and the board becomes a liability — a misleading picture that is worse than no picture
at all. Several well-intentioned GitHub Projects in comparable research-software
ecosystems have died this way.
The mitigation is not better discipline — it is removing the need for discipline
entirely. The scope is kept to the absolute minimum: one project, used solely as
a cross-repo release dashboard. Feature ideas, bug reports, and design discussions
live in individual repository issues and never touch the board. An item enters the
project only when it receives a concrete release milestone label, and from that point
it moves between columns automatically via GitHub Actions (see below) — no human
ever drags a card. The board has four columns: Planned — In progress — In review —
Done. If the automation is set up correctly, the only way the board goes stale is if
the underlying issues and PRs go stale, which is a different and pre-existing problem.
GitHub automation
The objective is a board that stays current without any manual curation. GitHub
provides two complementary mechanisms: built-in project automation rules for
simple state transitions, and GitHub Actions calling the Projects v2 GraphQL API
for anything that involves events in other repositories or external systems such as
ct-registry.Built-in automation (project settings → Workflows)
These rules require no code and handle the common transitions inside a single
repository:
Enable these for all source types (issues and PRs, all repositories linked to the
project).
Custom Actions workflows
For everything involving
ct-registry, cross-repo events, or custom project fields,GitHub Actions workflows call the Projects v2 GraphQL API via
octokit/graphql-action. The workflows below are defined once inCTActionsandreferenced as reusable workflows by each
CTXrepository, so maintenance iscentralised.
Workflow A — add to project on milestone label
Fires in any
CTXrepo when an issue or PR receives a label matching a releasemilestone (e.g.,
v2.1). Adds the item to the project and sets the Package customfield to the source repository name.
Workflow B — beta registration updates project field
Fires on every push to
ct-registry(i.e., everyLocalRegistry.register()call).Parses which package and version were registered, finds the corresponding project item
by label, updates the Beta version field, and moves the item to In review.
Workflow C — nightly CI result on project items
After
CTDev's nightly integration suite completes, updates a Nightly CI customfield on every active project item (pass ✓ / fail ✗ with a link to the run). The
result is visible directly in the project table without opening a separate Actions tab.
Workflow D — cascade notification on PR merge
When a PR tagged for a release is merged in any
CTXrepo, the workflow readsdependency_order.tomlfromCTDevto identify which downstream package can nowproceed, and posts a notification comment on that package's tracking issue. This
makes the cascade visible and actionable without anyone needing to monitor the
upstream repo manually.
Summary: what automation covers
ct-registryThe board stays current with no manual curation. The only human action required is
filing issues, opening PRs, and applying milestone labels — all of which happen
naturally as part of normal development.
Conclusion
A single GitHub Project, scoped to release milestones and populated automatically,
gives the control-toolbox ecosystem one missing piece: a cross-repo view of what is
in flight. Its value is not in replacing issues or PRs — it is in making the
release cascade visible as a unit, across eight repositories, without manual
aggregation. GitHub Actions keep the board current at zero curation cost: items enter
on labeling, advance on beta registration, and close on PR merge. Claude Code agents
handle the tasks that require judgment — opening the chain of compat PRs triggered by
a base-package change, diagnosing a nightly failure across logs and recent commits,
and producing a release readiness report on demand. The result is a lightweight,
mostly automated coordination layer that stays out of the way during normal development
and becomes useful precisely when a release is being prepared.
Appendix: AI agent automation with Claude Code
GitHub automation handles deterministic, event-shaped transitions. Tasks that require
reading and reasoning across multiple files, repositories, or log outputs belong to
an AI agent. Claude Code can be invoked as a GitHub Actions step via
anthropics/claude-code-action, with access to the repository filesystem, shellcommands, Julia scripts, and the GitHub API.
The boundary is approximately: anything deterministic → GitHub workflow;
anything requiring judgment across multiple sources → Claude Code agent. The two
layers compose naturally: a workflow detects an event and hands structured context to
an agent when the response requires reasoning.
Agent task 1 — cascade compat PR opener
Trigger: push to
ct-registryregistering a new beta of any CTX package.What the agent does: reads
dependency_order.toml, walks all downstream packagesin topological order, reads each
Project.toml, computes the correct new compatbound, and opens a PR in each affected repository updating the
[compat]entry.Links the PRs together in a summary comment. This replaces the six-step manual
cascade that is the main source of coordination errors.
Agent task 2 — nightly failure diagnosis
Trigger:
CTDev's nightly integration workflow completes with a failure.What the agent does: reads the test output, correlates the failure with recent
commits to
ct-registry, identifies the responsible package and likely cause(missing compat bound, breaking change without version bump, flaky test), and posts
a diagnostic comment on the relevant package's most recent PR or issue. If the fix
is mechanical, it opens a correction PR directly.
Agent task 3 — release readiness report
Trigger: manual dispatch when preparing a release, or scheduled weekly.
What the agent does: surveys all open issues and PRs tagged with the current
release milestone across all CTX repos, checks their CI status, verifies that the
current beta combination on
ct-registryis mutually consistent (no missing compatentries, nightly suite green), and posts a structured readiness report on the release
tracking issue. Replaces a manual survey of eight repositories.
Agent task 4 — issue triage
Trigger: a new issue is opened by an external contributor (first-time or outside
the core team).
What the agent does: reads the issue, applies appropriate labels, determines
whether it belongs in the current repository or should be redirected to another CTX
package, checks for duplicates, and posts an initial response. For bug reports it
sketches a minimal reproducer request or points to the relevant source file.
Division of labour between the two automation layers
Beta Was this translation helpful? Give feedback.
All reactions