JSON-Rohbericht maschinenlesbar
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 18540,
"has_wiki": false,
"homepage": null,
"languages": {
"Shell": 65736,
"Python": 9412247,
"Makefile": 230,
"Dockerfile": 6869,
"PowerShell": 9832
},
"pushed_at": "2026-07-22T17:41:21Z",
"created_at": "2026-03-23T16:55:42Z",
"owner_type": "User",
"updated_at": "2026-07-22T17:41:18Z",
"description": "AI IDE security hook: blocks directories, scans secrets, and protects AI interactions",
"is_archived": false,
"is_disabled": false,
"license_spdx": null,
"default_branch": "main",
"license_spdx_raw": "NOASSERTION",
"primary_language": "Python",
"significant_languages": [
"Python"
]
},
"owner": {
"blog": null,
"name": "Dominique Vernier",
"type": "User",
"login": "itdove",
"company": "Red Hat",
"location": null,
"followers": 6,
"avatar_url": "https://avatars.githubusercontent.com/u/28610057?v=4",
"created_at": "2017-05-10T21:35:07Z",
"is_verified": null,
"public_repos": 77,
"account_age_days": 3359
},
"license": {
"state": "custom",
"spdx_id": null,
"raw_spdx": "NOASSERTION",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "rc-1.16.0-dev-main.2f11f5e",
"kind": "other",
"published_at": "2026-07-22T17:41:22Z"
},
{
"tag": "rc-1.16.0-dev-main.22b17fd",
"kind": "other",
"published_at": "2026-07-22T17:40:35Z"
},
{
"tag": "v1.15.0",
"kind": "minor",
"published_at": "2026-07-22T17:38:15Z"
},
{
"tag": "rc-1.15.0-dev-1713",
"kind": "other",
"published_at": "2026-07-22T16:42:05Z"
},
{
"tag": "rc-1.15.0-dev-1709",
"kind": "other",
"published_at": "2026-07-22T13:02:07Z"
},
{
"tag": "rc-1.15.0-dev-1708",
"kind": "other",
"published_at": "2026-07-22T11:44:47Z"
},
{
"tag": "rc-1.15.0-dev-1707",
"kind": "other",
"published_at": "2026-07-22T11:23:10Z"
},
{
"tag": "rc-1.15.0-dev-1705",
"kind": "other",
"published_at": "2026-07-22T10:21:04Z"
},
{
"tag": "rc-1.15.0-dev-1704",
"kind": "other",
"published_at": "2026-07-22T01:45:37Z"
},
{
"tag": "rc-1.15.0-dev-1703",
"kind": "other",
"published_at": "2026-07-22T01:42:20Z"
},
{
"tag": "rc-1.15.0-dev-1702",
"kind": "other",
"published_at": "2026-07-22T01:00:19Z"
},
{
"tag": "rc-1.15.0-dev-1699",
"kind": "other",
"published_at": "2026-07-22T00:19:01Z"
},
{
"tag": "rc-1.15.0-dev-1698",
"kind": "other",
"published_at": "2026-07-21T23:25:57Z"
},
{
"tag": "rc-1.15.0-dev-1697",
"kind": "other",
"published_at": "2026-07-21T23:06:39Z"
},
{
"tag": "rc-1.15.0-dev-1696",
"kind": "other",
"published_at": "2026-07-21T20:52:13Z"
},
{
"tag": "rc-1.15.0-dev-1695",
"kind": "other",
"published_at": "2026-07-21T20:07:53Z"
},
{
"tag": "rc-1.15.0-dev-1694",
"kind": "other",
"published_at": "2026-07-21T19:35:52Z"
},
{
"tag": "rc-1.15.0-dev-1693",
"kind": "other",
"published_at": "2026-07-21T18:24:46Z"
},
{
"tag": "rc-1.15.0-dev-1677",
"kind": "other",
"published_at": "2026-07-21T17:43:00Z"
},
{
"tag": "rc-1.15.0-dev-1691",
"kind": "other",
"published_at": "2026-07-21T17:42:44Z"
},
{
"tag": "rc-1.15.0-dev-1685",
"kind": "other",
"published_at": "2026-07-21T16:47:54Z"
},
{
"tag": "rc-1.15.0-dev-1674",
"kind": "other",
"published_at": "2026-07-21T16:47:31Z"
},
{
"tag": "rc-1.15.0-dev-1679",
"kind": "other",
"published_at": "2026-07-21T14:05:00Z"
},
{
"tag": "rc-1.15.0-dev-1665",
"kind": "other",
"published_at": "2026-07-21T12:35:06Z"
},
{
"tag": "rc-1.15.0-dev-1675",
"kind": "other",
"published_at": "2026-07-20T20:57:13Z"
},
{
"tag": "rc-1.15.0-dev-1673",
"kind": "other",
"published_at": "2026-07-20T20:52:45Z"
},
{
"tag": "rc-1.15.0-dev-1671",
"kind": "other",
"published_at": "2026-07-20T20:07:43Z"
},
{
"tag": "rc-1.15.0-dev-1653",
"kind": "other",
"published_at": "2026-07-20T20:07:35Z"
},
{
"tag": "rc-1.15.0-dev-1666",
"kind": "other",
"published_at": "2026-07-20T19:11:24Z"
},
{
"tag": "rc-1.15.0-dev-1585",
"kind": "other",
"published_at": "2026-07-20T17:25:40Z"
},
{
"tag": "rc-1.15.0-dev-1661",
"kind": "other",
"published_at": "2026-07-20T16:29:48Z"
},
{
"tag": "rc-1.15.0-dev-1659",
"kind": "other",
"published_at": "2026-07-20T16:01:01Z"
},
{
"tag": "rc-1.15.0-dev-1658",
"kind": "other",
"published_at": "2026-07-20T15:40:16Z"
},
{
"tag": "rc-1.15.0-dev-1656",
"kind": "other",
"published_at": "2026-07-20T15:15:53Z"
},
{
"tag": "rc-1.15.0-dev-1654",
"kind": "other",
"published_at": "2026-07-20T14:07:30Z"
},
{
"tag": "rc-1.15.0-dev-1652",
"kind": "other",
"published_at": "2026-07-20T13:19:19Z"
},
{
"tag": "rc-1.15.0-dev-1651",
"kind": "other",
"published_at": "2026-07-17T22:29:39Z"
},
{
"tag": "rc-1.15.0-dev-1650",
"kind": "other",
"published_at": "2026-07-17T20:58:46Z"
},
{
"tag": "rc-1.15.0-dev-1649",
"kind": "other",
"published_at": "2026-07-17T20:24:34Z"
},
{
"tag": "rc-1.15.0-dev-1642",
"kind": "other",
"published_at": "2026-07-17T19:42:06Z"
},
{
"tag": "rc-1.15.0-dev-1648",
"kind": "other",
"published_at": "2026-07-17T19:39:50Z"
},
{
"tag": "rc-1.15.0-dev-1646",
"kind": "other",
"published_at": "2026-07-17T19:11:54Z"
},
{
"tag": "rc-1.15.0-dev-1645",
"kind": "other",
"published_at": "2026-07-17T19:05:07Z"
},
{
"tag": "rc-1.15.0-dev-1640",
"kind": "other",
"published_at": "2026-07-17T18:37:49Z"
},
{
"tag": "rc-1.15.0-dev-1638",
"kind": "other",
"published_at": "2026-07-17T17:14:12Z"
},
{
"tag": "rc-1.15.0-dev-1637",
"kind": "other",
"published_at": "2026-07-17T16:27:58Z"
},
{
"tag": "rc-1.15.0-dev-1635",
"kind": "other",
"published_at": "2026-07-17T15:56:23Z"
},
{
"tag": "rc-1.15.0-dev-1630",
"kind": "other",
"published_at": "2026-07-17T15:42:52Z"
},
{
"tag": "rc-1.15.0-dev-1632",
"kind": "other",
"published_at": "2026-07-17T14:42:53Z"
},
{
"tag": "rc-1.15.0-dev-1631",
"kind": "other",
"published_at": "2026-07-17T12:38:42Z"
},
{
"tag": "rc-1.15.0-dev-1629",
"kind": "other",
"published_at": "2026-07-17T11:47:58Z"
},
{
"tag": "rc-1.15.0-dev-1624",
"kind": "other",
"published_at": "2026-07-17T11:33:18Z"
},
{
"tag": "rc-1.15.0-dev-1623",
"kind": "other",
"published_at": "2026-07-17T10:13:44Z"
},
{
"tag": "rc-1.15.0-dev-1606",
"kind": "other",
"published_at": "2026-07-16T18:20:14Z"
},
{
"tag": "rc-1.15.0-dev-1619",
"kind": "other",
"published_at": "2026-07-16T17:15:02Z"
},
{
"tag": "rc-1.15.0-dev-1615",
"kind": "other",
"published_at": "2026-07-16T15:14:49Z"
},
{
"tag": "rc-1.15.0-dev-1613",
"kind": "other",
"published_at": "2026-07-16T14:16:51Z"
},
{
"tag": "rc-1.15.0-dev-1610",
"kind": "other",
"published_at": "2026-07-16T13:43:45Z"
},
{
"tag": "rc-1.15.0-dev-1611",
"kind": "other",
"published_at": "2026-07-16T13:09:18Z"
},
{
"tag": "rc-1.15.0-dev-1604",
"kind": "other",
"published_at": "2026-07-16T00:16:39Z"
},
{
"tag": "rc-1.15.0-dev-1605",
"kind": "other",
"published_at": "2026-07-15T22:26:57Z"
},
{
"tag": "rc-1.15.0-dev-937",
"kind": "other",
"published_at": "2026-07-15T20:30:17Z"
},
{
"tag": "rc-1.15.0-dev-1602",
"kind": "other",
"published_at": "2026-07-15T19:02:39Z"
},
{
"tag": "rc-1.15.0-dev-936",
"kind": "other",
"published_at": "2026-07-15T10:38:36Z"
},
{
"tag": "rc-1.15.0-dev-1598",
"kind": "other",
"published_at": "2026-07-14T20:55:40Z"
},
{
"tag": "rc-1.15.0-dev-650",
"kind": "other",
"published_at": "2026-07-14T20:47:37Z"
},
{
"tag": "rc-1.15.0-dev-1597",
"kind": "other",
"published_at": "2026-07-14T20:44:26Z"
},
{
"tag": "rc-1.15.0-dev-1593",
"kind": "other",
"published_at": "2026-07-14T18:36:26Z"
},
{
"tag": "rc-1.15.0-dev-1592",
"kind": "other",
"published_at": "2026-07-14T16:40:56Z"
},
{
"tag": "rc-1.15.0-dev-main.b0ebcb5",
"kind": "other",
"published_at": "2026-07-13T20:00:14Z"
},
{
"tag": "rc-1.15.0-dev-main.ecd036d",
"kind": "other",
"published_at": "2026-07-13T19:10:06Z"
},
{
"tag": "v1.14.0",
"kind": "minor",
"published_at": "2026-07-13T17:47:12Z"
},
{
"tag": "rc-1.14.0-dev-main.7f6aab6",
"kind": "other",
"published_at": "2026-07-13T14:25:34Z"
},
{
"tag": "rc-1.14.0-dev-1567",
"kind": "other",
"published_at": "2026-07-12T16:43:08Z"
},
{
"tag": "rc-1.14.0-dev-1534",
"kind": "other",
"published_at": "2026-07-09T08:31:06Z"
},
{
"tag": "rc-1.14.0-dev-1533",
"kind": "other",
"published_at": "2026-07-09T08:31:03Z"
},
{
"tag": "rc-1.14.0-dev-main.3180b07",
"kind": "other",
"published_at": "2026-07-09T00:44:28Z"
},
{
"tag": "rc-1.14.0-dev-main.496f536",
"kind": "other",
"published_at": "2026-07-09T00:43:27Z"
},
{
"tag": "v1.13.3",
"kind": "patch",
"published_at": "2026-07-09T00:41:28Z"
},
{
"tag": "rc-1.14.0-dev-1528",
"kind": "other",
"published_at": "2026-07-08T21:50:30Z"
},
{
"tag": "rc-1.14.0-dev-1525",
"kind": "other",
"published_at": "2026-07-08T20:33:59Z"
},
{
"tag": "rc-1.14.0-dev-1524",
"kind": "other",
"published_at": "2026-07-08T20:14:11Z"
},
{
"tag": "rc-1.14.0-dev-1523",
"kind": "other",
"published_at": "2026-07-08T19:41:46Z"
},
{
"tag": "rc-1.14.0-dev-1517",
"kind": "other",
"published_at": "2026-07-08T19:04:41Z"
},
{
"tag": "rc-1.14.0-dev-1519",
"kind": "other",
"published_at": "2026-07-08T17:24:31Z"
},
{
"tag": "rc-1.14.0-dev-1518",
"kind": "other",
"published_at": "2026-07-08T17:19:51Z"
},
{
"tag": "rc-1.14.0-dev-1516",
"kind": "other",
"published_at": "2026-07-08T16:54:42Z"
},
{
"tag": "rc-1.14.0-dev-1515",
"kind": "other",
"published_at": "2026-07-08T16:37:39Z"
},
{
"tag": "rc-1.14.0-dev-1514",
"kind": "other",
"published_at": "2026-07-08T16:26:40Z"
},
{
"tag": "rc-1.14.0-dev-1511",
"kind": "other",
"published_at": "2026-07-08T15:48:18Z"
},
{
"tag": "rc-1.14.0-dev-1509",
"kind": "other",
"published_at": "2026-07-08T14:10:58Z"
},
{
"tag": "rc-1.14.0-dev-1506",
"kind": "other",
"published_at": "2026-07-08T14:10:24Z"
},
{
"tag": "rc-1.14.0-dev-1499",
"kind": "other",
"published_at": "2026-07-08T12:44:09Z"
},
{
"tag": "rc-1.14.0-dev-1502",
"kind": "other",
"published_at": "2026-07-08T10:44:16Z"
},
{
"tag": "rc-1.14.0-dev-1498",
"kind": "other",
"published_at": "2026-07-07T15:45:18Z"
},
{
"tag": "rc-1.14.0-dev-main.ffed89e",
"kind": "other",
"published_at": "2026-07-06T20:05:30Z"
},
{
"tag": "v1.13.2",
"kind": "patch",
"published_at": "2026-07-06T19:46:27Z"
},
{
"tag": "rc-1.14.0-dev-main.1ea6c76",
"kind": "other",
"published_at": "2026-07-06T19:41:11Z"
},
{
"tag": "rc-1.14.0-dev-main.2e7febc",
"kind": "other",
"published_at": "2026-07-06T19:24:58Z"
},
{
"tag": "v1.13.1",
"kind": "patch",
"published_at": "2026-07-06T19:18:14Z"
}
],
"recent_commits": [
{
"oid": "2f11f5ed6f722e95a2f1618c918bff5049334bda",
"body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: regenerate notebooklm-export.md for v1.15.0",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-22T17:41:00Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "22b17fde013091f1d2ce62f30a8d3b1e0232eaac",
"body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: bump version to 1.16.0-dev, reset README URLs to main",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-22T17:40:02Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f3eed84a621a633462e400f8563f17608064f119",
"body": null,
"is_bot": false,
"headline": "Merge release-1.15 into main",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-22T17:39:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "36471c37308555bf59b54650cfba0bea16e32688",
"body": "- Bump version 1.15.0-dev → 1.15.0 in pyproject.toml and __init__.py\n- Populate CHANGELOG.md with all v1.15.0 changes (Added/Changed/Fixed/Security)\n- Remove 23 duplicate \"Exfiltration behavior detection\" entries from old releases\n- Update README: integration table (5→14 IDEs), feature rows, pattern\n[…]\nility verification\n- Update docs: CONFIGURATION, COOKBOOK, TOML_PATTERNS, SECRET_SCANNING, MULTI_DAEMON_TRAY, SCANNER_INSTALLATION\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: prepare v1.15.0 release",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-22T17:28:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "79806ddd7213ca0b02e4674eae44720b1f848dad",
"body": "…#1713)\n\n- Change missing config file status from failure to informational skip\n- Remove all_configured = False assignment for missing config paths\n- Add test for missing config file not causing FAIL status\n- Add test for mixed configured + missing config producing PASS\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: treat missing IDE config as \"not installed\" instead of failure (…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-22T16:41:44Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "0a4766ff49e0ca454c4fe0d413c51cc00efdd4dc",
"body": "- Add credentials-in-git-url rule to secrets.toml with regex matching\n real passwords/tokens while skipping placeholders and env vars\n- Add detection and false-positive test cases for GitHub, GitLab,\n Bitbucket, and Azure DevOps URL patterns\n- Exclude test_bundled_toml.py from gitleaks scanning\n- Bump secrets.toml expected rule count to 85\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: detect credentials embedded in git remote URLs (#1709)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-22T13:01:46Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2b1148d9f46a026ece031392dc7c3663ad0f0203",
"body": "- Relocate MCP Security nav item from Configuration to Tools group\n in both TUI and web navigation\n- Move corresponding help text to Tools section in TUI help docs\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: move MCP Security panel to Tools section (#1708)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-22T11:44:27Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "4c2d3937f78db5e7c0714032aefd8ce27e72489f",
"body": "- Add VIOLATION_FILTER_TYPES list to constants.py with display name,\n API value, and description for all 20 violation types\n- Refactor TUI violations page to derive filters from shared constant\n instead of hardcoded inline definitions\n- Refactor web violations page to derive filters from shared constant\n- Add slug/class mappings in TUI/web to adapt shared data to each UI\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: centralize violation filter types in constants (#1707)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-22T11:22:44Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d4700d6b7f8d00f478c9e0555c30e0319f85f667",
"body": "- Move check_project_config(cwd) before global/dir pause guards so\n _project_dir_last_seen is updated even when scanning is skipped\n- Wrap early config check in try/except to match prior error handling\n- Add parametrized test covering project dir tracking under both\n per-directory and global pause modes\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: load project config before pause check in daemon (#1705)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-22T10:20:41Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f97d2a6e5a8b85ed0ac0ce3cb0c063d3f38322e5",
"body": "…ge (#1704)\n\n- Remove badge_row UI element and its population logic\n- Remove per-category badge rendering in _update_mode_hint refresh\n- Simplify layout to content column only\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: remove unused category badge row from detection patterns pa…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-22T01:45:08Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "35a1f86eb67ab3541c97ce9d567cad7182c4b6c8",
"body": "- Build RULE_ID_TO_SLUG via dict comprehension over RULE_ID_TO_CONFIG_SECTION\n and a reverse lookup of SLUG_TO_CONFIG_SECTION, replacing hand-maintained dict\n- Add special-case for UNICODE-001 → /pi-unicode mapping\n- Add TestRuleIdToSlug test class covering validity, unicode override,\n and spot-check of expected values\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: derive RULE_ID_TO_SLUG from existing mappings (#1703)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-22T01:41:59Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "55fd6a0f14b9cdc6bda975a95ab59f0791d1115a",
"body": "- Add run_scan_pipeline() and ScanPipelineResult to scan_analyzer.py\n- Replace duplicated scan/analyze logic in TUI scan_configure with pipeline call\n- Replace duplicated scan/analyze logic in web scan_configure with pipeline call\n- Update web tests to mock centralized pipeline instead of individual components\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: extract shared scan pipeline from TUI and web (#1702)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-22T00:59:59Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "11e11eb8d29cb7029ba99c7eee5da0bfce170ded",
"body": "- Move RULE_ID_LABELS, RULE_ID_TO_SCANNER, and related dicts from\n scan_analyzer.py to constants.py\n- Add SLUG_TO_CONFIG_SECTION, RULE_ID_TO_SLUG, RULE_ID_TO_CONFIG_SECTION,\n and RULE_ID_TO_VIOLATION_TYPE mappings\n- Replace inline slug/config lookups in TUI and web modules with\n constant dict references\n- Update tests to match new import paths and config section routing\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: centralize rule ID mappings in constants module (#1699)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-22T00:18:42Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "614a1b660018de6ff35d1fe5b6de5438d184db07",
"body": "- Extract quiet_logging() context manager to tui/utils.py and logging_utils.py\n- Replace inline _suppress/_restore_logging methods across TUI modules\n- Add safe_int() and format_count() helpers to tui/utils.py\n- Add unit tests for new utility functions\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: centralize logging suppression into shared TUI utility (#1698)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T23:25:36Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d4ed5867d6d7f004f96cfb83e57ca9cade42ba07",
"body": "- Add ConfigSaveMixin to schema_defaults.py with shared config\n load/save/path-resolution helpers used across all TUI panels\n- Replace per-panel duplicated _get_config_path, JSON read/write,\n and _is_project_scope logic with mixin methods in 20 panel files\n- Add Skill \"release\" permission rule to ai-guardian.json\n- Update tests to match new mixin-based config plumbing\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: extract ConfigSaveMixin to deduplicate TUI config I/O (#1697)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T23:06:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7d483cf027f3d694675805262c095b777966e35a",
"body": "- Move _load_overlaid_config to scanners module with internal loader map\n- Pre-compute overlaid configs for all overlay-enabled scanners in both\n content_pipeline and post_tool_use hooks\n- Add _LOADER_MAP and get_loader to ScannerRegistry for loader lookup\n- Remove per-scanner loader_fn parameter in favor of registry-based dispatch\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: centralize language overlay config loading (#1696)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T20:51:51Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "633f614ab7356d85e42f451bb0740086fd17e17c",
"body": "- Replace line-count incremental reads with byte-offset (seek-based)\n positioning in _read_jsonl_incremental and all adapter callers\n- Add atomic write (tempfile + os.replace) for transcript positions file\n- Update copilot_chat, jsonl, kiro, openclaw, windsurf adapters to pass\n and receive byte offsets instead of line counts\n- Update corresponding unit tests for new position semantics\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: switch transcript scanning to byte-offset tracking (#1695)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T20:07:24Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7b1b3c205b868b69f5f4f00ac8abb897f78179bb",
"body": "- Add path traversal validation for session_files in _run_session_start_event\n- Add workspace_files param to _run_scenario_event for simulated project dirs\n- Set project_dir_override so language detection uses workspace file structure\n- Add language-overlay.yaml scenario files for minimal/moderator/standard/strict\n- Update scenario schema to include workspace_files and new test coverage\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add workspace_files support and path traversal guards (#1694)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T19:35:31Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e943a8cfa8c8841a4762e85010beafed3a18105d",
"body": "- Change _get_most_recent_entry return type to Optional[Tuple[str, float]]\n- Refactor copilot_chat to use shared _get_most_recent_entry helper\n- Refactor openclaw to use shared _get_most_recent_entry helper\n- Update cline and kiro callers to destructure new tuple return\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: return mtime from _get_most_recent_entry (#1693)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T18:24:20Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d98c8a9c8de78f50cae681505589245a4c90ab24",
"body": "…ole (#1690)\n\n* Feat: add init --scan UI to TUI and web console\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n* test: relax Directory Scan position assertion in TUI nav\n\n- Remove check that Directory Scan is last item in Tools group\n- Keep a\n[…]\ndocstring to match relaxed constraint\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1677: feat: add init --scan UI to TUI and web cons…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T17:42:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a5d567fe005a21e4a5d15c9c548eb48d279f556c",
"body": "Operation blocked by ai-guardian: secret detected\n\nOriginal prompt: Based on this git diff, generate a commit message in conventional commit format.\n\nGit Status:\nM tests/unit/test_copilot_chat_transcript.py\n M tests/unit/test_kiro_transcript.py\n M tests/unit/test_openclaw_transcript.py\n M tests/unit\n[…]\nFocus on WHAT changed, not WHY\n- NO JIRA keys or ticket numbers\n\nReturn ONLY the commit message.\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "UserPromptSubmit operation blocked by hook: (#1691)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T17:42:24Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0793d63ee1ba9bd5c28a07499fd81b02ef2801be",
"body": "- Remove pattern server URL/version config and test connection binding\n- Remove PatternServerSection widget and server connectivity testing\n- Replace pattern server help text with per-engine pattern server reference\n- Add privacy warning for external liveness validation API calls\n- Delete test_tui_s\n[…]\nets_pattern_server.py (dead tests)\n- Update web secrets page to match TUI pattern server removal\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: remove pattern server from secrets panel (#1685)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T16:47:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ad8b785740adc7186644a70fd66045023a6141ab",
"body": "…jection via ScannerEntry flag (#1683)\n\n* refactor: hoist language overlay into content pipeline\n\n- Add _load_overlaid_config() helper in content_pipeline.py\n- Move apply_language_overlays call from scanners.py to callers\n- Pass pre-overlaid config to run_prompt_injection_scan\n- Add supports_languag\n[…]\n (1M context) <noreply@anthropic.com>\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1674: refactor: pipeline-level language overlay in…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T16:47:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "999f926ecfb28d785bf39b17f20ef8b5b617870c",
"body": "- Replace **kwargs with explicit original_file_path param in run_single_engine\n- Pass original_file_path through _parse_secrets_result and _build_scan_result_from_dict\n- Use resolved original path in SecretMatch.file for python scanner and dict builder\n- Add parametrized tests verifying file path appears in scan results\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: thread original_file_path through all scan result paths (#1679)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T14:04:33Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "cc28ad1b6d436e3d74063ae262c8da76d89e4d03",
"body": "…ining scanner types (#1676)\n\n* refactor: extract config builders and table-driven scanner routing\n\n- Replace if/elif chains in fingerprint_finding and _scanner_for_rule_id\n with table-driven lookups (_FINGERPRINT_DETAIL_KEY, _RULE_ID_PATTERNS)\n- Extract reusable config builder functions (_build_es\n[…]\nforward slashes regardless of host OS\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1665: feat: init --scan config generation for rema…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-21T12:34:46Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4cb85cb9db194d4bfc8a55f04ff76ee4432e84bb",
"body": "- Extract apply_language_overlays() helper in scanners.py\n- Add scanner_name param to get_language_allowlist_patterns()\n- Cache all scanner patterns together per project_dir\n- Update tests for multi-scanner overlay support\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: generalize language overlay to all scanners (#1675)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T20:56:52Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a4d3827fa359d163deb130468d2e2bfe33e9f531",
"body": "- Add _read_jsonl_incremental() and _scan_jsonl_incremental() to common.py\n- Refactor copilot_chat, kiro, openclaw, windsurf scanners to use shared helpers\n- Remove duplicated JSONL reading/scanning boilerplate from each adapter\n- Update tests to match simplified adapter internals\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: extract shared JSONL scan logic into common helpers (#1673)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T20:52:19Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e79aa97577af8852ea594724c048da840a23c069",
"body": "- Add _get_most_recent_entry() to common.py for finding newest dir entry\n- Replace inline scandir loops in cline.py and kiro.py with shared helper\n- Update tests to cover new helper and parameterized match/mtime functions\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: extract shared _get_most_recent_entry helper (#1671)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T20:07:23Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d0f5342749d3542b9012507b260024e4b15cba07",
"body": "…er executor — skip_file_types relies on temp filename (#1668)\n\n* feat: pass original file path through scan pipeline\n\n- Add original_file_path parameter to run_engine and run_python_scanner\n- Extract original_file_path from strategy context and forward to executors\n- Use original path instead of te\n[…]\nal parameters like original file path\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1653: fix: thread original file_path through scann…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T20:07:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "02261d2e316f66965caf6b73b600e2b299555d5d",
"body": "- Add scan_analyzer module to cluster findings by pattern and identify high-frequency false positives\n- Add --scan and --threshold flags to init-project CLI command\n- Generate tuned config with allowlist patterns and per-scanner directory ignores\n- Add smoke tests for init-project --scan workflows\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add init-project --scan for false positive analysis (#1666)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T19:11:00Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3ea3ca2e7321cdbf433af65ad215268ae1ecb0cc",
"body": "…ess known false positive patterns per language (#1663)\n\n* feat: auto-allowlist language false positives in prompt injection scan\n\n- Add false_positive_patterns dict to LanguageDefinition for per-scanner allowlists\n- Populate prompt_injection patterns for Python, JS, TS, PHP, Ruby, C/C++, Go, Java, \n[…]\ns multiple lines for PEP 8 compliance\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1585: feat: auto-detect project language and suppr…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T17:25:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "82221e683f5701cb3d0ae401de04bd1dc02c2b9c",
"body": "- Add AiderDeskTranscriptAdapter for Markdown chat history files\n- Add OpenClawTranscriptAdapter for JSONL transcript files\n- Register both adapters in TRANSCRIPT_ADAPTERS list\n- Add unit tests for both new scanners\n- Update AGENT_SUPPORT.md with new transcript formats\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add AiderDesk and OpenClaw transcript scanners (#1661)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T16:29:27Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "40f55eebc0eaa2b99564b4b0c77fc8bfea22ddd8",
"body": "- Add Copilot Chat (VS Code) JSONL delta journal to transcript adapter table\n- Document Augment Code transcript scanning infeasibility (server-side storage, no UserPromptSubmit hook)\n- Note Crush PreToolUse-only limitation already existed; new entries placed before it\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add Copilot Chat and Augment Code agent support notes (#1659)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T16:00:32Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7784b05dc153107a85ae41cca63a516a026ec49f",
"body": "- Add CopilotChatTranscriptAdapter for VS Code JSONL delta journal files\n- Register adapter in TRANSCRIPT_ADAPTERS and __all__ exports\n- Document Copilot Chat session path in AGENT_SUPPORT.md\n- Add unit tests for copilot chat transcript scanning\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add Copilot Chat (VS Code) transcript scanner (#1658)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T15:39:46Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "12f02272f6b32c82f48f640c10b7c450a7357c47",
"body": "- Add KiroTranscriptAdapter for ~/.kiro/sessions/cli/*.jsonl files\n- Register adapter and incremental scanner in transcript __init__.py\n- Add unit tests for Kiro transcript parsing\n- Document Kiro in AGENT_SUPPORT.md agent table\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add Kiro transcript scanning support (#1656)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T15:15:33Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "acbed7ab5cd55ab1d8828468f3090d177f009da2",
"body": "- Add skip_file_types metadata field to TOML rules, converted to\n frozenset at compile time for fast lookup\n- Thread file_ext parameter through cache.scan() and\n TomlPatternsScanner to skip rules by extension\n- Apply skip_file_types to yaml-password rule to suppress false\n positives in source code files\n- Add unit tests for skip_file_types parsing and scanner filtering\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add skip_file_types support to pattern rules (#1654)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T14:07:05Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "59a5a3af334ca2f9fb2234e46dfbaefcc407bcdb",
"body": "- Add `ai-guardian ml setup` CLI command that checks deps, downloads\n model, and configures prompt_injection detection in one step\n- Add `ensure_model_downloaded()` for idempotent model download with\n verification, used by both CLI and daemon auto-download\n- Add `auto_download_model` config field \n[…]\ne templates with prompt_injection defaults and add\n unit tests for new setup/download functions\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add one-command ML detection setup and auto-download (#1652)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-20T13:18:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "543136ab43b0d0c447e343c8b903ffe7bf0495ae",
"body": "- Add _sanitize_warn_reason() and _build_warn_agent_context() to base\n adapter, stripping file/line/pattern details from agent-facing output\n- Pass violation_type through warn response chain in all adapters\n (Claude, Cline, Copilot, Cursor, Gemini, Kiro, Windsurf)\n- Keep full diagnostic details in\n[…]\nason mappings: offensive_language, canary_detected,\n code_security, exfil_detection, bash_exfil\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: sanitize warn-mode context sent to AI agents (#1651)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T22:29:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d901771f788997044a2fd6c446715e41f670704b",
"body": "- Add select-based read timeout (30s) to prevent hanging on\n unresponsive leaktk subprocess; kill and raise on expiry\n- Deduplicate restart() by delegating to stop()\n- Extract _make_started_proc helper in tests to reduce mock boilerplate\n- Replace empty-response test with timeout and crash test cases\n\n\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: add timeout guard to leaktk listen mode scans (#1650)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T20:58:27Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "409530bb74752d62d7842a2642adc9f2cb5a8bc1",
"body": "- Add token_prefixes config option for token_not_placeholder rules\n- Update Slack token rule to use short \"xox\" keyword with explicit prefixes\n- Update _build_token_prefix_re to prefer token_prefixes over keywords\n- Update sync test to validate token_prefixes with keywords fallback\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add token_prefixes field to secrets.toml rules (#1649)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T20:24:09Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "be1ffb48e8c8a665a80c2fabd53e5c26b2092528",
"body": "…ge — reason and systemMessage contain same text (#1647)\n\n* fix: use sanitized message in block response reason field\n\n- Replace raw sys_msg with sanitized value in _block_response reason\n- Update tests to assert reason contains sanitized label components\n- Verify reason differs from raw systemMessa\n[…]\nfor warning vs error in reason string\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1642: bug: PostToolUse block shows duplicate messa…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T19:41:46Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "14c379505b5316abb589925b644330de8050f66a",
"body": "- Add supports_listen_mode and version_hint fields to EngineConfig\n- Route listen mode and version hints via config flags instead of type checks\n- Make listen mode log message engine-agnostic\n- Add tests for capability flag defaults and preset values\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: replace leaktk hardcoding with capability flags (#1648)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T19:39:28Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b206637ed3e3334dc584a61506623ebae888d807",
"body": "- Change header nav button label from \"Menu\" to \"Quick Links\"\n- Replace hamburger menu icon with link icon\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: rename nav menu button to Quick Links (#1646)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T19:10:34Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7ea9cf32e0061f6233e34ab82b9b236b79756c7f",
"body": "- Add listen_mode.py managing a long-lived LeakTK process that accepts\n scan requests over stdin/stdout, reducing per-scan latency ~200ms→~5ms\n- Integrate listen mode lifecycle with daemon startup/shutdown and\n config-change restart\n- Fall back to standard subprocess execution when daemon is not running\n or listen mode is unavailable\n- Bump LeakTK pinned version to 0.3.4\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add LeakTK listen mode for persistent process scanning (#1645)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T19:04:37Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "08657855cc964eac1ff91300cc9b7bcacdd5ed66",
"body": "- Build _TOKEN_PREFIX_RE dynamically from secrets.toml rules with\n validation=\"token_not_placeholder\" instead of hardcoding prefixes\n- Update Slack token keywords from generic \"xox\" to specific prefixes\n (xoxb-, xoxa-, xoxp-, xoxr-, xoxs-)\n- Add tests ensuring prefix regex stays in sync with secrets.toml\n- Add fallback to never-match regex when secrets.toml missing or broken\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: derive token prefix regex from secrets.toml (#1640)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T18:37:23Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "de940fbb28f99109c27f754d7d2da89ae58ead39",
"body": "- Add _stderr_block_response() to HookAdapter base class\n- Replace duplicated combine/print/metadata pattern in copilot, kiro, windsurf adapters\n- Move sys import from child adapters to base.py\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: extract stderr block response into base adapter (#1638)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T17:13:47Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b35482280e8e6c6906ae3b5fa87bab2dfd103d72",
"body": "…#1637)\n\n- Add TOML rules for openrouter-api-key, google-gemini-auth-key,\n hashicorp-vault-token, and confluent-cloud-api-key\n- Register new prefixes in token_not_placeholder validator\n- Add display names to SECRET_TYPE_NAMES registry\n- Add detection and false-positive test cases for all four patterns\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add secret detection for OpenRouter, Gemini, Vault, Confluent (…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T16:27:37Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1cff2991482750fd0169c78a2fb4f2c10ba7f6de",
"body": "- Import threading module in stats refresh test helper\n- Replace fixed 0.3s sleep with explicit join on stats-refresh thread\n- Use 2.0s timeout on thread join for reliable synchronization\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "test: replace sleep with thread join in wake detection test (#1635)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T15:55:59Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7ca2b9a9c5f9a150e5755f83fa8b83d995ebbdd9",
"body": "…text on PostToolUse secret block (#1634)\n\n* feat: pass redacted output via additionalContext on secret block\n\n- Add redacted_output param to format_response across all hook adapters\n- Route redacted content through additionalContext so agents can\n continue working with sanitized output instead of \n[…]\nign with project formatting standards\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1630: feat: send redacted output via additionalCon…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T15:42:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2e5a91979f05b0cce2f5b82beaeee3fe77be6563",
"body": "- Rename env_not_file_path validator to env_not_false_positive and add\n ALL_CAPS_IDENTIFIER exclusion to skip programming constants\n- Add password_not_false_positive validator for password/secret fields\n that preserves underscore-prefixed and ALL_CAPS value detection\n- Keep env_not_file_path as ba\n[…]\ncompatible alias in registry\n- Add tests for ALL_CAPS identifier and password validator behavior\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: reduce false positives in env var secret detection (#1632)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T14:42:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7a090452843f4a2261719a8bba4d793b1151167c",
"body": "======================================================================\n🛡️ Secret Detected\n======================================================================\n\nProtection: Secret Scanning (first-match strategy)\nSecret Type: Environment Variable\nLocation: user_prompt:87:15\nScanner: toml-patterns\nPa\n[…]\nFocus on WHAT changed, not WHY\n- NO JIRA keys or ticket numbers\n\nReturn ONLY the commit message.\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "UserPromptSubmit operation blocked by hook: (#1631)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T12:38:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ca6abd37e8f6a8464e12c7201e99cb029da22f67",
"body": "- Merge TestNewSecretPatterns and TestGitleaksGapPatterns into single TestSecretPatterns class\n- Combine detection and false-positive cases into ALL_DETECTION_CASES and ALL_FALSE_POSITIVE_CASES lists\n- Remove duplicate parametrized test methods\n\n\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "test: consolidate secret pattern test classes (#1629)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T11:47:39Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "96d0281576340ee524d86fea61b147f392ba4cb4",
"body": "…tokens — toml patterns not wired into output scanning (#1625)\n\n* fix: block secret-containing output instead of redact-and-pass\n\n- Switch has_secrets to True so post_tool_use blocks when secrets found\n- Add fallback block when redactor produces zero redactions\n- Pass error_message and violation_typ\n[…]\no redact-and-pass / log-only behavior\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1624: bug: PostToolUse secret scan misses env var …",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T11:32:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6fd916cb941a660f2d9c2c87535106ede22aff90",
"body": "- Replace TestNewSecretPatterns class with parametrized test cases\n- Consolidate detection and false-positive tests into data-driven lists\n- Apply same parametrize pattern to TestNewProviderSecretPatterns\n- Reduce test boilerplate while preserving identical coverage\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "test: refactor secret detection tests to parametrized format (#1623)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-17T10:13:24Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "bb697e6ca51e6bc436ae1f685a6d29c6bbeb0df1",
"body": "- Add rules for secrets management (Doppler, HashiCorp TF, Pulumi)\n- Add rules for observability (Grafana, Sentry, Datadog)\n- Add rules for cloud providers (Cloudflare, DigitalOcean, Alibaba)\n- Add rules for developer tools (Snyk, Sourcegraph, Codecov, Buildkite)\n- Add Cohere API token detection\n- Update test assertions for new bundled rule count\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add 30 secret detection patterns for new providers (#1621)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-16T23:10:30Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "85a1d7b4f09ec116f45797994089dec6ec9d539a",
"body": "…transcript_text I/O (#1616)\n\n* refactor: extract prune helper and reduce IO in transcript scanner\n\n- Extract _prune_stale_keys() from inline dict comprehensions\n- Remove unused fcntl import block\n- Cache datetime.now() call to avoid redundant UTC lookups\n- Skip saving seen findings when no new entr\n[…]\nn hot path).\nTest updated from assertNotIn to assertIn to reflect this.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1606: Remove dead fcntl import and optimize _scan_…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-16T18:19:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "65c8f95d289d66a8efdac55b0d6d1bc7ea39efae",
"body": "- Fix scanner file paths in research reminder workflow to match\n current src/ai_guardian/scanners/ layout\n- Add supply chain, offensive language, canary detection, and exfil\n detection sections to research checklist\n- Record 2026-07-16 research review findings in AGENTS.md including\n new secret patterns (Gemini AQ., OpenRouter, Vault, Confluent)\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: update pattern research workflow and log review (#1619)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-16T17:14:43Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "54d4faf3531721c2b3417036e3f767b0c15de390",
"body": "- Wrap stats-refresh loop body in try/except to log and survive errors\n- Extract shared test helper _run_stats_refresh_tick to reduce nesting\n- Flatten deeply nested context managers using parenthesized with-statement\n- Add test for stats-refresh resilience when a sub-call raises\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: guard stats-refresh tick against unhandled exceptions (#1615)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-16T15:14:25Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "42c71db166636a3cba7e8b87761763f5dc218939",
"body": "- Fix prefix vs raw_prefix bug in else branch of read_cursor_transcript\n where SQL LIKE metachar in composer_id caused wrong key stripping\n- Add test for composer_id containing underscore covering both branches\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: use raw_prefix for bubble ID extraction in cursor scanner (#1613)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-16T14:16:27Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "ba8ebce2dd993e632e6cc36550eade157935bf26",
"body": "…rministic startup detection (#1612)\n\n* feat: add ready event to DaemonServer for deterministic startup sync\n\n- Add _ready_event (threading.Event) to DaemonServer, set after socket bind\n- Replace poll-based _wait_server_ready with event-based wait on _ready_event\n- Remove redundant retry loops and r\n[…]\n line before _wait_server_ready calls\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1610: Add readiness event to DaemonServer for dete…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-16T13:43:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "19973508838382b6eafd4f996db5493516ee1e6c",
"body": "- Move running_server fixture from class method to module-level\n- Extract _connect helper to module-level function\n- Add _wait_server_ready helper with proper ping-based readiness check\n- Replace poll-for-socket-file loop with connection+ping verification\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: extract shared test helpers in daemon server tests (#1611)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-16T13:08:54Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3c2e39fb4c65718e1aa6d97a21b55fe160c5d488",
"body": "…ript adapters (#1608)\n\n* refactor: extract shared position-tracking logic in transcript scanners\n\n- Add _scan_with_position_tracking helper to deduplicate incremental\n scan boilerplate across Cline, Cursor, OpenCode, Windsurf, and JSONL\n- Add _discover_path helper for common transcript path resolu\n[…]\ny shared _scan_with_position_tracking\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1604: Refactor: Extract shared helpers from transc…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-16T00:16:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6145a0655875a2fb181cb860d7ed88a0af752f60",
"body": "- Add WindsurfTranscriptAdapter and scan_windsurf_transcript_incremental\n- Register adapter in TRANSCRIPT_ADAPTERS and __all__ exports\n- Document Windsurf Cascade transcript path in AGENT_SUPPORT.md\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add transcript scanning for Windsurf (JSONL format) (#1605)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-15T22:26:35Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "feddb0a5c84b902c42322524834bdf8eb5d1b6cd",
"body": "…ON format) (#1603)\n\n* feat: add Cline/ZooCode transcript scanning adapter\n\n- Add ClineTranscriptAdapter for JSON array format conversations\n- Register adapter in TRANSCRIPT_ADAPTERS and __all__ exports\n- Add unit tests for Cline transcript scanning\n- Update AGENT_SUPPORT.md with Cline/ZooCode trans\n[…]\nth directly instead of tuple indexing\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#937: Add transcript scanning for Cline/ZooCode (JS…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-15T20:29:55Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2c7dfc481879dccf33a1f8853c23e50e3dd86695",
"body": "🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Remove _hp delegation shims in hook_events/ modules (#1602)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-15T19:02:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "63079b683570b41bd03e2fc34597111e6fc6480d",
"body": "…rmat) (#1600)\n\n* refactor: extract transcript scanning into polymorphic adapter package\n\n- Refactor monolithic transcript scanner into scanners/transcript/ package\n with per-IDE adapters (Claude Code, OpenCode, Cursor) behind a common\n TranscriptAdapter interface\n- Add Cursor IDE transcript scann\n[…]\nll in cursor.py across multiple lines\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#936: Add transcript scanning for Cursor (SQLite fo…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-15T10:38:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9a5583f50388fdf8352630b4af4be99cae91a33d",
"body": "…1598)\n\n- Add CRUSH_HOOK_EVENTS tuple to constants.py for centralized config\n- Tighten CrushAdapter.can_handle() to validate event against known\n display names and exclude Claude Code hook data\n- Replace hardcoded \"PreToolUse\" strings in hooks.py with constant\n- Add tests for CRUSH_HOOK_EVENTS and stricter detection logic\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: extract Crush hook events constant and tighten detection (#…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-14T20:55:17Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "5664ca16c8d8c03046e3328d69c4a2b7e205b780",
"body": "…sh notifications (#1596)\n\n* feat: add push-based event subscriptions to daemon\n\n- Add subscribe message type to protocol and server dispatcher\n- Implement container event streaming via Docker SDK in discovery\n- Add connect_subscriber() client helper for push event consumers\n- Wire tray app to recei\n[…]\ne_dir operate on existing directories\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#650: Enhancement: Event-driven tray updates via pu…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-14T20:45:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "64ca5461383dbef4d5c905d7c05803929f17611f",
"body": "…#1597)\n\n- Import CURSOR_HOOK_EVENTS from constants in release_helper, doctor,\n and test helpers instead of hardcoding event lists\n- Remove redundant Doctor._get_cursor_events() static method\n- Fix doctor _count_cursor_hooks falling back to full config instead\n of empty dict when \"hooks\" key missing\n- Update test helper to dynamically build settings from EXPECTED_EVENTS\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: use CURSOR_HOOK_EVENTS constant as single source of truth (…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-14T20:44:07Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "8a6e0fdfbac4597dd87498cd6cfe2b07e339ae70",
"body": "- Add crush.py hook adapter with PreToolUse event handling\n- Register crush adapter in hook_adapters __init__ and setup modules\n- Add Crush to hook simulator TUI and web interfaces\n- Document Crush support in AGENT_SUPPORT.md with capability matrix\n- Add unit tests for crush adapter detection and hook generation\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add Crush (Charmbracelet) hook adapter support (#1593)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-14T18:36:02Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9b2d9564dd77693d0cc7c577b60bae0221d24022",
"body": "- Add preToolUse to Cursor hook events constant and adapter\n- Update doctor checks and hook setup to handle 6 Cursor events\n- Expand release verification flow with preToolUse test steps\n- Update tests for new event count and hook configuration\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add preToolUse hook event for Cursor IDE (#1592)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-14T16:40:31Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b0ebcb53f180e964439109aa2655f717c16d8e65",
"body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: regenerate notebooklm-export.md for v1.14.0",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-13T19:59:40Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "ecd036dc8b2158b469599cc564031848b03619dd",
"body": "Post-release v1.14.0:\n- Bump version to 1.15.0-dev in pyproject.toml and __init__.py\n- Reset install URLs in README.md from v1.14.0 back to main\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: bump version to 1.15.0-dev, reset README URLs to main",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-13T19:09:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "27950d3642c4d7ddb0e4064aea8ab480b9e78de3",
"body": "v1.14.0 released — architecture refactor, no new features, no breaking changes.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Merge release-1.14 into main",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-13T18:42:26Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "fe140b66fd3438f853220da79ef52187ace183b1",
"body": "Prepare for v1.14.0 release:\n- Update version 1.14.0-dev → 1.14.0 in pyproject.toml and __init__.py\n- Move CHANGELOG.md Unreleased section to [1.14.0] - 2026-07-13\n- Update README.md install URLs to v1.14.0\n- Add Cursor v3.10.20 verification and CI fix to CHANGELOG\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: bump version to 1.14.0 for release",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-13T14:30:22Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7f6aab65958aa768fa534f6a664d10833c61bac7",
"body": "- Update 6 stale module paths in DEVELOPER_GUIDE.md (mcp_server, prompt_injection,\n ssrf_protector, tool_policy, violation_logger, daemon/tray → new subpackage locations)\n- Add 10 missing subpackages to project structure tree in DEVELOPER_GUIDE.md\n- Replace removed secret_scanning.action references\n[…]\nlease-readiness.yml: add secrets: inherit to scenario-tests job call\n so QUAY_USERNAME/QUAY_PASSWORD propagate to container build\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: update stale module paths and fix CI secrets passthrough",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-13T14:25:03Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "feda79cb3ed52e8408b046020931c33ccf29b773",
"body": "* itdove/ai-guardian#1527: refactor: extract shared _block_response/_warn_response/_allow_response methods in base_agent.py — eliminate duplicated format_response branches (#1535)\n\n* refactor(hook-adapters): extract shared response builders in BaseAgentAdapter\n\n- Extract _block_response, _warn_respo\n[…]\not just PRs.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Release 1.14.0 — refactor, bug fixes, CI improvements (#1567)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-12T16:42:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9a376afb00353cf6289318fb80bbb9215dec0a5d",
"body": "- Reformat release_helper.py to comply with black code style\n- Add trailing commas to dict literals and function args\n- Collapse single-expression function calls to one line\n- Update test file formatting to match\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "style(release): format release_helper with black (#1534)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-09T08:30:48Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9185fcb352cb2478f69a4e45a56a533c0e05f5ad",
"body": "- Add preferred approach to reuse existing release-x.y branch for patches\n- Update hotfix workflow with decision tree (release branch vs hotfix branch)\n- Revise branch diagrams and examples to reflect cherry-pick-based flow\n- Rename \"Hotfix Workflow\" to \"Patch / Hotfix Workflow\" throughout\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(release): prefer release branch for patch fixes (#1533)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-09T08:26:43Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3180b07e256d754f0596a0392980145894ba092c",
"body": "Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: regenerate notebooklm-export.md for v1.13.3",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-09T00:44:08Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "496f536834eeb48b5a82b9d2438b883ff3b5d9ad",
"body": "- Fix Cursor beforeShellExecution/afterShellExecution hooks (#1531):\n afterShellExecution misrouted to HookEvent.PROMPT instead of POST_TOOL_USE;\n top-level command field not extracted (Bash commands not scanned);\n can_handle() missing shell/tool events when sent via hook_event_name\n- Add [1.13.3\n[…]\ne docs: MULTI_DAEMON_TRAY.md (stale-code indicator, rebuild hint,\n in-progress guard), CONSOLE.md (violations directory filter)\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(cursor): shell execution hooks silent failure + v1.13.3 changelog",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-09T00:42:49Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "20f713fb751d865b7f9fd9cfcecba68c859337e7",
"body": "…esponse (#1528)\n\n- Replace `reason` with `systemMessage` in SessionStart block to avoid duplicate UI display\n- Add `additionalContext` via `_sanitize_block_reason` in `hookSpecificOutput`\n- Add `TestBaseAgentAdapterSessionStartFormat` covering block format, missing reason, additionalContext, and pass-through cases\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(session-start): use systemMessage + additionalContext for block r…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T21:50:18Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "eaf2647f66dbd8d7d29d93fc2a73a748c90ad3b7",
"body": "…et warnings (#1525)\n\n- Deduplicate transcript secrets by individual rule_id instead of a single\n fingerprint, so distinct secret types each get their own seen-key\n- Warning message now shows count and type list when _last_secret_findings\n is available; falls back to original single-finding path when not\n- Violation log includes count and types fields alongside the error reason\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(hook_processing): per-finding dedup and count in transcript secr…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T20:33:43Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "cafa194923ca62712cb4d28399fe8d17651f33ef",
"body": "…#1524)\n\n- Gate restart stale-vis to local runtime only; container/k8s get separate path\n- Add _stale_vis_remote/_mk_daemon_stale_vis_remote for container and kubernetes runtimes\n- Add version-aware label showing host vs daemon version mismatch with rebuild hint\n- Add disabled menu item for remote stale warning in both single- and multi-daemon menus\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(tray): show rebuild-image hint for stale container/k8s daemons (…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T20:13:56Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c6e5aae5e44bb51a9de8017ecd61fb6e1732d376",
"body": "…camelCase) — adapter only checks hook_event_name (snake_case) (#1523)\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bug: SessionStart not detected when Claude Code sends hookEventName (…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T19:41:28Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "5fb3b7355fd9c6f6cfbe59fc07696e0ec250c0c2",
"body": "…t + bootstrap scan scenario for AGENTS.md poisoning (#1520)\n\n* feat(dummy-agent): add SessionStart event support to scenario runner\n\n- Add `_run_session_start_event` helper that writes session files to a temp dir and fires the SessionStart hook\n- Thread `daemon_state` through `_run_hook`, `_run_sce\n[…]\nerlay destination path before copying\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1517: feat: add SessionStart support to dummy-agen…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T19:04:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c7211d3d1a7c5e786a6177efe1c62d4162c46d7f",
"body": "- Entrypoint validates config file exists after setup; exits 1 if missing\n- setup_hooks returns False on config failure regardless of other flags (ide_type, remote_config_url, etc.)\n- resolve_profile accepts bare built-in names without @ prefix (e.g. \"standard\" resolves same as \"@standard\")\n- Add tests for bare-name profile resolution and setup abort behavior\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: abort setup on config failure and accept bare profile names (#1519)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T17:24:11Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d8eaaf1fbfb3792134b66eeff6282850c7f525d8",
"body": "…ctions (#1518)\n\n- Block concurrent restart triggers with `_restart_in_progress` flag\n- Refresh menu immediately on restart to reflect in-progress state\n- Poll PID file for local daemons to detect process replacement (up to 10s)\n- Fall back to fixed 3s sleep for non-local runtime targets\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(tray): add in-progress guard and completion polling to restart a…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T17:19:33Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f8538efed7ab47821c194d7d2a8ffda7db33b764",
"body": "…(#1516)\n\n- Update `_count_claude_hooks` to check 5 hooks instead of 3\n- Add `SessionEnd` and `PostCompact` to the hook name list\n- Update display string and threshold from 3/3 to 5/5\n- Update tests to reflect new hook count and add missing hook fixtures\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(doctor): expand hook check to include SessionEnd and PostCompact …",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T16:54:29Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "8d28619cb3f8d662089628a38f6635206c21d045",
"body": "- Format block response with structured header, file, reason, and remediation steps\n- Add warn action branch returning warning_message instead of error_message\n- Both messages include recommended actions and false-positive escape hatch\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(bootstrap-scan): add formatted block and warn messages (#1515)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T16:37:26Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "eda6270f4d944f54da8b8daa0e6f4d7c47e7af91",
"body": "- Add `_is_target_stale()` helper routing local targets to `_stale_code_warned` and remote targets to `_version_mismatch_notified`\n- Add `_mk_daemon_stale_vis()` closure for per-slot stale visibility check\n- Inject \"⚠️ Running old code — click to restart\" menu item per daemon when stale and not restarting\n- Add unit tests for `_is_target_stale()` and multi-daemon stale visibility logic\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add per-daemon stale-code indicator to tray menu (#1514)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T16:26:00Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3eeab5269077f6cbcba789874df16b3937896d6e",
"body": "- Add `_violation_matches_dir` helper to match violations by file path prefix\n- Add directory dropdown with type-ahead and clearable support\n- Add \"Browse...\" button wired to existing directory picker dialog\n- Populate directory options from `load_web_projects` on page load\n- Apply dir filter client-side after fetching violations\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(violations): add directory filter to violations page (#1511)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T15:48:00Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "761ada61a467aab9c595b30c4c6eb28f15fa6a3b",
"body": "…1509)\n\n- BanditScanner raises BanditUnavailableError instead of silently returning no findings when bandit is not importable\n- doctor.check_bandit_scanner() added to run_all() checks; reports FAIL with reinstall hint when bandit is missing\n- Scanner checklist in AGENTS.md updated to require doctor \n[…]\n for new scanners\n- Tests updated for new BanditUnavailableError behavior and doctor check count\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: surface Bandit unavailability in scan output and doctor check (#…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T14:10:40Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "24cf24f318dd5dd09c1e4df669501fc5cd4fe928",
"body": "…ode — bootstrap scanning fires on first UserPromptSubmit instead of true session start (#1508)\n\n* feat: add SessionStart as distinct hook event\n\n- Add SESSION_START to HookEvent enum, separate from PROMPT/BeforeAgent\n- Handle SessionStart in base agent adapter with block-on-secrets logic\n- Update h\n[…]\nrt into parenthesized multi-line form\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1506: limitation: no SessionStart hook in Claude C…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T14:10:09Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2040762c70f5a6707c6cd2edc3653c28c960ab37",
"body": "… hook call — setup should create cache dir proactively (#1507)\n\n* fix(doctor): downgrade missing default cache dir from FAIL to WARN\n\n- Detect custom cache path via config, `AI_GUARDIAN_CACHE_DIR`, or `XDG_CACHE_HOME`\n- Return WARN (not FAIL) when default cache dir missing; FAIL only for custom pat\n[…]\neflect actual strict profile behavior\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "itdove/ai-guardian#1499: bug: doctor fails on cache path before first…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T12:43:53Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4c6945585187d7744cf714cc702d85e5e015167b",
"body": "* feat: add dummy-agent scenario tests to CI/CD pipeline (#1497)\n\nWire bundled dummy-agent scenarios into GitHub Actions. Scenarios are\norganized per profile (standard, strict, minimal, moderator) so each\nprofile's expected behavior is validated independently.\n\nKey decisions:\n- Dockerfile.test write\n[…]\n in minimal. Update expectations accordingly.\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add dummy-agent scenario tests to CI/CD pipeline (#1502)",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-08T10:43:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "268a8a6f4073d0c88ac4c68d78ab095a63c04a78",
"body": "…498)\n\n- Document test image build and run workflow in AGENTS.md and container/README.md\n- List bundled scenarios (basic-secret, pii-detection, ask-dialog, tool-policy)\n- Specify when to run tests (hook_processing.py, scanner, dummy-agent changes)\n- Add interactive REPL and per-scenario run commands\n\n🤖 Generated with [Claude Code](https://claude.ai/code)\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add hook regression testing guide for dummy-agent container (#1…",
"author_name": "Dominique Vernier",
"author_login": "itdove",
"committed_at": "2026-07-07T15:45:03Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "ffed89e3b01b469dd74b762bd9aa62f2c42b2be8",
"body": "Brings in container docs fix (#1495 follow-up):\n- README quick-start uses curl for run.sh, pinned v1.13.2, includes auth vars\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Merge release-1.13 into main (v1.13.2)",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-06T20:05:11Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "4332326de85473d393427ef4e2a39db84dcb4095",
"body": "- Bump version 1.13.1 → 1.13.2 in pyproject.toml and __init__.py\n- Add [1.13.2] CHANGELOG entry: container quick-start docs fix\n- Update install URLs and container image refs to v1.13.2\n- Update CHANGELOG comparison links\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: bump version to 1.13.2 for patch release",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-06T19:45:09Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3d6e9e234e45349f7aa106f592935faab44ca382",
"body": "- Use curl to download run.sh (no full repo clone needed)\n- Pin image version to v1.13.1 instead of :latest\n- Add missing ANTHROPIC_API_KEY and ACCEPT_PROPRIETARY_TOS vars\n\nCo-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(readme): fix container quick-start examples",
"author_name": "itdove",
"author_login": "itdove",
"committed_at": "2026-07-06T19:44:20Z",
"body_truncated": false,
"is_coding_agent": true
}
],
"releases_count": 100,
"commits_last_year": 1722,
"latest_release_at": "2026-07-22T17:41:22Z",
"latest_release_tag": "rc-1.16.0-dev-main.2f11f5e",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 17,
"days_since_latest_release": 0,
"mean_days_between_releases": 0.1
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": true,
"health_percentage": 71,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "ai-guardian",
"exists": true,
"license": "Apache-2.0",
"keywords": [
"ai",
"claude",
"cursor",
"gitleaks",
"hooks",
"secrets",
"security",
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.9",
"Topic :: Security",
"Topic :: Software Development"
],
"ecosystem": "pypi",
"matches_repo": true,
"registry_url": "https://pypi.org/project/ai-guardian/",
"is_deprecated": false,
"latest_version": "1.15.0",
"repository_url": "https://github.com/itdove/ai-guardian",
"versions_count": 33,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": "2026-03-24T01:42:59.545984Z",
"latest_published_at": "2026-07-22T17:37:59.953233Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
}
]
},
"popularity": {
"forks": 5,
"stars": 10,
"watchers": 0,
"fork_history": {
"days": [
{
"date": "2026-04-14",
"count": 1
},
{
"date": "2026-05-07",
"count": 1
},
{
"date": "2026-05-28",
"count": 1
},
{
"date": "2026-05-29",
"count": 1
},
{
"date": "2026-06-06",
"count": 1
}
],
"complete": true,
"collected": 5,
"total_forks": 5
},
"star_history": null,
"open_issues_and_prs": 33
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"examples"
],
"has_llms_txt": false,
"has_dockerfile": true,
"has_mcp_signal": true,
"bootstrap_files": [
"Makefile"
],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [],
"largest_source_bytes": 259298,
"source_files_sampled": 558,
"oversized_source_files": 17,
"agent_instruction_files": [
"AGENTS.md",
"CLAUDE.md",
"examples/aider/.aider.conf.yml"
],
"agent_instruction_max_bytes": 70167
},
"dependencies": {
"manifests": [
"pyproject.toml"
],
"advisories": {
"error": "No resolved dependencies carried a version and a supported ecosystem",
"scope": "repository_graph",
"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": 29,
"direct_affected_count": 0
},
"ecosystems": [
"pypi"
],
"dependencies": [
{
"name": "textual",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.47.0"
},
{
"name": "jsonschema",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=4.0.0"
},
{
"name": "requests",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=2.28.0"
},
{
"name": "tomli",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=2.0.0"
},
{
"name": "tomli-w",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=1.0.0"
},
{
"name": "pyyaml",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=6.0.0"
},
{
"name": "tree-sitter",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.25.0"
},
{
"name": "tree-sitter-json",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.24.0"
},
{
"name": "tree-sitter-python",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.23"
},
{
"name": "tree-sitter-javascript",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.23"
},
{
"name": "tree-sitter-typescript",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.23"
},
{
"name": "tree-sitter-go",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.23"
},
{
"name": "tree-sitter-rust",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.23"
},
{
"name": "tree-sitter-java",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.23"
},
{
"name": "tree-sitter-ruby",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.23"
},
{
"name": "tree-sitter-c",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.23"
},
{
"name": "tree-sitter-cpp",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.23"
},
{
"name": "tree-sitter-bash",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.23"
},
{
"name": "pystray",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.19.0"
},
{
"name": "Pillow",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=9.0.0"
},
{
"name": "docker",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=7.0,<9"
},
{
"name": "mcp",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=1.10.0"
},
{
"name": "rapidocr-onnxruntime",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=1.4.0"
},
{
"name": "onnxruntime",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=1.15.0"
},
{
"name": "nicegui",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=3.0.0"
},
{
"name": "tokenizers",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=0.15.0"
},
{
"name": "boto3",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=1.28.0"
},
{
"name": "bandit",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=1.7.0"
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "bandit",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "boto3",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "docker",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "jsonschema",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "mcp",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "nicegui",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "onnxruntime",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pillow",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pystray",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pyyaml",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "requests",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "textual",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tokenizers",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tomli-w",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-bash",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-c",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-cpp",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-go",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-java",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-javascript",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-json",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-python",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-ruby",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-rust",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tree-sitter-typescript",
"direct": true,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pygobject",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pytest",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pytest-asyncio",
"direct": false,
"version": null,
"ecosystem": "pypi"
}
],
"collected": true,
"truncated": false,
"total_count": 29,
"direct_count": 26,
"indirect_count": 3
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 811,
"open_issues": 33,
"closed_ratio": 0.963,
"closed_issues": 865,
"closed_unmerged_prs": 2
},
"bus_factor": 1,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "itdove",
"commits": 1723,
"avatar_url": "https://avatars.githubusercontent.com/u/28610057?v=4"
},
{
"type": "User",
"login": "shanemcd",
"commits": 4,
"avatar_url": "https://avatars.githubusercontent.com/u/773186?v=4"
}
],
"contributors_sampled": 2,
"top_contributor_share": 0.998
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"build-container.yml",
"build-wheel.yml",
"integration-tests.yml",
"lint.yml",
"parser-compat.yml",
"pattern-research-reminder.yml",
"publish.yml",
"release-readiness.yml",
"scenario-tests.yml",
"smoke-tests.yml",
"tag-monitor.yml",
"test.yml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": true
},
"security_signals": {
"lockfiles": [],
"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": 6,
"reason": "branch protection is not maximal on development and all release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 10,
"reason": "26 out of 26 merged PRs checked by a CI test -- score normalized to 10",
"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": 6,
"reason": "project has 2 contributing companies or organizations -- score normalized to 6",
"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": 9,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "30 commit(s) and 30 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": 10,
"reason": "packaging workflow 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": "SAST tool is not run on all commits -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not 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": 10,
"reason": "0 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "2f11f5ed6f722e95a2f1618c918bff5049334bda",
"ran_at": "2026-07-22T19:07:43Z",
"aggregate_score": 5.3,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": true
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-22T17:51:25Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2026-07-22T16:41:45Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 77,
"created_at": "2026-04-16T00:54:34Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 251,
"created_at": "2026-04-25T14:03:00Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 265,
"created_at": "2026-04-26T18:39:05Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 266,
"created_at": "2026-04-26T18:39:57Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 267,
"created_at": "2026-04-26T18:40:40Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 268,
"created_at": "2026-04-26T18:41:23Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 269,
"created_at": "2026-04-26T18:42:01Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 270,
"created_at": "2026-04-26T18:42:50Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 331,
"created_at": "2026-04-30T20:52:07Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 334,
"created_at": "2026-04-30T23:59:44Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 437,
"created_at": "2026-05-04T18:17:02Z",
"last_comment_at": "2026-05-07T17:03:40Z",
"last_comment_author": "itdove"
},
{
"number": 438,
"created_at": "2026-05-04T18:20:29Z",
"last_comment_at": "2026-05-07T17:03:41Z",
"last_comment_author": "itdove"
},
{
"number": 453,
"created_at": "2026-05-06T13:28:08Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 470,
"created_at": "2026-05-07T13:15:37Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 472,
"created_at": "2026-05-07T13:20:03Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 473,
"created_at": "2026-05-07T13:20:04Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 540,
"created_at": "2026-05-12T03:37:15Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 551,
"created_at": "2026-05-12T20:49:24Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 609,
"created_at": "2026-05-15T16:11:52Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 616,
"created_at": "2026-05-15T19:08:01Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/itdove/ai-guardian",
"host": "github.com",
"name": "ai-guardian",
"owner": "itdove"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 64,
"inputs": {
"security": 53,
"vitality": 82,
"community": 41,
"governance": 59,
"engineering": 82
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 82,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 76,
"inputs": {
"commits_last_year": 1722,
"human_commit_share": 1,
"days_since_last_push": 0,
"active_weeks_last_year": 17
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "17/52 weeks with commits",
"points": 11.8,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 17
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "1722 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 1722
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 30 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": 100,
"latest_release_tag": "rc-1.16.0-dev-main.2f11f5e",
"releases_from_tags": false,
"days_since_latest_release": 0,
"mean_days_between_releases": 0.1
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "100 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 100
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~0.1 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 0.1
}
}
],
"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": "unverified",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": "repository_too_young",
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": null,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "maintenance record not established from the collected data",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_unverified",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "at_risk",
"name": "Community & Adoption",
"value": 41,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 20,
"inputs": {
"forks": 5,
"stars": 10,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "10 stars",
"points": 15.5,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 10
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "5 forks",
"points": 5,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 5
}
}
],
"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": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 64,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": true,
"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": "license file present, not a recognized license",
"points": 16.9,
"status": "partial",
"details": [
{
"code": "license_custom",
"params": {}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 18,
"status": "met",
"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
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 59,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 18,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 2,
"top_contributor_share": 0.998
},
"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": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "2 contributors",
"points": 2.7,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 2
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 2 contributing companies or organizations -- score normalized to 6",
"points": 6,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 83,
"inputs": {
"merged_prs": 811,
"open_issues": 33,
"closed_issues": 865,
"issue_closed_ratio": 0.963,
"closed_unmerged_prs": 2
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "96% of issues closed",
"points": 45,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 96
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "811/813 decided PRs merged",
"points": 38.2,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 811,
"decided": 813
}
}
],
"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": 51,
"inputs": {
"followers": 6,
"owner_type": "User",
"is_verified": null,
"owner_login": "itdove",
"public_repos": 77,
"account_age_days": 3359
},
"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": "6 followers of itdove",
"points": 6.1,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 6,
"login": "itdove"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "77 public repos, account ~9 yr old",
"points": 25,
"status": "met",
"details": [
{
"code": "public_repos",
"params": {
"count": 77
}
},
{
"code": "account_age_years",
"params": {
"years": 9
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"ai-guardian"
],
"ecosystems": "pypi",
"any_deprecated": false,
"min_days_since_publish": 0
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on pypi",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "pypi"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 0 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 0
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "33 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 33
}
}
],
"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": "good",
"name": "Engineering Quality",
"value": 82,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "excellent",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 94,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": true
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "12 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 12
}
}
],
"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": 16,
"status": "met",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 9.6,
"status": "met",
"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": "26 out of 26 merged PRs checked by a CI test -- score normalized to 10",
"points": 20,
"status": "met",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 65,
"inputs": {
"topics": [],
"has_wiki": false,
"homepage": null,
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"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": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"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": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "moderate",
"name": "Security",
"value": 53,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "moderate",
"name": "Security posture",
"note": null,
"notes": [],
"value": 53,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 18,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 0,
"scorecard_aggregate": 5.3
},
"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 is not maximal on development and all release branches",
"points": 4.5,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "26 out of 26 merged PRs checked by a CI test -- score normalized to 10",
"points": 2.5,
"status": "met",
"details": [],
"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 2 contributing companies or organizations -- score normalized to 6",
"points": 1.5,
"status": "partial",
"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 detected",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 30 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 detected",
"points": 5,
"status": "met",
"details": [],
"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": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"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": "0 existing vulnerabilities detected",
"points": 7.5,
"status": "met",
"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": 2
},
"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": 73,
"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.99,
"agent_instruction_files": [
"AGENTS.md",
"CLAUDE.md",
"examples/aider/.aider.conf.yml"
],
"agent_instruction_max_bytes": 70167
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "AGENTS.md, CLAUDE.md, examples/aider/.aider.conf.yml",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "AGENTS.md, CLAUDE.md, examples/aider/.aider.conf.yml"
}
}
],
"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": "99 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 99,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "good",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 76,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": true,
"typed_language": false,
"bootstrap_files": [
"Makefile"
],
"has_devcontainer": false,
"has_linter_config": true,
"typecheck_configs": [],
"agent_commit_share": 0.99,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "Makefile",
"points": 18,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Makefile"
}
}
],
"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": 11,
"status": "met",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "Dockerfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Dockerfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "99 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 99,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "dependency automation configured, none observed in the sampled commits",
"points": 5,
"status": "partial",
"details": [
{
"code": "dependency_bot_config_only",
"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": "moderate",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 53,
"inputs": {
"primary_language": "Python",
"largest_source_bytes": 259298,
"source_files_sampled": 558,
"oversized_source_files": 17
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Python without a type-check config",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_typecheck_config_language",
"params": {
"language": "Python"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "17/558 source files over 60KB",
"points": 53.3,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 558,
"oversized": 17
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "moderate",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 60,
"inputs": {
"example_dirs": [
"examples"
],
"has_mcp_signal": true,
"api_schema_files": []
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 40
},
{
"key": "mcp_server",
"name": "MCP server",
"detail": null,
"points": 20,
"status": "met",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": "examples",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "examples"
}
}
],
"max_points": 40
}
]
}
],
"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": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"deps.dev does not index pypi:ai-guardian@1.15.0; advisories assessed against the repository dependency graph instead",
"No resolved dependencies carried a version and a supported ecosystem"
],
"report_type": "repository",
"generated_at": "2026-07-22T19:08:03.664262Z",
"schema_version": "0.26.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/i/itdove/ai-guardian.svg",
"full_name": "itdove/ai-guardian",
"license_state": "custom",
"license_spdx": null
}