Repository navigation
Description
Context and request
Workflow authors and their agents need a clear, evergreen GitHub Actions authoring standard. Apply ASD-STE100 Issue 9 writing practices and en-US to src/docs/Coding-Standards/GitHub-Actions.md. Preserve its technical contracts. This Task delivers one prose-only draft PR in the user-directed documentation writing campaign.
Observed before text
The complete baseline page was read, including all examples (1,265 lines at 1b0d4893c8fefabe604d04393068a8ff6f848082). It includes these writing gaps:
- Opening: workflows "are held to the same bar as application code".
- Manual pin audit: "Use the reusable
Update-GitHubActionPin.ps1utility to audit or deliberately synchronize external SHA pins: for example, when onboarding an existing repository, reconciling a repository after an update-service outage, or checking proposed changes before an update pull request is opened." - Job structure: "Reach for a step by default" and "raising the floor for everything".
- Concurrent steps: "Every step in a job historically ran in sequence", "GitHub has since added", and "Until it has settled in the ecosystem".
- Action design and diagnostics include
behaviour,labelled, metaphors, and long sentences.
Pinned expectations
Use the fixed MSX documentation baseline, not changes made by sibling campaign PRs:
- Documentation Model: preserve artifact purpose; use present-tense supported target-state prose. Normative policy is not proof of implementation or CI enforcement.
- Natural Language and Technical Writing Guide: use en-US, concrete terms, active voice, short sentences, and consistent technical vocabulary.
- Markdown and Documentation: preserve native syntax, linkable structure, examples, and inline reasons.
- Standard and guide templates: retain the authoring-standard purpose and direct, verifiable instructions. Do not restructure the existing page to copy a skeleton.
- Official STEMG overview, FAQ, and Issue 9: distinguish descriptive text from procedures; retain technical nouns and verbs. The local Issue 9 PDF has MD5
9c720341c350ed77943b2c73d01c716f. Consulted rules include 1.1-1.14, 3.6, 4.1-4.3, 5.1-5.4, and 6.1-6.6. Keep the PDF and extracted text local. Counts and automated scans do not establish full STE conformance.
Observable acceptance criteria
- The opening states the same application-code, supply-chain, and least-privilege obligations without the "same bar" idiom.
- The manual-audit section gives a short instruction, separate use cases, the same prerequisites and token boundary, all exclusions, and the same explicit failure contract.
- Prose throughout the page uses direct, concrete en-US and present-tense descriptions. Concurrent-step guidance retains compatibility checks without delivery-status prose.
- Every fenced example, command, action pin, heading, anchor, link target, front-matter value, and uppercase normative requirement remains unchanged. Manual review confirms that lowercase obligations, ownership exceptions, security boundaries, compatibility, and failure handling retain their force.
- The PR contains changes only to the owned page. Durable evidence records the complete read, changed and unchanged surfaces, concrete before/after examples, existing-check results, and unresolved contradictions. The PR remains DRAFT with no auto-merge or Agent merge.
Technical decisions
Make surgical prose changes in the existing sections. Do not change workflows, scripts, tests, dependencies, enforcement, shared navigation, or generated indexes. The existing standard is the documentation deliverable; no product behavior changes and no consumer migration are intended. Use the app-managed worktree branch github-actions-standard-writing.
Accepted differences and exclusions
Keep direct imperatives and normative MUST/SHOULD/MAY. Preserve exact native YAML, PowerShell, expressions, placeholders, comments, historical example evidence, and technical terminology. Keep existing headings, including the time-dependent concurrent-step heading and behaviour in a linkable heading, to preserve anchors. Record these exceptions rather than silently changing navigation. Other standards and active #240 code/tests are outside ownership.
Substantive contradiction retained
Separate a reusable workflow from the actions it consumes requires separate repositories for shared workflow/action libraries and calls self-checkout a last resort. Reusable workflows with colocated composite actions says an action with only that workflow as caller should stay colocated and requires self-checkout. This writing Task does not choose between these policies or alter their examples. Report the unresolved policy choice for owner review.
Factual coverage errors addressed in this Task
The inline-script impossibility description and universal lint-enforcement guarantee are factual coverage errors, not unresolved policy. Official actionlint documentation and source establish bounded inline Bash/sh support through ShellCheck when enabled and available. This Task corrects both descriptions narrowly without changing the extraction requirement, required CI, or blocking criteria. Only the separate-versus-colocated workflow/action-library choice remains an unresolved policy question.
Implementation plan
- Define repeatable local prose assertions and preservation comparisons against the fixed baseline. Run them before editing; capture the expected prose failures and passing preservation checks.
- Clarify the opening and manual pin-audit prose. Verify the complete improvement, commit it, push it, and immediately open the focused draft PR.
- Verify remaining examples and policy boundaries before rewriting their surrounding prose. Complete the page review in small logical commits and push each commit.
- Run the existing Markdown linter with
.github/linters/.markdown-lint.yml, relative-link check, scoped cross-repository-link check, Pester suite runner, and Zensical build. Do not add tooling or dependencies. Keep site output outside the checkout and report any pre-existing or environment failures without changing other owners' files. - Re-read the result, compare the complete base-to-head diff, and record preservation evidence, accepted differences, contradictions, standards alignment, and scoped issue-convergence results in the issue and PR.
- Leave the PR draft and report the Task/PR URLs and immutable head SHA to the campaign coordinator.
Existing-check plan
Use npx --no-install markdownlint-cli2 --config .github\linters\.markdown-lint.yml src\docs\Coding-Standards\GitHub-Actions.md, pwsh .github\scripts\Test-DocumentationLink.ps1, pwsh .github\scripts\Test-CrossRepositoryLink.ps1 -Path src\docs\Coding-Standards\GitHub-Actions.md, pwsh .github\scripts\Invoke-PesterSuite.ps1, and the repository's zensical build --clean command with an external output directory. Compare every fenced block, heading, link target, inline-code inventory, and uppercase normative keyword with the pinned page. Automated preservation checks support, but do not replace, the manual technical-meaning review.
Writing evidence at previous head 0ba7628
The complete original page (1,265 lines) and complete revised page (1,364 lines) have been read, including every example. Only src/docs/Coding-Standards/GitHub-Actions.md changes. Five logical commits are pushed. The immutable candidate is 0ba76283ef113db4eef91dda970f96486ee5a61d; the scoped base remains 1b0d4893c8fefabe604d04393068a8ff6f848082. The draft PR is MSXOrg/docs#264.
Concrete replacements include held to the same bar as application code -> Workflow authors apply the application-code standards and the supply-chain and least-privilege controls below.; Reach for a step by default -> Use a step by default.; Adjust behaviour through the input interface -> Adjust behavior through the input interface; and An action is a black box until it fails. -> An action reports what it reads, decides, and produces on every run. The manual-audit instruction has three separate use cases. Its prerequisites, token-header boundary, exclusions, and explicit failure result retain their meaning. Concurrent-step explanations state the default model and compatibility requirements without rollout history.
Preservation comparisons pass for all 31 fenced examples, 38 headings/anchors, 42 Markdown link destinations, 270 inline-code spans, front matter, and uppercase normative terms. The example content/order SHA-256 after Git newline normalization is f7d2fe9b4c16bd22690553fe56a833ab0c9b4ccc19d0e86077fb434531a59214. Manual review preserves lowercase obligations, ownership-controlled major-tag exceptions, external SHA requirements, compatibility, permissions, token scope, OIDC, untrusted-input controls, GHES exclusions, cancellation/result checks, and explicit failure behavior. Stable headings retain their wording, including the time-dependent concurrent-step title, idiomatic headings, and the behaviour heading/anchor. Native examples and comments retain their exact wording. Other owners' pages, generated indexes, configuration, scripts, tests, and dependencies have no diff.
| Verification | Result |
|---|---|
| Test-first prose observation | Seven expected prose failures before editing; preservation checks pass |
| Final temporary assertions | 15 pass; not a new repository test suite or full STE certification |
| Existing Markdown lint | One file, zero issues, shared configuration |
| Relative links and anchors | Pass: 130 files |
| Scoped cross-repository links | Pass: one link in the owned page |
| Existing Pester runner | Pass: 66 tests across six suites, zero failures or skips |
| Pinned Zensical 0.0.59 build | Pass: original configuration on an exact isolated source copy; no issues found |
| Rendered page | All 31 examples match source; revised prose and both explicitly checked stable anchors render |
| Diff and remote source | One owned file, no whitespace errors, all commits pushed |
The shared site executable was 0.0.50. The declared 0.0.59 dependency was restored in a session-local environment without changing the shared environment or repository manifests. An initial external-output configuration was rejected, so the existing command built an exact source copy outside the checkout with the original configuration. This was an environment/build-location adjustment, not a product change. The spelling observation excludes protected link destinations; no heading or anchor was changed to satisfy it.
Standards alignment uses the fixed documentation/writing standards and standard/guide templates. The result is a prose correction only; no framework-specific code changes apply. The scoped issue-convergence search finds this Task and #242, which explicitly excludes the owned page. No additional issue closes. #240 remains outside ownership.
The separate-versus-colocated workflow/action-library choice remains an unresolved policy question. The two lint-coverage descriptions are factual errors corrected in this same Task/PR, not policy decisions to defer. Final-head Docs and Cross-Repository Links CI pass. The explicitly requested review is APPROVED at the exact candidate, with zero new inline comments; the review-loop command exits 0. No writing or validation blocker remains. This PR remains draft; no ready, merge, auto-merge, or Agent merge action is authorized.
Review and CI at previous head 0ba7628
All final evidence refers to 0ba76283ef113db4eef91dda970f96486ee5a61d:
- Docs workflow: success.
- Cross-Repository Links workflow: success.
- Requested review: APPROVED, submitted at
2026-11-04T12:44:47Z, zero new inline comments. Its RESTcommit_idmatches the candidate.
The remote branch matches the candidate and the worktree is clean. The PR is open and draft, with auto_merge: null. No ready, merge, or Agent merge action was taken. The Task remains open for later review and merge. The temporary build copy, dependency environment, and unused derived configuration were cleaned up; local result logs and comparison JSON remain.
The requested parent-relative AGENTS.md is absent in this worktree layout. The repository's own AGENTS.md was read and followed. This did not block the scoped writing work or require an ownership change.
The final coordinator handoff was sent with the Task and draft PR URLs, immutable head, complete-read and changed/no-change evidence, concrete examples, validation results, exclusions, accepted differences, and retained owner questions. All assigned writing work is complete. This Task remains open for later review and merge of the draft.
Revision: factual lint coverage
The coordinator directed a narrow correction in this same Task and draft PR. No workflow, runtime, configuration, tooling, dependency, or authoring-policy change is included.
Verified sources and observations
Official actionlint source is fixed at rhysd/actionlint@011a6d15e749bb3f2d771eed9c7aa0e7e3e10ee7:
- ShellCheck integration documentation: actionlint applies ShellCheck to Bash/sh run scripts, detects the executable, and supports explicit disabling.
- ShellCheck dispatcher: supported shell names dispatch to ShellCheck; unsupported shells return without that check.
- Official example and expected diagnostics: SC2086 is expected for inline Linux Bash and explicitly selected Windows Bash at lines 6 and 14, not the default Windows PowerShell step at line 12.
- Separate Pyflakes integration: Python has a different optional integration. The correction must not imply that actionlint has no Python support merely because ShellCheck does not analyze Python.
Eight source/fixture consistency observations pass. These are source/test-fixture checks, not a local execution of actionlint or ShellCheck. A live local experiment is unavailable: native actionlint and ShellCheck are absent, the Docker Linux engine is unavailable, and its WSL distribution is stopped. No tool was installed and no runtime was started. The official source and independent expected diagnostic output establish the factual correction without a product/tooling change.
Before cases and acceptance
| At 0ba7628 | Required correction |
|---|---|
Linters, formatters, and editors cannot process that script as code |
State bounded inline Bash/sh support through actionlint and enabled, available ShellCheck. |
Tools can process the code only when it is in a file of its own language |
Describe the cross-language benefits of native standalone files, not exclusive tool capability. |
the shell of every run: step through shellcheck |
Limit the ShellCheck integration to supported Bash/sh scripts; do not imply PowerShell/Python coverage through ShellCheck. |
A workflow that breaks this standard fails the build |
State that lint checks do not detect every violation and require review of authoring rules, including skipped dependencies. |
Keep the complete non-trivial-script extraction requirement, required push/PR CI statement, and blocking/severity rules exactly unchanged from 0ba76283ef113db4eef91dda970f96486ee5a61d. Keep all 31 examples, 38 headings/anchors, 270 inline-code spans, front matter, and uppercase normative terms unchanged from the fixed campaign baseline. Preserve all 42 existing link destinations and permit only two additions: the official ShellCheck integration reference and the existing skipped-job section anchor. The two repository-layout policy sections remain exactly unchanged.
Test-first revision plan
- Verify immutable official documentation, implementation, tests, and example output; record the local live-experiment limitation.
- Run new repeatable observations before editing the page: six expected failures identify the missing coverage corrections and approved links; extraction, CI, severity, examples, and policy-preservation checks pass.
- Correct only the owned page's factual lint-coverage descriptions and standalone-file rationale.
- Compare the exact examples, extraction requirement, required CI, blocking criteria, and unchanged layout-policy sections; retain the updated link-addition record.
- Run applicable existing local checks, push the small correction commit, verify final-head CI/site validation, and request a review at the exact new source.
- Update both delivery records, report the new immutable head, and leave the PR draft without merge or automation changes.
Correction at 28947e5
The new immutable head is 28947e5248f162cd358a0b1fc45c7587fe60aa20. The narrow correction adds 16 lines and removes eight lines in the owned page. Six commits are now pushed in the same draft PR.
| Previous description | Corrected description |
|---|---|
Linters, formatters, and editors cannot process that script as code |
actionlint can send inline Bash and sh scripts to shellcheck when the integration is enabled and the executable is available. The following sentence excludes PowerShell/Python from that ShellCheck integration. |
Tools can process the code only when it is in a file of its own language |
Standalone source files give tools the script's native language and file context. They support language-specific linters such as ruff, formatters, type checkers, security scanners, and IDE features. |
the shell of every run: step through shellcheck |
The official ShellCheck integration checks inline Bash/sh run scripts when enabled and available. It does not check PowerShell or Python through ShellCheck. |
A workflow that breaks this standard fails the build |
The linters do not detect every violation of this standard. The page requires review of authoring rules and links to the skipped-job guidance. |
All 24 final temporary assertions pass. The 31 exact examples, their unchanged SHA-256 f7d2fe9b4c16bd22690553fe56a833ab0c9b4ccc19d0e86077fb434531a59214, all 38 headings/anchors, 270 inline-code spans, front matter, and uppercase normative terms remain preserved. The complete extraction bullet, required push/PR CI statement, severity/blocking criteria, and two layout-policy sections are exactly unchanged from the previous head. All 42 original link destinations remain; the two approved source/review references make 44 total.
Repeated local validation passes: Markdown lint (one file, zero issues), relative links (130 files), scoped cross-repository links (one link), and Pester (66 tests, six suites, zero failures or skips). No dependency or tool installation was performed.
The new-head Build job passes. The existing CI artifact 13325290117 was downloaded and inspected without executing site code. Ten render observations pass: all 31 examples exactly match the current source, the corrected bounded claims and extraction requirement render, both new references render, the false descriptions are absent, and the checked stable anchors remain. This is actual new-head site evidence, not the earlier local build reused as proof. Final overall Docs CI and Cross-Repository Links CI pass at the new head. The new requested review is APPROVED at that exact source, with zero new inline comments; review-loop exit 0.
Only the separate-versus-colocated workflow/action-library choice remains an unresolved policy question. The two coverage errors are corrected here and are not deferred to an owner decision.
Final revision validation
All final evidence refers to 28947e5248f162cd358a0b1fc45c7587fe60aa20:
- Docs CI: success.
- Cross-Repository Links CI: success.
- Build job: success. Its logs confirm
zensical==0.0.59, successful installation of that version, andNo issues found. - New requested review: APPROVED, submitted at
2026-11-04T13:06:46Z, zero new inline comments. Its RESTcommit_idmatches the new head. The review-loop command exits 0.
The new-head artifact passes ten render observations, including all 31 exact examples and the bounded coverage statements. The temporary artifact download was removed after inspection. The source/fixture observations, before/after comparison, render report, and build/review logs remain local. No local tooling installation, runtime start, or repository workflow/configuration/tooling change was performed. No live local ShellCheck execution is claimed.
The saved PR body now states the final source and complete new evidence. It classifies the two coverage errors as fixed here, not deferred policy. The only unresolved policy question is the separate-versus-colocated workflow/action-library choice, whose sections remain exactly unchanged. No writing or final-head validation blocker remains.
The PR is open and DRAFT, with auto_merge: null. The remote branch matches the new immutable head and the worktree is clean. The final revised handoff was sent with the new head, source/fixture evidence, before/after cases, preservation record, final-head validation, and review; this Task stays open for later review and merge.
The revised coordinator handoff is complete at 28947e5248f162cd358a0b1fc45c7587fe60aa20. The two factual coverage errors are fixed in the existing draft PR. Only the unchanged layout-policy question remains unresolved. Every revision-plan item is complete; the GitHub Task remains open for later review and merge.
Activity
MariusStorhaug commentedon Nov 4, 2026
Test-first baseline recorded before page edits: seven concrete prose assertions fail as expected. All seven preservation checks pass. The page has 31 fenced examples, 38 headings, 42 link targets, and 270 inline-code spans. Uppercase normative terms are MUST, MAY, and MUST NOT. Existing checks pass: Markdown lint (one file), relative links (130 files), scoped cross-repository links (one link), and Pester (66 tests across six suites). The local Zensical executable is 0.0.50, but requirements.txt pins 0.0.59; the final build must use the declared version or report this mismatch. No page or repository tooling has changed.
MariusStorhaug commentedon Nov 4, 2026
The first complete prose improvement is committed and pushed in 6fa38a0. The draft is open at #264. The opening and manual-audit slice passes all ten scoped assertions, Markdown lint, and whitespace checks. All protected content remains unchanged. The declared Zensical 0.0.59 dependency is restored in a session-local environment; the shared Python environment and repository manifests are unchanged. The remaining page review continues in the draft.
MariusStorhaug commentedon Nov 4, 2026
The permission, token, untrusted-input, job-structure, skipped-dependency, and concurrent-step prose is clarified in the next pushed commit. All 12 scoped assertions pass, including the seven baseline-preservation checks; Markdown lint and whitespace checks pass. The concurrent-step prose now states the default model and compatibility requirements without rollout history. The existing heading and all executable examples remain unchanged. Review of action reuse, script authoring, and diagnostics continues in the same draft.
MariusStorhaug commentedon Nov 4, 2026
Reusable automation and scripting-choice prose is clarified in another logical commit and pushed. The action/workflow distinction, promotion boundary, owned-tag exception, separate versioning, self-checkout limitations, GHES exclusions, and ordered PowerShell/module/Bash choices retain their technical meaning. All 12 current scoped assertions, Markdown lint, and whitespace checks pass. The known self-checkout policy contradiction remains explicit and unresolved; no policy is selected.
MariusStorhaug commentedon Nov 4, 2026
The issue body now records two additional baseline enforcement-coverage contradictions: inline-script lint visibility versus actionlint/shellcheck coverage, and a blanket build-failure claim versus the documented skipped-dependency gap. The prose work does not resolve these technical claims or add enforcement. They remain owner decisions outside this delivery leaf.
MariusStorhaug commentedon Nov 4, 2026
Action extraction, input/output design, defaults, module naming, toolchain, README, and colocated-action prose is clarified and pushed. All 13 current scoped assertions pass; Markdown lint and whitespace checks pass. Native examples and every inline-code span remain unchanged. The review retains both incompatible self-checkout policies and the existing lint-coverage claims; those contradictions are recorded in the issue body rather than resolved by a writing change.
MariusStorhaug commentedon Nov 4, 2026
The final prose slice is committed and pushed. All 15 local prose/preservation assertions pass, and the complete revised page has been read (1,364 lines). Markdown lint and whitespace checks pass; relative links pass across 130 files; the owned-page cross-repository check resolves one link; Pester passes 66 tests across six suites. Zensical 0.0.59 builds an exact session-local copy with the original configuration and reports no issues. The rendered page retains all 31 examples exactly and both explicitly checked stable anchors. The initial external-output config attempt was rejected by the builder, so the existing build command ran on an isolated source copy instead; repository configuration is unchanged. Final review and durable handoff evidence follow in the draft.
MariusStorhaug commentedon Nov 4, 2026
The issue body now records the complete prose result, immutable candidate, before/after examples, preserved technical surfaces, local validation, accepted differences, scoped convergence result, and retained owner questions. Implementation and local validation are complete. Final-head review/CI and the coordinator handoff remain in progress; the PR stays draft.
MariusStorhaug commentedon Nov 4, 2026
Final-head CI and the requested review are complete. Docs and Cross-Repository Links pass. The review is APPROVED at 0ba7628 with zero new inline comments. The PR description and Task body now retain the final source, read/preservation evidence, before/after examples, validation, accepted differences, and three retained technical owner questions. No writing or validation blocker remains. The coordinator handoff is the final planned action; the PR stays draft and this Task stays open.
MariusStorhaug commentedon Nov 4, 2026
The final handoff was sent to the campaign coordinator with all requested source, scope, before/after, preservation, validation, and owner-question evidence. Every implementation-plan item is complete. The PR remains DRAFT at 0ba7628. This delivery Task stays open for later review and merge.
MariusStorhaug commentedon Nov 4, 2026
The issue body now classifies the two lint-coverage descriptions as factual errors to correct in this same PR, not policy questions. Official actionlint sources are pinned and verified, including the independent example diagnostics and separate Pyflakes support. Six new acceptance observations fail before page edits, while the extraction/CI/severity/policy guards pass. Only the repository-layout choice remains unresolved policy. No native tooling or runtime was installed or started.
MariusStorhaug commentedon Nov 4, 2026
The bounded lint-coverage correction is committed and pushed. All 24 temporary assertions pass. The 31 exact examples, 38 headings, 270 inline-code spans, original 42 link destinations, front matter, and normative terms are preserved. Two approved links are added. The full extraction bullet, required push/PR CI statement, severity/blocking criteria, and layout-policy sections are exactly unchanged from 0ba7628. Markdown lint, relative links (130 files), the scoped cross-repository check (one link), and all 66 Pester tests pass. Final-head CI/site evidence and a new requested review follow; the PR stays draft.
MariusStorhaug commentedon Nov 4, 2026
The Task now records the new head, concrete before/after coverage cases, revised 42-plus-two link record, and exact requirement/example/policy guards. Local checks and the exact-head CI Build job pass. The downloaded new-head site artifact passes all ten render observations, including all 31 unchanged examples and the corrected coverage text. The new automated review and final overall CI result remain pending. Only the repository-layout choice remains policy; the two coverage errors are fixed.
MariusStorhaug commentedon Nov 4, 2026
The factual coverage revision is complete at 28947e5. Final-head Docs and Cross-Repository Links CI pass. CI logs verify Zensical 0.0.59; the new-head site artifact passes all ten render observations. The new requested review is APPROVED at the exact head with zero new inline comments. Task/PR evidence is updated, the extraction/CI/severity requirements remain exact, and only the layout-policy question remains unresolved. The PR stays draft; the revised coordinator handoff follows.
MariusStorhaug commentedon Nov 4, 2026
The revised final handoff was sent with head 28947e5 and the new source, before/after, exact-preservation, CI/site, and approval evidence. All revision-plan items are complete. The two coverage errors are fixed, not deferred. Only the unchanged layout-policy question remains open. The PR stays DRAFT and this Task remains open for later merge.
MariusStorhaug commentedon Nov 4, 2026
The retained, independently actionable workflow/action colocation contract is now owned by #278. It records the exact separate-repository versus only-caller/self-checkout evidence without choosing a layout policy. Inline-lint coverage and universal-CI claims were already corrected in the writing delivery and receive no duplicate issue. This follow-up stays outside #264's closing references.