Skip to content

Security lane's execution verdict is readable only by grepping its job log #460

Description

@kyle-sexton

Problem

The claude-security-review reusable computes an authoritative verdict on every run — the claude-lane-outcome composite classifies the attempt into review-ran / review-failed / failure-class — but that verdict never leaves the job. on.workflow_call declares no outputs:, and the security-review job declares none either, so a caller that must decide whether a review actually happened has nothing to read.

The only remaining channel is the job log, and the log is not a contract. melodic-software/claude-code-plugins#2517 is what that costs: its verify-security-review-evidence.sh guard grepped the log for the phrases that name a workflow-validation skip and matched the inline github-script SOURCE that mentions them as string literals, so the guard reddened exactly the in-scope pull requests it exists to approve. The fix there anchored the grep to ##[warning]/##[error] annotation lines, which works but keeps the consumer coupled to log text that no test in this repository pins.

Proposal

Surface the verdict as declared workflow_call outputs:

  • relevant — from the changes job, so a consumer can tell an out-of-scope skip from a no-verdict skip
  • review-ran, review-failed, failure-class — forwarded from the security-review job's review-outcome step

review-detail stays unsurfaced: it is free-text prose shaped for a human reading a marker comment, and a consumer branching on it would be back to parsing prose.

The change is additive — no existing input, job name, check name, or permission changes — so consumers pinned to the current release are unaffected until they re-pin.

Acceptance

  • on.workflow_call.outputs declares the four outputs, each documented with what an EMPTY value means (the job did not run).
  • A contract test pins the wiring and the agreement between the workflow's output names and the composite's declared names, so a rename cannot silently empty them.
  • claude-code-plugins can then replace its gh run view --log grep with needs.<job>.outputs.* (tracked separately in that repository).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions