Skip to content

Label Application Safety Guarantees โ€‹

Date: 2026-01-15
Status: โœ… Active
Related: .github/workflows/issue-triage.yml, .github/workflows/config/triage-categories.json

Overview โ€‹

The AI issue triage workflow (issue-triage.yml) applies labels to GitHub issues using a non-destructive append-only approach. This document guarantees that no existing labels will be overwritten or removed.

Safety Guarantee โ€‹

CRITICAL: The workflow uses gh issue edit --add-label which has these properties:

  1. Append-only: Only ADDS labels, never removes existing ones
  2. Idempotent: If a label already exists, command returns success without duplicating
  3. Non-destructive: No delete or overwrite logic exists in the workflow
  4. Reversible: Labels can be manually removed by humans if needed

Implementation โ€‹

Label Application Logic โ€‹

The workflow applies labels in this step (lines 183-205 in issue-triage.yml):

bash
# Convert comma-separated labels to array format for gh cli
IFS=',' read -ra LABEL_ARRAY <<< "$LABELS"

# Add each label with error handling
FAILED_LABELS=""
for label in "${LABEL_ARRAY[@]}"; do
  label=$(echo "$label" | xargs) # trim whitespace
  echo "Adding label: $label"
  
  # SAFE: --add-label only adds, never removes
  if gh issue edit "$ISSUE_NUMBER" --add-label "$label" 2>/dev/null; then
    echo "โœ… Applied: $label"
  else
    echo "โš ๏ธ Failed to apply: $label"
    FAILED_LABELS="$FAILED_LABELS,$label"
  fi
done

Key Safety Properties โ€‹

PropertyGuaranteeEvidence
No DeletionsNever removes labelsUses --add-label only, no --remove-label calls
No OverwritesNever replaces labelsNo --set-label or destructive operations
IdempotencySafe to run multiple timesGitHub CLI handles duplicate label adds gracefully
Error HandlingGraceful fallback on failureLogs failures but doesn't roll back existing labels
Existing DataPreserves manually-added labelsAppend-only model means human labels stay

Testing โ€‹

Test Coverage โ€‹

The workflow safety is verified by:

  1. Unit Tests (src/__tests__/workflows/ai-issue-triage.test.js):

    • Tests label parsing from AI response
    • Tests invalid label rejection
    • Tests format validation
  2. Mock Tests (src/__tests__/workflows/ai-issue-triage-mock.test.js):

    • Simulates label application with realistic responses
    • Verifies label arrays are properly formatted
  3. Real API Tests (src/__tests__/workflows/ai-issue-triage-real.test.js):

    • Applies labels to actual test issues
    • Verifies end-to-end workflow safety

Test Status: 44/44 tests passing โœ…

Manual Testing โ€‹

To verify safety locally, run:

bash
# Test with dry-run (no actual label application)
./.github/workflows/test-ai-triage.sh --dry-run

# Test with mock API (applies labels to test issue)
./.github/workflows/test-ai-triage.sh --mock

# Test with real API (applies labels to actual issue)
./.github/workflows/test-ai-triage.sh --real

Failure Modes โ€‹

Scenario 1: Label Already Exists โ€‹

What happens: GitHub CLI returns success, no duplicate created
User impact: Label appears once (correct)
Workflow status: Success โœ…

Scenario 2: Label Doesn't Exist in Project โ€‹

What happens: Label creation fails (workflow policy), error logged
User impact: Issue triaged, label not applied
Workflow status: Success with warning โš ๏ธ
Note: Issue triage suggestion comment still posted with explanation

Scenario 3: API Authentication Fails โ€‹

What happens: Label application skipped, error logged
User impact: Issue triaged, labels not applied
Workflow status: Graceful degradation โš ๏ธ
Note: Triage suggestion comment still provided

Scenario 4: GitHub Service Outage โ€‹

What happens: Label application fails with timeout
User impact: Issue triaged, labels not applied
Workflow status: Graceful degradation โš ๏ธ
Note: Triage suggestion still helpful to human reviewers

Data Integrity โ€‹

What Cannot Be Lost โ€‹

  • โœ… Existing labels added by humans
  • โœ… Existing labels added by other workflows
  • โœ… Issue title, description, assignees
  • โœ… Any metadata from issue creation

What Can Change โ€‹

  • โœ… New labels added by this workflow (append-only)
  • โœ… Category field (if created in GitHub Projects V2)
  • โœ… Triage comment (posted, not modifying existing comments)

Validation โ€‹

Pre-Deployment Validation โ€‹

The workflow includes validation to prevent invalid labels:

javascript
// From issue-triage.yml lines 60-85
const VALID_LABELS = [
  'bug', 'documentation', 'duplicate', 'enhancement',
  'good first issue', 'help wanted', 'invalid',
  'question', 'wontfix'
];

// Only labels in VALID_LABELS are applied
const filtered = labels.filter(l => VALID_LABELS.includes(l));

Configuration Validation โ€‹

Separate validation workflow (validate-triage-config.yml) ensures:

  • Category JSON is valid
  • Categories match GitHub Projects V2 (if field exists)
  • Configuration changes are reviewed before merge

See docs/engineering/deployment/VALIDATE_TRIAGE_CONFIG.md for validation details.

Rollback Procedures โ€‹

If labels need to be corrected:

Manual Removal โ€‹

  1. Go to GitHub issue
  2. Click "Label" button in sidebar
  3. Uncheck unwanted labels
  4. Close issue (labels persist)

Automation (If Needed) โ€‹

Create workflow to remove labels with --remove-label (does not exist yet, can be added if needed)

Monitoring โ€‹

Monitor for issues:

  1. Workflow Logs (Actions tab โ†’ Issue Triage โ†’ recent runs)

    • Check for โš ๏ธ Failed to apply messages
    • Check for API error logs
  2. Issue Comments (individual issues)

    • Verify triage suggestion posted
    • Check category field if applicable
  3. Configuration Drift (.github/workflows/config/)

    • Run validation script: ./.github/workflows/validate-triage-config.sh
    • Check GitHub Actions validation workflow status

Audit Trail โ€‹

Every label application is logged:

  1. GitHub Actions Logs (action runner output)

    • Timestamp of label application
    • Success/failure status
    • Which labels were applied
  2. Issue Timeline (GitHub issue history)

    • Visible in "Show more" on older events
    • "labels added by: GitHub" on timeline
  3. Audit Logs (if GitHub Enterprise)

    • Full audit trail of label changes
    • User/automation attribution

See Also โ€‹

Built with VitePress