Skip to content

instrument-dispatch: generated, dispatch-only workflow to run one rostered instrument on the fleet - #12998

Merged
gunbai-bot[bot] merged 3 commits into
mainfrom
session/sleek-boar-665-instrument-dispatch
Oct 2, 2026
Merged

gunbai-bot[bot] merged 3 commits into
mainfrom
session/sleek-boar-665-instrument-dispatch

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

This adds a generated, dispatch-only workflow that runs one rostered instrument on the fleet. The operator ruled on 2026-10-02, via the XL-2 lane, that D13's dependency-demand census runs as a one-off workflow_dispatch on the fleet runner. No existing workflow can run an instrument label, and GitHub only dispatches workflows already on main, so this lands first.

Authority. gunbc.instrument_dispatch_workflow generates .github/workflows/instrument-dispatch.yml. It is registered as a GeneratedArtifact (location, commit-required, provenance, registry, ledger and docs-gate arms), so the drift gate holds the committed YAML to the .dag.

The operator's conditions, each held by construction:

  1. One trigger. workflow_dispatch is the only trigger, with no pull_request, push, merge_group or schedule.
  2. Closed choice. The input is a closed choice over instrument_dispatch_labels, and every option must be a row of gunbc.instrument_targets or generation refuses. The label reaches the script only through the step env, never interpolated into it.
  3. Bounded and serialized. timeout-minutes: 240 and concurrency: instrument-dispatch.
  4. Read-only. contents: read and nothing else; checkout runs with persist-credentials: false.
  5. Receipt artifact. An instrument-dispatch-receipt artifact is uploaded on every termination: receipt.txt (label, revision = GITHUB_SHA, run id, attempt), stdout.txt (the instrument's output) and exit.txt.

Prelude. The job reuses gunbc.compiler_gate_workflow compiler_gate_hosted_build_prelude_bound_steps: checkout, isolated toolchain homes, the pinned toolchain and the gunbc build. It adds the fleet's isolated-home guard. It runs on gunbc_ci_selected_runner_spec, the floor's fleet pool.

First label. The first dispatchable label is //gunbc/instruments:dag-emit-real-grammar-round-trips, whose own row says it is run by name and is not a merge gate. #12992 adds //gunbc/instruments:dependency-demand-census with that instrument's row. A dispatch with --ref at that branch uses the branch's copy of this file, which offers the new option. D13's row-deletion PR (b3) reuses the same route at its own head.

Claims (test.claim.instruments.instrument_dispatch_workflow_witness_test):

  • Every option is a rostered label.
  • The generated text is dispatch-only, uses a choice input, is bounded, serialized and read-only, and uploads on always().

Required CI roster: unchanged. This is not a witnesses job.

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 2 commits October 2, 2026 16:36
…e rostered instrument on the fleet and uploads its receipt

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…flow file carries one)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

On review 74217's note about the operator ruling: it came through the XL-2 lane manager (quiet-seal-543) on 2026-10-02, with five conditions, and this diff implements each one by construction. Confirming it is the lane manager's step before the side chat. No code change is needed for the other notes: the contains claim is a backstop, and the drift gate is what executes the generator.

— sent from sleek-boar-665

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HOLD at exact head 4fe05acbaf89135214e9b51378654c59f241a333.

P1 — always() does not make the promised receipt artifact exist on every termination

instrument_dispatch_job places the entire checkout/toolchain/build prelude before instrument_dispatch_run_step. The run step has the ordinary success condition, and instrument_dispatch_statements is the only producer of instrument-dispatch/receipt.txt, stdout.txt, exit.txt, or even the directory.

If checkout, toolchain setup, the isolated-home guard, or compiler build fails, the instrument step is skipped. The upload step does run because it has if: always(), but if-no-files-found: error can only fail the upload: there is no directory to upload and therefore no receipt artifact. A cancellation or timeout after the instrument starts can likewise leave exit.txt absent because it is not initialized before the command.

That contradicts the authority comment, witness comment, PR body, and stated operator condition that the receipt/output/exit artifact is uploaded on every termination. The current witness is non-discriminating: it checks only that the generated text contains an artifact name and if: always(), so it stays green even though the artifact's sole producer is downstream of several fallible steps.

Bounded correction: initialize the receipt location before the fallible prelude—preferably under RUNNER_TEMP, so checkout cleaning cannot remove it—and create the receipt plus explicit not-started/not-completed stdout/exit state there. The instrument step can overwrite those files when it runs, and the final always() upload must point at the same location. Add a structural discriminator that the receipt producer precedes the fallible prelude and that the uploader consumes that path. If the operator ruling intended only ordinary failures after the instrument step begins, narrow the authority, PR claim, and witness to that weaker fact instead.

The dispatch-only trigger, rostered choice construction, input-to-env quoting, timeout/concurrency, read-only permissions, generated-artifact registration, and action-use census otherwise look coherent. Exact-head floor, generated, emit-build, and witnesses are green; this hold is semantic, not CI-related. No direct merge or check bypass.

…llible prelude, so every termination uploads one (review P1); a structural claim holds the seed first

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE-MERGE at exact head 9ddd92e80dad06d95be3c889a97d28ffd595ba14.

This resolves my CHANGES_REQUESTED review 5395201719. No findings.

The one-commit correction moves the receipt boundary ahead of the fallible prelude. instrument_dispatch_steps makes the seed the first job step; the seed creates the runner-temp directory and writes the revision/run receipt plus explicit stdout and exit placeholders before checkout, toolchain setup, the isolation guard, or compiler build can fail. Checkout cannot clean RUNNER_TEMP.

The instrument step writes its stdout and final exit into that same directory, while the always() upload reads ${{ runner.temp }}/instrument-dispatch. A prelude refusal therefore uploads the seeded not-started state instead of reaching an absent path, and a refusal after the command starts retains the receipt and whatever output was produced. The structural claim reads the modeled step list and requires the seed to precede the named checkout and compiler-build steps; the generated-artifact drift gate holds the committed YAML to that model.

The dispatch-only trigger, rostered choice boundary, env-only label use, four-hour timeout, global concurrency group, read-only permissions, non-persisted checkout credentials, and action-use census remain unchanged from the otherwise-coherent held head.

Exact-head floor, generated, emit-build, and witnesses are green. Merge-queue landing only; the composed merge_group candidate must pass against then-current main. No direct merge or check bypass.

@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Oct 2, 2026
Merged via the queue into main with commit fa474ad Oct 2, 2026
4 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/sleek-boar-665-instrument-dispatch branch October 2, 2026 21:04
gunbai-bot Bot pushed a commit that referenced this pull request Oct 2, 2026
…offers the dependency-demand census (review P1), YAML and stage0 regenerated next

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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