This chapter is for someone changing roc-automation itself: its manual or its shared actions. It assumes the rest of the manual.

Propose a change§

Use issues for bug reports and design discussion, and pull requests for changes. Explain the affected behavior, the change, and how it was validated. Report vulnerabilities privately, as SECURITY.md describes. Commits are signed, and changes reach the default branch through pull requests.

Change the manual§

The sources are the AsciiDoc files under docs/. Write for the shared renderer lists the conventions they follow.

Build the site, PDF and static Markdown locally with a precompiled renderer:

/path/to/roc-docs build --workspace . --pdf-filename roc-automation.pdf --docs-version 3

The output is written to .docs-out/. The Documentation workflow runs the same build on every pull request and deploys from the default branch. Upstream CI builds and caches the renderer; downstream consumers supply the released binary. To develop the renderer itself, follow Maintain the documentation renderer for its compiler, dependencies, architecture and verification procedures. The action uses the shared renderer and built-in theme. Python is used by the independent test harness; rendering does not invoke it.

Apply the editorial review to the affected chapter, README and contributor guide. Delete material without a current reader purpose instead of moving it to an archive chapter.

Explain the risk and control where they apply§

For a change to automation behavior, a workflow boundary or an evidence claim, update the relevant chapter’s risk-and-control narrative. State a concrete failure or attack scenario, the guiding principle, the mechanism that addresses it, the test or observation that verifies it, and the assumptions that remain. Name the affected source, compiler, artifact, target or authority when it matters. Explain a tradeoff in terms of that risk rather than a framework score.

Use connected prose beside the operational guidance. Do not add a generic security checklist to every task or duplicate command reference material. Keep the explanation specific to the chapter. Update the reference mapping when a risk or control moves, gains another owner chapter or changes its verification. The reference links to the authoritative narrative instead of maintaining a second copy of its rules.

Review failures as well as the happy path. Useful regressions demonstrate that wrong identities, stale or incomplete evidence, unsafe paths and interrupted execution cannot become a pass or privileged operation. A configuration check establishes configuration; runtime and operational claims need corresponding execution or observation. Describe intended practice without asserting that an unimplemented utility already provides it.

Investigate before expanding the model§

Further investigations use a scoped agent task whose outputs are a concrete proposal and a GitHub issue, creating or updating the appropriate issue rather than duplicating it. Give the agent a realistic scenario to investigate, the affected boundary, primary sources to consult, and existing behavior to inspect. Ask it to assess applicability, failure modes, cost, alternatives and residual assumptions, with proposed changes and acceptance evidence. Separate verified findings from hypotheses. Keep private vulnerability details in the private reporting channel.

Maintainers review the result before turning it into normative guidance or implementation. Investigation findings and implementation gaps stay in issues; the manual records the chosen practice and rationale. Do not create framework requirements, governance policy or product-specific security promises as an incidental outcome of an automation investigation.

Change a shared action§

Read the trust model first. It is normative: a change to an action’s behavior or permissions keeps those boundaries and arrives with regression tests for them. Controller implementation references live beside their source, separate from the consumer manual.

actions/nightly-report and actions/publish-release are Roc scripts, scripts/nightly_report.roc and scripts/publish_release.roc, and their tests are expect tests that blueprint run check runs; Change an action that is a Roc script says how they are built and tested. The documentation action invokes the native renderer through its shell wrapper. Other controllers and the independent test harnesses use Python. Python 3.10 or later and the standard library are sufficient for their tests:

python3 -m unittest discover -s tests -v

Change a script§

The repository’s own automation is Roc scripts under scripts/, written as Write product-specific automation as Roc scripts describes. With blueprint installed as Get blueprint describes:

blueprint run check

It runs the expect tests of the modules under scripts/src/, checks each script with roc-stable, checks their formatting, and holds every script’s roc field to the release Blueprint.roc names. CI runs the same task.

scripts/check_settings.roc must stay read-only. Its one request function states the GET method, and what it decides from GitHub’s answers is pure logic in scripts/src/Settings.roc. A change to a check arrives with expect tests for the passing and the failing answer, and a setting that cannot be read is reported as unknown. CI does not run it against a repository, because that needs administration access; see Confirm the settings.

Change an action that is a Roc script§

scripts/nightly_report.roc and scripts/publish_release.roc run with write tokens, so they are held to What the jobs with write access run and to the rules for every shared action.

Every decision is in a module without effects: scripts/src/NightlyReport.roc, scripts/src/PublishRelease.roc, and scripts/src/GitHub.roc for the gh invocation and the checks the two share. A module checks the inputs into a plan, and then decides one step at a time: given the answer to the last request, it names the next request or the end. The script only carries each request to gh, or to the runner’s disk, and brings the answer back.

To run a script by hand, give it the environment the action gives it: the inputs as INPUT_*, the token as GH_TOKEN, and the runner’s GITHUB_* variables. A pass with a title that no issue has only lists issues:

GH_TOKEN="$(gh auth token)" GITHUB_REPOSITORY=<owner>/<name> \
  GITHUB_SERVER_URL=https://github.com GITHUB_RUN_ID=1 GITHUB_OUTPUT=/tmp/outputs \
  INPUT_OUTCOME=success INPUT_NIGHTLY_TAG=probe INPUT_RELEASE_TAG=0.0.0 \
  INPUT_TITLE='nightly-report probe, never opened' \
  blueprint run nightly-report

ci.yml runs actions/nightly-report itself with those inputs, in a job whose token can only read issues. No job there holds a token that can write issues or releases, so the requests that write are covered by the expect tests and not by a run against GitHub.

Release the tools§

The tools release includes the action programs, roc-policy, roc-docs and the published-release compatibility runner. Release tools defines each tool’s build targets and native acceptance matrix. To build the Linux action programs locally:

blueprint run build-tools

This writes dist/<tool>-<system> for x86_64-linux and aarch64-linux. Other utilities use their own build entrypoints; see their maintenance references.

The workflow publishes under tools-<version> after read-only build jobs and native tests of the exact artifacts. Tests run without a checkout, Nix or build compiler, using the complete distributed runtime and declared external helpers. The dispatch-only publisher receives those files as inert bytes through actions/publish-release.

A pull request builds and tests as a dry run. Before dispatching a release, commit its notes as docs/releases/tools-<version>.md; remove the source notes when the published release owns them.

Release a shared action§

Repositories reference an action by full commit SHA and adopt a new one through a Dependabot or maintainer pull request. Nothing updates them automatically.

Shared workflows and composite actions reference sibling actions with GitHub’s $/ syntax. The consumer’s full workflow SHA fixes the complete shared implementation, including the installer and its checksum registry. Change the action, workflow and tests together; there is no separate internal pin to bump. External dependencies still require reviewed full SHAs. This composition targets GitHub.com; $/ is not supported on GitHub Enterprise Server.

Use a unique version tag for a published release, record any assigned vulnerability identifiers for fixes, and never move an existing tag.