Skip to content

t1428.5: Unified post-session security summary#4036

Merged
marcusquinn merged 13 commits intomainfrom
feature/security-summary
Mar 10, 2026
Merged

t1428.5: Unified post-session security summary#4036
marcusquinn merged 13 commits intomainfrom
feature/security-summary

Conversation

@marcusquinn
Copy link
Copy Markdown
Owner

@marcusquinn marcusquinn commented Mar 10, 2026

Summary

  • Add security command and --security flag to session-review-helper.sh that aggregates all security subsystem data into a single CLI summary
  • Computes overall security posture (CLEAN/LOW/MEDIUM/HIGH/CRITICAL) from audit chain integrity, denied network access, blocked injections, and flagged domains
  • Supports JSON output (--json), session filtering (--session <id>), and integration with the existing gather command (gather --security)

Data Sources Aggregated

Source Data Script
Cost breakdown LLM requests by model, token counts, costs observability-helper.sh (SQLite DB + JSONL)
Audit events Security event type breakdown, chain integrity audit-log-helper.sh
Network access Logged/flagged/denied domain counts network-tier-helper.sh
Prompt guard Blocked/warned/sanitized injection attempts prompt-guard-helper.sh
Session context Composite score (graceful when t1428.3 pending) session-security-helper.sh
Quarantine Pending items (graceful when t1428.4 pending) quarantine-helper.sh

Files Changed

  • .agents/scripts/session-review-helper.sh — new security command, --security/--session/--json flags, security aggregation functions
  • .agents/workflows/session-review.md — documentation for the security summary section
  • .agents/scripts/commands/session-review.md — updated command description

Testing

  • session-review-helper.sh security — produces formatted summary table
  • session-review-helper.sh security --json — produces valid JSON
  • session-review-helper.sh gather --security — appends security to standard review
  • session-review-helper.sh help — shows updated help text
  • ShellCheck: clean (only SC1091 for external source)
  • Markdown lint: 0 errors

Closes #4029

Summary by CodeRabbit

  • New Features

    • Adds a Security Summary command that aggregates cost, audit events, network activity, prompt-guard detections, session context, and quarantine status.
    • Supports running security as a standalone action or including it in the normal session-review flow via a --security flag; offers per-session filtering and JSON output.
    • Provides automated security posture levels (CLEAN → CRITICAL).
  • Documentation

    • Updated help and workflow docs with usage examples, JSON samples, session-filtering guidance, and related security references (Security Summary section added; also mirrored under integration guidance).

Add --security mode to session-review-helper.sh that aggregates:
- Cost breakdown by model from observability data (SQLite DB + JSONL)
- Audit event type breakdown with chain integrity check
- Network access summary (logged/flagged/denied domains)
- Prompt injection defense stats (blocked/warned/sanitized)
- Session security context placeholder (t1428.3 pending)
- Quarantine queue placeholder (t1428.4 pending)

Computes overall security posture (CLEAN/LOW/MEDIUM/HIGH/CRITICAL)
based on denied access, blocked injections, and audit chain integrity.

Supports: security command, --security flag with gather, --json output,
--session filter for session-scoped data.

Closes #4029
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the session-review-helper.sh script by adding a comprehensive security summary feature. This new capability provides developers and reviewers with a consolidated view of a session's security posture, drawing data from multiple security-related logs and tools. The aim is to offer quick, actionable insights into potential security issues, streamlining the review process and improving overall system security awareness.

Highlights

  • New Security Command: Introduced a new security command and --security flag to session-review-helper.sh for generating a unified post-session security summary.
  • Aggregated Security Data: The new command aggregates security data from various subsystems, including cost breakdown, audit events, network access, prompt guard detections, session context, and quarantine status.
  • Security Posture Calculation: It computes an overall security posture (CLEAN, LOW, MEDIUM, HIGH, CRITICAL) based on audit chain integrity, denied network access, blocked injections, and flagged domains.
  • Flexible Output Options: The security summary supports JSON output (--json) for programmatic use and session filtering (--session <id>), and can be integrated with the existing gather command (gather --security).
Changelog
  • .agents/scripts/commands/session-review.md
    • Updated the command description to include the new security argument and its associated flags, clarifying how to generate a unified post-session security summary.
  • .agents/scripts/session-review-helper.sh
    • Added a new security command to the script's main functionality.
    • Introduced new options: --security to include the security summary in gather output, --session <id> to filter security data by session, and --json for JSON-formatted security output.
    • Implemented several new functions (_security_cost_summary, _security_audit_events, _security_network_summary, _security_prompt_guard, _security_session_context, _security_quarantine) to collect and format data from various security sources.
    • Added _security_posture function to calculate an overall security level (CLEAN, LOW, MEDIUM, HIGH, CRITICAL).
    • Created output_security_summary and _security_summary_json functions to present the aggregated security data in human-readable and JSON formats, respectively.
    • Modified the main function to parse and handle the new security command and its flags, integrating it into the script's argument processing.
  • .agents/workflows/session-review.md
    • Added a new 'Security Summary' section detailing the purpose and usage of the session-review-helper.sh security command.
    • Provided examples for running the security summary, including JSON output and session filtering.
    • Documented the various data sources aggregated by the security summary, such as cost breakdown, audit events, network access, and prompt guard.
    • Included a table outlining the different security posture levels and their meanings.
    • Expanded the 'Related' section with links to audit log and prompt injection defender documentation.
Activity
  • No human activity (comments, reviews) has occurred on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 10, 2026

Caution

Review failed

Pull request was closed or merged during review

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a security-focused mode to session review: new security command and --security gather option in .agents/scripts/session-review-helper.sh that aggregates cost, audit events, network flags, prompt-guard detections, session context, and quarantine items into a unified post-session security summary with human and JSON outputs; docs updated.

Changes

Cohort / File(s) Summary
Session Review Core Implementation
.agents/scripts/session-review-helper.sh
Adds security command and --security gather option; implements security pipeline functions (_security_cost_summary, _security_audit_events, _security_network_summary, _security_prompt_guard, _security_session_context, _security_quarantine, _security_posture, _security_summary_json) and public output_security_summary(session_filter, format); adds --session and --json flags; integrates security output into gather/summary/json flows and updates help text.
CLI Command Docs
.agents/scripts/commands/session-review.md
Adds conditional branches and examples for security vs --security usage, documenting --session and --json options and expected outputs.
Workflow Documentation
.agents/workflows/session-review.md
Adds "Security Summary (t1428.5)" section describing aggregated data sources, posture levels, JSON examples, and references to related security docs; duplicated block appended under Integration with Other Workflows.

Sequence Diagram

sequenceDiagram
    participant User
    participant SessionReview as session-review-helper.sh
    participant Observability as observability-helper.sh
    participant AuditLog as audit-log-helper.sh
    participant NetworkTier as network-tier-helper.sh
    participant PromptGuard as prompt-guard-helper.sh
    participant SessionCtx as session-security-context
    participant Quarantine as quarantine-helper.sh

    User->>SessionReview: session-review security --session <id> [--json]
    activate SessionReview

    SessionReview->>Observability: query cost (session filter)
    Observability-->>SessionReview: cost by model

    SessionReview->>AuditLog: fetch audit events (session filter)
    AuditLog-->>SessionReview: tamper-evident events

    SessionReview->>NetworkTier: fetch network/access flags
    NetworkTier-->>SessionReview: domain counts / flags

    SessionReview->>PromptGuard: fetch prompt-guard detections
    PromptGuard-->>SessionReview: BLOCK/WARN/SANITIZE tallies

    SessionReview->>SessionCtx: fetch session security context
    SessionCtx-->>SessionReview: composite session data

    SessionReview->>Quarantine: check pending quarantine items
    Quarantine-->>SessionReview: quarantine status

    SessionReview->>SessionReview: compute _security_posture
    SessionReview-->>User: unified security summary (human or JSON)
    deactivate SessionReview
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

code-reviews-actioned

Poem

🔐 Post-session lights now hum and sing,
Costs and audits wrapped in one neat ring,
Prompt-guard whispers, quarantine bells ring,
A posture score the summary will bring,
JSON or human — the verdict takes wing.

🚥 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 't1428.5: Unified post-session security summary' directly and clearly identifies the primary change: implementing a unified post-session security summary feature.
Linked Issues check ✅ Passed PR comprehensively addresses all Phase 5 objectives: aggregates session-scoped cost data, security signals (audit/network/prompt-guard/quarantine), computes security posture (CLEAN to CRITICAL), provides JSON output with session filtering, gracefully handles pending dependencies, and documents in workflows.
Out of Scope Changes check ✅ Passed All changes align precisely with t1428.5 scope. session-review-helper.sh additions (security command, aggregation functions, flags) directly implement Phase 5. Documentation updates explain the new feature. No unrelated refactoring or scope creep 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 docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/security-summary

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.

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 395 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Tue Mar 10 02:04:01 UTC 2026: Code review monitoring started
Tue Mar 10 02:04:02 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 395

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 395
  • VULNERABILITIES: 0

Generated on: Tue Mar 10 02:04:04 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new security command to session-review-helper.sh for a unified security summary. While the feature is useful, it introduces several critical injection vulnerabilities due to improper handling of the user-supplied --session argument, specifically SQL, jq, and JSON injection. Additionally, there is a medium-severity maintainability issue regarding code duplication that could be improved. Addressing these security vulnerabilities and maintainability concerns is crucial for the robustness and security of the new feature.

Comment on lines +886 to +888
--session)
shift
session_filter="${1:-}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-critical critical

The session_filter variable, which comes from user input (--session), is not sanitized. It is later used to construct a SQL query (in _security_cost_summary), a jq filter, and a JSON string. This creates vulnerabilities for SQL injection, jq injection, and malformed JSON. A malicious session ID could be used to execute arbitrary SQL commands.

References
  1. To prevent SQL injection in shell scripts using sqlite3, create a helper function that uses .param set for safe parameterized bindings instead of direct string interpolation.
  2. In shell scripts, use jq --arg for strings and --argjson for other JSON types (like numbers) to safely pass variables into a jq filter. This avoids syntax errors if the variables contain special characters.
  3. In shell scripts, use jq --argjson to safely pass JSON content from variables when merging JSON arrays, instead of direct string interpolation, to prevent parsing errors.
  4. To reliably wrap the entire content of a shell variable as a single JSON string, use jq -Rn --arg v "$VAR" '$v'.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed. _sanitize_session_filter() strips all characters except [a-zA-Z0-9_.-] at the entry point. SQL path uses belt-and-suspenders escaping, jq path uses --arg, JSON path uses jq -n --arg. Defense-in-depth at both entry and per-function level.

Comment on lines +53 to +57
if [[ -n "$session_filter" ]]; then
where_clause="WHERE session_id = '${session_filter}'"
fi
local result
result=$(sqlite3 -separator '|' "$OBS_DB" "
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

The session_filter variable, which is derived from the user-supplied --session command-line argument, is directly concatenated into an SQL query string used with sqlite3. This allows an attacker to perform SQL injection by providing a malicious session ID (e.g., ' OR 1=1 --).

References
  1. To prevent SQL injection in shell scripts using sqlite3, create a helper function that uses .param set for safe parameterized bindings instead of direct string interpolation.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed. Session filter is sanitized via _sanitize_session_filter() (allowlist: [a-zA-Z0-9_.-]), then single quotes are escaped (''') before SQL interpolation. See lines 74-79.

cat <<EOF
{
"timestamp": "$(date -u '+%Y-%m-%dT%H:%M:%SZ')",
"session_filter": $(if [[ -n "$session_filter" ]]; then echo "\"$session_filter\""; else echo "null"; fi),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

The session_filter variable is directly echoed into a JSON structure within a heredoc. This introduces a JSON injection vulnerability, as special characters in the variable can break the JSON structure or inject additional fields, leading to malformed JSON output. This should be addressed by using jq's --arg flag or a dedicated JSON construction tool for safe embedding.

References
  1. In shell scripts, use jq --arg for strings and --argjson for other JSON types (like numbers) to safely pass variables into a jq filter. This avoids syntax errors if the variables contain special characters.
  2. In shell scripts, use jq --argjson to safely pass JSON content from variables when merging JSON arrays, instead of direct string interpolation, to prevent parsing errors.
  3. To reliably wrap the entire content of a shell variable as a single JSON string, use jq -Rn --arg v "$VAR" '$v'.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed. Heredoc replaced with jq -n --arg construction (line 559). Session filter is passed safely via --argjson session_filter — never interpolated into the JSON template.

Comment on lines +94 to +97
jq_filter="select(.session_id == \"${session_filter}\")"
fi
local result
result=$(jq -sr "[.[] | ${jq_filter}] | group_by(.model) | map({
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

The session_filter variable is directly concatenated into a jq filter string. This allows an attacker to inject arbitrary jq code by providing a malicious session ID (e.g., ") | .[] | select(true).

References
  1. In shell scripts, use jq --arg for strings and --argjson for other JSON types (like numbers) to safely pass variables into a jq filter. This avoids syntax errors if the variables contain special characters.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed. Replaced direct string interpolation with jq --arg sid "$safe_session" and $sid reference in the jq expression (line 130). The value is never embedded in the jq filter string.

coderabbitai[bot]
coderabbitai bot previously requested changes Mar 10, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
.agents/scripts/session-review-helper.sh (2)

73-74: Consider extracting repeated format strings (optional).

SonarCloud flagged the repeated printf format literals. Extracting to constants like FMT_COST_ROW would reduce duplication, but this is a minor maintainability concern - the current approach keeps formatting close to usage.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/scripts/session-review-helper.sh around lines 73 - 74, The two
identical printf format strings should be extracted to a single named constant
to remove duplication and improve maintainability; define a constant like
FMT_COST_ROW='  %-35s %6s %10s %10s %10s %10s\n' near the top of the script and
replace both printf calls with printf "$FMT_COST_ROW" "Model" "Reqs" ... and
printf "$FMT_COST_ROW" "---" "---" ...; update any nearby comments to document
the constant's purpose and ensure variable quoting when using printf.

339-352: Consider merging nested conditionals for clarity.

The static analysis tool suggests combining these nested if statements. This is a minor readability improvement.

♻️ Proposed simplification
 	if [[ -f "$PG_ATTEMPTS_LOG" ]]; then
 		local blocks
 		blocks=$(grep -c '"action":"BLOCK"' "$PG_ATTEMPTS_LOG" 2>/dev/null || echo "0")
-		if [[ "$blocks" -gt 0 ]]; then
-			if [[ "$posture" == "CLEAN" || "$posture" == "LOW" ]]; then
-				posture="MEDIUM"
-			fi
+		if [[ "$blocks" -gt 0 && ("$posture" == "CLEAN" || "$posture" == "LOW") ]]; then
+			posture="MEDIUM"
 		fi
 		local warns
 		warns=$(grep -c '"action":"WARN"' "$PG_ATTEMPTS_LOG" 2>/dev/null || echo "0")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/scripts/session-review-helper.sh around lines 339 - 352, The nested
conditionals around reading PG_ATTEMPTS_LOG can be simplified: keep computing
blocks=$(grep -c '"action":"BLOCK"' "$PG_ATTEMPTS_LOG" ...) and warns similarly,
then combine the checks so you only enter an outer if [[ -f "$PG_ATTEMPTS_LOG"
]]; then once and inside use single-line conditionals that test both the count
and the current posture variable; e.g., check if blocks -gt 0 and (posture ==
"CLEAN" || posture == "LOW") to set posture="MEDIUM", and check if warns -gt 0
and posture == "CLEAN" to set posture="LOW", ensuring you still compute both
blocks and warns before those combined tests (references: PG_ATTEMPTS_LOG,
blocks, warns, posture).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.agents/scripts/session-review-helper.sh:
- Around line 52-55: The WHERE clause currently interpolates session_filter
directly into where_clause, risking SQL injection; change the code to avoid
direct string interpolation by using a parameterized query or by safely escaping
the value: either build where_clause like "WHERE session_id = ?" and pass
session_filter as a bound parameter to the SQL execution command, or if binding
isn’t available, sanitize session_filter by escaping single quotes (replace '
with '') before embedding. Update references to where_clause and the SQL
execution invocation so the session_filter is passed as a parameter or the
escaped value is used.
- Around line 92-95: The jq filter currently interpolates the shell variable
session_filter directly into jq_filter, which allows injection; update the code
to pass session_filter to jq safely (e.g., use jq --arg or equivalent) instead
of embedding it in the expression so the value is handled as a string, and
change the variable/join logic around jq_filter and the jq invocation that uses
it (referencing session_filter and jq_filter) to use the --arg approach or
proper escaping of quotes/backslashes.

---

Nitpick comments:
In @.agents/scripts/session-review-helper.sh:
- Around line 73-74: The two identical printf format strings should be extracted
to a single named constant to remove duplication and improve maintainability;
define a constant like FMT_COST_ROW='  %-35s %6s %10s %10s %10s %10s\n' near the
top of the script and replace both printf calls with printf "$FMT_COST_ROW"
"Model" "Reqs" ... and printf "$FMT_COST_ROW" "---" "---" ...; update any nearby
comments to document the constant's purpose and ensure variable quoting when
using printf.
- Around line 339-352: The nested conditionals around reading PG_ATTEMPTS_LOG
can be simplified: keep computing blocks=$(grep -c '"action":"BLOCK"'
"$PG_ATTEMPTS_LOG" ...) and warns similarly, then combine the checks so you only
enter an outer if [[ -f "$PG_ATTEMPTS_LOG" ]]; then once and inside use
single-line conditionals that test both the count and the current posture
variable; e.g., check if blocks -gt 0 and (posture == "CLEAN" || posture ==
"LOW") to set posture="MEDIUM", and check if warns -gt 0 and posture == "CLEAN"
to set posture="LOW", ensuring you still compute both blocks and warns before
those combined tests (references: PG_ATTEMPTS_LOG, blocks, warns, posture).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d79b6784-8890-4ada-b469-efebfe3210c3

📥 Commits

Reviewing files that changed from the base of the PR and between e443d8b and 5d7f9e0.

📒 Files selected for processing (3)
  • .agents/scripts/commands/session-review.md
  • .agents/scripts/session-review-helper.sh
  • .agents/workflows/session-review.md

Address CHANGES_REQUESTED review feedback from CodeRabbit and Gemini
Code Assist on PR #4036:

- Add _sanitize_session_filter() to strip non-alphanumeric chars from
  --session input (defense-in-depth at entry point and per-function)
- SQL injection: sanitize session_filter before WHERE clause interpolation
- jq injection: use jq --arg for safe variable binding instead of
  string interpolation in JSONL fallback path
- JSON injection: replace heredoc with jq -n construction for safe
  JSON output in _security_summary_json()
- Merge nested conditionals in _security_posture() for clarity
- Extract repeated printf format string to FMT_COST_ROW constant
@marcusquinn
Copy link
Copy Markdown
Owner Author

Addressed all review feedback:

Security fixes (critical/high):

  • Added _sanitize_session_filter() — strips all characters except [a-zA-Z0-9_.-] from --session input
  • SQL injection (line 54): sanitized before WHERE clause interpolation
  • jq injection (line 94): replaced string interpolation with jq --arg for safe variable binding
  • JSON injection (line 488): replaced heredoc with jq -n construction for safe JSON output
  • Defense-in-depth: sanitization at entry point (main()) AND per-function

Nitpick fixes:

  • Merged nested conditionals in _security_posture()
  • Extracted repeated printf format string to FMT_COST_ROW constant

Verification:

  • ShellCheck: clean (only SC1091 for external source)
  • Tested injection attempt test'; DROP TABLE-- → sanitized to testDROPTABLE--
  • JSON output validated via jq

@coderabbitai re-review
@gemini-code-assist re-review

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 395 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Tue Mar 10 02:30:27 UTC 2026: Code review monitoring started
Tue Mar 10 02:30:27 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 395

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 395
  • VULNERABILITIES: 0

Generated on: Tue Mar 10 02:30:30 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 10, 2026

@marcusquinn — excellent work on the security hardening. The fixes are comprehensive and follow solid defense-in-depth principles:

  • _sanitize_session_filter() with an allowlist approach ([a-zA-Z0-9_.-]) is the correct pattern — stripping at the entry point and per-function covers both direct calls and any future code paths that bypass main().
  • jq --arg for variable binding and jq -n for JSON construction are the idiomatic safe patterns — well done replacing the interpolation risks.
  • SC1091 for external source is a well-known ShellCheck limitation and is acceptable to suppress with a targeted directive.
  • The injection test (test'; DROP TABLE--testDROPTABLE--) confirms the sanitizer is working as expected.

Triggering a full re-review now.


🧠 Learnings used
Learnt from: marcusquinn
Repo: marcusquinn/aidevops PR: 0
File: :0-0
Timestamp: 2026-03-03T16:33:18.313Z
Learning: For the marcusquinn/aidevops repository: The daily quality sweep system (pulse-wrapper.sh) should only mention coderabbitai for full codebase review when there are significant changes (Quality Gate failure, +10 issues in one day, etc.), not on every automated sweep with stable metrics.
✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a unified post-session security summary feature. While the implementation is well-structured, a high-severity command injection vulnerability was identified in the _security_cost_summary function due to insecure parsing of untrusted data, which could lead to arbitrary code execution. Additionally, performance improvements are needed for data aggregation in the script by reducing redundant computations, consolidating jq calls, and optimizing loop-based calculations.

Comment on lines +99 to +100
grand_total_cost=$(awk "BEGIN { printf \"%.6f\", $grand_total_cost + $cost }")
grand_total_reqs=$((grand_total_reqs + reqs))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

The _security_cost_summary function is vulnerable to high-severity command injection. Insecure parsing of SQLite output with pipe-separated data allows malicious model_id content to lead to arbitrary awk code execution or command execution within bash arithmetic expansions. This also highlights a performance issue: calling awk inside a while loop is inefficient as it spawns a new process for each row. It's critical to address the command injection by using safer parsing methods like awk -v and to improve performance by calculating totals outside the loop.

Suggested change
grand_total_cost=$(awk "BEGIN { printf \"%.6f\", $grand_total_cost + $cost }")
grand_total_reqs=$((grand_total_reqs + reqs))
grand_total_cost=$(awk -v total="$grand_total_cost" -v cost="$cost" 'BEGIN { printf "%.6f", total + cost }')
grand_total_reqs=$(awk -v total="$grand_total_reqs" -v reqs="$reqs" 'BEGIN { print total + reqs }')
References
  1. Do not use 'eval' to execute dynamically constructed commands in shell scripts due to security risks; use bash arrays and 'read -ra' to store and execute command parts safely, passing complex arguments like JSON payloads as separate elements.
  2. In shell scripts, move the calculation of loop-invariant variables outside of loops to improve efficiency.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed. The awk-in-loop pattern has been replaced with post-loop totalling: costs and request counts are collected during the loop, then a single awk call computes each total after the loop exits. Additionally, numeric field validation ([[ "$reqs" =~ ^[0-9]+$ ]]) has been added to reject malformed DB data before it reaches awk. The awk -v pattern was already safe against injection, but the field validation adds defense-in-depth against pipe-delimiter shifting from malicious model_id values.

Comment on lines +137 to +143
echo "$result" | jq -r '.[] | "\(.model)|\(.requests)|\(.input_tokens)|\(.output_tokens)|\(.cache_tokens)|\(.cost)"' 2>/dev/null | while IFS='|' read -r model reqs input_tok output_tok cache_tok cost; do
[[ -z "$model" ]] && continue
local short_model="${model##*/}"
short_model="${short_model:0:35}"
printf " %-35s %6s %10s %10s %10s \$%s\n" \
"$short_model" "$reqs" "$input_tok" "$output_tok" "$cache_tok" "$cost"
done
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This while loop re-parses the output of jq. You can make this more efficient and simpler by having jq format the output directly, which avoids the intermediate shell parsing step. For example:

echo "$result" | jq -r '.[] |
    "  \(.model | split("/")[-1] | .[:35] | ljust(35)) \
    \(.requests | tostring | rjust(6)) \
    \(.input_tokens | tostring | rjust(10)) \
    \(.output_tokens | tostring | rjust(10)) \
    \(.cache_tokens | tostring | rjust(10)) \
    $\(.cost)"'
References
  1. Consolidate multiple 'jq' calls into a single pass where possible to improve performance and script efficiency.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed. The JSONL fallback path now uses a single jq pass that formats all rows and computes totals in one expression, replacing the previous pattern of shell while-loop parsing + 2 additional jq calls for totals.

local session_filter="${1:-}"

local posture
posture=$(_security_posture)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The _security_posture function is called here, but it re-calculates several counts (e.g., denied_count, blocks) that are also calculated a few lines below in this function (_security_summary_json). This results in redundant file processing. To improve efficiency, consider refactoring _security_posture to accept these counts as arguments. This would allow you to calculate them once in this function and pass them to _security_posture.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed. _security_posture() now accepts optional pre-computed counts as arguments ($1=denied, $2=blocks, $3=warns, $4=flagged, $5=chain_intact). When called with arguments, it skips file reads entirely. When called without arguments (e.g., from output_security_summary text mode), it falls back to computing from logs. _security_summary_json() now computes counts first and passes them to _security_posture(), eliminating redundant file processing.

…ation

Address remaining CodeRabbit and Gemini review findings on PR #4036:
- Replace awk shell interpolation with -v flag to prevent command injection
  via malicious model_id content in SQLite output
- Replace bash arithmetic expansion with awk -v for reqs accumulation
- Add _sanitize_session_filter() at every function boundary
  (_security_cost_summary, output_security_summary, _security_summary_json)
  for defense-in-depth, not just at CLI parse time
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 395 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Tue Mar 10 02:46:19 UTC 2026: Code review monitoring started
Tue Mar 10 02:46:19 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 395

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 395
  • VULNERABILITIES: 0

Generated on: Tue Mar 10 02:46:22 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@marcusquinn
Copy link
Copy Markdown
Owner Author

Pulse dispatched a worker to address the CodeRabbit/Gemini CHANGES_REQUESTED feedback: SQL injection fix in session_filter WHERE clause, jq injection fix via --arg, printf format constant extraction, and nested conditional simplification.

@gemini-code-assist
Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

- Add SQL-level single-quote escaping as belt-and-suspenders defense
  alongside _sanitize_session_filter (prevents SQL injection)
- Add clarifying comment on jq --arg usage (already parameterized)
- Extract repeated printf data-row format to FMT_COST_DATA constant
- Simplify _security_posture nested conditionals into single if/elif
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 399 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Tue Mar 10 03:04:52 UTC 2026: Code review monitoring started
Tue Mar 10 03:04:53 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 399

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 399
  • VULNERABILITIES: 0

Generated on: Tue Mar 10 03:04:55 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Address PR #4036 review feedback item #4: replace negative match
($posture != HIGH && != CRITICAL) with explicit positive match
($posture == CLEAN || $posture == LOW) for clearer intent.

Items #1-3 were already addressed in prior commits (9b92562, 61ed0f7).
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 399 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Tue Mar 10 03:14:32 UTC 2026: Code review monitoring started
Tue Mar 10 03:14:32 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 399

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 399
  • VULNERABILITIES: 0

Generated on: Tue Mar 10 03:14:34 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@marcusquinn
Copy link
Copy Markdown
Owner Author

Dispatching worker to address CodeRabbit and Gemini review feedback (command injection vulnerability flagged).

…nd performance

- Replace awk-in-loop with post-loop totalling (single awk call per total)
- Add numeric field validation for SQLite pipe-parsed data (defense-in-depth)
- Consolidate JSONL fallback to single jq pass (was 3 separate jq calls)
- Refactor _security_posture() to accept pre-computed counts as args,
  eliminating redundant file reads when called from _security_summary_json()
- Backward compatible: _security_posture() still computes from logs when
  called without arguments (text mode path)
@marcusquinn
Copy link
Copy Markdown
Owner Author

Addressed all remaining Gemini and CodeRabbit review feedback (round 2):

Security hardening (high-severity):

  • awk injection via malformed DB data: Replaced awk-in-loop with post-loop totalling — costs/reqs collected during loop, single awk call computes totals after. Added numeric field validation ([[ "$reqs" =~ ^[0-9]+$ ]]) to reject malformed pipe-parsed data before it reaches awk.

Performance improvements (medium):

  • Consolidated jq calls: JSONL fallback path now uses a single jq pass for formatting rows + computing totals (was: while-loop parsing + 2 additional jq calls)
  • Eliminated redundant file reads: _security_posture() refactored to accept pre-computed counts as optional arguments. _security_summary_json() now computes counts once and passes them, avoiding double file reads. Backward compatible — text mode still computes from logs when called without args.

Verification:

  • ShellCheck: clean (only SC1091 for external source)
  • jq formatting tested with sample data
  • awk totalling verified

@gemini-code-assist re-review
@coderabbitai re-review

@gemini-code-assist
Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 399 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Tue Mar 10 03:51:02 UTC 2026: Code review monitoring started
Tue Mar 10 03:51:02 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 399

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 399
  • VULNERABILITIES: 0

Generated on: Tue Mar 10 03:51:05 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 10, 2026

@marcusquinn — great round 2 hardening. All three improvements are well-targeted:

  • awk injection via malformed DB data: post-loop totalling with numeric gate ([[ "$reqs" =~ ^[0-9]+$ ]]) is the correct pattern — it ensures no attacker-influenced string ever reaches awk's field separator logic.
  • Consolidated jq calls: collapsing the JSONL path to a single jq invocation is both safer (fewer shell-to-process boundaries) and meaningfully more efficient on long sessions.
  • Pre-computed counts in _security_posture(): threading the already-computed values through _security_summary_json() eliminates redundant file reads and avoids any TOCTOU window between the two reads of the same log. Keeping backward compatibility for the text path is the right call.

Triggering a full re-review now.


🧠 Learnings used
Learnt from: marcusquinn
Repo: marcusquinn/aidevops PR: 0
File: :0-0
Timestamp: 2026-03-03T16:33:18.313Z
Learning: For the marcusquinn/aidevops repository: The daily quality sweep system (pulse-wrapper.sh) should only mention coderabbitai for full codebase review when there are significant changes (Quality Gate failure, +10 issues in one day, etc.), not on every automated sweep with stable metrics.
✅ Actions performed

Full review triggered.

@marcusquinn
Copy link
Copy Markdown
Owner Author

@coderabbitai review

All 3 actionable items from the latest CHANGES_REQUESTED review (run 27ee72d4) have been addressed in commits 2248a4eb and 84d964ac:

  1. Doc clarity (session-review.md): security subcommand vs --security flag now clearly distinguished
  2. Session filter propagation: All 6 section functions now accept session_filter parameter; functions whose logs lack session_id display (global) note
  3. --focus guard: Validates next argument exists and is not a flag, mirroring --session guard pattern

ShellCheck: clean (SC1091 only). Please re-review to clear CHANGES_REQUESTED state.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 10, 2026

@marcusquinn — acknowledged. All three items are cleanly resolved:

  1. Doc clarity (session-review.md): The security subcommand (standalone security-only output) vs --security flag (additive to gather flow) distinction is a meaningful UX boundary and the corrected documentation makes it unambiguous for users.

  2. Session filter propagation: Threading session_filter through all 6 section functions is the correct completeness fix. The (global) annotation for logs that structurally lack a session_id field is honest and non-breaking — better than silently ignoring the filter or returning an error.

  3. --focus arg guard: Mirroring the --session validation pattern ([[ $# -le 1 ]] || [[ "${2:-}" == --* ]]) is consistent and defensive — good symmetry across argument guards.

Triggering a full re-review now to clear the CHANGES_REQUESTED state.


🧠 Learnings used
Learnt from: marcusquinn
Repo: marcusquinn/aidevops PR: 0
File: :0-0
Timestamp: 2026-03-03T16:33:18.313Z
Learning: For the marcusquinn/aidevops repository: The daily quality sweep system (pulse-wrapper.sh) should only mention coderabbitai for full codebase review when there are significant changes (Quality Gate failure, +10 issues in one day, etc.), not on every automated sweep with stable metrics.

Learnt from: alex-solovyev
Repo: marcusquinn/aidevops PR: 0
File: :0-0
Timestamp: 2026-03-04T05:50:49.615Z
Learning: In the marcusquinn/aidevops repository: As of 2026-03-04, the chrome-webstore-helper.sh SC2119/SC2120 (load_credentials argument mismatch) and stash-audit-helper.sh SC2181 (indirect exit code checking) ShellCheck issues have been resolved. ShellCheck now reports 0 errors and 0 warnings for these files.
✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
.agents/scripts/session-review-helper.sh (1)

493-529: ⚠️ Potential issue | 🟠 Major

Filtered runs still report a global posture as if it were session-scoped.

When --session is set, the headline posture is still derived from global audit/network/prompt-guard logs, but the header shows a specific session ID. The later (global …) notes in the section bodies do not fix that top-level ambiguity.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.agents/scripts/session-review-helper.sh:
- Around line 601-640: The JSON builder currently only emits availability flags
(session_context_available, quarantine_available) and omits any cost breakdown;
update the jq payload to include full objects for session_context and quarantine
(e.g., { available: $session_context_available, score: $session_context_score,
pending_items: $session_context_pending }) and ({ available:
$quarantine_available, score: $quarantine_score, pending_items:
$quarantine_pending }) and add cost fields (e.g., cost_total and cost_breakdown)
by wiring existing variables into jq via --argjson cost_total "$cost_total" and
--argjson cost_breakdown "$cost_breakdown" (or their equivalent names used
elsewhere), then reference those args in the final JSON so the machine-readable
output matches the text summary.
- Around line 1018-1025: The --session case currently accepts and silently
rewrites invalid IDs via _sanitize_session_filter which can produce an empty or
altered session_filter; instead, validate input after calling
_sanitize_session_filter in the --session branch: call _sanitize_session_filter
on "$1", then if the sanitized value is empty or does not exactly equal the
original raw "$1" (or fails the expected ID pattern), print an error to stderr
and exit 1 rather than assigning session_filter and continuing; reference the
--session case, the _sanitize_session_filter helper, and the session_filter
variable when making this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b757101d-e849-4d79-b815-65b6f6f6230e

📥 Commits

Reviewing files that changed from the base of the PR and between 0a0a7fb and 84d964a.

📒 Files selected for processing (3)
  • .agents/scripts/commands/session-review.md
  • .agents/scripts/session-review-helper.sh
  • .agents/workflows/session-review.md

…, JSON cost data, SQL column name

- --session now rejects altered/empty input instead of silently falling back
  to global scope (fail-closed validation per CodeRabbit review #3920297733)
- JSON output now includes cost.total and cost.breakdown with per-model data,
  matching the text summary's cost table
- session_context now includes score field, quarantine includes pending_items
  count (not just availability flags)
- Fix SQL column name: cost_total -> cost (matches actual DB schema)
@marcusquinn
Copy link
Copy Markdown
Owner Author

Addressed all remaining CodeRabbit review findings in commit f1b1963:

Fixes applied (from review #3920297733):

  1. Fail-closed --session validation (Major): --session 'abc$%' and --session '!!!' now reject with a clear error instead of silently sanitizing to a different/empty value that falls back to global scope. Validates that sanitized output exactly matches raw input.

  2. JSON output missing cost breakdown (Major): _security_summary_json() now includes:

    • cost.total — aggregate cost across all models
    • cost.breakdown — per-model array with requests, input/output/cache tokens, and cost
    • session_context.score — actual composite score from helper (not just availability flag)
    • quarantine.pending_items — actual pending count from helper (not just availability flag)
  3. SQL column name fix (bug found during testing): Both text and JSON mode SQL queries used cost_total but the actual DB column is cost. Fixed in both _security_cost_summary() and _security_summary_json().

Dismissed (by design):

  • "Filtered runs still report global posture as session-scoped" (duplicate): The underlying audit, network, and prompt-guard logs have no session_id field — this is a data source limitation, not a code bug. Each section already displays (global — X has no session_id field) when a session filter is active. The posture is necessarily computed from global data for these sources. Only cost data (from the observability DB) supports session-level filtering.

Verification:

  • shellcheck: clean (only SC1091 for external source)
  • security --session 'abc$%' → exits 1 with error
  • security --session '!!!' → exits 1 with error
  • security --session 'valid-session.123' → runs correctly
  • security --json → includes full cost breakdown with per-model data
  • security (text mode) → cost table now queries correct DB column

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 397 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Tue Mar 10 07:28:44 UTC 2026: Code review monitoring started
Tue Mar 10 07:28:45 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 397

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 397
  • VULNERABILITIES: 0

Generated on: Tue Mar 10 07:28:48 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@marcusquinn
Copy link
Copy Markdown
Owner Author

@coderabbitai review

All actionable items from the latest CHANGES_REQUESTED review (run b757101d) have been addressed in commit f1b1963:

  1. Fail-closed --session validation (Major): Invalid IDs now rejected instead of silently sanitized
  2. JSON cost breakdown (Major): Full cost.total + cost.breakdown array + session_context.score + quarantine.pending_items
  3. SQL column fix: cost_total -> cost (matches actual DB schema)

The global-posture-as-session-scoped finding is by design (underlying logs lack session_id field, noted inline with '(global — ...)' markers).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 10, 2026

@marcusquinn — solid finishing pass. All three items are well-resolved:

  1. Fail-closed --session validation: Rejecting invalid IDs on input (rather than silently sanitizing to a different effective value) is the strictly safer UX — it surfaces misconfiguration immediately rather than silently running against a broader scope. Validating that sanitized == raw is the clean pattern for this.

  2. JSON cost breakdown: Including cost.total, cost.breakdown (per-model with tokens and cost), session_context.score, and quarantine.pending_items as real values (not just availability flags) makes the JSON output genuinely useful for downstream consumers — the previous version was effectively a partial schema.

  3. SQL column fix (cost_totalcost): A silent correctness bug — queries against a non-existent column would return no rows and misrepresent the cost data. Good catch during testing.

The global-posture-as-session-scoped design call is well-reasoned. When the underlying data sources structurally lack a session_id field, the (global — X has no session_id field) inline annotation is the correct honest signal to the user rather than erroring or silently ignoring the filter.

Triggering a full re-review now.

✅ Actions performed

Full review triggered.

@sonarqubecloud
Copy link
Copy Markdown

@marcusquinn
Copy link
Copy Markdown
Owner Author

@coderabbitai review

All 5 inline review comments from the latest CHANGES_REQUESTED review have been addressed and replied to:

  1. --session mixed global/filtered summary (Major): Functions that can filter by session (cost, session-context, quarantine) do filter. Functions where the underlying logs have no session_id field (audit, network, prompt-guard) accept the parameter for API consistency and display a (global — X logs have no session_id field) note. This is the correct design.

  2. --focus guard before shifting (Minor): Fixed in commit 2248a4e — mirrors the --session validation pattern (lines 1097-1102).

  3. --security vs security routing in docs (Major): Fixed in commit 2248a4e — docs now distinguish standalone security subcommand from additive --security flag.

  4. is_protected_branch return 0 bug (Critical): Fixed in commit 849bd9d — confirmed by CodeRabbit.

  5. --session without value guard (Minor): Fixed in commit 09a5ff8 — confirmed by CodeRabbit.

Please re-review to clear the CHANGES_REQUESTED state.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 10, 2026

@marcusquinn — acknowledged. All five items from the latest CHANGES_REQUESTED round are cleanly resolved:

# Item Severity Status
1 --session mixed global/filtered summary — session-capable functions filter; structurally unindexed logs display (global — X logs have no session_id field) Major ✅ By design, correctly documented
2 --focus guard before shifting — mirrors --session validation pattern (lines 1097-1102) Minor ✅ Fixed in 2248a4eb
3 --security vs security routing in docs — standalone subcommand vs additive flag now unambiguous Major ✅ Fixed in 2248a4eb
4 is_protected_branch() unconditional return 0 bug — function now correctly returns non-zero off protected branches Critical ✅ Fixed in 849bd9d9
5 --session without value guard — rejects missing/flag-as-value inputs Minor ✅ Fixed in 09a5ff80

Combined with all prior rounds (SQL/jq/JSON/awk injection hardening, fail-closed session validation, full JSON cost breakdown, SQL column fix, format constants, posture pre-computation), this is a comprehensive and well-documented hardening pass. Triggering a full re-review now.


🧠 Learnings used
Learnt from: marcusquinn
Repo: marcusquinn/aidevops PR: 0
File: :0-0
Timestamp: 2026-03-03T16:33:18.313Z
Learning: For the marcusquinn/aidevops repository: The daily quality sweep system (pulse-wrapper.sh) should only mention coderabbitai for full codebase review when there are significant changes (Quality Gate failure, +10 issues in one day, etc.), not on every automated sweep with stable metrics.
✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Owner Author

@marcusquinn marcusquinn left a comment

Choose a reason for hiding this comment

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

@coderabbitai All 9 actionable review comments have been addressed across commits 9b92562, 849bd9d, 09a5ff8, 2248a4e, 84d964a, and f1b1963. All nitpick suggestions (format string constants, nested conditional simplification, jq stderr suppression, pre-compute counts for text mode) were also addressed. Please re-review to clear the stale CHANGES_REQUESTED state.

@marcusquinn marcusquinn dismissed stale reviews from coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], and coderabbitai[bot] March 10, 2026 09:49

All actionable comments addressed in subsequent commits. Nitpick suggestions (format string constants, nested conditionals) also addressed.

@marcusquinn
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 10, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.agents/scripts/session-review-helper.sh (1)

315-317: Consider extracting action grep patterns to constants.

Static analysis flags the repeated literals '"action":"BLOCK"', '"action":"WARN"', and '"action":"SANITIZE"' used 4 times each across _security_prompt_guard(), _security_posture(), output_security_summary(), and _security_summary_json().

Extracting these to constants at the top of the file (alongside FMT_*) would improve maintainability if the log format ever changes.

♻️ Suggested constants
 readonly FMT_SUMMARY_ROW="  %-20s %6s\n"
+
+# Grep patterns for prompt-guard action types (used in multiple functions)
+readonly PG_ACTION_BLOCK='"action":"BLOCK"'
+readonly PG_ACTION_WARN='"action":"WARN"'
+readonly PG_ACTION_SANITIZE='"action":"SANITIZE"'

Then replace usages:

-blocks=$(grep -c '"action":"BLOCK"' "$PG_ATTEMPTS_LOG" 2>/dev/null || echo "0")
+blocks=$(grep -c "$PG_ACTION_BLOCK" "$PG_ATTEMPTS_LOG" 2>/dev/null || echo "0")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/scripts/session-review-helper.sh around lines 315 - 317, Extract the
repeated literal grep patterns into shell constants (e.g. ACTION_BLOCK,
ACTION_WARN, ACTION_SANITIZE) defined near the existing FMT_* constants at the
top of the file, and replace all occurrences of '"action":"BLOCK"',
'"action":"WARN"', and '"action":"SANITIZE"' in _security_prompt_guard(),
_security_posture(), output_security_summary(), and _security_summary_json()
with those constants (use the constants when building the grep arguments against
$PG_ATTEMPTS_LOG) so the log-format tokens are centralized and easy to update.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.agents/scripts/session-review-helper.sh:
- Around line 315-317: Extract the repeated literal grep patterns into shell
constants (e.g. ACTION_BLOCK, ACTION_WARN, ACTION_SANITIZE) defined near the
existing FMT_* constants at the top of the file, and replace all occurrences of
'"action":"BLOCK"', '"action":"WARN"', and '"action":"SANITIZE"' in
_security_prompt_guard(), _security_posture(), output_security_summary(), and
_security_summary_json() with those constants (use the constants when building
the grep arguments against $PG_ATTEMPTS_LOG) so the log-format tokens are
centralized and easy to update.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d477a6e7-61ac-4274-a8b4-ea853d68e0a8

📥 Commits

Reviewing files that changed from the base of the PR and between 0a0a7fb and f1b1963.

📒 Files selected for processing (3)
  • .agents/scripts/commands/session-review.md
  • .agents/scripts/session-review-helper.sh
  • .agents/workflows/session-review.md

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

t1428.5: Unified post-session security summary

1 participant