fix(compliance-audit): use null-safe jq for boolean settings checks#131
Conversation
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
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughNormalized how JSON is passed into jq across two scripts: replaced Changesjq input and key-lookup normalization
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
@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 |
There was a problem hiding this comment.
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 explicitnullcheck andtostringconversion for boolean settings.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@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>
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:
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:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@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>
Merge conflicts resolved in c10108f. The conflict in |
don-petry
left a comment
There was a problem hiding this comment.
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— Replacesecho | jq -r '.$key ...'withprintf '%s' | jq -r --arg key '$key' '.[$key] ...'. Usingprintfavoids echo flag edge-cases (-e,-n) when$settingscontains 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— Sameecho→printfchange fordefault_branchextraction. 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.
Outdated review (superseded by re-review at
|
Outdated review (superseded by re-review at
|
|
@dev-lead - please fix this PR |
donpetry-bot
left a comment
There was a problem hiding this comment.
Automated review — APPROVED ✓
Risk: LOW
Reviewed commit: abecf97137f23da376e3ef7c9407ebd85aa1f0c8
Review mode: triage-approved (single reviewer)
Summary
Small, targeted bash fix (5+/5- across 2 files) that hardens jq invocations in scripts/compliance-audit.sh and scripts/apply-repo-settings.sh. Replaces echo "$json" | jq -r ".$key // \"null\"" with printf '%s' "$json" | jq -r --arg key "$key" '.[$key] | if . == null then "null" else tostring end'. The fix correctly distinguishes a missing/null setting from a literal false (the prior // operator treated false as falsy, producing the long-standing has_wiki false positive). printf '%s' is preferred over echo for verbatim JSON, and --arg key eliminates a jq-filter injection surface from interpolated keys. Triage tier already cleared this as low-risk; this confirmation review agrees.
Linked issue analysis
Closes petry-projects/ContentTwin#63 (compliance audit false-positive on has_wiki: false). The PR body walks through the root cause and shows a reproducer demonstrating both the broken // behavior and the corrected null-safe expression. The fix is applied at the exact spot the issue identifies, and is mirrored consistently across both audit and apply scripts.
Findings
- No new findings.
- All prior inline review comments from Copilot (use
printf '%s'instead ofecho; pass keys via--argto avoid jq filter injection) and CodeRabbit (mirror the fix inapply-repo-settings.sh) are addressed in the current commit; all review threads are resolved. - Risk profile: LOW — bash-only defensive hardening in audit/apply tooling, no auth/secret/migration/CI-security surface, no new dependencies, no behavioral change beyond fixing the documented false-positive.
CI status
All required checks green at abecf97137f23da376e3ef7c9407ebd85aa1f0c8: ShellCheck, Lint, CodeQL (Analyze actions), SonarCloud, Secret scan (gitleaks), Agent Security Scan, agent-shield, pr-auto-review, CodeRabbit. Ecosystem-specific audits (npm/pnpm/pip/cargo/govulncheck) skipped as expected for a shell-only change. Dependabot automerge skipped (non-dependabot PR).
Reviewed automatically by the PR-review agent (single-reviewer mode: opus 4.7). Reply if you need a human review.
|
…ate-github check (#165) The check incorrectly flagged petry-projects/.github/.github/workflows/ as invalid, but this is the CORRECT pattern per GitHub's reusable workflow syntax: - First .github = repository name - Second .github/workflows = directory path within that repository This check was producing false positives across all repos: - petry-projects/TalkTerm (issues #131, #130, #129) - petry-projects/broodly (issues #159, #158) - petry-projects/google-app-scripts (issues #226, #225) - petry-projects/ContentTwin (issues #111, #110) - petry-projects/markets (issues #137, #136) - petry-projects/bmad-bgreat-suite (issues #123, #122) Disable the check to reduce compliance audit noise and prevent auto-issue creation for valid patterns. Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
…ate-github check (#165) The check incorrectly flagged petry-projects/.github/.github/workflows/ as invalid, but this is the CORRECT pattern per GitHub's reusable workflow syntax: - First .github = repository name - Second .github/workflows = directory path within that repository This check was producing false positives across all repos: - petry-projects/TalkTerm (issues #131, #130, #129) - petry-projects/broodly (issues #159, #158) - petry-projects/google-app-scripts (issues #226, #225) - petry-projects/ContentTwin (issues #111, #110) - petry-projects/markets (issues #137, #136) - petry-projects/bmad-bgreat-suite (issues #123, #122) Disable the check to reduce compliance audit noise and prevent auto-issue creation for valid patterns. Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
…ate-github check (#165) The check incorrectly flagged petry-projects/.github/.github/workflows/ as invalid, but this is the CORRECT pattern per GitHub's reusable workflow syntax: - First .github = repository name - Second .github/workflows = directory path within that repository This check was producing false positives across all repos: - petry-projects/TalkTerm (issues #131, #130, #129) - petry-projects/broodly (issues #159, #158) - petry-projects/google-app-scripts (issues #226, #225) - petry-projects/ContentTwin (issues #111, #110) - petry-projects/markets (issues #137, #136) - petry-projects/bmad-bgreat-suite (issues #123, #122) Disable the check to reduce compliance audit noise and prevent auto-issue creation for valid patterns. Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
…131) * fix(compliance-audit): use null-safe jq expression for boolean checks 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 * Merge main and apply Copilot review suggestions - 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> * ci: trigger CI with clean check-suite preferences * fix(apply-repo-settings): use null-safe jq for boolean settings checks Mirror the compliance-audit.sh fix into apply-repo-settings.sh: - Replace `.$key // "null"` with `--arg key / .[$key] | if . == null` pattern to correctly handle boolean false values (jq's `//` treats false as falsy, causing false→null misread and spurious PATCH calls) - Replace `echo` with `printf '%s'` for consistent, safe JSON piping Co-authored-by: Don Petry <don-petry@users.noreply.github.com> --------- Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Don Petry <don-petry@users.noreply.github.com>



Summary
//operator bug that causedhas_wiki: falseto always be reported ascurrent: null//(alternative) operator treatsfalseas falsy — sofalse // "null"returns"null"instead of"false"false(e.g.has_wiki) to perpetually flag as non-compliant even when correctly setRoot 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