Context
During PR #340, plugins/claude-code/review-utils/actions/run-agent/action.yaml was accidentally corrupted into a base64-encoded blob (twice — see ff846e8 and c86f5424, both flagged by henry-nsheaps[bot]'s review). The existing mise run lint pipeline (Prettier-check + tsc --noEmit + shell-syntax + plugin validate) did not catch either corruption, because a base64 blob is itself a technically valid YAML scalar document — yaml.safe_load() succeeds, it just returns a string instead of the expected mapping.
Proposal
Add actionlint (schema-aware, validates runs.using/runs.steps[*].uses|run for composite actions) or a yamllint rule requiring a mapping at the document root, scoped to plugins/**/*.yaml. Either would have caught both corruption commits before merge, since a single-scalar document fails a composite-action schema check even though it parses as valid YAML.
Acceptance criteria
References
Context
During PR #340,
plugins/claude-code/review-utils/actions/run-agent/action.yamlwas accidentally corrupted into a base64-encoded blob (twice — seeff846e8andc86f5424, both flagged byhenry-nsheaps[bot]'s review). The existingmise run lintpipeline (Prettier-check +tsc --noEmit+ shell-syntax + pluginvalidate) did not catch either corruption, because a base64 blob is itself a technically valid YAML scalar document —yaml.safe_load()succeeds, it just returns a string instead of the expected mapping.Proposal
Add
actionlint(schema-aware, validatesruns.using/runs.steps[*].uses|runfor composite actions) or ayamllintrule requiring a mapping at the document root, scoped toplugins/**/*.yaml. Either would have caught both corruption commits before merge, since a single-scalar document fails a composite-action schema check even though it parses as valid YAML.Acceptance criteria
mise run lint(or equivalent CI job) coveringplugins/**/*.yamlplugins/**/*.yamlcomposite actionsReferences