Skip to content

t1412.11: Per-repo security posture in aidevops init#3628

Merged
marcusquinn merged 10 commits intomainfrom
feature/t1412.11-security-posture-init
Mar 9, 2026
Merged

t1412.11: Per-repo security posture in aidevops init#3628
marcusquinn merged 10 commits intomainfrom
feature/t1412.11-security-posture-init

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Mar 7, 2026

Summary

Implements per-repo security posture configuration in aidevops init (t1412.11).

Changes

aidevops.sh:

  • Add scaffold_agents_md() function that generates context-aware .agents/AGENTS.md with a Security section:
    • JS/TS repos (detected via package.json): recommends @stackone/defender for prompt injection defense with install/usage examples
    • Non-JS/TS repos: provides framework-agnostic prompt injection guidance (input sanitization, structured prompts, system/user boundaries)
    • Both variants include general security rules and link to framework security docs
  • Fix .aidevops.json structure: beads and sops config blocks were incorrectly nested inside the database object — now properly at root level
  • Add sops boolean to .features object so downstream code that reads .features correctly detects SOPS enablement (CodeRabbit review feedback)

.agents/scripts/security-posture-helper.sh:

  • Fix collaborator API call to use --paginate with per_page=100 as required by t1412.11 spec (never use a global trusted-users cache)

Already implemented (prior work)

The security-posture-helper.sh script already implements all 6 audit phases:

  1. GitHub Actions workflow scanning (injection risks, pwn requests, unpinned actions)
  2. Branch protection verification (PR reviews, status checks)
  3. Review-bot-gate status check
  4. Dependency vulnerability scanning (npm/pip/cargo audit)
  5. Collaborator access audit (per-repo, never cached)
  6. Repository security basics (SECURITY.md, .gitignore, secret files, Dependabot/Renovate)

The aidevops security audit command and posture storage in .aidevops.json were also already functional.

Closes #3883

Summary by CodeRabbit

  • New Features

    • Centralized, idempotent AGENTS.md scaffolding with automated, project-type–aware Security guidance and automatic root documentation creation.
  • Improvements

    • Standardized severity levels and per-file informational/pass counters with JSON summary for findings.
    • Unified posture computation and exit behavior to treat warnings as actionable.
    • Paginated collaborator checks and clearer messaging when access or resources are missing.

@gemini-code-assist
Copy link

Warning

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 7, 2026

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 severity constants and JSON/info finding tracking to the security posture helper, paginates collaborator fetch via gh api, centralizes AGENTS.md scaffolding with scaffold_agents_md(project_root) plus _generate_security_section and _update_agents_md_security, and updates cmd_init to delegate AGENTS.md creation/update and adjust init data assembly.

Changes

Cohort / File(s) Summary
Security Posture Helper
.agents/scripts/security-posture-helper.sh
Introduce SEVERITY_CRITICAL/WARNING/INFO/PASS, add FINDINGS_INFO and FINDINGS_JSON, standardize add_finding calls to use severity constants, extend JSON findings to include info/pass, map final posture from severity counts, and change collaborator retrieval to gh api --paginate "repos/{slug}/collaborators?per_page=100".
AGENTS.md Scaffolding & Init Flow
aidevops.sh
Add scaffold_agents_md(project_root), _generate_security_section(), and _update_agents_md_security(); centralize and idempotentize AGENTS.md creation/update during cmd_init, create root AGENTS.md when missing, and include sops in init features JSON.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant CLI as aidevops CLI
    participant Scaffold as scaffold_agents_md
    participant Posture as .agents/security-posture-helper.sh
    participant GH as GitHub API
    participant FS as Filesystem

    User->>CLI: run `aidevops init`
    CLI->>Scaffold: scaffold_agents_md(project_root)
    Scaffold->>Posture: request Security section content / posture scan
    Posture->>GH: gh api --paginate collaborators & repo checks
    GH-->>Posture: collaborator data & API responses
    Posture->>FS: write findings to `.aidevops.json`
    Scaffold->>FS: create/update `.agents/AGENTS.md` and root `AGENTS.md`
    CLI-->>User: init complete (AGENTS.md updated, posture stored)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Suggested labels

enhancement

Poem

✨ A script that counts each finding's name,
Constants set so severities tame,
A hundred collaborators paged with grace,
AGENTS.md rebuilt in the right place,
Small changes keep the project safe.

🚥 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 't1412.11: Per-repo security posture in aidevops init' directly references the task identifier and accurately summarizes the main feature addition—implementing per-repo security posture scanning within the init workflow.
Linked Issues check ✅ Passed The PR implements all primary coding objectives from #3883: adds security scanning infrastructure, implements collaborator API pagination per spec, scaffolds AGENTS.md with context-aware Security sections, stores posture in .aidevops.json, and fixes config structure issues.
Out of Scope Changes check ✅ Passed All changes are directly aligned with #3883 objectives: security-posture-helper.sh refactoring (severity constants, pagination), aidevops.sh scaffolding functions (Security section generation), and .aidevops.json structure fixes are all in-scope.
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
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/t1412.11-security-posture-init

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
Contributor

github-actions bot commented Mar 7, 2026

🔍 Code Quality Report

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

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

�[0;34m[INFO]�[0m Recent monitoring activity:
Sat Mar 7 20:58:16 UTC 2026: Code review monitoring started
Sat Mar 7 20:58:17 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 125

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 125
  • VULNERABILITIES: 0

Generated on: Sat Mar 7 20:58:19 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@marcusquinn
Copy link
Owner Author

@coderabbitai review

Review bots were rate-limited when this PR was created (affected: coderabbitai gemini-code-assist). Requesting a review retry.

@gemini-code-assist
Copy link

Warning

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 7, 2026

@marcusquinn Sure, kicking off the review of PR #3628 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

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@marcusquinn
Copy link
Owner Author

This PR appears orphaned — no active worker process found and no activity for 7+ hours. Flagging for re-dispatch.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

🔍 Code Quality Report

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

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

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Mar 8 11:56:37 UTC 2026: Code review monitoring started
Sun Mar 8 11:56:37 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 366

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 366
  • VULNERABILITIES: 0

Generated on: Sun Mar 8 11:56:39 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Copy link
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: 1

🧹 Nitpick comments (1)
aidevops.sh (1)

1470-1472: Consider backfilling the Security section for older repos.

This only creates .agents/AGENTS.md when it is missing, so re-running aidevops init security on an already-initialized repo keeps the old instructions. An idempotent merge/update step would make the new security guidance the actual repo source of truth.

Based on learnings "All instructions, documentation, and operational guidance should be maintained in AGENTS.md as the single source of truth".

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

In `@aidevops.sh` around lines 1470 - 1472, The current logic only creates
.agents/AGENTS.md when missing (scaffold_agents_md "$project_root"), leaving
older docs unchanged; change the init path so that running "aidevops init
security" updates/merges the Security section into an existing .agents/AGENTS.md
instead of skipping it: call or extend scaffold_agents_md (or add a new
merge_agents_md function) to perform an idempotent merge/update of the Security
section into "$project_root/.agents/AGENTS.md" (preserving existing custom
content outside the Security section) and log whether it created or updated the
file (keep print_success messages for both create and update).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@aidevops.sh`:
- Around line 1402-1410: The .features object is missing a boolean entry for
sops so re-registering from .aidevops.json will drop SOPS; add a "sops":
$enable_sops entry to the same object where "beads" is defined (mirror the
pattern used for "beads" and other features), ensuring proper JSON
commas/structure and that the variable name $enable_sops is used so downstream
code that reads .features (the consumers of the "sops" flag) will correctly see
SOPS enabled.

---

Nitpick comments:
In `@aidevops.sh`:
- Around line 1470-1472: The current logic only creates .agents/AGENTS.md when
missing (scaffold_agents_md "$project_root"), leaving older docs unchanged;
change the init path so that running "aidevops init security" updates/merges the
Security section into an existing .agents/AGENTS.md instead of skipping it: call
or extend scaffold_agents_md (or add a new merge_agents_md function) to perform
an idempotent merge/update of the Security section into
"$project_root/.agents/AGENTS.md" (preserving existing custom content outside
the Security section) and log whether it created or updated the file (keep
print_success messages for both create and update).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6103804c-eccb-4e41-a3c7-4e2f34abb34b

📥 Commits

Reviewing files that changed from the base of the PR and between 2b20a17 and b3bd121.

📒 Files selected for processing (2)
  • .agents/scripts/security-posture-helper.sh
  • aidevops.sh

…llaborator pagination

- Extract scaffold_agents_md() function from cmd_init() for context-aware
  .agents/AGENTS.md generation (t1412.11)
- JS/TS projects (package.json detected) get @stackone/defender recommendation
  for prompt injection defense
- Non-JS/TS projects get framework-agnostic prompt injection guidance
- Both variants include general security rules and link to framework docs
- Fix collaborator check to use --paginate with per_page=100 per issue spec
@marcusquinn marcusquinn force-pushed the feature/t1412.11-security-posture-init branch from b3bd121 to d058c69 Compare March 8, 2026 14:07
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

🔍 Code Quality Report

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

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

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Mar 8 14:07:45 UTC 2026: Code review monitoring started
Sun Mar 8 14:07:46 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 366

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 366
  • VULNERABILITIES: 0

Generated on: Sun Mar 8 14:07:49 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

…existing files

Re-running 'aidevops init' on an already-initialized repo now updates the
Security section in .agents/AGENTS.md instead of skipping it. Custom content
outside the Security section is preserved.

Refactored into three functions:
- _generate_security_section(): produces Security content based on project type
- scaffold_agents_md(): creates file if missing, delegates to update if exists
- _update_agents_md_security(): replaces Security section, preserves everything else

Addresses CodeRabbit nitpick on PR #3628.
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

🔍 Code Quality Report

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

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

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Mar 8 15:09:22 UTC 2026: Code review monitoring started
Sun Mar 8 15:09:22 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 368

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 368
  • VULNERABILITIES: 0

Generated on: Sun Mar 8 15:09:25 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Copy link
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: 3

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

Inline comments:
In `@aidevops.sh`:
- Around line 1207-1215: Update the "General Security Rules" list to include one
concrete secure-storage pointer: add a bullet that directs users to the
supported local secret workflow under ~/.aidevops (e.g., reference the local API
key setup helper script at
~/Git/aidevops/.agents/scripts/setup-local-api-keys.sh and the framework's
secret store guidance) and instruct to use placeholders in code examples rather
than embedding secrets; modify the block under the "General Security Rules"
heading (the existing bullet list) to contain this new line so new repos use the
documented secure storage flow instead of ad-hoc dotfiles or shell-history.
- Around line 1317-1333: The current heading check uses a prefix match on the
variable "line" (if [[ "$line" == "## Security" || "$line" == "## Security "*
]]) which also matches headings like "## Security Architecture" and will clobber
user sections; change the condition so it only matches the exact "## Security"
heading (allowing only optional trailing whitespace) when setting in_security,
has_security_section, writing security_content and setting security_replaced,
e.g. replace the glob prefix test with a stricter pattern match (anchored/regex
or explicit trim+equality) on "line" and leave the subsequent next-heading
detection (the "## " check that turns off in_security and writes the next
heading) unchanged.
- Around line 1185-1202: Replace the incorrect example that uses a non-existent
defend(userInput) API with the actual StackOne Defender usage: import and call
createPromptDefense to construct a defense instance, then call its
defendToolResult method on untrusted tool outputs (pass the tool response and
tool name), check result.allowed and handle blocked content, and use
result.sanitized as the safe content; reference the createPromptDefense factory
and the defendToolResult method and ensure the example emphasizes defending tool
results before adding them to the LLM context rather than sanitizing raw user
input.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b766feba-1ce2-4b09-8b8d-188fa3187f89

📥 Commits

Reviewing files that changed from the base of the PR and between b3bd121 and a993e87.

📒 Files selected for processing (2)
  • .agents/scripts/security-posture-helper.sh
  • aidevops.sh

… pointers, heading match

- Replace incorrect defend(userInput) example with actual StackOne Defender API:
  createPromptDefense() + defendToolResult() for sanitizing tool outputs
- Add concrete secure-storage pointer (aidevops secret set) to both JS/TS and
  generic General Security Rules sections
- Narrow ## Security heading match to exact string only, preventing accidental
  clobbering of user headings like '## Security Architecture'
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

🔍 Code Quality Report

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

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

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Mar 8 20:06:58 UTC 2026: Code review monitoring started
Sun Mar 8 20:06:59 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 367

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 367
  • VULNERABILITIES: 0

Generated on: Sun Mar 8 20:07:01 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@marcusquinn
Copy link
Owner Author

Dispatching worker to address review feedback and fix CI.

  • Model: sonnet (anthropic/claude-sonnet-4-6)
  • Branch: feature/t1412.11-security-posture-init
  • Scope: Address CHANGES_REQUESTED review feedback and fix SonarCloud CI failure on PR t1412.11: Per-repo security posture in aidevops init #3628
  • Attempt: 1 of 1
  • Direction: Push fixes to existing branch feature/t1412.11-security-posture-init — no new PR needed. SonarCloud failure is systemic (GH#3837) but address review feedback regardless.

@marcusquinn
Copy link
Owner Author

@coderabbitai review

All review feedback has been addressed in commits d058c69, a993e87, and d50b77b:

  1. sops in .features — Added at line 1471 (d058c69)
  2. Idempotent Security section update — scaffold_agents_md handles both create and update (a993e87)
  3. StackOne Defender API — Uses correct createPromptDefense + defendToolResult API (d50b77b)
  4. Heading match — Exact "## Security" match only, no prefix match (d50b77b)
  5. Secure-storage pointer — References aidevops secret set <NAME> in General Security Rules (d50b77b)

Requesting re-review to clear the stale CHANGES_REQUESTED status.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 8, 2026

@marcusquinn Thanks for the detailed breakdown of changes — the five addressed items look thorough! Kicking off a fresh review of PR #3628 now to clear the stale CHANGES_REQUESTED status. 🐇


🧠 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: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-08T12:35:20.071Z
Learning: Consult tools/build-agent/agent-review.md for guidance on reviewing and improving agents
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

🔍 Code Quality Report

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

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

�[0;34m[INFO]�[0m Recent monitoring activity:
Mon Mar 9 04:16:03 UTC 2026: Code review monitoring started
Mon Mar 9 04:16:04 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 393

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 393
  • VULNERABILITIES: 0

Generated on: Mon Mar 9 04:16:06 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Copy link
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: 1

🧹 Nitpick comments (2)
.agents/scripts/security-posture-helper.sh (1)

52-56: Finish the literal cleanup with category constants too.

Centralizing the severity strings helps, but the repeated category keys (workflows, branch_protection, dependencies, etc.) are still duplicated throughout the file, so Sonar will keep flagging this script.

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

In @.agents/scripts/security-posture-helper.sh around lines 52 - 56, Centralize
repeated category string literals by adding readonly CATEGORY_* constants (e.g.,
CATEGORY_WORKFLOWS="workflows", CATEGORY_BRANCH_PROTECTION="branch_protection",
CATEGORY_DEPENDENCIES="dependencies", etc.) alongside the existing SEVERITY_*
constants, then replace all raw category string usages in functions and
conditionals with those constants (search for the literal keys like "workflows",
"branch_protection", "dependencies", "secrets", "actions", etc.) to avoid
duplication and satisfy SonarCloud; keep naming consistent with the SEVERITY_
prefix pattern and update any comments or docs referencing the literals.
aidevops.sh (1)

1259-1273: Make scaffold_agents_md() create .agents/ itself.

The helper advertises “creates the file if missing”, but it still depends on the caller having created the parent directory first. Adding the directory creation here makes the function reusable and keeps its contract true.

♻️ Minimal hardening
 scaffold_agents_md() {
 	local project_root="$1"
 	local agents_md="$project_root/.agents/AGENTS.md"
+
+	mkdir -p "$(dirname "$agents_md")"
 
 	if [[ -f "$agents_md" ]]; then
 		# File exists — update the Security section idempotently
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@aidevops.sh` around lines 1259 - 1273, scaffold_agents_md currently assumes
the parent directory exists; modify scaffold_agents_md to ensure the directory
for "$agents_md" exists before writing the file by creating the .agents
directory (use mkdir -p on the directory portion of the agents_md path) right
after computing agents_md and before checking [[ -f "$agents_md" ]], so both the
update and creation paths are safe; reference scaffold_agents_md, the agents_md
variable, and _update_agents_md_security/_generate_security_section when making
the change.
🤖 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/security-posture-helper.sh:
- Around line 582-589: The posture logic currently sets posture_status for
warnings but leaves the script exit code unchanged; update the block handling
FINDINGS_WARNING and total_findings so that when FINDINGS_WARNING > 0 (or
total_findings > 0 but no criticals) you both set
posture_status="$SEVERITY_WARNING" (or "good" as appropriate) and set a non-zero
exit indicator (e.g., EXIT_CODE=1 or call exit 1), and ensure the script's final
termination uses that EXIT_CODE; reference the variables posture_status,
FINDINGS_WARNING, FINDINGS_CRITICAL, total_findings and SEVERITY_WARNING so the
change is applied where those symbols are used.

---

Nitpick comments:
In @.agents/scripts/security-posture-helper.sh:
- Around line 52-56: Centralize repeated category string literals by adding
readonly CATEGORY_* constants (e.g., CATEGORY_WORKFLOWS="workflows",
CATEGORY_BRANCH_PROTECTION="branch_protection",
CATEGORY_DEPENDENCIES="dependencies", etc.) alongside the existing SEVERITY_*
constants, then replace all raw category string usages in functions and
conditionals with those constants (search for the literal keys like "workflows",
"branch_protection", "dependencies", "secrets", "actions", etc.) to avoid
duplication and satisfy SonarCloud; keep naming consistent with the SEVERITY_
prefix pattern and update any comments or docs referencing the literals.

In `@aidevops.sh`:
- Around line 1259-1273: scaffold_agents_md currently assumes the parent
directory exists; modify scaffold_agents_md to ensure the directory for
"$agents_md" exists before writing the file by creating the .agents directory
(use mkdir -p on the directory portion of the agents_md path) right after
computing agents_md and before checking [[ -f "$agents_md" ]], so both the
update and creation paths are safe; reference scaffold_agents_md, the agents_md
variable, and _update_agents_md_security/_generate_security_section when making
the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2d0c9678-1505-4cd5-8568-2cef34fd976e

📥 Commits

Reviewing files that changed from the base of the PR and between a993e87 and bfcd349.

📒 Files selected for processing (2)
  • .agents/scripts/security-posture-helper.sh
  • aidevops.sh

…ents_md

- check/audit/store now return exit 1 when FINDINGS_WARNING > 0 (not just
  critical), matching the script header contract: exit 1 = findings detected
- scaffold_agents_md() creates .agents/ directory itself via mkdir -p,
  making the function self-contained and reusable without caller setup
@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

🔍 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:
Mon Mar 9 05:01:07 UTC 2026: Code review monitoring started
Mon Mar 9 05:01:08 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 395

📈 Current Quality Metrics

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

Generated on: Mon Mar 9 05:01:10 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@marcusquinn
Copy link
Owner Author

Review feedback addressed (commit 07abb32)

Fixed (valid findings)

  1. Warning postures exit code (Major) — check|audit and store now return exit 1 when FINDINGS_WARNING > 0, matching the documented contract: exit 1 = findings detected / actions needed.

  2. scaffold_agents_md() mkdir -p (Nitpick) — Function now creates .agents/ directory itself via mkdir -p "$(dirname "$agents_md")", making it self-contained and reusable without caller setup.

Dismissed (with reasoning)

  1. Category constants (Nitpick) — The category strings ("workflows", "branch_protection", etc.) are JSON data labels passed to add_finding, not control-flow values used in conditionals. Extracting them to CATEGORY_* constants would add 7+ readonly declarations and indirection without meaningful safety benefit — they're never compared or branched on, just stored as JSON keys. The severity constants were worth extracting because they appear in conditionals (if posture_status == ...); category strings don't. SonarCloud's "repeated string literal" rule is a heuristic, not a correctness issue here.

Previously addressed (commits d058c69, a993e87, d50b77b, bfcd349)

  • sops in .features
  • StackOne Defender API ✅
  • Secure-storage pointer ✅
  • Heading match (exact + regex) ✅
  • Idempotent Security section update ✅

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 9, 2026

@marcusquinn Thanks for the thorough breakdown — the fixes in 07abb32 look solid:

  • Exit code alignment — Returning exit 1 when FINDINGS_WARNING > 0 in check|audit and store is the right call for contract correctness; callers can now reliably detect actionable findings.
  • mkdir -p self-containment — Having scaffold_agents_md() own its own directory setup is a clean defensive pattern for a reusable function.
  • Category constants dismissal — Well-reasoned. The distinction between severity constants (branched on in conditionals) vs. category strings (pure JSON data labels, never compared) is exactly right. SonarCloud's repeated-string heuristic doesn't distinguish between those two cases, so dismissing it here is appropriate.

Kicking off a fresh review to clear the stale CHANGES_REQUESTED status. 🐇


🧠 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: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-08T12:35:20.071Z
Learning: Consult tools/build-agent/agent-review.md for guidance on reviewing and improving agents
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@marcusquinn
Copy link
Owner Author

All CodeRabbit review feedback addressed

Round 1 (review 3911369662)

  1. sops in .features (Major) — Fixed in d058c69
  2. Backfill Security section (Nitpick) — Fixed in a993e87 (idempotent update via _update_agents_md_security) ✅

Round 2 (review 3911584722)

  1. StackOne Defender API (Major) — Fixed in d50b77b (correct createPromptDefense + defendToolResult) ✅
  2. Secure-storage pointer (Minor) — Fixed in d50b77b (aidevops secret set <NAME>, placeholders) ✅
  3. Heading match prefix (Major) — Fixed in d50b77b + bfcd349 (regex ^'## Security'[[:space:]]*$) ✅

Round 3 (review 3912793672)

  1. Warning postures exit code (Major) — Fixed in 07abb32, confirmed by CodeRabbit ✅
  2. Category constants (Nitpick) — Dismissed: category strings are JSON data labels, not control-flow values; extracting to constants adds indirection without safety benefit ✅
  3. scaffold_agents_md() mkdir -p (Nitpick) — Fixed in 07abb32

All inline comments now have replies. CI is green (all checks passing including SonarCloud Quality Gate).

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 9, 2026

@marcusquinn Excellent — that's a clean, well-documented close-out across all three rounds. The commit-level traceability for each item (d058c69a993e87d50b77bbfcd34907abb32) makes this easy to verify. The reasoning on category constants is also solid — the distinction between values used in conditionals vs. pure JSON data labels is exactly the right lens for that call.

Kicking off a fresh review now to clear the stale CHANGES_REQUESTED status. 🐇


🧠 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: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-08T12:35:20.071Z
Learning: Consult tools/build-agent/agent-review.md for guidance on reviewing and improving agents
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.agents/scripts/security-posture-helper.sh (1)

582-605: ⚠️ Potential issue | 🟠 Major

Don't label info-only audits as fully good.

With the new SEVERITY_INFO/skip tracking, a repo that could not be fully assessed still falls through to status="good" as soon as there are no warnings or criticals. print_summary() then reports “all checks passed,” even when phases were skipped because gh is missing, the repo has no GitHub remote, or collaborator data was inaccessible. Persist a separate partial/incomplete state so stored posture does not overstate audit coverage.

🔧 Minimal fix
 	local posture_status="unknown"
 	if [[ "$FINDINGS_CRITICAL" -gt 0 ]]; then
 		posture_status="$SEVERITY_CRITICAL"
 	elif [[ "$FINDINGS_WARNING" -gt 0 ]]; then
 		posture_status="$SEVERITY_WARNING"
+	elif [[ "$FINDINGS_INFO" -gt 0 && "$FINDINGS_PASS" -eq 0 ]]; then
+		posture_status="partial"
 	elif [[ "$total_findings" -gt 0 ]]; then
 		posture_status="good"
 	fi
 
 	local temp_file="${config_file}.tmp"
 	jq --arg status "$posture_status" \
 		--arg ts "$timestamp" \
 		--argjson critical "$FINDINGS_CRITICAL" \
 		--argjson warnings "$FINDINGS_WARNING" \
+		--argjson info "$FINDINGS_INFO" \
 		--argjson passed "$FINDINGS_PASS" \
 		--argjson findings "$FINDINGS_JSON" \
 		'.security_posture = {
 			"status": $status,
 			"last_audit": $ts,
 			"critical": $critical,
 			"warnings": $warnings,
+			"info": $info,
 			"passed": $passed,
 			"findings": $findings
 		}' "$config_file" >"$temp_file" && mv "$temp_file" "$config_file"
 			case "$stored_status" in
 			critical)
 				echo "Security: $stored_critical critical issue(s), $stored_warnings warning(s) — run \`aidevops security audit\` (last: $stored_ts)"
 				;;
 			warning)
 				echo "Security: $stored_warnings warning(s) — run \`aidevops security audit\` for details (last: $stored_ts)"
 				;;
+			partial)
+				echo "Security: audit completed with skipped checks — review findings (last: $stored_ts)"
+				;;
 			good)
 				echo "Security: all checks passed (last: $stored_ts)"
 				;;

As per coding guidelines, ".agents/scripts/*.sh: Automation scripts - focus on: Reliability and robustness".

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

In @.agents/scripts/security-posture-helper.sh around lines 582 - 605, The
current posture_status assignment treats any repo with zero warnings/criticals
as "good" even when info-only findings or skipped phases exist; update the logic
in the posture_status block (the posture_status variable assignment) to detect
incomplete audits—e.g., check FINDINGS_INFO, a SKIPPED_PHASES or INCOMPLETE_SCAN
flag, or rely on SEVERITY_INFO—and set posture_status to a distinct value like
"partial" or "$SEVERITY_INFO" instead of "good" when those indicators are
present, keeping the existing precedence for SEVERITY_CRITICAL and
SEVERITY_WARNING; ensure the revised posture_status is what gets passed into jq
(the same $posture_status/$temp_file flow) so print_summary and stored config
reflect an incomplete audit.
🧹 Nitpick comments (1)
aidevops.sh (1)

1227-1249: Broaden the non-JS threat model wording.

The generic variant only calls out direct user input, but indirect prompt injection usually arrives through retrieved docs, tool outputs, tickets, emails, and webhook payloads too. Matching the broader boundary you use in the JS/TS section would make the scaffold less likely to under-specify the real risk.

✏️ Suggested wording
-Any feature that accepts user input and passes it to an LLM must defend against
-prompt injection. Sanitize and validate all untrusted input before including it
-in prompts:
+Any feature that passes untrusted content to an LLM — user input, tool outputs,
+retrieved documents, emails, tickets, or webhook payloads — must defend against
+prompt injection. Sanitize and validate that content before including it in
+prompts:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@aidevops.sh` around lines 1227 - 1249, Update the "### Prompt Injection
Defense" section to broaden the threat model beyond direct user input by
explicitly calling out indirect vectors (retrieved docs, tool outputs, tickets,
emails, webhook payloads, database/content stores, and agent/toolchain results)
and align its guidance with the JS/TS section; change the bullets under that
heading (the list starting with "Strip or escape control characters...") to
include an item advising validation/sanitization of all externally sourced
content before inclusion in prompts, add examples of indirect sources, and
ensure wording for "Never concatenate raw user input..." covers "raw external
content" as well so uses of function names or templates that build prompts
(e.g., the structured prompt template advice) are updated to enforce boundaries
for both direct and indirect inputs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In @.agents/scripts/security-posture-helper.sh:
- Around line 582-605: The current posture_status assignment treats any repo
with zero warnings/criticals as "good" even when info-only findings or skipped
phases exist; update the logic in the posture_status block (the posture_status
variable assignment) to detect incomplete audits—e.g., check FINDINGS_INFO, a
SKIPPED_PHASES or INCOMPLETE_SCAN flag, or rely on SEVERITY_INFO—and set
posture_status to a distinct value like "partial" or "$SEVERITY_INFO" instead of
"good" when those indicators are present, keeping the existing precedence for
SEVERITY_CRITICAL and SEVERITY_WARNING; ensure the revised posture_status is
what gets passed into jq (the same $posture_status/$temp_file flow) so
print_summary and stored config reflect an incomplete audit.

---

Nitpick comments:
In `@aidevops.sh`:
- Around line 1227-1249: Update the "### Prompt Injection Defense" section to
broaden the threat model beyond direct user input by explicitly calling out
indirect vectors (retrieved docs, tool outputs, tickets, emails, webhook
payloads, database/content stores, and agent/toolchain results) and align its
guidance with the JS/TS section; change the bullets under that heading (the list
starting with "Strip or escape control characters...") to include an item
advising validation/sanitization of all externally sourced content before
inclusion in prompts, add examples of indirect sources, and ensure wording for
"Never concatenate raw user input..." covers "raw external content" as well so
uses of function names or templates that build prompts (e.g., the structured
prompt template advice) are updated to enforce boundaries for both direct and
indirect inputs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b9884805-3b0c-45e2-8624-63a6739c9b35

📥 Commits

Reviewing files that changed from the base of the PR and between bfcd349 and 07abb32.

📒 Files selected for processing (2)
  • .agents/scripts/security-posture-helper.sh
  • aidevops.sh

- Add 'partial' posture status when only info findings exist with no
  passes (skipped checks should not report 'good')
- Include info count in stored .aidevops.json security_posture
- Add 'partial' case to print_summary for accurate status display
- Broaden non-JS prompt injection defense to cover indirect vectors
  (tool outputs, retrieved docs, emails, tickets, webhook payloads)

Addresses CodeRabbit review round 4 on PR #3628.
@marcusquinn
Copy link
Owner Author

Review round 4 feedback addressed (commit 41060fa)

Fixed (both suggestions)

  1. Partial posture status (Major, outside diff) — store_posture() now detects info-only audits (where FINDINGS_INFO > 0 && FINDINGS_PASS == 0) and sets posture_status="partial" instead of falling through to "good". The info count is also persisted in .aidevops.json and print_summary() displays "audit completed with skipped checks" for partial audits. This prevents overstating audit coverage when phases are skipped (missing gh, no remote, inaccessible collaborator data).

  2. Broaden non-JS threat model (Nitpick) — The non-JS/TS ### Prompt Injection Defense section now explicitly calls out indirect vectors: tool outputs, retrieved documents, emails, tickets, and webhook payloads. Wording aligned with the JS/TS variant's broader threat model. Added bullet for validating externally sourced content (tool results, API responses, database records).

@coderabbitai review

@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

🔍 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:
Mon Mar 9 05:53:42 UTC 2026: Code review monitoring started
Mon Mar 9 05:53:43 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 395

📈 Current Quality Metrics

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

Generated on: Mon Mar 9 05:53:45 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 9, 2026

@marcusquinn Both fixes in 41060fa are well-executed:

  • Partial posture detection — The FINDINGS_INFO > 0 && FINDINGS_PASS == 0 guard is exactly the right heuristic for detecting skipped-phase audits. Surfacing "partial" in .aidevops.json and in print_summary() prevents a misleading "good" posture when gh is unavailable, there's no remote, or collaborator data is inaccessible. Clean and defensively correct.
  • Indirect vector coverage — Explicitly naming tool outputs, retrieved documents, emails, tickets, and webhook payloads as injection surfaces in the non-JS/TS section is a meaningful upgrade. Those indirect channels are where prompt injection is most likely in agentic workflows, and aligning that section's threat model with the JS/TS variant's breadth is the right call.

Kicking off a fresh review to clear the stale CHANGES_REQUESTED status. 🐇


🧠 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: CR
Repo: marcusquinn/aidevops PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-08T12:35:20.071Z
Learning: Consult tools/build-agent/agent-review.md for guidance on reviewing and improving agents
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

🔍 Code Quality Report

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

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

�[0;34m[INFO]�[0m Recent monitoring activity:
Mon Mar 9 06:06:17 UTC 2026: Code review monitoring started
Mon Mar 9 06:06:18 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 398

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 398
  • VULNERABILITIES: 0

Generated on: Mon Mar 9 06:06:20 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@marcusquinn
Copy link
Owner Author

Review feedback addressed

All CodeRabbit suggestions from the latest review round have been resolved:

Already addressed (prior commits)

  • Partial posture status (major, outside diff): Implemented in 41060fapartial status when FINDINGS_INFO > 0 && FINDINGS_PASS == 0, with print_summary() case and info field in stored JSON.
  • Broaden non-JS threat model wording (nitpick): Implemented in 41060fa — non-JS variant already includes "tool outputs, retrieved documents, emails, tickets, or webhook payloads".
  • mkdir -p in scaffold_agents_md() (nitpick): Already present at line 1266 since commit 07abb32.

Newly addressed

  • Category string constants (nitpick): Implemented in c7ff7f5 — added CAT_WORKFLOWS, CAT_BRANCH_PROTECTION, CAT_REVIEW_BOT_GATE, CAT_DEPENDENCIES, CAT_COLLABORATORS, CAT_REPO_SECURITY constants, replacing all 51 raw category string literals. ShellCheck clean.

Previously confirmed (all 5 inline comments)

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 9, 2026

@marcusquinn
Copy link
Owner Author

Dispatching fix worker to address 1 unresolved bot review suggestion before merge.

  • Model: sonnet (anthropic/claude-sonnet-4-6)
  • Scope: Address unresolved inline review suggestion from bot on this PR
  • Attempt: 1 of 1

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.

t1412.11: Per-repo security posture in aidevops init

1 participant