{"id":47593760,"url":"https://github.com/raiderrobert/ownrs","last_synced_at":"2026-04-01T17:49:17.840Z","repository":{"id":345357067,"uuid":"1168698941","full_name":"raiderrobert/ownrs","owner":"raiderrobert","description":"Auditing ownership of repos","archived":false,"fork":false,"pushed_at":"2026-03-26T22:42:39.000Z","size":155,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-27T05:38:47.823Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/raiderrobert.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-27T17:37:27.000Z","updated_at":"2026-03-26T22:42:34.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/raiderrobert/ownrs","commit_stats":null,"previous_names":["raiderrobert/ownrs"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/raiderrobert/ownrs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raiderrobert%2Fownrs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raiderrobert%2Fownrs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raiderrobert%2Fownrs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raiderrobert%2Fownrs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/raiderrobert","download_url":"https://codeload.github.com/raiderrobert/ownrs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raiderrobert%2Fownrs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290619,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-01T17:49:17.177Z","updated_at":"2026-04-01T17:49:17.829Z","avatar_url":"https://github.com/raiderrobert.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ownrs\n\nFind out who owns what across your GitHub org.\n\nReconciles three ownership signals — CODEOWNERS, Backstage `catalog-info.yaml`, and GitHub team permissions — and tells you where they agree, disagree, or have gone stale.\n\n## Install\n\n```bash\ncurl -sSL https://raw.githubusercontent.com/raiderrobert/ownrs/main/install.sh | sh\n```\n\nOr with cargo:\n\n```bash\ncargo install --path .\n```\n\nRequires a GitHub token with `read:org` and `repo` scopes. If you have the [GitHub CLI](https://cli.github.com) installed and authenticated, ownrs picks up your token automatically. Otherwise:\n\n```bash\nexport GITHUB_TOKEN=\u003cyour-token\u003e\n```\n\n## Quick Start\n\n```bash\n# See the full picture for your org\nownrs org my-org --detail\n\n# Which repos does my team own?\nownrs org my-org --team platform\n\n# What's broken? Show stale and mismatched repos\nownrs org my-org --status stale,mismatched --format csv\n\n# Check a single repo\nownrs repo my-org/my-repo\nownrs repo  # auto-detects from git remote\n\n# Who might own this orphaned repo? (auto-runs for missing/stale)\nownrs repo my-org/forgotten-service\n\n# Force suggestions for a repo with partial ownership\nownrs repo my-org/my-repo --suggest partial\n\n# Combine modes\nownrs repo my-org/my-repo --suggest missing,stale,partial\n```\n\n## What It Checks\n\nownrs compares three sources for each repo:\n\n- **CODEOWNERS** — who reviews PRs (`* @org/team-name`)\n- **catalog-info.yaml** — who's listed in the Backstage service catalog (`spec.owner`)\n- **GitHub admin teams** — which teams actually have admin access to the repo\n\nBy default, if there's any team that appears across all present sources, the repo is **aligned**. Use `--strict` to require all sources to list the exact same teams.\n\n## Alignment States\n\n| Status | What it means |\n|--------|--------------|\n| `aligned` | Sources agree (at least one team in common) |\n| `mismatched` | Sources present but no team overlap |\n| `catalog-only` | Only `catalog-info.yaml` declares ownership |\n| `codeowners-only` | Only `CODEOWNERS` declares ownership |\n| `admin-only` | Team has admin access but no metadata files |\n| `stale` | A referenced team no longer exists in the org |\n| `missing` | No ownership signal at all |\n\n## Ownership Suggestions\n\nWhen a repo has no ownership metadata (`missing`) or references a team that no longer exists (`stale`), ownrs automatically suggests likely owners based on recent commit and PR review activity.\n\nIt works by resolving contributors to their org teams and ranking teams by total activity:\n\n```\nRepository: forgotten-service\nStatus:     missing\nSuggested owners (based on last 90 days of activity):\n  platform-team    12 commits, 4 reviews (alice, bob)\n  infra-team       3 commits, 1 review (charlie)\n```\n\nUse `--suggest` to override which statuses trigger suggestions:\n\n| Mode | Triggers for |\n|------|-------------|\n| (default) | `missing` and `stale` |\n| `--suggest missing` | `missing` only |\n| `--suggest stale` | `stale` only |\n| `--suggest mismatched` | `mismatched` (sources present, no team overlap) |\n| `--suggest partial` | `catalog-only`, `codeowners-only`, `admin-only` |\n\nOrg-wide teams are filtered out by default (teams with \u003e20 members). Tune with `--max-team-size` or `--exclude-team`.\n\n## Options\n\n```\nGlobal:\n  --refresh            Force re-fetch (bypass 24h cache)\n  --strict             Require exact team set match across sources\n  --cache-ttl \u003cSECS\u003e   Cache TTL in seconds (default: 86400)\n  --token \u003cTOKEN\u003e      GitHub token (default: GITHUB_TOKEN env var)\n\norg subcommand:\n  --limit \u003cN\u003e          Audit only first N repos\n  --sort \u003cORDER\u003e       stale (default), active, name\n  --team \u003cTEAM\u003e        Filter to repos where this team appears in any source\n  --status \u003cSTATUS\u003e    Filter by alignment status (comma-separated)\n  --format \u003cFMT\u003e       table (default), csv, json\n  --detail             Show per-repo breakdown\n\nrepo subcommand:\n  --status \u003cSTATUS\u003e    Filter by alignment status\n  --format \u003cFMT\u003e       table (default), csv, json\n\nSuggestion Options:\n  --suggest \u003cMODE\u003e           Override suggestion trigger (missing, stale, mismatched, partial)\n  --lookback-days \u003cDAYS\u003e     Activity lookback window (default: 90)\n  --max-team-size \u003cN\u003e        Filter out teams larger than N (default: 20)\n  --exclude-team \u003cTEAM\u003e      Teams to exclude from suggestions (comma-separated)\n```\n\n## Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | Success (or no repos matched filter) |\n| 1 | Filter matched results |\n| 2 | Runtime error |\n\n## License\n\n[PolyForm Shield 1.0.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraiderrobert%2Fownrs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraiderrobert%2Fownrs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraiderrobert%2Fownrs/lists"}