Skip to content

fix(compliance-audit): use null-safe jq for boolean settings checks#131

Open
don-petry wants to merge 8 commits intomainfrom
fix/compliance-audit-jq-boolean
Open

fix(compliance-audit): use null-safe jq for boolean settings checks#131
don-petry wants to merge 8 commits intomainfrom
fix/compliance-audit-jq-boolean

Conversation

@don-petry
Copy link
Copy Markdown
Contributor

@don-petry don-petry commented Apr 14, 2026

Summary

  • Fix jq // operator bug that caused has_wiki: false to always be reported as current: null
  • jq's // (alternative) operator treats false as falsy — so false // "null" returns "null" instead of "false"
  • This caused any boolean check with expected value false (e.g. has_wiki) to perpetually flag as non-compliant even when correctly set

Root Cause

Line 303 in scripts/compliance-audit.sh:

Before (broken for false values):
actual=$(echo "$settings" | jq -r ".$key // "null"")

After (null-safe):
actual=$(echo "$settings" | jq -r "if .$key == null then "null" else (.$key | tostring) end")

Verification

echo '{"has_wiki": false}' | jq -r 'if .has_wiki == null then "null" else (.has_wiki | tostring) end'
=> false (correct)

echo '{"has_wiki": false}' | jq -r '.has_wiki // "null"'
=> null (broken — was causing the false positive)

Closes petry-projects/ContentTwin#63

Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Enhanced reliability of the compliance audit process through improved JSON data extraction and null value handling.

jq's // operator treats false as falsy, so false // "null" returns
"null" rather than "false". This caused boolean settings checks with
expected value of false (e.g. has_wiki) to always report a compliance
finding even when the setting was correctly set to false.

Replace the // "null" fallback with an explicit null test:
  if .$key == null then "null" else (.$key | tostring) end

This correctly returns "false" for a false value and "null" only when
the field is actually absent.

Closes petry-projects/ContentTwin#63
Copilot AI review requested due to automatic review settings April 14, 2026 14:11
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 14, 2026

Warning

Rate limit exceeded

@github-actions[bot] has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 45 minutes and 48 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 45 minutes and 48 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e7178ef2-274a-4397-887b-7484a131090f

📥 Commits

Reviewing files that changed from the base of the PR and between 5358531 and 3162cfa.

📒 Files selected for processing (1)
  • scripts/compliance-audit.sh
📝 Walkthrough

Walkthrough

This PR fixes JSON value extraction logic in the compliance audit script to properly handle null values from the GitHub API. The change improves null-to-string conversion and adjusts the default branch extraction method to use printf instead of echo.

Changes

Cohort / File(s) Summary
Compliance Audit Script
scripts/compliance-audit.sh
Updated check_repo_settings to use indexed jq lookup with explicit null-to-string conversion (.[$key] | if . == null then "null" else tostring end) instead of dynamic filtering. Modified default branch extraction to use printf for cleaner output handling.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: addressing null-safe jq handling for boolean settings checks in the compliance audit script.
Linked Issues check ✅ Passed The PR fixes the root cause of issue #63 by correcting the jq expression to properly handle false boolean values, ensuring has_wiki false is no longer reported as null.
Out of Scope Changes check ✅ Passed All changes in scripts/compliance-audit.sh are directly related to fixing the jq boolean handling bug; no out-of-scope modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/compliance-audit-jq-boolean

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@don-petry
Copy link
Copy Markdown
Contributor Author

@don-petry This PR fixes the root cause of the compliance finding in petry-projects/ContentTwin#63. The ContentTwin wiki is already correctly set to false via the GitHub API — the audit script had a jq bug where false // "null" returns "null" (jq's // operator treats false as falsy). Please review and merge when CI is green.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR fixes compliance audit false-positives for boolean repo settings (notably when the correct value is false) by making the jq extraction null-safe instead of using jq’s // operator.

Changes:

  • Replace jq // "null" fallback with an explicit null check and tostring conversion for boolean settings.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/compliance-audit.sh Outdated
Comment thread scripts/compliance-audit.sh Outdated
@don-petry
Copy link
Copy Markdown
Contributor Author

@claude[agent] - Fix merge conflicts

- Merge PR #133 from main (same jq boolean fix)
- Apply printf instead of echo for JSON piping (safer)
- Use jq --arg for key interpolation (prevents injection)

Agent-Logs-Url: https://github.com/petry-projects/.github/sessions/bc09d7ce-9add-488c-a416-223d826cc900

Co-authored-by: don-petry <36422719+don-petry@users.noreply.github.com>
@Claude
Copy link
Copy Markdown

Claude AI commented Apr 15, 2026

@claude[agent] - Fix merge conflicts

Merge conflicts resolved in commit 5358531. The resolution merges PR #133 from main (which had the same boolean fix with cleaner jq syntax) and applies both Copilot review suggestions:

  1. Use printf '%s' instead of echo for JSON piping (safer, prevents escape issues)
  2. Use jq --arg key "$key" with .[$key] for safe key interpolation (prevents injection with special characters)

All changes tested and verified working correctly.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh gh repo view petry-projects/.github --json defaultBranchRef --jq .defaultBranchRef.name /home/REDACTED/.nvm/nvm.sh /home/REDACTED/.nvm/package.json /home/REDACTED/.nvm/rename_test.sh /home/REDACTED/.nvm/test ARGV�� --abbrev-ref HEAD /usr/bin/awk (http block)

If you need me to access, download, or install something from one of these locations, you can either:

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 15, 2026
@don-petry
Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

…intf and --arg key

Co-authored-by: don-petry <36422719+don-petry@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI commented Apr 16, 2026

@copilot resolve the merge conflicts in this pull request

Merge conflicts resolved in c10108f. The conflict in scripts/compliance-audit.sh was between main's echo "$settings" | jq -r ".$key | ..." form and our branch's safer printf '%s' "$settings" | jq -r --arg key "$key" '.[$key] | ...' form — kept the safer version from this PR.

Copy link
Copy Markdown
Contributor Author

@don-petry don-petry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review — APPROVED

Risk: LOW
Reviewed commit: 07060da8ae3a4246d6b830ca73cac46687248652
Cascade: triage → deep (see triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6 for models)

Summary

Single-file shell script fix replacing echo with printf '%s' and dynamic jq key interpolation with --arg/.[$key] for safer jq invocation. All CI checks pass (ShellCheck, Lint, SonarCloud quality gate, CodeQL, Agent Security Scan). The triage escalation was caused by a triage-tier failure, not a real risk signal — the change itself is a low-risk correctness and hardening improvement.

Findings

Info — Correctness

  • scripts/compliance-audit.sh:305 — Replaces echo | jq -r '.$key ...' with printf '%s' | jq -r --arg key '$key' '.[$key] ...'. Using printf avoids echo flag edge-cases (-e, -n) when $settings contains leading-dash or backslash content, and --arg/.[$key] prevents jq filter injection if a key name ever contains special characters. Minor but strictly better.
  • scripts/compliance-audit.sh:315 — Same echoprintf change for default_branch extraction. No functional difference for a static field path, but consistent with the pattern above.

Info — CI

  • All checks green: Lint, ShellCheck, Agent Security Scan, CodeQL (actions), SonarCloud (0 new issues, 0 security hotspots), CodeRabbit. No failures or warnings.

Info — Triage

  • Triage escalation reason was triage-output-invalid — the triage tier failed to produce output, not a genuine risk signal in this PR. No HIGH-risk patterns (auth/secrets/credentials/crypto, DB migrations, injection, hardcoded secrets, CI tampering) were present.

CI status

All checks green: Lint, ShellCheck, Agent Security Scan, CodeQL (actions), SonarCloud (0 new issues, 0 security hotspots), CodeRabbit. No failures or warnings.


Reviewed by the don-petry PR-review cascade (triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6). Reply with @don-petry if you need a human.

@don-petry don-petry enabled auto-merge (squash) April 16, 2026 13:14
@don-petry
Copy link
Copy Markdown
Contributor Author

Automated review — APPROVED

Risk: LOW
Reviewed commit: d43f2944bb56ba96c1de7e55703e63792cf49383
Cascade: triage → deep (see triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6 for models)

Note: GitHub does not allow self-approval. Review posted as a comment; auto-merge is being requested below.

Summary

Single-file shell script hardening: replaces echo with printf '%s' and switches from dynamic jq filter string interpolation (.$key) to parameterized key lookup (--arg key / .[$key]), which is strictly safer. All CI checks pass (ShellCheck, Lint, AgentShield, CodeQL, SonarCloud 0 new issues/hotspots, CodeRabbit); the triage escalation was caused by a triage-tier output failure, not any genuine risk signal in the PR itself.

Findings

Info

  • [info] scripts/compliance-audit.sh:305printf '%s' is safer than echo for piping JSON: avoids misinterpretation of leading-dash or backslash content on shells where echo processes flags/escapes.
  • [info] scripts/compliance-audit.sh:305 — Using --arg key "$key" with .[$key] prevents jq filter injection if a key name ever contains special characters (], |, etc.). Strictly better than embedding $key directly in the filter string.
  • [info] scripts/compliance-audit.sh:315echoprintf '%s' change for default_branch extraction is a consistency improvement; no functional impact for a static field path.
  • [info] (CI) — All checks green: Lint, ShellCheck, AgentShield, CodeQL (actions), SonarCloud (0 new issues, 0 security hotspots), CodeRabbit. No failures or warnings.
  • [info] (Triage) — Triage escalation reason was triage-output-invalid — the triage tier failed to produce output, not a genuine risk signal in this PR. No HIGH-risk patterns (auth/secrets/credentials/crypto, DB migrations, injection, hardcoded secrets, CI tampering) are present.
  • [info] (Re-review) — Prior review approved at SHA 07060da8; current head d43f2944 is a no-op merge-main-into-branch commit — actual code changes are identical to the previously approved state.

CI status

All checks green: Lint, ShellCheck, AgentShield, CodeQL, SonarCloud (0 new issues, 0 security hotspots), CodeRabbit.


Reviewed by the don-petry PR-review cascade (triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6). Reply with @don-petry if you need a human.

@sonarqubecloud
Copy link
Copy Markdown

@don-petry
Copy link
Copy Markdown
Contributor Author

Automated review — APPROVED

Risk: LOW
Reviewed commit: 8226d0f2b1957400ad08e31d9f9c9762eb1b0e79
Cascade: triage → deep (see triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6 for models)

Summary

Single-file shell script hardening in compliance-audit.sh: replaces echo with printf '%s' for safer JSON piping and switches from dynamic jq key interpolation (.$key) to parameterized access (--arg key / .[$key]), which is strictly safer against jq filter injection. All CI checks pass (Lint, ShellCheck, AgentShield, CodeQL, SonarCloud 0 new issues/hotspots, CodeRabbit). The triage escalation was caused by a triage-tier output failure, not any genuine risk signal in this PR; a prior deep-review cycle at SHA d43f294 already approved the same change as LOW risk, and the current head (8226d0f) is a no-op merge-of-main commit with no substantive code delta.

Findings

Info (informational only — no action required)

  • [info/correctness] scripts/compliance-audit.sh:305printf '%s' is safer than echo for piping JSON: avoids misinterpretation of leading-dash content or backslash sequences on shells where echo processes flags/escapes.
  • [info/security-hardening] scripts/compliance-audit.sh:305 — Using --arg key "$key" with .[$key] prevents jq filter injection if a key name ever contains special characters (], |, etc.). Strictly better than embedding $key directly in the filter string.
  • [info/correctness] scripts/compliance-audit.sh:315echoprintf '%s' change for default_branch extraction is a consistency improvement; no functional impact for a static field path.
  • [info/triage] Triage escalation reason was triage-output-invalid — the triage tier failed to produce output, not a genuine risk signal in this PR. No HIGH-risk patterns present (no auth/secrets/credentials/crypto, no DB migrations, no injection introduced, no hardcoded secrets, no CI workflow tampering).
  • [info/re-review] Prior deep-review cycle approved at SHA d43f294; current head 8226d0f is a no-op merge-of-main commit — actual code changes are identical to the previously approved state.

CI status

All checks green: Lint, ShellCheck, AgentShield, CodeQL (actions), SonarCloud (0 new issues, 0 security hotspots), CodeRabbit, Agent Security Scan, Dependency audit. No failures or warnings.


Reviewed by the don-petry PR-review cascade (triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6). Reply with @don-petry if you need a human.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compliance: has_wiki

4 participants