Skip to content

feat(runner-policy): review issue-triage-label.yml@c5e729c reusable contract - #236

Merged
kyle-sexton merged 1 commit into
mainfrom
feat/235-issue-triage-label-runner-contract
Jul 21, 2026
Merged

feat(runner-policy): review issue-triage-label.yml@c5e729c reusable contract#236
kyle-sexton merged 1 commit into
mainfrom
feat/235-issue-triage-label-runner-contract

Conversation

@kyle-sexton

Copy link
Copy Markdown
Contributor

Closes #235

Summary

Registers ci-workflows' issue-triage-label reusable workflow as a
reviewed runner-input contract in components/runner-policy/policy.json,
pinned to its merged SHA c5e729c0af0e55ffed4675ec85c1b57356fef79e:

"melodic-software/ci-workflows/.github/workflows/issue-triage-label.yml@c5e729c0af0e55ffed4675ec85c1b57356fef79e": {
  "routing": "runner-input",
  "runnerInput": "runner",
  "allowedInputs": ["runner", "label", "label-prefix"],
  "allowedSecrets": {},
  "allowedCallerPermissions": { "issues": "write" }
}
  • allowedInputs covers the reusable's full workflow_call.inputs surface
    (runner, label, label-prefix) — a caller may pass any subset.
  • allowedSecrets: {} — the reusable takes no secrets.
  • allowedCallerPermissions: { issues: write } — the reusable's job needs
    exactly issues: write to read and add labels; no contents (no checkout).
  • No selectorResultInput — the reusable has no chained-selector
    (prerequisite-result-style) input.

Locally verified: npm run test:runner-policy (227/227 passing),
npm run lint:runner-policy ("Runner policy passed."), npm run lint:md,
npm run lint:hooks, plus lefthook's pre-commit gate (typos, gitleaks,
editorconfig, biome) on commit.

Related

Test plan

  • npm run test:runner-policy (227 passing)
  • npm run lint:runner-policy ("Runner policy passed.")
  • npm run lint:md
  • npm run lint:hooks
  • lefthook pre-commit gate (typos, gitleaks, editorconfig, biome)

…ontract

Registers ci-workflows' issue-triage-label reusable (merged as
ci-workflows#191, dogfooded via ci-workflows#195's self-caller and
proven end-to-end by ci-workflows#192) as a runner-input contract:
allowedInputs covers its full workflow_call surface (runner, label,
label-prefix), no secrets, and allowedCallerPermissions limited to the
issues: write the reusable's job actually needs.

Closes #235
@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 42s —— View job


PR Review

  • Gather context
  • Read changed files and REVIEW.md
  • Analyze the policy.json entry for correctness and security
  • Post review findings

File reviewed: components/runner-policy/policy.json

Summary: Clean, minimal addition. The new contract is structurally consistent with its peers, the permission surface is tight, and no secrets are introduced. No blocking issues found.


Structural correctness

The new entry conforms to every pattern established by existing runner-input contracts:

Field Value Assessment
routing runner-input Correct for a reusable that accepts a runner input
runnerInput runner Matches the conventional input name
allowedInputs ["runner", "label", "label-prefix"] PR states this is the full workflow_call.inputs surface — author-attested
allowedSecrets {} Correct; reusable takes no secrets
allowedCallerPermissions { "issues": "write" } Matches minimum needed for label operations
selectorResultInput (absent) Correct; no chained-selector (prerequisite-result-style) input

The SHA is a pinned, immutable commit reference (c5e729c0af0e55ffed4675ec85c1b57356fef79e), not a branch or tag — consistent with the threat model requirement that workflow identities be immutable.


Security (REVIEW.md "always check" criteria)

  • No secrets in tracked source: allowedSecrets: {} — nothing to expose. ✓
  • Permission minimality: Only issues: write is granted. No contents permission, confirming no checkout path is needed. Comparing against link-check.yml and pulumi-version-drift-check.yml which do grant contents: read alongside issues: write (because they checkout), the absence of contents here is intentional and correct. ✓
  • No injection surface: This is a JSON configuration addition with no string interpolation or dynamic evaluation paths. ✓
  • Other REVIEW.md "always check" criteria (object-level authorization, multi-tenancy scoping, audit logging, atomicity) are not applicable to a config-only addition.

Minor observation

The allowedInputs list is author-attested against the live workflow but cannot be independently verified in this review (the workflow definition lives in melodic-software/ci-workflows at that SHA). The cross-references in the PR body — ci-workflows#191 (the reusable), ci-workflows#195 (dogfood self-caller at the same SHA), and ci-workflows#192 (end-to-end proof) — provide strong corroborating evidence. This is consistent with how other contracts in this file are registered.


Verdict: LGTM. The entry is minimal, correctly structured, and the permission surface matches what label-only issue operations require.

@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Operator basis recorded (in-session approval, 2026-07-21 ~16:5xZ): operator approved merging this runner-policy allowlist entry via explicit in-session confirmation to the control tower. 227/227 policy tests green; the workflow it authorizes is merged and runtime-proven (ci-workflows#192 e2e). Merging under that recorded basis.

This was generated by AI (control tower, session 6).

@kyle-sexton
kyle-sexton merged commit 372bcc4 into main Jul 21, 2026
42 checks passed
@kyle-sexton
kyle-sexton deleted the feat/235-issue-triage-label-runner-contract branch July 21, 2026 16:57
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.

feat(runner-policy): review issue-triage-label.yml@c5e729c reusable contract

1 participant