Skip to content

ADR-014: GitHub Action v2 Design

Status: Implemented Date: 2026-01-28 Deciders: @Rul1an

Context

The current assay-action@v1 provides basic coverage checking. The AI-assisted development landscape has shifted significantly:

  1. GitHub SARIF Change (July 2025): GitHub stopped merging multiple runs with same tool+category in one SARIF file. Uploads can now fail silently.
  2. Agent-heavy workflows: More iterations, more supply-chain risk, need for verifiable outputs.
  3. Shift from "test runners" to "quality gates": Binary pass/fail → multi-dimensional evaluation.

Two design proposals were evaluated. This ADR captures the combined decision.

Decision

Architecture: Separate Repository

Repository: https://github.com/Rul1an/assay/tree/main/assay-action Marketplace: https://github.com/marketplace/actions/assay-ai-agent-security

Factor Decision Rationale
Repository Separate GitHub Marketplace requires action.yml in root
Reference Rul1an/assay/assay-action@v2 Simple, short, marketplace-friendly
Composability Deferred to v2.1 Simplicity first, sub-actions later

Note: Initial design was monorepo (assay/assay-action/), but GitHub Marketplace doesn't support subdirectory actions for automatic listing. Moved to separate repo for better DX and discoverability.

Core Capability: Verify + Lint + Diff → SARIF

- uses: Rul1an/assay/assay-action@v2

Default behavior (zero-config): 1. Auto-detect bundles: **/*.tar.gz under .assay/evidence/ 2. assay evidence verify all bundles 3. assay evidence lint --format sarif 4. Upload SARIF to GitHub Code Scanning 5. Post PR comment (only if findings or delta) 6. Upload artifacts (bundle, lint.json, diff.json)

SARIF Discipline (Critical)

Per GitHub's July 2025 change:

# Auto-generated (matrix-safe): workflow + job + runner.os
# Default: "assay-${{ github.workflow }}-${{ github.job }}-${{ runner.os }}"
category: "assay-ci-lint-Linux"
  • Matrix-safe: Auto-includes runner.os to prevent collisions in matrix builds
  • One SARIF run per bundle per job
  • Explicit automationDetails.id for fingerprint stability
  • SARIF 2.1.0 only
  • upload-sarif pinned to SHA for supply-chain security

Input Contract

Input Type Default Description
bundles glob **/*.tar.gz Evidence bundle pattern
fail_on enum error error, warn, info, none
sarif bool true Upload to Code Scanning
category string auto SARIF category (auto-generated if omitted)
baseline_dir path - Path to baseline bundles
baseline_key string - Key for baseline lookup
write_baseline bool false Write baseline (main branch only)
comment_diff bool true Post PR comment with diff
upload_artifacts bool true Upload bundles + reports
compliance_pack string - e.g., eu-ai-act@1.0.0

Output Contract

Output Type Description
verified bool All bundles passed verification
findings_error int Count of error-level findings
findings_warn int Count of warn-level findings
sarif_path path Path to generated SARIF
sarif_uploaded bool Whether SARIF was uploaded to Code Scanning
diff_summary string One-line diff summary
diff_new_findings int Count of new findings vs baseline

Exit Codes

Code Meaning
0 Success, no findings above threshold
1 Findings exceed fail_on threshold
2 Verification failed (bundle integrity)
3 Configuration error

Artifacts Uploaded

assay-evidence-${{ github.run_id }}/
├── bundles/
│   └── *.tar.gz
├── lint.json
├── lint.sarif
├── diff.json
└── summary.md

PR Comment Format

## 🛡️ Assay Evidence Report

| Check | Status |
|-------|--------|
| Verified | ✅ 3/3 bundles |
| Lint | ⚠️ 2 warnings |
| Baseline | ✅ No regressions |

<details>
<summary>Diff vs baseline</summary>

| Category | Added | Removed |
|----------|-------|---------|
| Hosts | +1 (api.new.com) | - |
| Files | - | -2 |

</details>

📦 [View artifacts](link) | 🔍 Run locally: `assay evidence explore bundle.tar.gz`

GitHub Job Summary

Always written. Contains: - Verification status per bundle - Findings by severity (table) - Top 3 new hosts/files/processes (if baseline provided) - Link to artifacts

Permissions Required

permissions:
  contents: read          # Checkout
  security-events: write  # SARIF upload
  pull-requests: write    # PR comment (optional)

Rationale

Why Combined Approach

Source Contribution
Analysis 1 Adoption tiers, MCP integration, monorepo decision
Analysis 2 SARIF discipline, concrete contract, "no noise" principle

Why Not Sub-Actions (Yet)

Sub-actions (/setup, /lint, /evidence) add complexity: - More repos/paths to maintain - Version matrix explosion - User confusion on composition

Decision: Ship v2.0 as single action, evaluate sub-actions for v2.1 based on user feedback.

Why Not Reusable Workflow (Yet)

Reusable workflows are powerful for enterprise standardization but: - Require workflow_call trigger (breaks simple adoption) - Less flexible for customization - Can be added later as assay/workflows/

Implementation Phases

v2.0 (MVP) ✅ Completed

  • Zero-config auto-discovery
  • SARIF upload with correct category discipline (matrix-safe: includes runner.os)
  • PR comment with diff (no noise if clean)
  • Baseline regression gate (cache-based, fingerprint comparison)
  • GitHub Job Summary (includes SARIF upload status warning)
  • Artifact upload (with include-hidden-files fix for .assay-reports/)
  • Separate repository for Marketplace publication
  • Upload failure detection (sarif_uploaded output + warning)
  • Cross-platform temp file handling (RUNNER_TEMP)
  • Supply-chain security: upload-sarif pinned to SHA
  • Privacy: workingDirectory removed from SARIF (no path leakage)

v2.1

  • assay init command (generates starter workflow)
  • Compliance pack support (--pack eu-ai-act@1.0.0)
  • Coverage badge generation
  • MCP config scanning (mcp-scan: true)

v2.2+

  • Composable sub-actions
  • Sigstore attestation
  • Rekor transparency logging
  • LangSmith/Braintrust trace ingestion

Consequences

Positive

  • 1-minute adoption for new users
  • Native GitHub Security tab integration
  • Verified-only diff prevents false positives
  • Artifact trail for auditors

Negative

  • Single action = less granular caching
  • SARIF category naming requires user awareness for matrix builds

Risks

Risk Mitigation
SARIF rejection Auto-generate unique category per job
Noisy PR comments Only comment if findings or delta
Slow binary download Cache binary in toolcache pattern

References