Raw JSON report machine-readable
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 8892,
"has_wiki": true,
"homepage": "https://doomedramen.github.io/hitch/",
"languages": {
"CSS": 5206,
"HTML": 619,
"Just": 16873,
"Rust": 1144181,
"Shell": 5254,
"JavaScript": 82,
"TypeScript": 123687
},
"pushed_at": "2026-07-24T10:37:41Z",
"created_at": "2025-11-15T21:01:51Z",
"owner_type": "User",
"updated_at": "2026-07-24T10:37:24Z",
"description": null,
"is_archived": false,
"is_disabled": false,
"license_spdx": null,
"default_branch": "main",
"license_spdx_raw": null,
"primary_language": "Rust",
"significant_languages": [
"Rust"
]
},
"owner": {
"blog": null,
"name": "Martin Page",
"type": "User",
"login": "doomedramen",
"company": "@Pikl-Insurance",
"location": "UK",
"followers": 58,
"avatar_url": "https://avatars.githubusercontent.com/u/445964?v=4",
"created_at": "2010-10-19T20:34:38Z",
"is_verified": null,
"public_repos": 33,
"account_age_days": 5757
},
"license": {
"state": "absent",
"spdx_id": null,
"raw_spdx": null,
"file_present": false,
"scorecard_found": false,
"profile_has_license": false
},
"activity": {
"releases": [
{
"tag": "v1.3.2",
"kind": "patch",
"published_at": "2026-07-24T10:04:41Z"
},
{
"tag": "v1.3.1",
"kind": "patch",
"published_at": "2026-07-23T11:54:52Z"
},
{
"tag": "v1.2.49",
"kind": "patch",
"published_at": "2026-07-22T14:10:06Z"
},
{
"tag": "v1.2.48",
"kind": "patch",
"published_at": "2026-07-22T13:56:39Z"
},
{
"tag": "v1.2.47",
"kind": "patch",
"published_at": "2026-07-17T11:29:31Z"
},
{
"tag": "v1.2.46",
"kind": "patch",
"published_at": "2026-07-17T11:06:55Z"
},
{
"tag": "v1.2.45",
"kind": "patch",
"published_at": "2026-07-17T10:56:00Z"
},
{
"tag": "v1.2.44",
"kind": "patch",
"published_at": "2026-07-10T09:29:15Z"
},
{
"tag": "desktop-v0.0.12",
"kind": "other",
"published_at": "2026-07-06T17:55:51Z"
},
{
"tag": "desktop-v0.0.11",
"kind": "other",
"published_at": "2026-07-06T16:58:12Z"
},
{
"tag": "v1.2.43",
"kind": "patch",
"published_at": "2026-07-06T16:42:27Z"
},
{
"tag": "desktop-v0.0.10",
"kind": "other",
"published_at": "2026-07-06T16:25:31Z"
},
{
"tag": "v1.2.41",
"kind": "patch",
"published_at": "2026-07-06T15:44:48Z"
},
{
"tag": "desktop-v0.0.7",
"kind": "other",
"published_at": "2026-04-18T21:21:21Z"
},
{
"tag": "desktop-v0.0.5",
"kind": "other",
"published_at": "2026-04-18T20:22:25Z"
},
{
"tag": "v1.2.38",
"kind": "patch",
"published_at": "2026-04-16T09:13:43Z"
},
{
"tag": "v1.2.37",
"kind": "patch",
"published_at": "2026-04-15T20:15:14Z"
},
{
"tag": "v1.2.36",
"kind": "patch",
"published_at": "2026-04-14T19:12:08Z"
},
{
"tag": "v1.2.35",
"kind": "patch",
"published_at": "2026-04-14T13:12:39Z"
},
{
"tag": "v1.2.34",
"kind": "patch",
"published_at": "2026-03-27T14:09:17Z"
},
{
"tag": "v1.2.33",
"kind": "patch",
"published_at": "2026-03-27T11:25:01Z"
},
{
"tag": "v1.2.32",
"kind": "patch",
"published_at": "2026-03-27T11:08:20Z"
},
{
"tag": "v1.2.31",
"kind": "patch",
"published_at": "2026-03-26T16:56:21Z"
},
{
"tag": "v1.2.28",
"kind": "patch",
"published_at": "2026-02-03T11:40:30Z"
},
{
"tag": "v1.2.27",
"kind": "patch",
"published_at": "2026-01-19T13:46:26Z"
},
{
"tag": "v1.2.25",
"kind": "patch",
"published_at": "2025-12-15T16:50:19Z"
},
{
"tag": "v1.2.24",
"kind": "patch",
"published_at": "2025-12-15T15:17:58Z"
},
{
"tag": "v1.2.23",
"kind": "patch",
"published_at": "2025-12-15T11:29:39Z"
},
{
"tag": "v1.2.20",
"kind": "patch",
"published_at": "2025-12-10T07:47:31Z"
},
{
"tag": "v1.2.19",
"kind": "patch",
"published_at": "2025-12-04T12:46:26Z"
},
{
"tag": "v1.2.18",
"kind": "patch",
"published_at": "2025-12-04T12:41:37Z"
},
{
"tag": "v1.2.17",
"kind": "patch",
"published_at": "2025-12-04T12:30:04Z"
},
{
"tag": "v1.2.16",
"kind": "patch",
"published_at": "2025-11-27T12:51:07Z"
},
{
"tag": "v1.2.15",
"kind": "patch",
"published_at": "2025-11-27T12:38:01Z"
},
{
"tag": "v1.2.14",
"kind": "patch",
"published_at": "2025-11-27T12:32:00Z"
},
{
"tag": "v1.2.13",
"kind": "patch",
"published_at": "2025-11-27T11:13:45Z"
},
{
"tag": "v1.2.10",
"kind": "patch",
"published_at": "2025-11-19T13:31:26Z"
},
{
"tag": "v1.2.7",
"kind": "patch",
"published_at": "2025-11-19T12:50:23Z"
},
{
"tag": "v1.2.5",
"kind": "patch",
"published_at": "2025-11-17T19:12:07Z"
},
{
"tag": "v1.2.4",
"kind": "patch",
"published_at": "2025-11-17T18:54:00Z"
},
{
"tag": "v1.2.3",
"kind": "patch",
"published_at": "2025-11-17T18:36:32Z"
},
{
"tag": "v1.2.2",
"kind": "patch",
"published_at": "2025-11-17T18:20:51Z"
},
{
"tag": "v1.2.1",
"kind": "patch",
"published_at": "2025-11-17T18:13:36Z"
},
{
"tag": "v1.1.25",
"kind": "patch",
"published_at": "2025-11-17T17:52:53Z"
},
{
"tag": "v1.1.17",
"kind": "patch",
"published_at": "2025-11-17T17:20:44Z"
},
{
"tag": "v1.1.16",
"kind": "patch",
"published_at": "2025-11-17T12:08:10Z"
},
{
"tag": "v1.1.15",
"kind": "patch",
"published_at": "2025-11-16T14:27:20Z"
},
{
"tag": "v1.1.14",
"kind": "patch",
"published_at": "2025-11-16T13:03:11Z"
}
],
"recent_commits": [
{
"oid": "063f146be7608cc9c6c1d5f8a56b7b4228b04a57",
"body": "The stdin-inherited hang wasn't fully fixed by the previous commit: it\nonly covered hitch's own internal git calls (git_operations.rs). The\ntest framework has a completely separate, independent code path —\nGitCommandRunner::run (tests/test_framework/command_runners.rs) spawns\ngit directly for test s\n[…]\nextra insurance against\nany editor invocation regardless of platform/config.\n\nUpdated the AGENTS.md gotcha entry to record that this class of bug\nneeds checking in both src/ and tests/test_framework/.",
"is_bot": false,
"headline": "fix: null stdin in test framework's own git/hitch subprocess spawns",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-24T10:37:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "277ba9bb9b3769ffca1b0605cdfd32875b09a979",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.3.2",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-24T10:00:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "37ff823d970f5210d41bde532c2309fbb70136a2",
"body": "Command::output() captures stdout/stderr but leaves stdin at Rust's\ndefault of inherited, not null. Any git subprocess hitch spawns could\ntherefore block reading from the actual terminal hitch (or the test\nsuite) was launched from, if git or anything it shells out to in turn\n(GPG/SSH commit signing,\n[…]\nfails fast instead of hanging. hitch resolve --tool\n(git mergetool) is left untouched since it's deliberately interactive.\n\nRecorded as a gotcha in AGENTS.md for future git/gh Command::new call\nsites.",
"is_bot": false,
"headline": "fix: never let git/gh subprocesses inherit a real terminal's stdin",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-24T09:39:12Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6052658d54e61e6c01183f04c5c8309f972998ff",
"body": null,
"is_bot": false,
"headline": "docs: add merge-conflict handling flow to README",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-24T09:17:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ac5bb050bee4e6d2735d80dbbe82f5dfabb658dd",
"body": "Phase 5, part 3 (final): the forcing function that keeps recorded\nresolutions from becoming permanent load-bearing infrastructure.\n\nhitch doctor now reports every recorded resolution and its age;\nhitch doctor --max-resolution-age-days <n> exits nonzero when any exceed\nthe threshold, so CI can gate o\n[…]\now each red-team\ncritical is met; AGENTS.md names src/utils/resolutions.rs; SKILL.md adds\nthe resolve/replay/resolutions/doctor commands. Full suite green\n(303 integration + 55 lib), clippy/fmt clean.",
"is_bot": false,
"headline": "feat(doctor): resolution debt SLA + docs; complete phase 5",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-24T09:16:00Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d2901040db06126a54bb71976c9a01b41de5d000",
"body": "Phase 5, part 2: opt-in replay. hitch rebuild --replay-resolutions makes\na conflicting branch first try a recorded, content-addressed resolution\nbefore being held — turning a previously hand-resolved peer conflict back\ninto a clean compose without re-resolving it. rebuild_environment gains a\nrebuild\n[…]\n up-front refusal is skipped when\nreplaying so a resolution gets its chance (the in-loop halt still fires\non a genuinely unresolved conflict). Verified end-to-end locally and by\ntwo integration tests.",
"is_bot": false,
"headline": "feat(rebuild): replay recorded resolutions with --replay-resolutions",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-24T09:11:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "80ca524ad8b5b2071b85e0cb5421fe3c7aeec0d1",
"body": "…sed refs\n\nPhase 5, part 1 of docs/merge-conflict-handling-plan.md: recording and\ninspection (replay comes next). hitch resolve --continue --record (or\n--share, which also pushes) stores a resolved peer-vs-peer conflict as a\nref under refs/hitch/resolutions/<key>, where <key> is a git hash over\nthe \n[…]\nch_refspec, push_refspec. Recording verified end-to-end locally\n(resolve --record -> resolutions list -> show); replay is not wired yet,\nso a recorded resolution has no effect on rebuild until part 2.",
"is_bot": false,
"headline": "feat(resolutions): record peer-conflict resolutions as content-addres…",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-24T09:05:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2962824ecc3d9a36ee15abf91079e47a0ae40b0b",
"body": "Last deferred phase-3 piece from docs/merge-conflict-handling-plan.md.\nhitch tree threads GlobalContext through its recursive display and\nruns the same local-only, no-fetch preflight_compatibility_report_local\nhitch status already uses, so a promoted branch that would be held on\nthe next rebuild shows the same ⛔ glyph and \"conflicts with X — held\non rebuild\" suffix in both commands. Phase 3 is now fully done.",
"is_bot": false,
"headline": "feat(status): show ⛔ glyph for branches that would be held on rebuild",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-24T08:54:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "317e0731899c99890eec87001197b60cb1a812c6",
"body": "Adds a maintenance section up front: update the relevant section in\nthe same change that makes it stale, record new gotchas the way the\nmerge-base bug already is, fix wrong lines on sight even if unrelated\nto the task at hand.",
"is_bot": false,
"headline": "docs: tell agents to keep AGENTS.md up to date",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T17:01:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cf318154db413004ad24e8675795516b9acf7702",
"body": "AGENTS.md is the actual content: build/test/lint commands, an\narchitecture map (where domain logic vs CLI parsing lives, the\ngit_operations.rs single-shell-out-point pattern, the three-command\nchecklist for registering a new CLI command), known dead/aspirational\ncode not to build on, house conventio\n[…]\n\nanyone touching merge-tree invocations next.\n\nCLAUDE.md is a thin pointer that imports it via Claude Code's @-file\nsyntax, so there's a single source of truth instead of two documents\ndrifting apart.",
"is_bot": false,
"headline": "docs: add AGENTS.md and CLAUDE.md",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T17:01:22Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4e7146a109a9e3bf93209dba7fad2bed02674fa9",
"body": "Phase 4 of docs/merge-conflict-handling-plan.md.\n\nhitch resolve <env> [--branch b] [--continue|--abort|--path] [--tool]\nauto-detects mode from what the branch actually conflicts with:\n\n- Mode A (conflicts with base): checks out the branch and runs\n git rebase <base>, handing off to plain Git's own \n[…]\nrified end-to-end locally for both modes plus 4 new integration\ntests; full suite (300 tests) green, clippy/fmt clean.\n\nDetails in docs/merge-conflict-handling-plan.md's Implementation\nstatus section.",
"is_bot": false,
"headline": "feat(resolve): guided Mode A/B conflict resolution + fix merge-base bug",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T16:59:44Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "79b6dad553c67e5f88857990df5e8bc80391a9ac",
"body": "Fourth and last deferred phase-3 piece from\ndocs/merge-conflict-handling-plan.md. hitch rebuild <env> --pr-comments\nupserts a single marker-tagged comment on each promoted branch's open PR\nreporting its held/re-included status: a newly-held branch gets one\ncomment (pair, conflicting files, exact fix\n[…]\n\nrepo with an open PR, which is why it's unit-tested at the message/marker\nlevel instead — flagged explicitly in the plan doc's status tracker.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(rebuild): opt-in GitHub PR status comments for held branches",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T16:42:00Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "890bdba564f7364123409ab183321c46f5fbb37b",
"body": "Third deferred phase-3 piece from docs/merge-conflict-handling-plan.md.\nAdds preflight_compatibility_report_local: a local-only, no-fetch variant\nof the phase-2 exhaustive preflight, for callers like hitch status that\nrun on every invocation and must stay fast and offline (unlike\nrebuild --dry-run a\n[…]\nural change\nthan status's addition. Left as still-deferred, along with PR comment\nintegration, in the plan doc's Implementation status section.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(status): show ⛔ glyph for branches that would be held on rebuild",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T16:37:03Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5a03cde9970605d9f9f41a01c010e50ac3d2bcef",
"body": "…om clean\n\nSecond deferred phase-3 piece from docs/merge-conflict-handling-plan.md.\nhitch rebuild now exits 2 (not 0) when it succeeded but held one or more\nconflicting branches, so CI can warn on holds without treating them as a\nbuild failure, and --dry-run reflects the same code for what a real ru\n[…]\nts.\n\nAdds HitchCommandResult::assert_exit_code to the test framework and uses\nit in the two eject/dry-run rebuild tests that now expect exit 2.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(rebuild): exit-code taxonomy — distinguish held-but-succeeded fr…",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T16:32:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "89c28d231e11f3f517feed7d0cb9584b95353f16",
"body": "Completes the visibility piece of phase 3 deferred in the previous\ncommit. hitch conflicts <env> runs the same exhaustive preflight\nhitch rebuild --dry-run uses, scoped to one environment, and reports\nevery currently-conflicting branch with its pair, files, the exact\nfix command, and what the enviro\n[…]\n status/tree glyph, PR\ncomment integration, and the exit-code taxonomy are still owed before\nphase 3 is fully done; phases 4-5 haven't started.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(conflicts): add hitch conflicts <env> standup command",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T16:27:24Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "858630ecb19d2d3723fa07f90337f68798050997",
"body": "… opt-out\n\nPhase 3 of docs/merge-conflict-handling-plan.md. Adds Environment.on_conflict\n(eject | halt, default eject) and makes rebuild_environment act on it live,\nbranch by branch, using the pinned SHAs from phase 1: a branch that conflicts\nis excluded from the composition and recorded as held (wi\n[…]\nert the new eject behavior\n(success, held branch, dev built from the rest) and adds coverage for\n--dry-run and the --on-conflict halt override.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(rebuild): eject-and-continue conflict policy (default) with halt…",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T16:21:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bfc521014891ca6148fff60123c75e1d41aa7d06",
"body": "Phase 2 of docs/merge-conflict-handling-plan.md. Adds\npreflight_compatibility_report, which simulates the same sequential\nsquash composition as preflight_compatibility_merge_tree but skips a\nconflicting branch and keeps folding instead of stopping at the first\none, so a single rebuild names every br\n[…]\nbranches touching the\nsame file, the second is now correctly attributed to the first\n(the branch it actually collides with) instead of to base.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(rebuild): exhaustive conflict attribution + --dry-run",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T16:10:03Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "12e0f4966dc3cd1a9cee882e73ec422e82ccf1b9",
"body": "…via CAS\n\nPhase 1 of docs/merge-conflict-handling-plan.md. rebuild_environment no\nlonger touches the user's checkout: it syncs and pins base + every\npromoted branch to concrete SHAs once, composes the squash merges in a\ndisposable linked worktree (sibling to the repo, never inside .git),\nand publish\n[…]\ncus.\n\nNew GitOperations primitives: add_worktree, remove_worktree,\nupdate_ref_cas, update_ref, rev_parse_opt, force_push_with_lease,\nworkdir().\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(rebuild): compose environments in an isolated worktree, publish …",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T16:06:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "df553389d487c1ceed67f59d67528636933e1e50",
"body": "Synthesized from a five-design panel (git-native, merge-queue,\ninteractive-UX, state-machine, team-product lenses), judged by three\nindependent reviewers, and stress-tested with a red-team pass. Covers\nworktree-isolated rebuilds, eject-and-continue policy, pair\nattribution, guided Mode A/B resolution, and hardened shared\nresolutions via rerere-backed refs.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add merge-conflict handling design plan",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T15:54:25Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c563e32b4f757b5a95dddeca8b7d39eaace7fb53",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.3.1",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T11:50:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a98e60302a0fa7780f340c52bce307575b9b85ce",
"body": "Interactive prompts had no non-interactive escape hatch, so `hitch rebuild`\nwould block forever in CI or when driven by an agent. Every prompt now goes\nthrough the `Confirm` trait, selected once from a new global `--yes` / `-y`\nflag (also settable via `HITCH_YES=1`). Without a TTY and without `--yes\n[…]\nhitch setup` remains an interactive wizard (branch selection has no\nnon-interactive default) but now errors up front when there is no terminal.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(cli)!: add global --yes and unify confirmation prompt handling",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-23T11:43:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "abdf0fad9721767dc6410bb0f06909d827003ffc",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.2.49",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-22T14:05:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e5aa6f7d665ff46c6d0b438ee075580f5eea87ea",
"body": "- discover_branches now pre-checks environment names alongside bases\n- save_protection_cache writes protected branches list to\n ~/.config/hitch/<owner>_<repo>_protection.json after setup\n- hitch status warns when env/bases aren't covered by ruleset",
"is_bot": false,
"headline": "feat(setup): pre-check env branches, cache protection state",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-22T13:59:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c711da50f1942894ef27c978468cb1a6081f8f9c",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.2.48",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-22T13:51:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "065752104746735c9a356e58bf9832e3bd3a7d77",
"body": null,
"is_bot": false,
"headline": "style: apply cargo fmt and fix clippy warning",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-22T13:47:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b8f97a98ecbc588340a86b536a94dab4fa4b68ef",
"body": "Replace GitHub App + backend token exchange with per-user deploy keys:\n- hitch setup generates ed25519 SSH key (~/.ssh/hitch_<owner>_<repo>)\n- Adds public key as repo deploy key via gh api\n- Sets git config core.sshCommand to use the key\n- Creates ruleset with DeployKey bypass (actor_type: DeployKey\n[…]\nha2\ndeps. Remove token-auth push URL machinery from git_operations\nand release.rs.\n\nFix gh_api_post -> gh_api_with_body to not override caller's\nHTTP method (was appending -X POST after -X PUT/other).",
"is_bot": false,
"headline": "refactor(setup): switch to deploy key bypass, drop backend/App auth",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-22T13:46:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "30f5792c99a551753bf91ee8349597f1cd04291d",
"body": "Add hitch setup command for interactive branch protection configuration:\n- Branch discovery from hitch.json + remote listing\n- Interactive branch selection via inquire crate\n- OAuth device flow for Hitch GitHub App authentication\n- Ruleset creation/activation via gh api\n- Token storage in ~/.config/\n[…]\non tokens.\n\nUpdate hitch release: resolve_push_url injects installation tokens\nfor authenticated pushes to protected branches.\n\nAdd git_operations: push_branch_to_url, push_tag_to_url,\nget_remote_url.",
"is_bot": false,
"headline": "feat(setup): hitch setup command + GitHub App token infrastructure",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-22T13:28:08Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "efa897efccdc18d679419cd5c1b576f0884b743a",
"body": null,
"is_bot": false,
"headline": "drop pr branch",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-22T12:52:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4acab3c6d414dd43036cfb2712d9162edfb0004a",
"body": null,
"is_bot": false,
"headline": "Create hitch-setup-commands-plan.md",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-21T10:08:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cf44833e18f2791c919d00c1dcdd80f9f4561717",
"body": null,
"is_bot": false,
"headline": "snap",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-21T10:05:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0866beac22d9e20b1d864e286d0ca3afc9cbe33b",
"body": "…tion",
"is_bot": false,
"headline": "docs: add hitch doctor and hitch pr to README key commands and pr sec…",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-21T09:53:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ff93c3213c5b224fa7fa2c0c5060e0c81cb25e4d",
"body": "- New command: infers PR base from promotion targets'\n shared base, pushes branch, shells out to gh pr create\n- flag: create branch, push, and open PR in one step\n- README: add GitHub Pull Requests with Hitch section documenting\n ruleset setup, workflow, and caveats\n- release --squash help: note that squash mode prevents GitHub\n auto-detecting merged PRs",
"is_bot": false,
"headline": "feat: add github PR workflow commands (hitch pr, branch --pr)",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-21T09:36:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "30e71c9ed92dbfa99ad6f7a21b8fd2ee02e97fd7",
"body": null,
"is_bot": false,
"headline": "Create github-pr-workflow-plan.md",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-21T09:24:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6526d3e05f22bef09ed86aea6371e783e5b63b6b",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.2.47",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-17T11:25:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fb2186c9c3ccc45590bbb4118faab8891ed7d15a",
"body": "`hitch completion <shell>` failed with \"Not in a git repository\" when run\nfrom anywhere but a repo, because GlobalContext (which opens one) was\nconstructed unconditionally before command dispatch — even though completion\nonly reads the static clap command tree and never touches git. It's now\nhandled in main() before GlobalContext exists, so e.g. piping straight into\na completions folder from $HOME now works.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(completion): allow completion generation outside a git repository",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-17T11:18:19Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3f2c77191c69b34a6e880b8adbbfe738774d7048",
"body": "Releasing an environment to a target branch also rebuilds any environment\nwhose base is that target (transitively) — non-obvious enough that a\nteammate mistook the extra rebuild for a bug. Document what triggers it, that\nit's usually a no-op, and the --no-rebuild-dependents escape hatch.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: explain release's automatic dependent-environment rebuild",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-17T11:18:14Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f78522473d8d54990394505b2e151ec4cd68979e",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.2.46",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-17T11:02:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fea4db2f966307b294115bbe960b43934072f5c7",
"body": "hitch completion <shell> previously emitted hand-written, hardcoded scripts\nper shell — already stale, missing tree/approvals/branch/cleanup/diff/set\nentirely and none of their flags, with no way to keep them in sync as\ncommands were added.\n\nMoved the Cli/Commands clap definitions from the hitch bin\n[…]\netions for bash/zsh/fish/powershell/elvish now\ncover every subcommand and per-command flag automatically and can never drift\nout of sync again.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(completion): generate shell completions from the real command tree",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-17T10:55:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ce4563c15aa8cd5394f13ddc2d266cc643f30099",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.2.45",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-17T10:51:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5a18d849bd10a9634e41ec761b4da2ec3129b4fa",
"body": "Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "style: apply rustfmt",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-17T10:44:09Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7fde49e89e370b9c3c277ece1a0aea8f27abed1f",
"body": "Teammates who never personally ran `hitch init` got \"hitch-metadata branch\ndoes not exist locally\" from every hitch command, even after `git pull` and\neven though the metadata was sitting on origin the whole time — a plain pull\non another branch never creates a local tracking branch for a separate b\n[…]\nit` or any\nmetadata-writing command create a brand new, unrelated root commit — silently\ndiverging from the team's real hitch-metadata history.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(metadata): bootstrap hitch-metadata locally from origin when missing",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-17T10:42:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "33ce6cd8290ebe8480363b49d1e21c76f5399ef9",
"body": "…checkout\n\nEvery metadata write (lock/unlock, promote/demote, approvals, init) used to\nrecord the current branch, checkout hitch-metadata, commit, then checkout\nback — needing an auto-stash to protect it and leaving users stranded on the\nwrong branch if the return checkout failed. Reads already avoi\n[…]\nite\nbootstraps hitch-metadata as a root commit through the same path, so\ncreate_orphan_branch is now dead code and removed along with its test.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor(metadata): write hitch-metadata via git plumbing instead of …",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-17T10:13:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ad1f82a8b10418505b12e4e28f08eaea0cf2adf2",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.2.44",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-10T09:24:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "65b9112d84c8845557828a8632e56c2e989be05c",
"body": "Formats the new code and pre-existing drift so the release pre-flight\n(cargo fmt --check) passes.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "style: apply rustfmt",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-10T09:12:59Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "458542cf993e69b0557fb31dc0975cc76878211c",
"body": "squash_merge already commits each branch, so the trailing commit was always\na no-op yet logged a misleading \"Committed release\" line. Remove it; squash\nreleases produce one squash commit per branch.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(release): drop no-op commit in squash mode",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-10T09:08:44Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e3f72c5aa4e57c60f7ad2841f0e8d8271d31e4d2",
"body": "When demoting a source environment, the success message counted the full\nresolved batch even though demotion no-ops branches not present in the\ntarget. Report the count of branches actually promoted to the target.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(demote): report the number of branches actually demoted",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-10T09:08:44Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f2d834179f72041509979dbbb6a3165e718401f1",
"body": "Previously it locked (a no-op if already locked) and then always unlocked,\nso calling it on an already-locked environment would release a lock it did\nnot take. Not reachable through current commands (callers pre-check), but a\nfootgun for re-entrant/force paths. Now it checks the lock state first and\nonly locks/unlocks when it actually acquires the lock.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(lock): with_locked_env only unlocks a lock it acquired",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-10T09:08:44Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "70134dc94536d0fd5e83ab610c4e7ec25fa9c86a",
"body": "promote/demote created one approval request per branch, each in its own\nmetadata transaction (commit + push). If a later branch failed — e.g. it\nalready had a pending request — the earlier branches' requests were left\ncommitted, and retrying could worsen the inconsistent state.\n\nAdd create_approval_\n[…]\nbatch. promote and demote now use it (demote also filters to branches\nactually promoted to the target). Removes the now-unused singular helper.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(approvals): create batched approval requests atomically",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-10T09:04:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7bbb70f41df451f5ecbf343deab1aa1242de7a2b",
"body": "Post-release pruning iterated every environment and removed merged\nbranches from their metadata without checking locks. A locked env has its\nrebuild skipped, so pruning its metadata left the metadata and the built\nbranch inconsistent (and mutated an env another operation holds a lock\non). Skip pruni\n[…]\nnv being released is locked by\nthis release itself and is still pruned. Deferred prunes are picked up the\nnext time the environment is rebuilt.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(release): don't prune promoted branches from locked environments",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-10T08:58:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5c802060b793b8fd1f341989260ce1d187dc8cc2",
"body": "When demoting a source environment into an approval-gated target, the\napproval loop created a request for every resolved branch even though\nvalidation only requires one to be present. Branches never promoted to\nthe target got bogus approval requests that demote nothing when approved.\nOnly create requests for branches actually promoted to the environment.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(demote): skip approval requests for branches not in the target env",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-10T08:56:17Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "25e62700bb80ff0b0d26c8917a84b06a93436d79",
"body": "Two release correctness bugs:\n\n1. The post-release rebuild skipped the just-released environment because\n the release holds its lock (\"Skipping rebuild of '<env>' because it is\n locked\"), pruning its metadata but leaving its branch stale against the\n new base. The released env is now rebuilt d\n[…]\nto its pre-release commit on\n failure (new GitOperations::reset_hard_to helper).\n\nAdds regression tests for both; each fails without its fix.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(release): rebuild released env when locked, and make release atomic",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-10T08:56:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ecb1d1122c457ac3ba64944d41992015dc190783",
"body": null,
"is_bot": false,
"headline": "fixes",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-08T11:34:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "70ff8ef91cd4be3dd7f5cbb8996c167a3e156abd",
"body": null,
"is_bot": false,
"headline": "Update icon.json",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-07T07:39:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "421b8f7c7498ee2f6fec9e50c8cae8235caa66b4",
"body": null,
"is_bot": false,
"headline": "chore: bump desktop version to v0.0.12",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T17:49:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6b48e912e61888d726d875439405f2219c135fdb",
"body": null,
"is_bot": false,
"headline": "updates to ui",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T17:48:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "486908f91164a5096a6370d67176bae36da919fa",
"body": "test_add_and_commit_empty_files asserted the old behavior (error on a\nmissing file), which the tolerate-missing-optional-file fix intentionally\nchanged. Rewrite it to verify present files still commit while a missing\none is skipped, and that committing only-missing files is a no-op.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "test: update add_and_commit test for skip-missing-file behavior",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T17:27:35Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a6bace7c3c40d6e4c120aa599072199543758c23",
"body": "The cross-platform integration suite spawns hitch+git per test. On the\nWindows runner the detached 'git gc --auto' inherits the captured stdout\npipe, so Command::output() never sees EOF and the job hangs. Disable\ngc.auto for tests and add a 25m timeout so any future hang fails fast\nwith retained logs.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "ci: bound Windows test job + disable git auto-gc to prevent hangs",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T17:21:03Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "da52b74c150c0173d844567dc6982ee881072203",
"body": "Mutating ops run with the default StdinConfirm, but the desktop has no\nstdin — so the rebuild force-push prompt read EOF, declined, and the\nrebuilt branch was silently never pushed to the remote. The UI button is\nthe confirmation, so wire AlwaysYesConfirm into the op context (used only\nby the locked mutating commands; read-only context_at is untouched).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "desktop: auto-confirm the rebuild force-push prompt",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T17:17:17Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "47feef54e48ad8e34e4305060063394115956cb6",
"body": "A hitch-metadata branch without a .gitignore (older init, or removed)\nbroke every metadata mutation: add_and_commit([\"hitch.json\",\n\".gitignore\"]) hard-failed on 'git add .gitignore' ('did not match any\nfiles'), leaving hitch.json staged but uncommitted. The operation was\nthen stranded on hitch-metad\n[…]\nld be\noverwritten by checkout'. Skip an add whose pathspec matches nothing,\nmatching how the commit step already tolerates 'nothing to commit'.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: tolerate a missing optional file in add_and_commit",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T17:17:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "be4dda7ab3b0d47a402641ad15a0b6886f97b750",
"body": null,
"is_bot": false,
"headline": "chore: bump desktop version to v0.0.11",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T16:51:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "de5bb3fd453029bd5303262043efcb6a46f47114",
"body": "GitHub rewrites spaces to dots in release asset filenames, so the DMG\nuploaded as 'Hitch Desktop_<ver>.dmg' became 'Hitch.Desktop_<ver>.dmg'\nwhile the cask URL used %20 — a guaranteed 404 on brew install. Rename\nthe DMG to a hyphenated, space-free name before upload and point the\ncask at that exact name.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "desktop-release: use space-free DMG asset name so the cask URL resolves",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T16:50:57Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "dade21d6db195e601a0e5ecf214f721ea1ea69e7",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.2.43",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T16:37:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f96383842317d1e1703742ac5526096d4c65254d",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: sync Cargo.lock for hitch-desktop 0.0.10",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T16:29:46Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "85185268295db184fff750901853781223327874",
"body": "The integration test harness looked for target/debug/hitch, but on\nWindows the executable is hitch.exe, so every add/remove integration\ntest failed with 'Could not find or build hitch binary'. Use\nCARGO_BIN_EXE_hitch when present and fall back to a path built with\nenv::consts::EXE_SUFFIX.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "test: locate hitch binary with platform exe suffix on Windows",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T16:29:33Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1cfce8561a900f27b8526cb0822a10e27b255da1",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "dist: allow-dirty ci so the desktop-v* trigger exclusion sticks",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T16:20:45Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "27ced8e23b0945c2b773cbd73754525f9650b44f",
"body": null,
"is_bot": false,
"headline": "chore: bump desktop version to v0.0.10",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T16:17:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d17f6be9f83317eb0ac99adfa1c0f0c5fb53bcb0",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.2.42",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T16:16:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6e167d0d2d97445d4f408bee74e74b38f36afb4a",
"body": "- clippy: drop needless lifetime in timeline.rs (needless_lifetimes)\n- audit: bump plist 1.8->1.10 (quick-xml 0.38->0.41) for RUSTSEC-2026-0194/0195\n- desktop: pin pnpm@10.30.3 (corepack was pulling pnpm 11 -> ERR_PNPM_IGNORED_BUILDS)\n- release: exclude desktop-v* tags from the cargo-dist CLI release trigger\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ci): green CI + unblock desktop release",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T16:11:31Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "dd4fc18871851ec38a3e83bff89923e550a4e48b",
"body": null,
"is_bot": false,
"headline": "chore: bump desktop version to v0.0.9",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T15:58:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "36b9aa4029789e5408492901366eedc2c80a6c86",
"body": null,
"is_bot": false,
"headline": "Update desktop-release.yml",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T15:57:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "86ae75dd7bee20bdd2e245a030d33314d9825c95",
"body": null,
"is_bot": false,
"headline": "desktop fixes",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T15:54:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5419e1c87dea88c2f31b3ac09f451b550cdc37b1",
"body": null,
"is_bot": false,
"headline": "chore: bump desktop version to v0.0.8",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T15:49:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d2ad9cd0097817072aca71f7aa5d4fa77568c8b0",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.2.41",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T15:40:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bb4b8e9f06bfb22c2b42bc585d8e3377d4597c36",
"body": null,
"is_bot": false,
"headline": "Update dist-workspace.toml",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T15:36:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2382b3dd72a210a46485c4ad49f86093bdaa9bde",
"body": null,
"is_bot": false,
"headline": "chore: bump version to v1.2.40",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T15:18:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "36c54e95f4118374a6fafea52b78eceb120100c9",
"body": null,
"is_bot": false,
"headline": "release",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T15:14:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4f30ad59adb002aeddff04ee229ddbe42048829b",
"body": null,
"is_bot": false,
"headline": "desktop redesign",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T13:15:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "92b8a5d349abd026838fe1a9fefb55ece0d957ef",
"body": null,
"is_bot": false,
"headline": "snap",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-07-06T12:20:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0f52882988155660367ec2fb37ebf50bcc8aea08",
"body": null,
"is_bot": false,
"headline": "Update repo.rs",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-06-30T14:45:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "342eafcb23d842184ff13a306bac77228be855ec",
"body": "Delete several dead/unused helper methods from GitOperations (rev_parse_fallback, get_git_config, set_git_config, unset_git_config, stash_top_message) to reduce unused code surface. Also minor whitespace/formatting adjustment in a repo_lock test assertion for readability.",
"is_bot": false,
"headline": "Remove unused git helper functions",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-06-30T14:40:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f0fab11a80740f5712c4e1e4eed6992a98565b1d",
"body": null,
"is_bot": false,
"headline": "Update git_operations.rs",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-06-30T14:38:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5340eea8bc379d3f3abd88bd1827cd5cd0faa60e",
"body": "Introduce a repository-wide lock (src/utils/repo_lock.rs) to serialize mutating Hitch operations and prevent concurrent clobbering of the working tree. Acquire the lock in CLI main (for mutating commands) and in the desktop app for promote/rebuild/release. Make approvals aware of which subcommands m\n[…]\n boundary) and document behavior.\n\nSmall fixes: validation disallows names starting with '-', detached-HEAD handling cleaned up, and various minor refactors to keep rollback/metadata handling simpler.",
"is_bot": false,
"headline": "Add repository lock & approval workflow fixes",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-06-30T14:37:40Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "82757163cd0311e5363715a190afc432cbdccd1b",
"body": null,
"is_bot": false,
"headline": "updated docs",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-05-28T11:57:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3edaf2a32818cccab54df543b53665bd07d1295a",
"body": null,
"is_bot": false,
"headline": "chore: update Cargo.lock",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T21:15:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "67c3457088cbc65a5c2f668906b4d74cc4724e82",
"body": null,
"is_bot": false,
"headline": "chore: bump desktop version to v0.0.7",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T21:13:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a1384e377e1fe23ea5da8cb4785b2b7b747ee1c6",
"body": null,
"is_bot": false,
"headline": "feat: add variant and noShadow props to HitchIcon for title bar",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T21:12:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "06251dd4da18491ba5cb9b5afe1d812a3684c6d4",
"body": null,
"is_bot": false,
"headline": "fix: remove invalid iOS config from tauri.conf.json",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T21:02:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f9abad8a2b22b2fee552a7abf09df227f6fba885",
"body": null,
"is_bot": false,
"headline": "chore: bump desktop version to v0.0.6",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T21:01:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ce89ab3c099983b32fa726b602c228aea9e0f6eb",
"body": null,
"is_bot": false,
"headline": "fix: correct iOS minimumSystemVersion key in tauri.conf.json",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T21:00:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "569a9dc803f67cee3278a703f919c11832e6e7d2",
"body": null,
"is_bot": false,
"headline": "chore: update Cargo.lock",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T20:59:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "530177a727e6e19017a7c149510530491e534338",
"body": null,
"is_bot": false,
"headline": "fix: enable ad-hoc code signing and disable hardened runtime for macOS",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T20:58:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e4aa46c6ea0fa18589e34e069a32e4158f3f5024",
"body": null,
"is_bot": false,
"headline": "fix: correct version extraction and URL encode DMG name in cask",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T20:26:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9e6255a63b4374fdee7ec562c195325541074624",
"body": null,
"is_bot": false,
"headline": "chore: bump desktop version to v0.0.5",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T20:17:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dc5c1a2ce3b6aa5d53b7628b8745f267d7e324fa",
"body": null,
"is_bot": false,
"headline": "chore: update Cargo.lock",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T20:17:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1d94b66c2f8cd9804110e11248decd4834fe96f2",
"body": null,
"is_bot": false,
"headline": "chore: bump desktop version to v0.0.4",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T20:16:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "40c3f7832e6288d1b40725748c882fddec3b070e",
"body": null,
"is_bot": false,
"headline": "fix: create release if not exists before uploading DMG",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T20:15:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6efbb4dacbe80376b781210d503bba330f11f913",
"body": null,
"is_bot": false,
"headline": "fix: correct bundle path in desktop release workflow",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T20:03:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "34432516ded3d54e2abbf7753133cf644f09ab75",
"body": null,
"is_bot": false,
"headline": "fix: narrow release.yml tag pattern to only v* tags",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T20:01:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3814e5b23d3cc2d6b90f2859c59bc1aa16c72046",
"body": null,
"is_bot": false,
"headline": "chore: bump desktop version to v0.0.3",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T19:58:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1d4ff836b31a9edba10c790b6b2d80a94a1970ec",
"body": null,
"is_bot": false,
"headline": "fix: use desktop-v prefix for desktop release tags",
"author_name": "Martin Page",
"author_login": "doomedramen",
"committed_at": "2026-04-18T19:56:51Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 48,
"commits_last_year": 461,
"latest_release_at": "2026-07-24T10:04:41Z",
"latest_release_tag": "v1.3.2",
"releases_from_tags": false,
"days_since_last_push": 1,
"active_weeks_last_year": 21,
"days_since_latest_release": 1,
"mean_days_between_releases": 2
},
"community": {
"has_readme": true,
"has_license": false,
"has_description": false,
"has_contributing": false,
"health_percentage": 28,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "hitch",
"exists": true,
"license": "MIT",
"keywords": [
"command-line-utilities"
],
"ecosystem": "crates",
"matches_repo": null,
"registry_url": "https://crates.io/crates/hitch",
"is_deprecated": false,
"latest_version": "0.1.1",
"repository_url": null,
"versions_count": 2,
"total_downloads": 42,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 5,
"first_published_at": "2026-03-17T16:41:38.470268Z",
"latest_published_at": "2026-03-17T21:13:55.651630Z",
"latest_version_yanked": false,
"days_since_latest_publish": 129
}
]
},
"popularity": {
"forks": 0,
"stars": 0,
"watchers": 0,
"fork_history": {
"days": [],
"complete": true,
"collected": 0,
"total_forks": 0
},
"star_history": {
"days": [],
"complete": true,
"collected": 0,
"total_stars": 0,
"collected_at": null
},
"open_issues_and_prs": 0
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [
"justfile"
],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [
"crates/hitch-desktop/tsconfig.json"
],
"toolchain_manifests": [
"Cargo.toml",
"crates/hitch-desktop/src-tauri/Cargo.toml"
],
"largest_source_bytes": 96079,
"source_files_sampled": 138,
"oversized_source_files": 3,
"agent_instruction_files": [
"AGENTS.md",
"CLAUDE.md"
],
"agent_instruction_max_bytes": 12291
},
"dependencies": {
"manifests": [
"Cargo.toml"
],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"crates"
],
"dependencies": [
{
"name": "clap",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "4.5"
},
{
"name": "anyhow",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1.0"
},
{
"name": "thiserror",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "2.0"
},
{
"name": "serde",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1.0"
},
{
"name": "serde_json",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1.0"
},
{
"name": "colored",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "3.1"
},
{
"name": "clap_complete",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "4.5"
},
{
"name": "git2",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.20"
},
{
"name": "chrono",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.4"
},
{
"name": "uuid",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1.0"
},
{
"name": "tokio",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1.49"
},
{
"name": "fs4",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1"
},
{
"name": "inquire",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.7"
},
{
"name": "tempfile",
"manifest": "Cargo.toml",
"ecosystem": "crates",
"version_constraint": "3.25"
}
],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 21,
"open_issues": 0,
"closed_ratio": null,
"closed_issues": 0,
"closed_unmerged_prs": 31
},
"bus_factor": 1,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "doomedramen",
"commits": 432,
"avatar_url": "https://avatars.githubusercontent.com/u/445964?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"ci.yml",
"desktop-release.yml",
"release.yml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"Cargo.lock",
"pnpm-lock.yaml"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": null,
"reason": "no pull request found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/30 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 10,
"reason": "project has 3 contributing companies or organizations -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 10,
"reason": "update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 0,
"reason": "license file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": null,
"reason": "packaging workflow not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "no SAST tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 10,
"reason": "security policy file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": 0,
"reason": "Project has not signed or included provenance with any releases.",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 0,
"reason": "32 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "063f146be7608cc9c6c1d5f8a56b7b4228b04a57",
"ran_at": "2026-07-25T17:42:34Z",
"aggregate_score": 4.1,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": true,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-24T10:46:00Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2026-01-19T13:15:42Z",
"ci_last_conclusion": "FAILURE",
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/doomedramen/hitch",
"host": "github.com",
"name": "hitch",
"owner": "doomedramen"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 52,
"inputs": {
"security": 41,
"vitality": 83,
"community": 12,
"governance": 46,
"engineering": 68
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 83,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 78,
"inputs": {
"commits_last_year": 461,
"human_commit_share": 1,
"days_since_last_push": 1,
"active_weeks_last_year": 21
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 1 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 1
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "21/52 weeks with commits",
"points": 14.5,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 21
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "461 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 461
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"releases_count": 48,
"latest_release_tag": "v1.3.2",
"releases_from_tags": false,
"days_since_latest_release": 1,
"mean_days_between_releases": 2
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "48 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 48
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 1 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 1
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~2 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 2
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 1,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 1 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 1
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "critical",
"name": "Community & Adoption",
"value": 12,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 0,
"stars": 0,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "0 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 0
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "0 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 0
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "critical",
"name": "Community health",
"note": null,
"notes": [],
"value": 25,
"inputs": {
"has_readme": true,
"has_license": false,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "no license file detected",
"points": 0,
"status": "missed",
"details": [
{
"code": "license_absent",
"params": {}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "critical",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 13,
"inputs": {
"packages": [
"hitch"
],
"dependents": null,
"ecosystems": "crates",
"total_downloads": 42,
"monthly_downloads": 5
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "5 downloads/month across crates",
"points": 10.4,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 5,
"ecosystems": "crates"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "at_risk",
"name": "Sustainability & Governance",
"value": 46,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 20,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 1,
"top_contributor_share": 1
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 100% of commits",
"points": 0,
"status": "missed",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "1 contributors",
"points": 1.4,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 1
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 3 contributing companies or organizations -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "critical",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"issue_resolution"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 29,
"inputs": {
"merged_prs": 21,
"open_issues": 0,
"closed_issues": 0,
"issue_closed_ratio": null,
"closed_unmerged_prs": 31
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "no issues or no data",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_issues_or_data",
"params": {}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "21/52 decided PRs merged",
"points": 15.4,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 21,
"decided": 52
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"verified_domain"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 57,
"inputs": {
"followers": 58,
"owner_type": "User",
"is_verified": null,
"owner_login": "doomedramen",
"public_repos": 33,
"account_age_days": 5757
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "personal (user) account",
"points": 10,
"status": "partial",
"details": [
{
"code": "owner_personal",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": "not applicable to user accounts",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_applicable_to_user_accounts",
"params": {}
}
],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "58 followers of doomedramen",
"points": 12.7,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 58,
"login": "doomedramen"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "33 public repos, account ~15 yr old",
"points": 23.2,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 33
}
},
{
"code": "account_age_years",
"params": {
"years": 15
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 92,
"inputs": {
"packages": [
"hitch"
],
"ecosystems": "crates",
"any_deprecated": false,
"min_days_since_publish": 129
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on crates",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "crates"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 129 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 129
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "2 published versions",
"points": 12,
"status": "partial",
"details": [
{
"code": "published_versions",
"params": {
"count": 2
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "moderate",
"name": "Engineering Quality",
"value": 68,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_ci_tests"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 60,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "3 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 3
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "good",
"name": "Documentation",
"note": null,
"notes": [],
"value": 80,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": "https://doomedramen.github.io/hitch/",
"has_readme": true,
"has_docs_dir": true,
"has_description": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://doomedramen.github.io/hitch/",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 41,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): CI-Tests, Packaging. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"ci_tests",
"packaging"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 41,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 16,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 2,
"scorecard_aggregate": 4.1
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 3 contributing companies or organizations -- score normalized to 10",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "update tool detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow not detected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "no SAST tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "32 existing vulnerabilities detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 3
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "good",
"name": "AI Readiness",
"value": 81,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "excellent",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.84,
"agent_instruction_files": [
"AGENTS.md",
"CLAUDE.md"
],
"agent_instruction_max_bytes": 12291
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "AGENTS.md, CLAUDE.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "AGENTS.md, CLAUDE.md"
}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "84 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 84,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "good",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 71,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"Cargo.lock",
"pnpm-lock.yaml"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [
"justfile"
],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [
"crates/hitch-desktop/tsconfig.json"
],
"agent_commit_share": 0.32,
"toolchain_manifests": [
"Cargo.toml",
"crates/hitch-desktop/src-tauri/Cargo.toml"
],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "justfile",
"points": 18,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "justfile"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "crates/hitch-desktop/tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "crates/hitch-desktop/tsconfig.json"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "32 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 32,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 99,
"inputs": {
"primary_language": "Rust",
"largest_source_bytes": 96079,
"source_files_sampled": 138,
"oversized_source_files": 3
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Rust (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Rust"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "3/138 source files over 60KB",
"points": 53.8,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 138,
"oversized": 3
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
],
"report_type": "repository",
"generated_at": "2026-07-25T17:42:39.179052Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/d/doomedramen/hitch.svg",
"full_name": "doomedramen/hitch",
"license_state": "absent",
"license_spdx": null
}