$ AI agent governance, security tooling, and mechanical enforcement.

rigscore v2.0.0

  • #rigscore
  • #security
  • #ai
  • #devtools
  • #open-source
  • #breaking-change
  • #v2

Changes: v1.0.0 → v2.0.0

Public-release hardening pass. Four parallel tracks — security, distribution, scoring, docs — plus a dogfood-fixture fix. The scoring change is the reason this is a major bump.

Breaking

ChangeWhat it does
Continuous coverage scalingThe step at totalApplicableWeight < 50 is gone. Scaling is now scale = min(1, totalApplicableWeight / 100), applied always. Closes a gameable cliff where projects at applicable weight 48 scored visibly differently from projects at 50 despite representing the same coverage. Overall scores will shift downward for projects with applicable weight between 50 and 100. --fail-under thresholds calibrated against the old formula may need adjustment.

Security

ChangeWhat it does
ANSI escape injection closedstripAnsi applied to every file-sourced title / detail / evidence / remediation / learnMore before Chalk wrapping. Blocks terminal-hijack payloads (OSC 8, clear-screen, set-title) planted in scanned skill files.
Atomic saveStateState writes go to <path>.<pid>.<hex>.tmp and are rename()’d in place. Prevents SIGINT / concurrent-scan corruption of .rigscore-state.json and the silent loss of MCP pin hashes that followed.
Strict config parsingNew ConfigParseError + readJsonStrict. loadConfig, diff, and saveState propagate the structured error. CLI exits 2 with rigscore: <file> is not valid JSON (<err>). Fix and retry. instead of a raw Node stack.
Symlink-loop defenseShared walkDirSafe with lstat + visited-inode set + maxDepth (default 50, overridable via config.limits.maxWalkDepth). deep-secrets, skill-files, and the k8s/ enumeration in docker-security all use it. An info finding surfaces once per scan when a cycle is skipped.
Network timeout + per-file capfetch calls in src/http.js and src/mcp-registry.js wrap an AbortController with a 5s default (config.limits.networkTimeoutMs); the deep scanner skips files over 512 KB (config.limits.maxFileBytes) with an info finding.
windows-security desyncedSynchronous execSync replaced with the promisified execSafe used elsewhere. Same 5s timeout, no event-loop blocking.

Distribution

ChangeWhat it does
Lockfile regeneratedBuilt against package.json 1.0.0 — npm ci is reproducible again.
Runtime + dev deps pinned to exact versionsCaret ranges on chalk, yaml, vitest gone. Closes the self-own of a supply-chain scanner re-resolving deps on every install.
engines.node floor → >=18.17.0fs.promises.readdir({ recursive: true }) guaranteed available.
User-Agent derived from package.jsoncreateRequire at module load. No more hardcoded rigscore/0.8.0 drift across releases.
--init-hook pins @v${pkg.version}Writes the current version’s tag into .git/hooks/pre-commit. Older pinned versions during re-install warn rather than silently append.
CI matrix expandedNode 18.17, 20, 22 across ubuntu-latest and macos-latest, with a lockfile-drift guard (npm ci && git diff --exit-code package-lock.json) to prevent future lockfile regressions.
Dockerfile hardenedNon-root rigscore user runs the scan. ARG VERSION + org.opencontainers.image.* labels replace the stale v1.1.0 comment. Image no longer reads mounted /workspace as root.
action.yml stops swallowing crashes`2>/dev/null

Docs

ChangeWhat it does
README — Platform notes + Exit codesWSL / macOS / Git Bash / Docker Desktop behaviour documented honestly. CI authors can branch on exit codes without reading the source.
docs/FINDING_IDS.mdEnumerates every explicitly-emitted findingId, documents the <check>/<slug> schema, states the stability contract (explicit findingIds do not change within a major version).
README — Advisory escalation, First run, Documentation sectionsNew.
docs/TROUBLESHOOTING.mdNew.
docs/examples/ starter governance templatesCursor, Cline, Continue, Windsurf, Aider.

Scoring & checks

ChangeWhat it does
claude-mdNOT_APPLICABLE on non-AI dirsReturns NOT_APPLICABLE (not CRITICAL) when no AI tooling markers are present in cwd. Banner printed at the top of the terminal report when every AI-tooling check is NOT_APPLICABLE, pointing the user to --include-home-skills or adding a governance file. Generic hygiene checks still score.
Narrowed claude-md anti-injection keywordBare injection (which gave “dependency injection” anti-injection credit) rejected in favour of prompt.?injection, instruction.?override, injection.?attack, ignore previous, disregard.?instructions.
skill-files — defensive-context suppression in shell-execFixes false fires on Do not use curl http:// etc. No longer stops at first match in the shell-exec / escalation / persistence / indirect-injection loops. Findings now carry a matches: N count; escalates to CRITICAL when ≥ 3 distinct patterns match the same file.
deep-secrets — no blanket dotfile skipconfig/.env.production and similar are now scanned. SKIP_DIRS extended with common machine-generated dotfolders (.cache, .idea, .turbo, .tox, .pytest_cache, .svelte-kit, .terraform) so that lifting the blanket guard doesn’t cause noise.

Test hygiene

  • test/fixture-dogfood.test.js scrubs .rigscore-state.json from the fixture dir beforeEach / afterEach; fixture .gitignore lists the state file. A prior run’s per-user mode-0600 state file can no longer mask the mcp-config check and drift the locked finding count.

Install

1npx github:Back-Road-Creative/rigscore

No accounts, no telemetry, no network calls. MIT licensed.

github.com/Back-Road-Creative/rigscore