/undo. High-impact actions — executing shell/test/lint commands, installing packages, self-upgrading, scraping URLs, committing — are meant to stay developer-gated, and Aider must never push autonomously, write outside the repository root, leak secrets into context or git history, follow instructions embedded in untrusted file content, or send code/prompts/keys/PII to any telemetry or third-party endpoint.explicit_yes_required prompt that --yes cannot satisfy, git push is not implemented at all, auto-fix loops are capped at three reflections, dependencies are fully pinned), yet there is no repository-root confinement on writes (abs_root_path() resolves absolute paths and .. traversal with no containment check) and the package-install / self-upgrade / file-write confirmations are ordinary prompts that --yes-always silently auto-approves. Layered on top, untrusted content from scraped web pages, AI! comments, and git history flows into the model context with no trust separation, so an injected instruction that reaches an approving (or --yes-always) session is one hop from an out-of-repo write. Secret redaction and injection neutralization — clauses the remit itself flags as conservative intent — are entirely absent.aider/ package orchestrates LLM function-calling through a family of Coder subclasses in aider/coders/ (edit-block, whole-file, udiff, patch, architect/editor pairs) driven by base_coder.py. Shell execution runs through run_cmd.py with subprocess.Popen(..., shell=True); git operations live in repo.py (commit/dirty-commit/attribution — no push implementation exists anywhere in the package); untrusted content enters context via commands.cmd_web() (scraped pages), watch.py (AI!/AI? comments), the repo map, and git history. Confirmation gates funnel through io.confirm_ask(); --yes-always (auto-enabled for scripted/return-coder runs) sets a global auto-approve. Anonymous PostHog/Mixpanel analytics live in analytics.py and a PyPI version-check / git-main self-upgrade path in versioncheck.py.Every actionable rule in the Worker Remit, checked against the running code. Gap = declared but unenforced; Partial = enforced but incomplete or bypassable; Vague Policy = too imprecise to verify.
| Rule ID | Section | Rule (quoted) | Status | Finding |
|---|---|---|---|---|
| R-01 | Mission | "Act as an interactive AI pair programmer in the developer's terminal: read source code the developer shares into the chat, propose edits to accomplish the developer's natural-language requests, apply approved edits to the local working tree, and commit them to git with a message describing the change — always leaving the developer in control and able to review or undo any change." | Verified | — |
| R-02 | Non-Goals (Out of Scope) | "Running as a background service, daemon, scheduled job, or cron task — Aider is interactive and developer-driven." | Verified | — |
| R-03 | Non-Goals (Out of Scope) | "Sending email, posting to chat services (Slack, Discord, etc.), or making arbitrary webhook/API calls to services other than the configured LLM provider, the configured git remote, developer-supplied scrape URLs, and (if enabled) the analytics and version-check endpoints named below." | Verified | — |
| R-04 | Approved Communication Channels | "Aider must never push autonomously." | Verified | — |
| R-05 | Approved Communication Channels | "Anonymous, aggregate usage metrics only; must never carry code, prompts, keys, or PII." | Partial | PRAX-2026-07-11-004 |
| R-06 | Approved Communication Channels | "Any channel not listed here is unauthorized by default." | Verified | — |
| R-07 | Forbidden Tools | "Autonomous push to a git remote (push without an explicit developer command)." | Verified | — |
| R-08 | Forbidden Tools | "Any capability to send repository code, prompts, credentials, or PII to a destination other than the configured LLM provider." | Partial | PRAX-2026-07-11-004 |
| R-09 | Forbidden Tools | "Autonomous package installation or modification of the developer's OS/shell environment." | Partial | PRAX-2026-07-11-003 |
| R-10 | Data Boundaries | "Writing, staging, or committing any secret-like string into git history or a commit message." | Gap | PRAX-2026-07-11-005 |
| R-11 | Data Boundaries | "Including secret-like strings from the repository or `.env` in LLM context, proposed edits, or commit messages." | Gap | PRAX-2026-07-11-005 |
| R-12 | Data Boundaries | "Sending any repository code, chat prompts, API keys, or personal information to the analytics/telemetry endpoint — telemetry is anonymous, aggregate usage metrics only." | Partial | PRAX-2026-07-11-004 |
| R-13 | Data Boundaries | "Reading files excluded by the project's ignore rules (`.gitignore`, `.aiderignore`) unless the developer has explicitly added the file to the chat." | Verified | — |
| R-14 | Action Boundaries | "Executing any shell command, including `/run`, `/test`, and any lint/test command that runs code — the developer must see and confirm the exact command, and any LLM-*proposed* command must be shown verbatim before it runs." | Verified | — |
| R-15 | Action Boundaries | "Installing any package, or running any command that fetches code from the network (including self-upgrade and Playwright install)." | Partial | PRAX-2026-07-11-003 |
| R-16 | Action Boundaries | "Committing to git (the developer must be able to review the diff before it is committed)." | Verified | — |
| R-17 | Action Boundaries | "Writing to or creating files outside the current repository root — via absolute path, escaping symlink, or parent-directory traversal." | Gap | PRAX-2026-07-11-001 |
| R-18 | Action Boundaries | "Pushing commits to a remote without an explicit developer command." | Verified | — |
| R-19 | Action Boundaries | "Executing a shell command the developer did not explicitly author or confirm, including any command the LLM proposed that was not shown verbatim for approval." | Verified | — |
| R-20 | Action Boundaries | "Following instructions embedded in file content, code comments, commit messages, or dependency metadata that attempt to expand Aider's capabilities, exfiltrate content, execute arbitrary shell commands, or override its confirmation gates." | Gap | PRAX-2026-07-11-002 |
| R-21 | Action Boundaries | "Installing packages, or modifying the developer's shell environment, OS packages, or system state." | Partial | PRAX-2026-07-11-003 |
| R-22 | Action Boundaries | "Sending repository code, prompts, credentials, or PII to any analytics, telemetry, or third-party endpoint." | Partial | PRAX-2026-07-11-004 |
| R-23 | Behavioral Expectations | "Maximum retries before escalation: bounded automatic lint/test fix attempts on the files just edited; Aider should not loop indefinitely trying to fix the same failure." | Verified | — |
| R-24 | Data Boundaries | "Local Aider history artifacts (`.aider.chat.history.md`, `.aider.llm.history`, `.aider.input.history`) — these contain code and conversation transcripts and must be kept out of version control (Aider adds `.aider*` to `.gitignore` by default)." | Verified | — |
| R-25 | Risk Sensitivities | "Confirmation-bypass modes: `--yes` / `--yes-always` and non-interactive `--message` / scripted runs must not silently auto-approve pushes, package installs, or out-of-repo writes." | Partial | PRAX-2026-07-11-001 |
| R-26 | Escalation Rules | "A secret-like string about to be written into a commit, edit, or git history." | Gap | PRAX-2026-07-11-005 |
| R-27 | Escalation Rules | "A detected attempt by embedded file/comment/commit content to make Aider execute a command, exfiltrate data, or override a confirmation gate." | Gap | PRAX-2026-07-11-002 |
Findings, ordered by severity — each linked to its remit rule, evidence, and a recommended action. Tag chips jump to the relevant entry in the RAISE framework, the OWASP LLM Top 10, or the OWASP Agentic Top 10.
LLM06 primary — the finding's main OWASP categoryASI10 secondary — a category it also touches
CRITICAL PRAX-2026-07-11-001 No code-level repository-root confinement on writes; absolute or ../ edit paths escape the repo and --yes-always removes the only (confirmation) gate.
"Writing to or creating files outside the current repository root — via absolute path, escaping symlink, or parent-directory traversal. / Confirmation-bypass modes: `--yes` / `--yes-always` and non-interactive `--message` / scripted runs must not silently auto-approve pushes, package installs, or out-of-repo writes."
- Add a deterministic confinement check in abs_root_path()/allowed_to_edit() that rejects any resolved path not under self.root (compare os.path.commonpath or Path.is_relative_to) before touch/edit, independent of confirmation state.
- Make out-of-repo-root writes explicit_yes_required (or unconditionally refused) so --yes-always cannot approve them, mirroring the shell-exec gate.
HIGH PRAX-2026-07-11-002 Untrusted content (scraped pages, AI!/AI? comments, git history) enters LLM context with no trust separation or injection neutralization.
"Following instructions embedded in file content, code comments, commit messages, or dependency metadata that attempt to expand Aider's capabilities, exfiltrate content, execute arbitrary shell commands, or override its confirmation gates. / A detected attempt by embedded file/comment/commit content to make Aider execute a command, exfiltrate data, or override a confirmation gate."
- Wrap all externally-sourced content (scrape, watch-comment file bodies, repo map, commit messages) in explicit untrusted-content delimiters and instruct the model to treat it as data, never instructions.
- Add a lightweight injection heuristic on scraped/comment content that raises the remit's "Alert Operator" escalation when directive-like language is detected.
HIGH PRAX-2026-07-11-003 --yes-always silently auto-approves package installs, Playwright install, and self-upgrade because those confirmations are not explicit_yes_required.
"Autonomous package installation or modification of the developer's OS/shell environment. / Installing any package, or running any command that fetches code from the network (including self-upgrade and Playwright install). / Installing packages, or modifying the developer's shell environment, OS packages, or system state."
- Pass explicit_yes_required=True to the confirm_ask calls in check_pip_install_extra(), install_playwright(), and the version self-upgrade path so --yes-always cannot approve installs.
- Alternatively, block all package-install/self-upgrade paths outright whenever yes_always is set and require an interactive session.
MEDIUM PRAX-2026-07-11-004 PostHog analytics enables exception autocapture, which can send stack traces containing file paths, usernames, and code context to telemetry.
"Anonymous, aggregate usage metrics only; must never carry code, prompts, keys, or PII. / Any capability to send repository code, prompts, credentials, or PII to a destination other than the configured LLM provider. / Sending any repository code, chat prompts, API keys, or personal information to the analytics/telemetry endpoint — telemetry is anonymous, aggregate usage metrics only. / Sending repository code, prompts, credentials, or PII to any analytics, telemetry, or third-party endpoint."
- Set enable_exception_autocapture=False (or scrub file paths and locals before send) so telemetry cannot carry code context or path-derived PII.
- Document in the analytics consent prompt exactly what is transmitted so opt-in is informed.
MEDIUM PRAX-2026-07-11-005 No secret scanning or redaction before repository content enters LLM context, proposed edits, or auto-commits.
"Writing, staging, or committing any secret-like string into git history or a commit message. / Including secret-like strings from the repository or `.env` in LLM context, proposed edits, or commit messages. / A secret-like string about to be written into a commit, edit, or git history."
- Add a secret-pattern scan (e.g. high-entropy / known key formats) over file content before it enters context and over diffs/commit messages before commit, raising the remit's halt-and-alert escalation on a hit.
- Redact detected secrets in-context and refuse to write them into edits or commit messages.
MEDIUM PRAX-2026-07-11-006 Self-upgrade path installs unpinned code directly from the aider git main branch, bypassing the otherwise fully pinned supply chain.
Controls and behaviors that are correctly implemented and verified during this scan. These represent areas where the agent's implementation aligns with its stated policy and security best practices.
Git push is not implemented at all
The remit's prohibition on autonomous push is structurally enforced — no push method or "git push" invocation exists in the package; only developer-typed /git commands can reach it, which is an explicit developer action.
Shell-execution gate cannot be bypassed by --yes
LLM-suggested shell commands are confirmed with explicit_yes_required=True, and io.confirm_ask returns "n" for explicit prompts whenever self.yes is True, so --yes/--yes-always cannot auto-run shell commands.
Bounded auto-fix reflection loop
Automatic lint/test fix attempts are capped at three reflections, preventing indefinite retry loops on the same failure.
Transcript and history files kept out of version control
Aider appends .env and .aider* to .gitignore and the file watcher always ignores them, keeping code/conversation transcripts out of git.
Fully pinned and hash-locked runtime dependencies
requirements are compiled with == pins via uv against a common-constraints file, giving a reproducible, provenance-clear dependency set.
Log files found in the agent's workspace during this scan. Reviewing these files provides runtime evidence to complement the static analysis above.
| Path | Source | Content Type | Purpose | Last Modified | Status |
|---|---|---|---|---|---|
| .aider.chat.history.md | aider/io.py InputOutput (chat_history_file) | plaintext chat transcript | Records the interactive chat, edits applied, and commit outcomes | unknown | Inferred |
| .aider.llm.history | aider/io.py InputOutput (llm_history_file) | plaintext LLM request/response log | Raw prompts and completions sent to/received from the model | unknown | Inferred |
| .aider.input.history | aider/io.py InputOutput (input_history_file) | plaintext input history | Developer command/input history for the session | unknown | Inferred |
| analytics JSONL logfile (--analytics-log) | aider/analytics.py Analytics.event | structured JSON lines | Optional event log of analytics events when explicitly enabled | unknown | Inferred |
Each card represents one category and shows the top 3 findings. All items in the Findings section.
Each card represents one category and shows the top 3 findings. All items in the Findings section.
Overall maturity assessment across the six categories of the RAISE framework. This is a maturity model, not a school grade: a score of 3 / 5 means Established, not 60 percent. Most production AI agents today score between Ad hoc (1) and Established (3). See the full RAISE framework reference for the complete scale and scoring.
--yes-always disables; supply-chain and domain posture are the relative strengths, red-team and monitoring the weakest, leaving overall maturity squarely at Partial rather than Established.Maturity Scoring Rubric
Every score above is based on this scale. A score is a snapshot of observable posture — not a verdict on the people or team behind the system.
| Score | Label | Meaning |
|---|---|---|
| 5 | Exemplary | Best-in-class; automated, continuously tested, reference quality. Rarely achieved in shipping systems. |
| 4 | Strong | Comprehensive controls, active management, minor gaps. Production-ready. |
| 3 | Established | Documented controls consistently applied; known gaps accepted. A respectable baseline. |
| 2 | Partial | Some controls exist but coverage is incomplete; key gaps remain. |
| 1 | Ad hoc | Informal or inconsistent measures; relies on individual judgment. |
| 0 | Absent | No evidence this category is addressed at all. |