- 1.1 Integrate agents into the SDLC — which steps agents take, anti-patterns, inputs, outputs and success criteria
- 1.2 Define boundaries between planning, reasoning and action — plan distinct from execution, structured plans, validation, no action before approval
- 1.3 Configure observability and control for autonomous agents — degree of autonomy, inspectable artifacts, human intervention without slowing delivery
1.1 Integrate agents into the SDLC
Map agent responsibilities to SDLC stages
An agent treated as a general-purpose developer across the whole lifecycle is hard to reason about, hard to limit and hard to audit. The reliable pattern is to scope agents to specific stages where GitHub can enforce a boundary. Most teams start with implementation and validation, because pull requests and workflows provide natural control points there.
flowchart LR PLAN["Planning<br/>draft scope · steps · success criteria"] --> IMPL["Implementation<br/>branch · commits · pull request"] IMPL --> VAL["Validation<br/>checks · scans · artifacts"] VAL --> ACC["Acceptance<br/>CODEOWNERS · reviews · rulesets"] ACC --> DEP["Deployment<br/>environment approval"]
| SDLC stage | Typical agent responsibility | Primary artifact |
|---|---|---|
| Planning | Draft scope, plan steps, define success criteria, research the codebase | Issues, PR description, the Agents tab research and plan session |
| Implementation | Create a branch, make changes, open or update the PR | Branch, commits, pull request |
| Validation | Run checks, attach evidence, iterate on failures | Workflow runs, status checks, artifacts |
| Acceptance | None — this is human judgement plus policy | CODEOWNERS reviews, rulesets, required checks |
| Deployment | Usually restricted: the agent prepares, a human approves | Environments with required reviewers |
Three architectural boundaries follow from this map:
- Scope early to reduce blast radius — limit which directories an agent may change, by policy and by ownership.
- Treat workflow and infrastructure changes as higher risk than application code — a two-line diff in
.github/workflows/can change what every future run is allowed to do. - Prefer PR-based work even for automation — never direct-to-default-branch changes.
Agents propose; humans and policy accept
This one sentence resolves a large share of Skill 1 questions. The agent's responsibility for a dependency fix ends when it has opened a pull request with a plan and the expected success signals. Validation and acceptance happen through checks, reviews and policy — not through the agent declaring success.
Identify steps for agents to perform
Copilot cloud agent does best with clear, well-scoped tasks: a clear description of the problem, complete acceptance criteria, and directions about which files need to change. Think of an issue assigned to Copilot as a prompt — would it work as one?
| Good first candidates for an agent | Keep for a human (or plan-first with heavy review) |
|---|---|
| Bug fixes with a reproducible symptom · UI tweaks · improving test coverage · documentation updates · accessibility fixes · technical debt · dependency bumps · lint and formatting fixes · resolving merge conflicts · CI failure investigation | Broad, cross-repository refactoring · complex legacy dependencies · deep domain or business logic · large changes that need design consistency · production-critical issues · security, PII or authentication changes · incident response · ambiguous or open-ended tasks · tasks the developer wants to learn from |
Identify and mitigate common anti-patterns
| Anti-pattern | Symptom | Mitigation |
|---|---|---|
| Planless execution | The PR has a diff but no plan or rationale | PR template with a required plan section, a plan-gate check, plan-first for risky work |
| General-purpose agent | One agent touches app code, workflows and infra in the same PR | Narrow custom agents, each with a scoped prompt and tool list; CODEOWNERS on sensitive paths |
| Over-permissioned agent | Token or tools can write anywhere and read every secret | Least-privilege permissions, tool allowlists, Agents secrets only for what it needs |
| Hidden reasoning | Reviewers see only the output | Plan artifact, session logs, decisions recorded in the PR |
| Vague success criteria | "Tests pass" while the real goal is unmet | Criteria that encode intent ("vulnerability no longer resolvable") and map to checks |
| Blind trust in automation | "CI is green, merge it" | Checks plus code-owner review plus risk-based approvals |
| Unbounded iteration | The agent retries the same failing check forever | Retry limit, then escalate with a summary |
| Controls in docs only | "Agents must not edit workflows" written in a README | Enforce it: tool allowlist, preToolUse hook, CODEOWNERS with required review |
Define inputs, outputs and success criteria
Every agent task should be defined as a small contract. Under-specified tasks produce changes that look plausible but do not solve the underlying problem.
- Inputs
- What the agent needs: the issue or alert, repository scope (allowed and forbidden paths), constraints and non-goals.
- Outputs
- What it must produce: a plan, a bounded changeset on its branch, a pull request, and links to the evidence.
- Success criteria
- How the result is judged: required checks, security signals, review outcome, scope matching intent, a rollback note for risky changes.
## Task: remediate CVE in lodash (issue #482)
### Inputs
- Security alert: dependabot/alerts/57
- Allowed paths: package.json, package-lock.json, src/**
- Not allowed: .github/workflows/**, infra/** (platform review required)
- Constraints: no new dependencies; no direct pushes to main
### Outputs
- A pull request with: plan section, bounded commits on copilot/*,
links to the workflow run and the code scanning result
### Success criteria
- [ ] Vulnerable version no longer resolvable (including transitive paths)
- [ ] Required checks pass: build, test, lint, CodeQL
- [ ] Only files in the allowed paths changed
- [ ] Rollback note present (revert the merge commit) The criteria only become enforced when they map to required status checks. A workflow like the one below, marked as required in a ruleset, means the pull request cannot merge until it passes — success is decided by the system, not assumed by the agent.
# .github/workflows/pr-validation.yml
# Marked as a *required* status check in the branch ruleset, so a PR —
# human or agent — cannot merge until every job here passes.
name: PR validation
on:
pull_request:
branches: [main]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: npm ci
- run: npm test
codeql:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write # upload SARIF results
steps:
- uses: actions/checkout@v7
- uses: github/codeql-action/init@v4
with:
languages: javascript-typescript
- uses: github/codeql-action/analyze@v4 "CI passed" is necessary, not sufficient
Make success criteria describe the intent of the task. An agent can bump a dependency and keep every test green while the vulnerable version is still reachable through a transitive dependency. "Vulnerability resolved" is a success criterion; "tests pass" is only one of its signals.
1.2 Define boundaries between planning, reasoning and action
Why separate planning from execution
Reliable agent systems separate three things: planning (what will be done and why), execution (the concrete changes) and validation (evidence the outcome meets the criteria). When planning and execution are mixed, reviewers see only the final diff and lose the chance to catch a misunderstanding before it becomes code. GitHub maps the three naturally: the plan in the PR description or an issue, execution as commits on a branch, validation as checks, scans and reviews.
Plan-first versus plan + execution
Whether the plan starts from an issue assigned to Copilot or from a planning session in the Agents tab, all work converges on a pull request. The real design choice is when human validation happens relative to code being generated.
| Option A — plan-first | Option B — plan + execution in one PR | |
|---|---|---|
| How it works | The PR (or session) contains only the plan; reviewers approve it; implementation follows | The PR carries a plan section and initial commits; the plan evolves with the code |
| Validation happens | Before any code is written | After code exists, but still before merge |
| Risk exposure | Lowest — nothing to unwind if the plan is wrong | Early exposure: unnecessary changes, more reviewer effort, plan and code can drift apart |
| Use it for | High-risk or hard-to-reverse work: workflows, infra, auth, production, security | Low and medium-risk, easily reversible work where speed matters |
sequenceDiagram participant H as Human reviewer participant P as Planning agent (read-only tools) participant GH as Pull request participant I as Implementation agent participant CI as Required checks H->>P: Assign the issue P->>GH: Open PR containing only the plan H->>GH: Review, refine, approve the plan H->>I: Explicit handoff: implement the approved plan I->>GH: Push commits to the same branch GH->>CI: Run build, tests, scans CI-->>H: Evidence for the merge decision
Both options use the same GitHub controls, and in both the code cannot merge without checks and reviews. The risk difference exists during the proposal stage, not after merge. The choice is never whether the work is reviewed — it always is — but how early change is allowed into the workflow.
Enforcing the planning boundary
- Capability boundary. Give the planning agent read-only tools (
tools: ["read", "search"]) so it physically cannot modify files while planning. - Explicit handoff. Execution starts only after the plan is approved, through a deliberate transition to an implementation agent — a new session, a selected custom agent, or a
@copilot implement the approved plancomment. - Tool gating in orchestrators. In automated pipelines, run planning with no write tools and enable them only once the plan is accepted.
- Plan mode. Copilot CLI has a plan mode (Shift+Tab,
/planor--plan) that produces a plan and pauses; Copilot cloud agent can research and plan on GitHub.com before any code is written, and sessions do not open a pull request unless you ask.
Guidance versus enforcement, again
"Do not edit files during planning" in the agent's prompt is guidance. A tools list without
edit or execute is enforcement. When a question asks how to guarantee that the
planning phase cannot change code, pick the tool restriction.
Configure an agent to output a structured plan
A plan is only reviewable — and only machine-checkable — if it has a predictable shape. Three complementary techniques:
- A custom planning agent whose prompt prescribes the structure and whose tools are read-only.
- A pull request template (
.github/pull_request_template.md) with required Plan, Evidence and Rollback sections. - A machine-readable plan (
plan.json) uploaded as a workflow artifact, so downstream jobs can route on fields such asrisk.
---
name: implementation-planner
description: Produces a structured, reviewable implementation plan. Never edits source code.
tools: ["read", "search"]
---
You are a planning specialist. For the task you are given:
1. Restate the goal and list explicit non-goals.
2. List every file you expect to change, and why.
3. Break the work into numbered steps with a risk rating (low | medium | high).
4. Define verifiable success criteria that map to CI checks.
5. Describe the rollback path and when to escalate to a human.
Write the plan as the pull request description. Do not modify any file. {
"goal": "Remove vulnerable lodash 4.17.20",
"risk": "medium",
"paths": ["package.json", "package-lock.json"],
"steps": [
"Bump lodash to 4.17.21",
"Regenerate the lockfile",
"Run tests and CodeQL"
],
"success_criteria": ["alert #57 closed", "required checks green"],
"rollback": "revert merge commit"
} Validate agent plans
Validation combines people and automation. Humans check that the plan's goal matches the issue, the listed paths are within scope, risky steps have a rollback, and success criteria are verifiable. Automation checks the structure: a plan-gate workflow, marked as a required check, fails the pull request when the description is missing mandatory sections.
# .github/workflows/plan-gate.yml
# Fails the PR unless its description contains the required plan sections.
name: Plan gate
on:
pull_request:
types: [opened, edited, synchronize, reopened]
permissions:
contents: read
pull-requests: read
jobs:
require-plan:
runs-on: ubuntu-latest
steps:
- name: Check the PR body for a plan
env:
BODY: ${{ github.event.pull_request.body }}
run: |
for section in "## Plan" "Success criteria" "Rollback"; do
if ! grep -qF "$section" <<< "$BODY"; then
echo "::error::PR description is missing: $section"
exit 1
fi
done A plan gate validates shape, not quality
A required check can prove that a plan exists and has the right sections; only a reviewer can decide that
it is right. Pair the gate with CODEOWNERS routing so the plan for a change to infra/ is read
by the platform team.
Prevent agent action until the plan is checked and approved
The platform gives you several independent brakes; combine them according to risk:
| Brake | What it stops |
|---|---|
| Plan-first session or PR | Code generation until a human approves the plan |
| Read-only planning agent | File edits and shell commands during planning |
| Draft pull request | Copilot cloud agent cannot mark its PR ready for review, approve it or merge it |
| "Approve and run workflows" | By default, Actions workflows do not run on Copilot's pushes until someone with write access approves |
| Required checks and reviews (ruleset) | Merging before evidence and approval exist |
| Environment with required reviewers | The job that applies a plan — and its secrets — until approved |
preToolUse hook | Specific tool calls, deterministically, at execution time |
# The agent can prepare the change, but the job that applies it pauses
# until a required reviewer on the "production" environment approves.
jobs:
apply:
runs-on: ubuntu-latest
environment:
name: production # required reviewers + scoped secrets
steps:
- uses: actions/checkout@v7
- run: ./scripts/apply-plan.sh plan.json 1.3 Configure observability and control for autonomous agents
Plan and implement the degree of autonomy
Autonomy is not one switch. It is designed per task from the impact and reversibility of the action, and expressed by combining PR rules, environments, workflow permissions and tool access.
flowchart LR R["Read-only<br/>inspect · summarize · recommend"] --> P["Propose-only<br/>branch and PR, cannot merge"] P --> G["Execute with guardrails<br/>pre-approved workflows, staging"] G --> H["Human-authorized execution<br/>prod deploy · secrets · workflow edits"]
| Task type | Example paths | Risk | Autonomy design |
|---|---|---|---|
| Docs, formatting | docs/, *.md | Low | Auto-merge once required checks (and any configured reviews) pass |
| Code, dependency bumps | src/, lockfiles | Medium | PR + required checks + at least one review |
| Infra, workflows | infra/, .github/workflows/ | High | CODEOWNERS review + multiple approvals + stricter ruleset |
| Production, secrets | Deploy jobs, environment secrets | Critical | Environment approval; the agent prepares but cannot execute |
Teams usually grow autonomy progressively: first the agent may only open PRs; then it may auto-merge low-risk PRs after checks; then deploy to staging; and production only ever through an environment approval. Each phase is earned by evidence that the previous one is reliable. The guardrails page covers the risk classification in depth.
Produce inspectable artifacts in standard tooling
An agent's work must leave evidence in the tools people already use — not in a separate dashboard nobody checks. Copilot cloud agent does much of this by default:
- Session logs show the agent's reasoning and every tool it used; open them from the Agents tab or the PR timeline.
- Commits are authored by Copilot, with the person who started the task as co-author, and are signed ("Verified").
- Every agent commit message links to the session log, so a reviewer or auditor can trace why a change was made.
- The PR description notes which custom agent did the work, and Copilot keeps the title and body up to date as it iterates.
- Blocked network requests are reported as a firewall warning in the PR body or a comment.
- Administrators see audit log events filtered by
actor:Copilot, each carrying anagent_session_id.
For agents you run in workflows, make the evidence yourself: upload reports with actions/upload-artifact,
write a summary to $GITHUB_STEP_SUMMARY, and link the run from the PR's Evidence section.
Configure human intervention without slowing delivery
Human oversight belongs at decision points — merge, deploy, secret access — not at every step. Intervention should be quick, targeted and never require stopping the whole system.
| Intervention | How | Why it keeps velocity |
|---|---|---|
| Steer a running session | Type a follow-up in the session's prompt box on the Agents page | Redirects the agent after its current tool call — no restart |
| Iterate on the PR | Mention @copilot in a review comment (batch comments with Start a review) | Copilot pushes fixes to the same branch |
| Stop a session | Stop session in the log viewer | Ends the Actions run but keeps commits already pushed |
| Route reviews | CODEOWNERS | The right expert sees the change first time |
| Hold low-confidence triage | Automation level: Full control · Cautious · Balanced · Full automation | Only uncertain issue changes wait for a person |
| Evidence-first review | Plan, checks and artifacts in the PR | Reviewers decide quickly instead of re-deriving the context |
Friction is a risk too
Approvals that do not materially reduce risk train reviewers to click "approve" without reading — rubber-stamping. Automate the reversible, low-risk path completely, keep pull requests small, and spend human attention where a mistake would be expensive or irreversible.