Звіт у форматі JSON машиночитний
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 32313,
"has_wiki": true,
"homepage": null,
"languages": {
"Go": 2431022,
"Shell": 39711,
"Makefile": 3451,
"Batchfile": 1362,
"PowerShell": 7357
},
"pushed_at": "2026-07-24T16:47:05Z",
"created_at": "2026-03-10T07:34:34Z",
"owner_type": "Organization",
"updated_at": "2026-07-24T16:52:00Z",
"description": "Scan your dev machine for AI agents, MCP servers, IDE extensions, and suspicious packages - in seconds.",
"is_archived": false,
"is_disabled": false,
"license_spdx": "Apache-2.0",
"default_branch": "main",
"license_spdx_raw": "Apache-2.0",
"primary_language": "Go",
"significant_languages": [
"Go"
]
},
"owner": {
"blog": "https://www.stepsecurity.io",
"name": "StepSecurity",
"type": "Organization",
"login": "step-security",
"company": null,
"location": "United States of America",
"followers": 251,
"avatar_url": "https://avatars.githubusercontent.com/u/88700172?v=4",
"created_at": "2021-08-10T04:28:22Z",
"is_verified": null,
"public_repos": 497,
"account_age_days": 1811
},
"license": {
"state": "standard",
"spdx_id": "Apache-2.0",
"raw_spdx": "Apache-2.0",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v1.14.0",
"kind": "minor",
"published_at": "2026-07-17T18:53:26Z"
},
{
"tag": "v1.13.0",
"kind": "minor",
"published_at": "2026-07-09T18:52:35Z"
},
{
"tag": "v1.12.0",
"kind": "minor",
"published_at": "2026-06-10T20:13:35Z"
},
{
"tag": "v1.11.7",
"kind": "patch",
"published_at": "2026-06-01T08:42:33Z"
},
{
"tag": "v1.11.6",
"kind": "patch",
"published_at": "2026-05-27T22:29:41Z"
},
{
"tag": "v1.11.5",
"kind": "patch",
"published_at": "2026-05-27T20:09:39Z"
},
{
"tag": "v1.11.4",
"kind": "patch",
"published_at": "2026-05-26T16:29:24Z"
},
{
"tag": "v1.11.3",
"kind": "patch",
"published_at": "2026-05-22T06:51:28Z"
},
{
"tag": "v1.11.1",
"kind": "patch",
"published_at": "2026-05-11T05:13:06Z"
},
{
"tag": "v1.11.0",
"kind": "minor",
"published_at": "2026-04-29T22:18:08Z"
},
{
"tag": "v1.10.2",
"kind": "patch",
"published_at": "2026-04-22T08:40:26Z"
},
{
"tag": "v1.10.1",
"kind": "patch",
"published_at": "2026-04-21T17:28:40Z"
},
{
"tag": "v1.10.0",
"kind": "minor",
"published_at": "2026-04-20T18:41:17Z"
},
{
"tag": "v1.9.2",
"kind": "patch",
"published_at": "2026-04-15T17:52:50Z"
},
{
"tag": "v1.9.1",
"kind": "patch",
"published_at": "2026-04-08T20:08:31Z"
},
{
"tag": "v1.9.0",
"kind": "minor",
"published_at": "2026-04-03T18:38:08Z"
},
{
"tag": "v1.8.2",
"kind": "patch",
"published_at": "2026-03-17T18:23:27Z"
},
{
"tag": "v1.8.1",
"kind": "patch",
"published_at": "2026-03-10T07:48:58Z"
}
],
"recent_commits": [
{
"oid": "2cf07e270ae355919a8c48fd41bc315cdbe8ceaf",
"body": "…pport\n\nfeat(devicepolicy): enforce VS Code private-marketplace URL + add MDM verify-only channel",
"is_bot": false,
"headline": "Merge pull request #178 from raysubham/feat/vsc-private-markeplace-su…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-24T16:47:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "707b8aac573ce8e0b4e4d593bdc4c550099acda6",
"body": "…nical enforcement channel\n\nAddress PR review comments:\n\n- ApplyManaged built the RFC-6902 patch path by raw string concat with the\n backend-supplied key. RFC 6901-escape the pointer token (~->~0, /->~1) and\n JSON-encode the path (jsonPointerPath) so an unusual key cannot forge a nested\n pointer \n[…]\nhe raw string. Resolve and stamp the canonical channel\n the cycle actually ran -- always \"dmg\" or \"mdm\" (empty/unknown -> \"dmg\") -- so\n the backend's exact-match gate sees the channel that executed.",
"is_bot": false,
"headline": "fix(devicepolicy): harden managed-settings patch keys and report cano…",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-24T11:14:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "bbc89352eab64394632c411f187beb0a002a9fe6",
"body": "…xtension policy\n\nEnforcement selects a channel per cycle: \"dmg\" (or \"\") is the write-and-verify\npath; \"mdm\" is verify-only — the agent probes the OS-managed VS Code policy and\nreports what it observed, and never writes, patches, or clears settings.json\n(an external MDM owns the policy).\n\n- ProbeMan\n[…]\nnnels fail safe to the\n DMG write path.\n- The presence probe (DMG-mode yield) also gates on REG_SZ/REG_MULTI_SZ, so a\n wrong-typed policy value that VS Code ignores no longer suppresses enforcement.",
"is_bot": false,
"headline": "feat(devicepolicy): add MDM verify-only enforcement channel for IDE-e…",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-23T21:35:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d935b13f18ebb4ab9e4b059ccfa34573a933d028",
"body": "… map)\n\nThe run-config policy payload is now a settings map (setting id → compiled value) instead of the bare extensions.allowed object plus a sibling gallery_service_url field; the hash covers the whole map.\n\nenforce and clear are fully driven by the settings map and recorded ownership — no per-key\n[…]\n and a JSON object. Deleted managedKeys/managedGalleryValue; added compactSettings/sortedUnion/sortedKeys.\n\nBreaking run-config wire change (pre-GA): requires agent-api to emit the settings-map shape.",
"is_bot": false,
"headline": "refactor(devicepolicy): key run-config policy by setting id (settings…",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-23T10:15:23Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7177bed25ecf0bf8f44f56e031c15a1e60abde5d",
"body": "…tings\n\nMove the VS Code allowlist's ownership record from the scalar WrittenValue\ninto the WrittenSettings map alongside the gallery URL, so every managed key\nis tracked uniformly by setting id. WrittenValue is now used only by the\nsingle-key (npm) writer; adds omitempty so managed records no longer carry a\ndead written_value field. No behavior change: ownership is read back from the\nsame values the agent writes.",
"is_bot": false,
"headline": "refactor(devicepolicy): track all managed-key ownership in WrittenSet…",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-22T22:05:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c26420a3d8ce5d91b8b4bc04fa28b8bd4f74306c",
"body": "Fold an optional extensions.gallery.serviceUrl into the existing\nide_extension#vscode reconciler, written into the user-scope\nsettings.json beside extensions.allowed via one atomic multi-key write.\nThe agent owns both keys: set is authoritative, removal is\nownership-gated (never deletes a user-confi\n[…]\nsions OR\n ExtensionGalleryServiceUrl (Windows / macOS / Linux)\n\nAdditive and regression-guarded: an allowlist-only policy writes exactly\nas before (byte-identical settings.json and ownership record).",
"is_bot": false,
"headline": "feat(devicepolicy): enforce VS Code private marketplace URL",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-22T21:30:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e96ecd31cddad99a0cb1bfe37f93ea1ffb1cffcf",
"body": "…scan-missing\n\nfix(brew): detect Homebrew installed outside PATH",
"is_bot": false,
"headline": "Merge pull request #172 from swarit-stepsecurity/swarit/fix/homebrew-…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-20T05:49:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c3bd6eb46ec15e66a9a28bde50cff376ba442c7f",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into swarit/fix/homebrew-scan-missing",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-18T19:41:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3854d8839bc6eb6ac0143b299b354050b8dcf37d",
"body": "…-multi-at\n\nfix(configaudit): mask full userinfo in malformed multi-@ index URLs",
"is_bot": false,
"headline": "Merge pull request #173 from swarit-stepsecurity/swarit/fix/wt/redact…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-18T19:40:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e92bd4769cbbd9d923ffca1e357f1b34120de9e4",
"body": "- resolveBrewExecutable now uses the resolved absolute path as the command\n even when found via PATH, so all invocations are PATH-independent.\n- describe-cache version is reduced to its base tag and validated against\n brewVersionTagPattern, so strings like \"4.3.5-17-g<sha>\" no longer leak\n into PkgManager.Version.",
"is_bot": false,
"headline": "fix(brew): address review — use resolved path, normalize version",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-18T06:59:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "709b2673f25243da5f3238ac2226dcfb90b1bb2c",
"body": "redactCredsInValue split userinfo at the first `@`, so a user-typed\nvalue with several `user:pass@host` runs concatenated before the real\nhost (e.g. a mangled pip index-url) had everything after the first `@`\ntreated as host and shipped verbatim — leaking the trailing credential,\nin one real case a \n[…]\nng up to its *last* `@`. When the userinfo itself contains an\nextra `@` it's malformed and can't be safely parsed into user/pass, so\nmask the whole run. Well-formed single user:pass@host is unchanged.",
"is_bot": false,
"headline": "fix(configaudit): mask full userinfo in malformed multi-@ index URLs",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-18T05:04:41Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c8c2b6d937eafbff442bb59d246e75ef59f1b359",
"body": "Resolve the brew executable from standard install locations (/opt/homebrew,\n/usr/local, /home/linuxbrew) when it is not on PATH, and read the version from\nthe Homebrew git repo metadata (describe-cache / packed-refs) instead of\nshelling out to `brew --version`. Detection and formula/cask listing now work\nfor scans run without the user's interactive PATH.",
"is_bot": false,
"headline": "fix(brew): detect Homebrew installed outside PATH",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-17T18:29:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2652d20dfd0593874e43b08d08450569786959d9",
"body": "…er-1.14.0\n\nchore(release): update to 1.14.0",
"is_bot": false,
"headline": "Merge pull request #171 from swarit-stepsecurity/swarit/chore/wt/up-v…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-17T14:37:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "94ff75765ed86738e6eaff2a79b67aaaeb82d40e",
"body": "Minor release: adds the AI agent skills inventory scanner; broadens MCP config\ndiscovery (filename recognition, VS Code, vendor heuristic, Windows dedup); adds\nmetadata-first tool version detection and the macOS Gatekeeper pre-exec guard;\nand extends Python package discovery to a filesystem walk. Also backfills\nCHANGELOG entries for features that landed since 1.13.0 without release notes.\n\nSigned-off-by: Swarit Pandey <swarit@stepsecurity.io>",
"is_bot": false,
"headline": "chore(release): update to 1.14.0",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-17T14:00:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b5e80eebc0619f4a33215e0663d4592907832349",
"body": "…scovery\n\nfix(mcp): recognize MCP configs by name, add VS Code + broaden discovery",
"is_bot": false,
"headline": "Merge pull request #170 from swarit-stepsecurity/swarit/fix/wt/mcp-di…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-17T08:48:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d092267da05d5ddd6ce5ce1d4bc5c342ae167135",
"body": "…iscovery\n\n# Conflicts:\n#\tinternal/detector/mcp.go",
"is_bot": false,
"headline": "Merge remote-tracking branch 'upstream/main' into swarit/fix/wt/mcp-d…",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-17T08:29:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "50b23ab41ebc10c6c8fc6cfb56f5a1f812e07f70",
"body": "feat(detector): resolve tool versions from install metadata before exec and skip exect of Gatekeeper-rejected quarantined binaries",
"is_bot": false,
"headline": "Merge pull request #169 from ashishkurmi/main",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-17T07:41:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ea704984cc729878c4210495229b2f7811cac209",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into main",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-17T07:38:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4779d7c2cbe6dd71c32df2af5e6331b47b02cebb",
"body": "fix(mdm): show telemetry-upload lines in downloaded logs; stop double-capturing Claude Desktop",
"is_bot": false,
"headline": "Merge pull request #168 from shubham-stepsecurity/sm/dmg-download-logs",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-17T05:27:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9be280ecc254f9d42403e7d59cba1c50ebe60ce8",
"body": "…ork agent only)",
"is_bot": false,
"headline": "fix(detector): stop capturing Claude Desktop as an IDE (report as cow…",
"author_name": "Shubham Malik",
"author_login": "shubham-stepsecurity",
"committed_at": "2026-07-17T04:45:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b21198f9182873f001983d8a3cafb83607cc44a5",
"body": null,
"is_bot": false,
"headline": "fix(telemetry): include upload-intent lines in downloaded execution logs",
"author_name": "Shubham Malik",
"author_login": "shubham-stepsecurity",
"committed_at": "2026-07-17T04:45:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3894108de8cdcf1ac8ae71f1e2f2f2f97a4b98b2",
"body": "feat: add AI agent skills inventory scanning support",
"is_bot": false,
"headline": "Merge pull request #162 from raysubham/feat/ai-agent-skills-inventory",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-16T16:54:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "818b8e0626bf5d31dda3ac060847ceb8ac2b627a",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into feat/ai-agent-skills-inventory",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-16T14:54:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ca4fb5c0588a67704e504c7992ea2bce39c9489f",
"body": "…erpreter-discovery\n\nfix(python): discover interpreters to find all site-packages",
"is_bot": false,
"headline": "Merge pull request #165 from swarit-stepsecurity/swarit/fix/wt/py-int…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-16T14:53:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4a05c0929c3e27bad59dadea8cd0ae4a17461c70",
"body": "Address review on PR #165:\n- Thread the executor through Python install-root discovery and resolve the\n home directory via executor.ResolveHome instead of os.UserHomeDir, so a\n root-run launchd scan anchors the version-manager trees (pyenv/asdf/uv/\n conda/pipx) on the logged-in user's home rather\n[…]\n_COVERAGE.md: clarify that the whole-home walk skips ~/Library while the\n global user-site ~/Library/Python/* is still scanned as its own explicit\n root, so global user-site packages remain covered.",
"is_bot": false,
"headline": "fix(python): resolve console-user home for root-run scans; clarify docs",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-16T13:48:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f3891dcff96ecd1857bd7896960b46ab60fde7d1",
"body": "…ccheck S1016\n\npipeDirEntry and pipeFileInfo are structurally identical (struct{ name string }), so use a type conversion instead of a field-by-field struct literal.",
"is_bot": false,
"headline": "test(detector): convert pipeDirEntry to pipeFileInfo to satisfy stati…",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-16T11:02:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0e1aa7e25734876562b12d0f5095d3b8e0d48bd2",
"body": "…gnize\n\nThe disk-based Python scanner gathered site-packages from a fixed allow-list\nof globs, so packages installed under any interpreter not on that list were\ninvisible — most visibly Apple's Command Line Tools python\n(/Library/Developer/CommandLineTools/.../Python3.framework), whose\nsite-packages\n[…]\n) so\n field logs show exactly where the agent looked.\n\nStill TCC-safe (the walk uses the existing tcc.Skipper). SCAN_COVERAGE.md is\nupdated to document the model and what is/isn't covered by default.",
"is_bot": false,
"headline": "fix(python): discover installed packages via filesystem walk-and-reco…",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-16T10:29:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a45201c097768ba2ca0766d2e5cf7e8f7361bfd4",
"body": "Add a TCC-safe recursive walk of the search dirs (default $HOME) that finds\nproject-convention marker dirs (.claude, .agents, .gemini, .aider, …) and feeds\ntheir parents into discoverProjects, so projects never registered in\n~/.claude.json and unseen by the node/python scanners are still inventoried\n[…]\nmpt can fire under\nthe default posture.\n\nAlso add Gemini CLI (~/.gemini/skills, .gemini/skills) and Aider (.aider/skills)\nsources plus the Zed alias, and walk_dirs_visited / walk_roots_found counters.",
"is_bot": false,
"headline": "feat(skills): discover unregistered projects via home-directory walk",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-16T10:06:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "39016f01ddad6c0f07ae05980f6d424b5c8686f7",
"body": "- mcpVendorForPath: only label VS Code when the path is a .vscode* dotfile\n root or the actual Code/User config shape, so project roots like ~/code are\n no longer mislabeled Microsoft.\n- allConfigLocations: case-fold the dedup key on Windows so the same file\n found via different casings isn't reported twice.\n- Reword the Detect doc comment (it doesn't return content) and the\n basename-set comment (complete sentence).\n- Add a regression test for the vendor heuristic.",
"is_bot": false,
"headline": "fix(mcp): address review — vendor heuristic, Windows dedup, comments",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-16T08:16:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6823550e70a3ad3ecd2bd5c82643bfe135824022",
"body": "… claim\n\nReview feedback fixes:\n\n- nodepm, pythonpm, and configaudit yarn/bun assessed the resolved\n absolute path with execguard but then executed the bare command name,\n letting a PATH re-resolution at exec time reach a binary the guard\n never assessed. All version-probe fallbacks now run the e\n[…]\native\n plugins it may dlopen later — metadata-first resolution remains the\n primary defense; the guard removes the main scan-triggered vector.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(detector): exec the guard-assessed path, bound PlistBuddy, temper…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-16T03:23:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e7515a3cd03302cbe6495ae44df4f029d7d2f382",
"body": "… on macOS\n\nMetadata-first version resolution removed most third-party execs, but a\ntool with no readable install metadata still fell back to running\n`--version` — and if that binary is quarantined (com.apple.quarantine,\nset by browser downloads and Homebrew casks) and not notarized, macOS\nshows the\n[…]\nbin/xattr, /usr/sbin/spctl) are\nexecuted by the guard itself. Non-macOS platforms are unaffected.\nGeneralizes the existing IsAppleCLTStub guard.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(detector): skip exec of Gatekeeper-rejected quarantined binaries…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-16T00:47:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "10e773f722dfaf342fb35db9a56df8653f4ad47e",
"body": "Executing third-party binaries for --version popped macOS Gatekeeper\n\"could not verify\" dialogs when a tool ships un-notarized native code\n(cursor-agent dlopens merkle-tree-napi.darwin-arm64.node on any\ninvocation, including --version).\n\n- new internal/versionmeta package resolves versions from on-d\n[…]\nogs a stderr line\n (\"exec fallback: running ...\") so rollouts can track which tools\n still get executed; detectors gain a chainable WithLogger\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(detector): resolve tool versions from install metadata before exec",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-16T00:43:06Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e7b865e935dc5a359ffd8fc474d687f2acb5d388",
"body": "has_code / code_file_count is a coarse \"this skill could run code\" signal that\ncomplements has_shell_injection and has_hooks. The census counted only\n.py/.js/.ts/.sh, so PowerShell, Ruby, ESM (.mjs/.cjs), .bash/.zsh, and Windows\n.bat/.cmd skills read as has_code=false, understating risk.\n\nWiden code\n[…]\np/.lua). Compiled languages are intentionally excluded\n(build step required, prone to vendored-dep/build-artifact false positives).\n\nNo logic change — the stat-only census keys off this map unchanged.",
"is_bot": false,
"headline": "feat(skills): broaden has_code detection to more executable script types",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-15T19:25:21Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b3ea87d49471324db431a9114266137e87aea466",
"body": "…scovery\n\nThe agent-skills detector was the one filesystem walker not wired to the\nshared tcc.Skipper, so a project registered in ~/.claude.json under a\nTCC-protected directory (e.g. ~/Documents) was probed directly and could fire\na macOS permission prompt, breaking the agent's \"never triggers a TCC\n[…]\nng the\n XDG_STATE_HOME-under-~/Library vector.\n- Wire the skipper at the community-scan and telemetry construction sites.\n\nA nil skipper (--include-tcc-protected) and non-macOS builds are unaffected.",
"is_bot": false,
"headline": "fix(skills): honor macOS TCC-protected directories in agent-skills di…",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-15T17:13:24Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "497d317aa380c72b73a1a099d7ba5430645074e1",
"body": "MCP discovery only checked a hard-coded list of exact config paths plus\n.mcp.json files in Claude-registered projects. Anything else was invisible —\nnotably VS Code's user-level mcp.json (%APPDATA%\\Code\\User\\mcp.json,\n~/Library/Application Support/Code/User/mcp.json) and .mcp.json files under\n~/.vsc\n[…]\nss into protected trees is introduced.\n\nThe content parser is unchanged, so once a config is located its servers\n(local command and remote url/serverUrl) are extracted with secrets stripped\nas before.",
"is_bot": false,
"headline": "fix(mcp): recognize MCP configs by name, add VS Code + broaden discovery",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-15T06:04:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d7556be31619c70248aad2d73e810fd4912cedc0",
"body": "…nputs\n\nTruncation honesty: mark the scan Truncated on context cancellation or\ndeadline and in the panic-recovery path, and enforce a 2000-record\naggregate cap (matching the backend payload cap) through a\nfinalizeSkills helper shared by the normal return and the recovery\npath, so a partial inventory\n[…]\ne telemetry\nskills bridge (skills live under <project>/.claude/skills, not the\nvenv), and render \"Not scanned\" vs \"None detected\" distinctly in pretty\nand HTML output when the skills scan did not run.",
"is_bot": false,
"headline": "fix(detector): harden agent skills scan against partial and hostile i…",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-14T18:03:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "da7bc69184a8d3cd3e009ff88b2e4c04c9267117",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into feat/ai-agent-skills-inventory",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-13T20:53:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b08f2b26fd22637e5219f8a2c6fe2dae8bf955d0",
"body": "The ~/.claude/plugins/{cache,repos} subtrees are no longer walked for\nskill directories, and claude_plugin is removed from the source set.\nSkills are discovered through the global, project, and skills.sh\nlock-managed roots only; a plugin's skill is inventoried when it is\nsymlinked or installed into \n[…]\ng and the skills.sh lock's\nplugin_name provenance are unchanged.\n\nAlso stop echoing the canonical record's own source into symlink_sources\nwhen another member of its collapse group shares that source.",
"is_bot": false,
"headline": "feat(detector): stop walking Claude Code plugin trees for skills",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-09T19:16:17Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5afc0d4b66cbcc44f6423792831a98a26239e716",
"body": "skills.sh installs a skill once and symlinks it into each agent's own\nroot, so enumeration emitted one record per root and inflated a single\nphysical skill into N+1 records. Collapse those shadows into one record\nper physical skill dir, keyed on the symlink-resolved path: the real\ndirectory is canon\n[…]\ne now-constant\nis_symlink and present_on_disk fields.\n\nAlso add Pi, Factory, Amp, and Copilot skill roots (global and project),\nincluding Factory's singular .agent/skills and Copilot's .github/skills.",
"is_bot": false,
"headline": "feat(detector): collapse symlink shadows in agent skills inventory",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-09T18:39:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "22df21ed653c48a5290c3360f58c3bf097eae11e",
"body": "…repo-flag\n\nfix(ci): pin repo target for gh release upload/delete-asset in macOS …",
"is_bot": false,
"headline": "Merge pull request #164 from ashishkurmi/akurmi/fix/release-macos-gh-…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-09T17:03:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1de49a5b69b91a261b36c143aea865b35146ca45",
"body": "…notarize job\n\nThis job never checks out the repo, so gh has no git remote to infer\nthe target repository from. The upload/cleanup step omitted -R and\nfailed with \"not a git repository\", unlike the earlier download step\nwhich already passes -R.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ci): pin repo target for gh release upload/delete-asset in macOS …",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-09T16:58:13Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2d2e69f32892b5d4307e6ab9848bd1f0894af1b7",
"body": "…raft-race\n\nfix(ci): wait for release-list propagation before resolving draft tag",
"is_bot": false,
"headline": "Merge pull request #163 from ashishkurmi/akurmi/fix/release-resolve-d…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-09T15:20:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "03253261d8afe44fb565cafec1cb710c6e25f71b",
"body": "GoReleaser creates the draft release for a tag pushed earlier in the\nsame job, and GitHub can take a few seconds to index that tag before\nthe new release shows up in the releases-list API. Querying\nimmediately can return an empty list and fail with \"Could not find\ndraft release\", even though the release was created successfully.\n\nAdd a fixed 30s sleep before the lookup to give GitHub's API time to\ncatch up.",
"is_bot": false,
"headline": "fix(ci): wait for release-list propagation before resolving draft tag",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-09T15:12:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "53c5fac6e2a88e8c2fd061db85b291f024952993",
"body": "…s-inventory\n\n# Conflicts:\n#\tinternal/featuregate/featuregate.go",
"is_bot": false,
"headline": "Merge remote-tracking branch 'upstream/main' into feat/ai-agent-skill…",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-09T13:53:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6eda105a49232455cdac2932f40c7cfd4de83adc",
"body": "The home directory appears in the ~/.claude.json project registry whenever\nClaude Code has been run from $HOME. Treating it as a project re-scanned the\nglobal skill dirs (~/.claude/skills, ~/.agents/skills) and re-emitted every\nglobal skill as a project-scoped duplicate, also double-counting roots_scanned.\n\nSkip the home directory in project discovery — its dotfile skill dirs are the\nglobal roots. Adds a regression test covering a registry that lists both home\nand a genuine sub-project.",
"is_bot": false,
"headline": "fix(detector): exclude home dir from skills project discovery",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-09T13:47:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e539e5644e2e5196e68b2e37b259ca9615c80733",
"body": "Scan for Agent Skills installed for AI coding agents at global and\nper-project scope, covering Claude Code skills and skills.sh-managed\ninstalls (including plugin-provided skills).\n\nFor each skill the scan records metadata (name, agent, scope, source),\na SHA-256 hash of its SKILL.md for drift detect\n[…]\nare never read beyond SKILL.md and are never transmitted; local\nsource paths from lock files are recorded by alias only.\n\nThe ~/.claude.json project-registry discovery is shared with the MCP\ndetector.",
"is_bot": false,
"headline": "feat(detector): add AI agent skills inventory scanning",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-09T13:15:59Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8f0e5912b37ad8f7afcfe6ed7d6e433c2ac6f224",
"body": "feat(featuregate): enable device-policy enforcement by default",
"is_bot": false,
"headline": "Merge pull request #161 from raysubham/subham/feat/wt/device-policy-ga",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-09T10:35:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ac979bb00afe39ea931d3caa4b59eadc109e8999",
"body": "Turn on the device-policy feature gate so IDE-extension policy enforcement\nruns for all enterprise customers instead of staying behind the beta gate.\n\nAll enforcement code is already on main (run-config policy fetch,\ntarget-aware policy identity, user-scope settings.json convergence,\ncompliance repo\n[…]\n0, matching this build's version\nfloor, so enabling enforcement is safe.\n\nDrop the now-stale gate comment, and note general availability plus\nenabled-by-default on the existing 1.13.0 changelog entry.",
"is_bot": false,
"headline": "feat(featuregate): enable device-policy enforcement by default",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-07-09T09:15:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b837f57d15a145ae7ab97c62e4bf62b2cc2209e2",
"body": "…s-yarn-globals\n\nfix(node): enumerate yarn classic globals on Windows",
"is_bot": false,
"headline": "Merge pull request #160 from swarit-stepsecurity/swarit/fix/wt/window…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-08T20:36:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "71c052caff4e9e1be938fcb36bc34497779ee45a",
"body": "NodeGlobalRoots only had the POSIX yarn global path (~/.config/yarn/global),\nwhich never resolves on Windows (yarn 1.x installs to %LOCALAPPDATA%\\Yarn\\Data\\global).\nSo yarn globals (gulp/grunt-cli) were invisible on Windows while npm/pnpm\nworked. Add the Windows yarn global location(s).",
"is_bot": false,
"headline": "fix(node): enumerate yarn classic globals on Windows",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-08T10:59:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b0c88ce222271b034c8ed45e5d7d610a423f33d8",
"body": "…lobal-discovery\n\nfix(node): discover pnpm globals (v10+ layout + store lockfile fallback)",
"is_bot": false,
"headline": "Merge pull request #159 from swarit-stepsecurity/swarit/fix/wt/node-g…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-08T10:40:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4dd5db89596d7912778114f2402c81eff715c774",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into swarit/fix/wt/node-global-discovery",
"author_name": "Swarit",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-08T10:05:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a911076f9011e408651aad9a34bd0303b1ec8efc",
"body": "…m store)\n\npnpm installs global packages as symlinks into a content-addressed store, so\nwalking the global node_modules yields nothing. When ScanGlobalModules returns\nempty, fall back to parsing the install dir's lockfile (parent of node_modules)\nkeyed on the root's PM, recovering pnpm globals (webpack/jest) with is_direct.",
"is_bot": false,
"headline": "fix(node): parse global lockfile when node_modules walk is empty (pnp…",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-08T09:19:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c69100fd6ba38ad0b0ab50bd7d7c97662b632ef1",
"body": "…dules)\n\nNodeGlobalRoots only globbed <pnpm-home>/global/*/node_modules, matching\npnpm <=9. pnpm v10+ nests each global install under global/v<major>/<hash>/,\nso the disk scan found zero pnpm globals (webpack/jest missing). Add the\nextra-level glob so both layouts are enumerated.",
"is_bot": false,
"headline": "fix(node): discover pnpm v10+ globals (global/v<major>/<hash>/node_mo…",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-08T09:03:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6b7a999bcac282cf2b4e0095e0fd2af0d6686c12",
"body": "…er-1.12.1\n\nchore(release): update to 1.13.0",
"is_bot": false,
"headline": "Merge pull request #158 from swarit-stepsecurity/swarit/chore/wt/up-v…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-08T05:39:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0bb1dc8fe638fe15c08b504ae262d21c2a8580fc",
"body": "Minor release: carries device-policy enforcement, disk-based npm/Python\npackage scanning, scheduler diagnostics + run-on-login, heartbeat, and the\nopt-in scan-state delta protocol.\n\nSigned-off-by: Swarit Pandey <swarit@stepsecurity.io>",
"is_bot": false,
"headline": "chore(release): update to 1.13.0",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-08T05:24:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f797e76e91a73cc0127be16f8e49d18b1c62a0fa",
"body": "…ng-guidelines\n\ndocs: add coding guidelines derived from existing patterns",
"is_bot": false,
"headline": "Merge pull request #157 from swarit-stepsecurity/swarit/chore/wt/codi…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-07T06:51:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5e1b1727933631a747f90b1864cb99e2b6346f7f",
"body": null,
"is_bot": false,
"headline": "docs: rename coding-guidelines.md to AGENTS.md at repo root",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-07T06:41:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b4f9888a2002d5271886bbb20dafd8eb726b63ea",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into swarit/chore/wt/coding-guidelines",
"author_name": "Swarit",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-07T06:40:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f585dc0589ed268fe49e8d3a99731c4cd98d6f23",
"body": "feat(devicepolicy): enforce VS Code extension allowlist",
"is_bot": false,
"headline": "Merge pull request #138 from raysubham/feat/dmg-policy-profiles",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-06T06:18:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "413cc837066787de43145c676bb6a988a85db10f",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into feat/dmg-policy-profiles",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-06T06:14:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c9b913c0c37a3115923ba559d7a7442d8816ce2a",
"body": "…te-npm-scanning\n\nfeat(node): add disk-based package scanning (lockfile parsing)",
"is_bot": false,
"headline": "Merge pull request #156 from swarit-stepsecurity/swarit/feat/wt/migra…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-03T06:26:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "02b0de77e3ef97b484906d0fd3f95bee6062e2ed",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into swarit/feat/wt/migrate-npm-scanning",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-03T06:21:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "665eaaaa8e8a50adf4317d78429b3ca25004187c",
"body": "…hooting\n\ndocs: add macOS launchd troubleshooting guide",
"is_bot": false,
"headline": "Merge pull request #143 from shubham-stepsecurity/sm/launchd-troubles…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-03T06:20:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e6a1427b7a74b65e3a02a9e8d5cbd4c6164beeda",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into swarit/feat/wt/migrate-npm-scanning",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-03T06:19:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "83915ba45c4c9fa17835d0dc81a941c240cc22e1",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into sm/launchd-troubleshooting",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-03T06:17:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5bb357e3a3bfe402c3ac9b5f824f0a8f3d8d60db",
"body": "…tudio\n\nfeat(detector): discover classic Visual Studio extensions and installs",
"is_bot": false,
"headline": "Merge pull request #142 from shubham-stepsecurity/sm/classic-visual-s…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-03T05:58:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8b3b85f673faa603ce1b0bdaba73dfaae7b09038",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into sm/classic-visual-studio",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-03T05:54:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8a34e8cdd9222daa0eb8b4509ea7a72d08584e13",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into swarit/feat/wt/migrate-npm-scanning",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-03T05:20:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "992f385a2dfc93f59f454b97d58e243085f4a694",
"body": null,
"is_bot": false,
"headline": "feat(detector): discover classic Visual Studio extensions and installs",
"author_name": "Shubham Malik",
"author_login": "shubham-stepsecurity",
"committed_at": "2026-07-03T04:27:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "74fbd1cd805339452b9f2de5393c137fc0ae3fa8",
"body": "…te-py-scanning\n\nfeat(python): disk-based package scanning (dist-info metadata)",
"is_bot": false,
"headline": "Merge pull request #155 from swarit-stepsecurity/swarit/feat/wt/migra…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-02T16:26:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "59e25b7b4276ac3e60dbaed9f8a7032c63d6fc16",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into swarit/feat/wt/migrate-py-scanning",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-02T06:13:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "44474f0c29cb7d093a52336c589bcc218822907e",
"body": "…acquire-logging\n\nfeat(telemetry): log and report lock-acquisition contention at info",
"is_bot": false,
"headline": "Merge pull request #152 from swarit-stepsecurity/swarit/feat/wt/lock-…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-02T06:13:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9b596f92d49a4d93cd4f6f3eff9b3be1342ff82c",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into swarit/feat/wt/lock-acquire-logging",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-07-02T06:08:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1d6ac5edff82c5b1a040764523ae5ea53cddf605",
"body": null,
"is_bot": false,
"headline": "fix(node): count disk packages in scan cap; gate delta on PMVersion",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-07-02T03:49:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4abd891091696bc439bed5ae5131f7aa9a33b1ac",
"body": null,
"is_bot": false,
"headline": "docs(tcc): configure Full Disk Access for all devices only",
"author_name": "Shubham Malik",
"author_login": "shubham-stepsecurity",
"committed_at": "2026-07-01T01:53:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ff29a5ba5df74755b9847c0de98da191a8252c32",
"body": "Document the conventions the codebase already follows and link from\nCONTRIBUTING.md's Code Style section.",
"is_bot": false,
"headline": "docs: add coding guidelines derived from existing patterns",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-06-30T15:10:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3f35a34234f967555b7ab94058eebc6da80bd385",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into swarit/feat/wt/migrate-npm-scanning",
"author_name": "Swarit",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-06-30T11:06:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e5c66331e6bde8bcaaf03582b25da4818fb6441d",
"body": "Read installed Node packages by parsing lockfiles (package-lock v1/v2/v3,\npnpm-lock, yarn.lock, bun.lock) and node_modules instead of running\nnpm/yarn/pnpm/bun. Default to disk scan; legacy command path kept behind\n--legacy-node-scan / use_legacy_node_scan.\n\nEmits structured {name, version, is_direc\n[…]\nth\nempty raw output; the backend stores it via pass-through (no agent-api\nchange). is_direct keys on declared deps to match npm-ls tree semantics; no\n--depth cap, so the full resolved set is reported.",
"is_bot": false,
"headline": "feat(node): add disk-based package scanning (lockfile parsing)",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-06-30T10:53:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4b927a303705ef5b1c32329fd517b2841a034cfb",
"body": "fix(detector): resolve node PM versions via default install paths",
"is_bot": false,
"headline": "Merge pull request #141 from shubham-stepsecurity/sm/fix",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-06-30T07:19:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7360ce38f3616557c8868081d23f77b3d5325b7b",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into sm/fix",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-06-30T07:17:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1abf3c056275afc60fe3077da2c58581c8a59fed",
"body": "lock.Acquire can also fail on permission/IO errors creating the lock\nfile; the underlying error carries the specific cause. Reword the log\nline and comment so they no longer hard-code the 'another instance is\nrunning' assumption.",
"is_bot": false,
"headline": "fix(telemetry): don't assume lock failure means contention",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-06-29T15:23:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d85e9c526f80e2e076a7fe28737f92d8f5881d81",
"body": "- PythonGlobalRoots anchors per-user paths on the console user via\n executor.ResolveHome (falling back to os.UserHomeDir), so the\n root/launchd agent scans the logged-in user's ~/.local, ~/.pyenv, pipx.\n- readBounded stats file size before reading to avoid large allocations,\n keeping the post-read length check as a race-safety fallback.\n- ScanVenv limits its walk to the venv's site-packages dirs instead of\n the whole tree.",
"is_bot": false,
"headline": "fix(python): address PR review on disk-based scanning",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-06-29T15:19:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8266443e2bf11f5b5b301f0429dff3c99af19829",
"body": "…get)\n\nPolicy identity is now (category, target) rather than category alone. An\nempty target defaults to vscode for ide_extension, so a future IDE family\nbecomes a new target instead of a new category or an on-disk migration. v1\nstill enforces only ide_extension/vscode and preserves VS Code behavior\n[…]\net through fetch, state read/write/clear, and\n reporting; an empty Reconciler.Target defaults to vscode, so main.go needs\n no change.\n\nDetection-rules fetch/scan path is untouched (zero regression).",
"is_bot": false,
"headline": "feat(devicepolicy): make policy identity target-aware (category + tar…",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-06-29T12:35:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "70e644a406e2de973679d472902de9b6ca868a65",
"body": "…aticcheck S1016)",
"is_bot": false,
"headline": "fix(python): use type conversion for PackageDetail->PythonPackage (st…",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-06-28T18:53:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d113b9526529353be89ab9dbe8e684e1ead7c040",
"body": "Read installed Python packages from *.dist-info/METADATA and *.egg-info/\nPKG-INFO instead of running pip. Default to disk scan; legacy pip path\nkept behind --legacy-python-scan / use_legacy_python_scan.",
"is_bot": false,
"headline": "feat(python): add disk-based package scanning (dist-info metadata)",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-06-28T18:30:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "efbd43bbb5fae47cc0b2212b02d63ec262b00ce9",
"body": "…evel\n\nSurface lock-acquisition failures (another instance already running) at info\nlevel instead of Debug so the contention is visible in agent.log, and report\nthe failed run immediately at the failure site so the backend records that a\nsecond invocation contended for the lock. reportFailedOnce is idempotent, so\nthe deferred handler firing on the error return is a no-op.",
"is_bot": false,
"headline": "feat(telemetry): log and report lock-acquisition contention at info l…",
"author_name": "Swarit Pandey",
"author_login": "swarit-stepsecurity",
"committed_at": "2026-06-25T06:52:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8d7920c50594481d237033dc05d09fb1ffb68c74",
"body": "The Windows-as-SYSTEM install branch ran runIDEExtensionEnforce inline\nwhile running as NT AUTHORITY\\SYSTEM. Enforce writes user-scope\nsettings.json (%APPDATA%\\Code\\User), which under SYSTEM resolves to the\nservice profile — a phantom write no real VS Code reads, plus a false\n\"compliant\" report agai\n[…]\neady fires the /ru INTERACTIVE task, which enforces in the\nlogged-in user's profile via send-telemetry. Drop the inline call so the\nSYSTEM branch does no user-profile work, mirroring the macOS branch.",
"is_bot": false,
"headline": "fix(install): don't enforce IDE policy inline under SYSTEM",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-06-24T20:13:42Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c36dfd47333a466cf330f9a556e3aa9a1fea998d",
"body": "…ve-policy endpoint\n\nThe backend consolidated the per-device IDE-extension policy into the existing\nrun-config response as a `policy` sub-object; the dedicated effective-policy\nendpoint is gone (404). Repoint HTTPFetcher.Fetch at run-config and lift the\ndirective from `policy`.\n\n- GET run-config?dev\n[…]\n document parses to reach `policy`; shared maxBodyBytes stays\n 256 KiB for the error-snippet/drain reads.\n\nEnforcement is inert until the consolidated backend is live in the target env\n(live on int).",
"is_bot": false,
"headline": "fix(devicepolicy): fetch policy from run-config, drop removed effecti…",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-06-24T19:59:12Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d52c94129902382446c2bc559ad4160d2b0eb820",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into feat/dmg-policy-profiles",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-06-24T18:49:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "68fdfb3ab74557264429fd620923ee456bc76459",
"body": "…dule-24h\n\nfix(schtasks): use DAILY schedule for scan frequencies of 24h+",
"is_bot": false,
"headline": "Merge pull request #151 from raysubham/subham/fix/schtasks-daily-sche…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-06-24T09:37:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "83a8f73833299ffa295c57dac807ebc82bac68e2",
"body": "schtasks caps the HOURLY /mo modifier at 23, so a 24-hour scan frequency\nproduced `/sc HOURLY /mo 24`, which schtasks rejects with \"Invalid value\nfor /MO option\". The install custom action then exits non-zero and the MSI\nrolls back, surfacing under Intune as 0x80070643 (and failing identically\non a \n[…]\nr() with table-driven unit coverage (boundaries 23/24, the\n24h case, and pathological 0/100000 inputs) plus a regression guard that\nthe hourly path and the admin /ru INTERACTIVE binding are untouched.",
"is_bot": false,
"headline": "fix(schtasks): use DAILY schedule for scan frequencies of 24h+",
"author_name": "Subham Ray",
"author_login": "raysubham",
"committed_at": "2026-06-24T07:53:09Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1c83b7d792cb6b1ec4fa9707595dff75895fe73f",
"body": "…nterval-gate\n\nfeat: run-on-login scheduling, reliability fixes, scheduler diagnostics",
"is_bot": false,
"headline": "Merge pull request #146 from shubham-stepsecurity/sm/scheduler-info-i…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-06-24T06:43:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "37a0a422cd6111af6ba8584cd06dbbfc8af896bf",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into sm/scheduler-info-interval-gate",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-06-24T06:40:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2412a3fb30b32940f5d55c2237f76082ff9405e1",
"body": "…logs-python\n\nchore: add per-venv scan logging to Python project detector",
"is_bot": false,
"headline": "Merge pull request #144 from swarit-stepsecurity/swarit/chore/wt/add-…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-06-24T06:39:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "911866efa0532b5a086ae3cf5458cb8510005b2f",
"body": null,
"is_bot": false,
"headline": "Merge branch 'main' into swarit/chore/wt/add-logs-python",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-06-24T06:34:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2a5db1c437edd30f9b562837fb54c32570712acb",
"body": null,
"is_bot": false,
"headline": "feat(telemetry): include this run's loader-script logs",
"author_name": "Shubham Malik",
"author_login": "shubham-stepsecurity",
"committed_at": "2026-06-23T23:47:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "af7bb2f659c6d2eb7df6617ecb05977384293d76",
"body": null,
"is_bot": false,
"headline": "feat: enable Windows Task Scheduler history; address review feedback",
"author_name": "Shubham Malik",
"author_login": "shubham-stepsecurity",
"committed_at": "2026-06-23T23:31:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "823bedb66d31e67132018ee90cd4c7b19e81fc0b",
"body": null,
"is_bot": false,
"headline": "feat: run-on-login scheduling, reliability fixes, scheduler diagnostics",
"author_name": "Shubham Malik",
"author_login": "shubham-stepsecurity",
"committed_at": "2026-06-23T23:31:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c9b55b78c588aabd341039afbe859d0fa1d1118e",
"body": "…-heartbeat\n\nfeat(heartbeat): write last-run.json at top of send-telemetry",
"is_bot": false,
"headline": "Merge pull request #148 from swarit-stepsecurity/swarit/feat/last-run…",
"author_name": "Ashish Kurmi",
"author_login": "ashishkurmi",
"committed_at": "2026-06-23T13:06:22Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 18,
"commits_last_year": 513,
"latest_release_at": "2026-07-17T18:53:26Z",
"latest_release_tag": "v1.14.0",
"releases_from_tags": false,
"days_since_last_push": 2,
"active_weeks_last_year": 19,
"days_since_latest_release": 9,
"mean_days_between_releases": 8.8
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": true,
"health_percentage": 87,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": true
},
"ecosystem": {
"packages": [
{
"name": "github.com/step-security/dev-machine-guard",
"exists": true,
"license": null,
"keywords": [],
"ecosystem": "go",
"matches_repo": true,
"registry_url": "https://pkg.go.dev/github.com/step-security/dev-machine-guard",
"is_deprecated": false,
"latest_version": "v1.14.0",
"repository_url": "https://github.com/step-security/dev-machine-guard",
"versions_count": 18,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-17T14:37:14Z",
"latest_version_yanked": null,
"days_since_latest_publish": 9
}
]
},
"popularity": {
"forks": 23,
"stars": 169,
"watchers": 5,
"fork_history": {
"days": [
{
"date": "2026-03-12",
"count": 2
},
{
"date": "2026-03-13",
"count": 1
},
{
"date": "2026-03-15",
"count": 1
},
{
"date": "2026-03-16",
"count": 2
},
{
"date": "2026-03-17",
"count": 1
},
{
"date": "2026-03-24",
"count": 1
},
{
"date": "2026-04-02",
"count": 1
},
{
"date": "2026-04-03",
"count": 1
},
{
"date": "2026-04-08",
"count": 1
},
{
"date": "2026-04-17",
"count": 1
},
{
"date": "2026-04-24",
"count": 1
},
{
"date": "2026-04-29",
"count": 1
},
{
"date": "2026-05-05",
"count": 1
},
{
"date": "2026-05-10",
"count": 1
},
{
"date": "2026-06-01",
"count": 1
},
{
"date": "2026-06-21",
"count": 1
},
{
"date": "2026-06-23",
"count": 2
},
{
"date": "2026-06-26",
"count": 1
},
{
"date": "2026-06-28",
"count": 1
},
{
"date": "2026-07-25",
"count": 1
}
],
"complete": true,
"collected": 23,
"total_forks": 23
},
"star_history": null,
"open_issues_and_prs": 33
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"examples"
],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [
"Makefile"
],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [
"go.mod"
],
"largest_source_bytes": 70180,
"source_files_sampled": 333,
"oversized_source_files": 2,
"agent_instruction_files": [
"AGENTS.md"
],
"agent_instruction_max_bytes": 42944
},
"dependencies": {
"manifests": [
"go.mod"
],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"go"
],
"dependencies": [
{
"name": "golang.org/x/sys",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.33.0"
},
{
"name": "github.com/google/shlex",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.0.0-20191202100458-e7afc7fbc510"
},
{
"name": "github.com/google/uuid",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.6.0"
},
{
"name": "github.com/pelletier/go-toml/v2",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v2.3.1"
},
{
"name": "github.com/tailscale/hujson",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.0.0-20260302212456-ecc657c15afd"
},
{
"name": "github.com/tidwall/gjson",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.18.0"
},
{
"name": "github.com/tidwall/pretty",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.2.1"
},
{
"name": "github.com/tidwall/sjson",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.2.5"
},
{
"name": "gopkg.in/yaml.v3",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v3.0.1"
},
{
"name": "howett.net/plist",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.0.1"
}
],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 8,
"merged_prs": 121,
"open_issues": 25,
"closed_ratio": 0.219,
"closed_issues": 7,
"closed_unmerged_prs": 20
},
"bus_factor": 2,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "ashishkurmi",
"commits": 196,
"avatar_url": "https://avatars.githubusercontent.com/u/100655670?v=4"
},
{
"type": "User",
"login": "swarit-stepsecurity",
"commits": 172,
"avatar_url": "https://avatars.githubusercontent.com/u/208925350?v=4"
},
{
"type": "User",
"login": "shubham-stepsecurity",
"commits": 79,
"avatar_url": "https://avatars.githubusercontent.com/u/171509047?v=4"
},
{
"type": "User",
"login": "raysubham",
"commits": 57,
"avatar_url": "https://avatars.githubusercontent.com/u/66999381?v=4"
},
{
"type": "User",
"login": "Prateek-stepsecurity",
"commits": 4,
"avatar_url": "https://avatars.githubusercontent.com/u/209430544?v=4"
},
{
"type": "User",
"login": "eromosele-stepsecurity",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/193469761?v=4"
},
{
"type": "User",
"login": "varunsh-coder",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/25015917?v=4"
}
],
"contributors_sampled": 7,
"top_contributor_share": 0.384
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"check-notarization-status.yml",
"gosec.yml",
"msi-smoke.yml",
"release-macos.yml",
"release.yml",
"test-azure-signing.yml",
"test-build.yml",
"test-macos-signing.yml",
"tests.yml",
"verify-release.yml"
],
"has_docs_dir": true,
"linter_configs": [
".golangci.yml"
],
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"go.sum"
],
"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": 8,
"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": "9 out of 9 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": 10,
"reason": "all changesets reviewed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 10,
"reason": "project has 3 contributing companies or organizations -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no 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": 10,
"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 12 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": 10,
"reason": "all dependencies are pinned",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 10,
"reason": "SAST tool is run on all commits",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 10,
"reason": "security policy file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": 8,
"reason": "5 out of the last 5 releases have a total of 5 signed artifacts.",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 10,
"reason": "GitHub workflow tokens follow principle of least privilege",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 9,
"reason": "1 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "2cf07e270ae355919a8c48fd41bc315cdbe8ceaf",
"ran_at": "2026-07-27T03:59:36Z",
"aggregate_score": 8.2,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": true,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-24T16:48:36Z",
"oldest_open_prs": [
{
"number": 78,
"created_at": "2026-05-16T20:00:18Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 79,
"created_at": "2026-05-18T03:27:09Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 84,
"created_at": "2026-05-19T02:18:41Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 85,
"created_at": "2026-05-19T02:36:13Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 89,
"created_at": "2026-05-20T18:50:53Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 174,
"created_at": "2026-07-19T10:09:54Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 179,
"created_at": "2026-07-23T04:36:02Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 180,
"created_at": "2026-07-25T07:28:31Z",
"last_comment_at": null,
"last_comment_author": null
}
],
"last_merged_pr_at": "2026-07-24T16:47:05Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 2,
"created_at": "2026-03-12T06:31:58Z",
"last_comment_at": "2026-04-08T14:32:30Z",
"last_comment_author": "swarit-stepsecurity"
},
{
"number": 3,
"created_at": "2026-03-12T06:33:21Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4,
"created_at": "2026-03-12T06:34:52Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 5,
"created_at": "2026-03-12T06:36:14Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 6,
"created_at": "2026-03-12T06:36:57Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 9,
"created_at": "2026-03-16T18:59:22Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 11,
"created_at": "2026-04-02T15:23:47Z",
"last_comment_at": "2026-04-02T15:36:02Z",
"last_comment_author": "koesper"
},
{
"number": 12,
"created_at": "2026-04-02T18:29:43Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 13,
"created_at": "2026-04-02T18:30:53Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 14,
"created_at": "2026-04-03T16:25:25Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 46,
"created_at": "2026-04-27T05:59:59Z",
"last_comment_at": "2026-04-27T06:00:17Z",
"last_comment_author": "swarit-stepsecurity"
},
{
"number": 57,
"created_at": "2026-05-01T10:25:59Z",
"last_comment_at": "2026-06-11T18:28:10Z",
"last_comment_author": "ashishkurmi"
},
{
"number": 58,
"created_at": "2026-05-01T10:30:16Z",
"last_comment_at": "2026-05-04T07:48:21Z",
"last_comment_author": "ashishkurmi"
},
{
"number": 66,
"created_at": "2026-05-06T06:45:20Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 83,
"created_at": "2026-05-18T21:40:23Z",
"last_comment_at": "2026-05-19T02:37:01Z",
"last_comment_author": "swarit-stepsecurity"
},
{
"number": 90,
"created_at": "2026-05-20T22:08:47Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 96,
"created_at": "2026-05-21T21:04:39Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 102,
"created_at": "2026-05-22T12:25:15Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 110,
"created_at": "2026-05-25T21:48:18Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 139,
"created_at": "2026-06-11T23:25:27Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/step-security/dev-machine-guard",
"host": "github.com",
"name": "dev-machine-guard",
"owner": "step-security"
},
"metrics": {
"overall": {
"key": "overall",
"band": "good",
"name": "Overall health",
"note": null,
"notes": [],
"value": 77,
"inputs": {
"security": 82,
"vitality": 85,
"community": 70,
"governance": 70,
"engineering": 80
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 85,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 77,
"inputs": {
"commits_last_year": 513,
"human_commit_share": 1,
"days_since_last_push": 2,
"active_weeks_last_year": 19
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 2 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 2
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "19/52 weeks with commits",
"points": 13.2,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 19
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "513 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 513
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 12 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": 98,
"inputs": {
"releases_count": 18,
"latest_release_tag": "v1.14.0",
"releases_from_tags": false,
"days_since_latest_release": 9,
"mean_days_between_releases": 8.8
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "18 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 18
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 9 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 9
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~8.8 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 8.8
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "5 out of the last 5 releases have a total of 5 signed artifacts.",
"points": 8,
"status": "partial",
"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": "good",
"name": "Community & Adoption",
"value": 70,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "moderate",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 51,
"inputs": {
"forks": 23,
"stars": 169,
"watchers": 5,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "169 stars",
"points": 36.1,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 169
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "23 forks",
"points": 11.2,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 23
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "5 watchers",
"points": 3.3,
"status": "partial",
"details": [
{
"code": "watchers",
"params": {
"count": 5
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "excellent",
"name": "Community health",
"note": null,
"notes": [],
"value": 92,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": true,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (Apache-2.0)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "Apache-2.0"
}
}
],
"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": 13.5,
"status": "met",
"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": 6.3,
"status": "met",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "good",
"name": "Sustainability & Governance",
"value": 70,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "moderate",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 59,
"inputs": {
"bus_factor": 2,
"contributors_sampled": 7,
"top_contributor_share": 0.384
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "2 contributor(s) cover half of all commits",
"points": 25.2,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 2
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 38% of commits",
"points": 13.9,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 38
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "7 contributors",
"points": 9.5,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 7
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 3 contributing companies or organizations -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "moderate",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 58,
"inputs": {
"merged_prs": 121,
"open_issues": 25,
"closed_issues": 7,
"issue_closed_ratio": 0.219,
"closed_unmerged_prs": 20
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "22% of issues closed",
"points": 10.2,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 22
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "121/141 decided PRs merged",
"points": 32.8,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 121,
"decided": 141
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "all changesets reviewed",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "good",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 70,
"inputs": {
"followers": 251,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "step-security",
"public_repos": 497,
"account_age_days": 1811
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "251 followers of step-security",
"points": 17.3,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 251,
"login": "step-security"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "497 public repos, account ~4 yr old",
"points": 22.9,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 497
}
},
{
"code": "account_age_years",
"params": {
"years": 4
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"github.com/step-security/dev-machine-guard"
],
"ecosystems": "go",
"any_deprecated": false,
"min_days_since_publish": 9
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on go",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "go"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 9 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 9
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "18 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 18
}
}
],
"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": 80,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "good",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 84,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "10 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 10
}
}
],
"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": ".golangci.yml",
"points": 16,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": ".golangci.yml"
}
}
],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "9 out of 9 merged PRs checked by a CI test -- score normalized to 10",
"points": 20,
"status": "met",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "good",
"name": "Documentation",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"topics": [],
"has_wiki": true,
"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": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "good",
"name": "Security",
"value": 82,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "good",
"name": "Security posture",
"note": null,
"notes": [],
"value": 82,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 18,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 0,
"scorecard_aggregate": 8.2
},
"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": 6,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "9 out of 9 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": "all changesets reviewed",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 3 contributing companies or organizations -- score normalized to 10",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"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.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 12 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": "all dependencies are pinned",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is run on all commits",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "5 out of the last 5 releases have a total of 5 signed artifacts.",
"points": 6,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "GitHub workflow tokens follow principle of least privilege",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "1 existing vulnerabilities detected",
"points": 6.8,
"status": "partial",
"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": 9
},
"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": 82,
"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.79,
"agent_instruction_files": [
"AGENTS.md"
],
"agent_instruction_max_bytes": 42944
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "AGENTS.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "AGENTS.md"
}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "79 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 79,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "excellent",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"go.sum"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [
"Makefile"
],
"has_devcontainer": false,
"has_linter_config": true,
"typecheck_configs": [],
"agent_commit_share": 0.04,
"toolchain_manifests": [
"go.mod"
],
"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": ".golangci.yml",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": ".golangci.yml"
}
}
],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "Go (statically typed)",
"points": 11,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Go"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "4 of the last 100 commits agent-authored or agent-credited",
"points": 8,
"status": "partial",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 4,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "all dependencies are pinned",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "Go",
"largest_source_bytes": 70180,
"source_files_sampled": 333,
"oversized_source_files": 2
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Go (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Go"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "2/333 source files over 60KB",
"points": 54.7,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 333,
"oversized": 2
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "at_risk",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"example_dirs": [
"examples"
],
"has_mcp_signal": false,
"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": 0,
"status": "missed",
"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",
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
],
"report_type": "repository",
"generated_at": "2026-07-27T03:59:57.559871Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/s/step-security/dev-machine-guard.svg",
"full_name": "step-security/dev-machine-guard",
"license_state": "standard",
"license_spdx": "Apache-2.0"
}