How the owner-liveness-sweep GitHub Action Monitors Plugin Health in the Claude Plugins Community
The owner-liveness-sweep GitHub Action is a daily, read-only workflow that validates plugin source owner identities by comparing current GitHub account IDs against a persistent baseline, flagging any identity changes, missing owners, or repository drift for human review.
The owner-liveness-sweep workflow protects the integrity of the Claude plugins marketplace by ensuring every plugin's source owner remains authentic and reachable. Running daily before version bumps, this action in the anthropics/claude-plugins-community repository detects account hijacking, ownership transfers, and repository disappearances without modifying marketplace data.
How the Sweep Scans the Marketplace
The action begins by reading .claude-plugin/marketplace.json to extract every distinct GitHub owner/repo pair. This manifest serves as the source of truth for all published plugins.
The core orchestration happens in scripts/sweep.sh, which feeds these owners into GitHub's GraphQL API. For each login, it resolves the current account ID—a stable numeric identifier that survives renames but changes when a login is released and re-registered by a different entity.
Six Categories of Drift Detection
The sweep classifies findings into distinct failure modes. These categories appear in workflow logs, step summaries, and JSON artifacts:
| Category | Trigger | Severity |
|---|---|---|
| identity_changed | Login resolves to a different account ID than baselined | ❌ Fails workflow |
| owner_missing | Login no longer resolves at all | ⚠️ Warning |
| repo_moved | Repository's canonical nameWithOwner differs from stored value |
⚠️ Warning |
| repo_missing | Repository deleted or made private | ⚠️ Warning |
| unbaselined | Live owner not yet in baseline (new plugin) | ℹ️ Informational |
| baseline_orphans | Owners in baseline with no marketplace entries | ℹ️ Informational |
The identity_changed finding is deliberately destructive: the workflow aborts immediately, forcing manual intervention before any automated baseline updates.
Baseline Maintenance: Additive-Only Protection
The baseline file .github/owner-baseline.json stores the historic mapping of login → account_id. The sweep's refresh mode operates under strict constraints:
- Adds newly discovered live owners (
unbaselined) - Removes orphaned entries with no marketplace presence
- Never overwrites an existing ID, even if GraphQL returns a different value
This design prevents silent acceptance of account hijacking. When identity_changed is detected, the refresh is blocked entirely.
Running the Sweep Locally
Mirror CI behavior for debugging or pre-flight checks:
MARKETPLACE_PATH=.claude-plugin/marketplace.json \
BASELINE_PATH=.github/owner-baseline.json \
MODE=report \
bash .github/actions/owner-liveness-sweep/scripts/sweep.sh
The MODE=report setting ensures read-only operation—safe for local development without write permissions.
CI Integration and Failure Handling
The production workflow .github/workflows/owner-liveness-sweep.yml executes:
- uses: ./.github/actions/owner-liveness-sweep
with:
marketplace-path: .claude-plugin/marketplace.json
baseline-path: .github/owner-baseline.json
mode: report
When identity drift occurs, the log contains explicit failure markers:
❌ identity_changed: login "exampleOwner" now resolves to ID 123456 (was 654321)
Remediation requires locating all plugins under that owner in the marketplace, verifying legitimacy, and manually updating entries before the baseline can refresh.
Test Coverage and Validation
The test-sweep.sh script provides hermetic unit tests for the action's logic. These tests run as part of validate-plugins.yml, ensuring sweep behavior remains correct across repository changes. The test suite covers GraphQL response parsing, drift classification, and baseline update decisions without requiring live GitHub API calls.
Key Files and Their Roles
.github/workflows/owner-liveness-sweep.yml— Daily scheduled workflow definition.github/actions/owner-liveness-sweep/scripts/sweep.sh— Core resolution and detection logic.github/actions/owner-liveness-sweep/test-sweep.sh— Automated test suite.github/owner-baseline.json— Persistent owner-to-ID mapping.claude-plugin/marketplace.json— Plugin manifest driving the scan.github/actions/owner-liveness-sweep/README.md— Complete documentation of detection categories and usage
Summary
- The owner-liveness-sweep action runs daily, before automated version bumps, to catch ownership problems early
- It detects six categories of drift, with
identity_changedas the only workflow-failing condition - The account ID comparison prevents silent acceptance of re-registered logins—a security-critical design
- Additive-only baseline updates ensure no existing identity mapping is ever overwritten automatically
- Local execution via
sweep.shsupports debugging with identical logic to CI - Comprehensive tests in
test-sweep.shvalidate behavior without live API dependencies
Frequently Asked Questions
What happens when a GitHub username changes?
The sweep handles this transparently. Username changes preserve the account ID, so no drift is detected. However, if the repository was transferred to a different account, the repo_moved or identity_changed category will flag it depending on whether the new owner has a different ID.
Why does identity_changed fail the workflow while other findings only warn?
identity_changed indicates a login was released by GitHub (typically after 90 days of inactivity) and re-registered by a different entity. This is the primary attack vector for repository namespace hijacking. The hard failure forces human verification that the new owner is legitimate before any automated processes continue.
Can I run the sweep against a custom marketplace file?
Yes. The marketplace-path input accepts any valid path. For testing proposed marketplace changes:
MARKETPLACE_PATH=my-test-marketplace.json \
BASELINE_PATH=.github/owner-baseline.json \
MODE=report \
bash .github/actions/owner-liveness-sweep/scripts/sweep.sh
How does the sweep distinguish owner_missing from repo_missing?
When a login fails to resolve, the sweep performs successor verification—attempting to resolve any of that owner's previously known repositories directly. If repositories still resolve under a new owner, this suggests a transfer rather than deletion, and the finding is categorized accordingly for review.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →