Context Engineering for AI Coding Agents: Keeping Autonomous Assistants Under Control

    This article explains why command-line AI coding assistants are not ordinary code completion tools but autonomous execution agents with very limited memory. It covers why control failures are structural, how context compression can erase verbal instructions, and how context engineering can keep them reliable. The article walks through project rules files, task decomposition, verification gates, permission boundaries, runtime safeguards, observability, team governance, and a practical deployment checklist.

    1. First, correct a common misunderstanding: it is not “super code completion”

    Many teams, when they first use a command-line AI coding assistant, treat it as an “upgraded code completion tool”: I describe a requirement, it returns a piece of code, and that is all.

    This mental model leads to almost every subsequent management mistake, because you are effectively managing a “typewriter,” while what you are actually facing is an autonomous execution agent.

    Its operating mechanism is actually close to plain simplicity:

    1. Send the current context to the model.
    2. The model decides whether to call a tool, such as reading a file, modifying a file, running a command, or searching the codebase.
    3. The tool result is returned to the model.
    4. The model enters the next reasoning step.

    The cycle repeats until the task is completed or a limit is reached.

    In this structure, only a very small amount of code actually carries “decision-making.” Most of the engineering effort goes into runtime safeguards: permission checks, tool-call wrappers, context compression, session recovery, command allowlists, dangerous-operation blocking, result trimming, and error retries.

    The imbalance is intentional. The model’s reasoning capability is largely handled by general-purpose models. The hardest remaining part is: how to make an autonomous program act safely inside a real codebase.

    The conclusion matters: it is not a stronger completer. It is a highly capable executor with very short memory, and its constraints must be supplied externally.

    2. Why “loss of control” is structural, not bad luck

    2.1 Statelessness is a design choice, not a defect

    In each turn, the model only sees the portion of information currently assembled into the context.

    It does not retain memory across sessions, nor does it implicitly know the historical decisions in your project.

    Therefore, “loss of control” is not an occasional failure. It is the default outcome: unless you make the constraints explicit in the context, the model can only rely on generic statistical inference.

    2.2 The context window is a limited resource and must be compressed

    Long tasks, large repositories, and large amounts of log output can quickly consume the context budget.

    To continue working, the runtime compresses or summarizes the conversation history: earlier turns are folded into a summary, while the original details are discarded.

    There is one mechanism detail that is easy to overlook and expensive to get wrong:

    • Rule files written to disk at the project level will be re-read after compression and reinjected into the system prompt, so the rules remain effective.
    • Instructions you give verbally in the chat window exist only in the conversation history, and once compression occurs, they are permanently lost.

    This leads to a familiar scenario: you repeatedly remind the assistant not to use an obsolete tool, not to touch generated files, and to run tests before committing. The model behaves perfectly for the first ten minutes, then starts reverting to old habits by minute thirty.

    It is not that it remembered and then forgot. It is that the instruction is no longer in the context.

    2.3 Goal drift and error accumulation

    Autonomous execution agents continuously update their own “current task description” while taking small steps.

    Without an external anchor, a mid-course misjudgment, such as modifying a configuration file to bypass an error, can be treated by later turns as an established premise and used to continue reasoning. This creates an error chain that becomes increasingly difficult to reverse.

    3. Core countermeasure: turn rules into assets that are reloaded in every session

    3.1 The correct role of rules files

    A rules file in the repository root, usually written in Markdown with naming that varies by implementation, is read when each session starts and reinjected after context compression.

    Its value is not that it is a “memo.” Its value is that it turns implicit team knowledge into explicit constraints that can be versioned, reviewed, and shared.

    A recommended layered structure follows the principle of “the closer the rule, the higher the priority,” while separating general rules from local exceptions:

    1. ~/.config/agent/rules.md # Personal preferences: response language, output format, commit habits
    2. <repo>/AGENT_RULES.md # Repository level: build/test commands, directory conventions, forbidden areas, dependency policy
    3. <repo>/services/api/rules.md # Directory level: service-specific technology details and special constraints

    Subdirectory rules are loaded only when relevant work occurs in that path. This helps control context size and avoids global rule bloat.

    3.2 What should actually go into a rules file

    The first writing principle is: write instructions that a machine can follow, not impressions or opinions.

    Short, executable, and verifiable instructions are better than exhaustive, lengthy descriptions.

    1. # Project conventions
    2. ## Environment and commands
    3. - Use the lockfile in the workspace root for dependency management; do not run standalone commands that add dependencies
    4. - Build: make build Test: make test Single-file test: make test T=path/to/file
    5. - Static checks: make lint (must pass before commit)
    6. ## Code style
    7. - Follow the repository's existing style; do not introduce new formatting tools or change indentation/newline rules
    8. - New exported symbols must have documentation comments; do not use type assertions to bypass compilation errors
    9. ## Change discipline
    10. - Make only the requested changes; do not opportunistically refactor unrelated code
    11. - Read the full file before editing; edit only the necessary fragments
    12. - Stop after each verifiable subtask and wait for confirmation
    13. ## Forbidden areas (do not modify unless I explicitly approve)
    14. - src/generated/ Generated code artifacts
    15. - migrations/ Released database migrations
    16. - infra/*.tf Infrastructure definitions
    17. ## Definition of Done
    18. 1. make lint passes
    19. 2. make test passes
    20. 3. Change explanation is no more than 5 lines

    A few common mistakes:

    • Do not write unverifiable requirements such as “write good code.” Rewrite them as checkable actions, such as which command to run or which comment to add.
    • Commands are better than descriptions. “Verify with make test” is much more effective than “remember to test,” because it gives the model a clear tool-call target.
    • Explicitly list forbidden paths. A file-level blocklist is one of the easiest safeguards to maintain, with almost no cost.
    • Declare the collaboration mode in advance. For example, “stop after each subtask and report” can effectively suppress large changes within a single turn.

    3.3 Task-side constraints: small steps, verifiable outcomes, and rollback points

    Rules files address long-term constraints. Task decomposition addresses short-term drift.

    The most effective combination in practice is:

    1. First, ask the model to read the relevant files and output a change plan. Review it before allowing edits.
    2. Split large requirements into small blocks where each step can be independently verified, for example: change one function and run the corresponding test.
    3. After each block is completed, review the diff once so errors can be caught before they spread.
    4. Before starting work, make sure the workspace is clean so you can use git diff for review and git checkout for rollback at any time.

    Shift the review target from “the final commit” to “the diff after each tool call.” This is the lowest-cost control gate.

    4. Permissions and runtime safeguards: prevent loss of control from causing real damage

    • Separate read and write permissions. By default, allow only read operations and safe build/test commands. Write operations, network requests, package management, and deployment-related commands should require explicit confirmation.
    • Hard-block dangerous operations. Recursive deletion, forced pushes, modifying version-control configuration, and writing CI credentials should be rejected directly at the tool layer, not left to the model’s judgment.
    • Use sandboxed execution. Run in a container or isolated workspace, limit writable directories and network egress, and keep execution of generated code isolated from the local environment.
    • Keep credentials out of the context. Inject secrets and tokens through environment variables or a credential manager, and explicitly list them in the rules file under a “do not read / do not echo” section to avoid having them summarized into the compressed context.
    • Control cost and quota. Set maximum turns per session, timeouts, and budget limits to prevent endless looping.

    5. Observability and team governance

    Once an AI coding assistant is treated as a formal production tool, it should be observed and governed like other development tools:

    • Logs: record the tool-call sequence, duration, token consumption, and failure retries, so you can identify where the process starts to deviate.
    • Metrics: track task success rate, average number of interventions, lint/test pass rate, and rollback rate.
    • Governance: keep rules files in the same repository and under the same review process as code, so changes remain traceable. The team shares a repository-level rules file, while personal preferences are stored separately.

    In enterprise R&D systems, these audit logs often need to be retained for a long time and centrally searched. They can be integrated through common cloud capabilities such as logging services, object storage, monitoring, and alerting. For example, general cloud capabilities from Baidu AI Cloud can be one implementation option, but availability, pricing, and compliance should be verified against the official documentation. Once the rules files are added to the code repository and the CI/CD pipeline, the pipeline can automatically validate their presence and the completeness of key entries, preventing team-wide degradation caused by accidental deletion.

    6. Deployment checklist

    • The repository root contains a rules file, and it is under version control.
    • The rules file contains explicit build, test, and static-check commands.
    • Forbidden directories and files are listed.
    • The Definition of Done and the “pause after each step” collaboration convention are defined.
    • Write operations require confirmation by default, and dangerous commands are blocked at the tool layer.
    • Secrets do not enter the context, and the execution environment is isolated.
    • Tool-call logs and key metrics are connected to the observability system.

    In one sentence: the reliability of these tools does not come from how smart the model is, but from where you place the constraints. Rules written in the chat window will evaporate under context compression. Rules written to disk and automatically reloaded will remain effective. That is the real technical gap between loss of control and reliable take-off.