Skip to content

IaC Compliance Audit — 2026-02-19

Scope: Complete inventory and IaC assessment of all BoB tooling components. Reference: Prime Directive | Part of #28, #42

Overall IaC compliance: ~78%. Strong declarative foundations with gaps in portability and settings management.

Area Count Compliance Key Gap
Skills (universal + registry) 42 Full None
Commands (universal + registry) 17 Full None
Agents (universal + registry) 15 Full 1 stale reference
Hooks (declarations) 12 Full Absolute paths in settings.json
Hooks (git-level) 1 Partial Copy instead of symlink
Scripts 12+ Partial bob-install.sh not idempotent
Templates 12 Full None
Provision manifests 15 Full None
Global settings 1 Partial Absolute paths, no update mechanism
Project settings auto Partial Template embedded in cdi script
Machine settings 1 Non-compliant Stale, no generation mechanism
Runbooks 4 Partial Manual steps that could be automated

Most state is JSON or markdown. Gaps:

  • Project settings.json template embedded in claude-init.sh (not a standalone file)
  • Automation levels require runtime script execution (switch-level.sh)
  • Some runbook steps are “do this manually” without automation

Nearly everything in git. Exceptions:

  • settings.local.json is gitignored (by design, but stale)
  • Machine-specific overrides not tracked

Fresh installs work well. Gaps on incremental:

  • cdi prompts on re-run (disruptive for scripts/CI)
  • Project settings don’t update when template changes
  • No mechanism to propagate global hook updates to git-level hooks

Most scripts check before acting. Gaps:

  • bob-install.sh fails if already installed
  • Idempotency not explicitly documented on most scripts
  • Git hook installation uses copy + diff (fragile)

Main blocker:

  • settings.json hooks use absolute paths: /Users/paulirving/.claude/hooks/...
  • Not usable on another machine without path rewriting

settings.json declares hooks with absolute paths. These paths are correct for runtime (Claude Code requires them) but break CI validation and aren’t portable across machines. Workaround exists (check-hooks.sh remaps paths) but the root cause remains.

cdi copies the commit-msg hook from template instead of symlinking. Local copies don’t track updates to the global template. Uses fragile diff detection for re-copy.

GAP-3: Settings Template Embedded in Script (Medium)

Section titled “GAP-3: Settings Template Embedded in Script (Medium)”

Project settings.json template is a heredoc inside claude-init.sh. Changes to the template require modifying the script. Existing projects don’t get template updates on re-run.

settings.local.json (the global one in ~/.claude/) is stale (Jan 28). No generation mechanism, no documented merge strategy with settings.json, no template.

GAP-5: Automation Levels Require Runtime Switch (Medium)

Section titled “GAP-5: Automation Levels Require Runtime Switch (Medium)”

Automation levels (Level 1/2/3) are set via switch-level.sh which writes to settings.local.json. The level isn’t part of the version-controlled settings.json. Not reproducible from git state alone.

Runbooks contain “check manually” and “fix manually” steps that could be replaced with scripts or helper commands. Examples:

  • “Check warp-drive state file manually” (agent-handoff)
  • “Check migrations manually” (incident-response)
  • “Manually create provisions manifest” (project-onboarding)

GAP-7: bob-install.sh Non-Idempotent (Low)

Section titled “GAP-7: bob-install.sh Non-Idempotent (Low)”

The shell profile installer fails if markers already exist. Requires manual removal before reinstall. No --force flag.

lessons-extractor.md referenced in claude-init.sh universal agents list but not present on filesystem.

Tested provision.sh with --status and --diff flags. Confirmed:

  • State detection works (distinguishes registry links, universal links, local files, broken links)
  • --diff shows only actual changes needed
  • Running provision twice produces identical state
  • Verdict: provisioning is fully idempotent
Gap Issue Priority
GAP-1: Hook path portability #49 p3-medium
GAP-2: Git hook symlinks #52 p3-medium
GAP-3: Settings template #50 p3-medium
GAP-7: bob-install.sh #51 p4-low
Pre-existing: Dangling symlinks #44 p2-high

Gaps 4–6 and 8 are lower priority and tracked as notes in this audit rather than separate issues.