GitHub Copilot AI Credits Optimization — Optional Module 4: Agent Fleet Efficiency and Cost Governance — Hands-On Lab Guide

Duration: ~77 minutes of hands-on exercises within the 170-minute module; the optional runnable appendix adds 45 minutes
Format: Design and review exercises with worksheets and answer keys, plus one optional runnable appendix
Audience: Platform and DevEx engineers, automation and SRE-adjacent engineers, Copilot program owners
Repository: No repository is required for the core labs. The optional appendix requires a personal or non-production sandbox repository you own


Lab Overview

This lab guide contains the hands-on work for Optional Module 4 of the GitHub Copilot AI Credits Optimization curriculum. Each lab maps to one workshop section and to one learning objective. Complete them in order — Lab 6 consumes the outputs of Labs 1–5.

Important: Labs 1–6 require no paid AI request, no Copilot license, and no live product access. They are completed with the supplied scenarios, worksheets, and answer keys. Appendix A is optional, bounded, and spends AI credits; it is not required for any learning objective.

Important: All scenarios in this guide are synthetic. Do not use customer repositories, production identities, production queues, or real incident data in any exercise.

Prerequisites

Requirement Applies to Details
Module 2 and Module 3 concepts Labs 1–6 AI credits, token categories, cached input, budgets, durable accepted outcomes
Printed or shared templates Labs 1–6 Printable copies are inlined in Appendix B of this guide; editable sources are in templates/ beside this guide
Pen, worksheet, or text editor Labs 1–6 No product access needed
Copilot CLI installed Appendix A only Verify with copilot --version — this proves installation only
Copilot CLI authenticated Appendix A only Separate step: authenticate with copilot login, or supply COPILOT_GITHUB_TOKEN / GH_TOKEN / GITHUB_TOKEN (that precedence)
Copilot license you are authorized to spend from Appendix A only Appendix A makes a small number of bounded paid calls
Non-production sandbox repository you own Appendix A only Never a customer, production, or shared repository
Approval to spend a small number of AI credits Appendix A only Confirm your budget owner is aware before running
A shell you can copy commands into Appendix A only Appendix A gives PowerShell (Windows-first) commands with a bash alternative for each step

Setup

  1. Open the four templates. Printable copies are inlined in Appendix B of this guide; the editable sources live in the templates/ folder beside it:
    • lane-profile-worksheet.md
    • cache-key-review-worksheet.md
    • failure-taxonomy-worksheet.md
    • canary-scorecard.md
  2. Form pairs or groups of three. Each group needs one person who can describe a real automated workload from their own environment in general terms — no customer names, repository names, or internal figures.
  3. Agree on a shared vocabulary before starting: lane, lane profile, session tax, pre-spend gate, fingerprint, lease, outcome, durable accepted outcome.

Setup Checkpoint

Lab Summary

Lab Workshop section Exercise Time
1 1 — Measure the Fixed Session Tax Session-tax inventory and baseline design 10 min
2 2 — Lane Profiles Design three lane profiles 15 min
3 3 — Isolation and Ownership Two-watcher fleet review 10 min
4 4 — Pre-Spend Gates and Caching Unsafe cache-key review 15 min
5 5 — Runtime Governance Dispatcher outcome taxonomy 15 min
6 6 — Landing, Telemetry, and Rollout Capstone: checklist and canary scorecard 12 min
A Optional Runnable bounded Copilot CLI probes 45 min
B Reference Printable copies of the four templates Not timed

Core hands-on total: 77 min (inside the 170-minute module). Optional appendix A: +45 min. Appendix B is reference material and adds no time.


Lab 1: Session-Tax Inventory and Baseline Design (10 min)

Workshop Section: 1 — Measure the Fixed Session Tax
Objective: Identify what a programmatic invocation pays for before it starts working, and design a baseline experiment that could prove it.

Starting State

You are handed the following lane description. Nothing has been measured.

LANE: nightly-dependency-audit
Runs:        1 invocation per repository per night, 240 repositories
Invocation:  copilot -p "$PROMPT" --allow-all-tools
Working dir: /home/automation/workspaces/monorepo-parent/<repo>
Discovered:  AGENTS.md at the monorepo parent (human onboarding guide, long)
             .github/copilot-instructions.md in each repository (short, mechanical)
             3 MCP servers configured at user scope (issue tracker, wiki, code search)
             2 skills installed at user scope
Model:       not specified
Effort:      not specified
Memory:      not specified
Output:      plain text captured to a log file
Task:        list dependencies with known advisories and open one issue per finding

Steps

  1. (3 min) List every contributor to this lane's session tax. For each, mark it REQUIRED, OPTIONAL, or UNKNOWN for this task, and name the instrument you would use to inspect it.
  2. (3 min) List every unbounded or unspecified element that could change cost from night to night.
  3. (4 min) Write a baseline experiment for one single factor. Specify: probe prompt, pinned configuration, number of repetitions, recorded fields, and the one variable that changes between arms.

Expected Result

A one-page inventory plus a baseline experiment that a colleague could run without asking you a question.

Answer Key

Session-tax contributors

Contributor Verdict Instrument
System prompt and built-in tool definitions REQUIRED /context — System Prompt and System Tools rows
Parent AGENTS.md (human onboarding guide) OPTIONAL — almost certainly not needed by this task /context — Custom Instructions row; copilot plugins list --kind instruction
Repository copilot-instructions.md UNKNOWN — may carry dependency conventions Same as above, plus a quality comparison
Wiki MCP server OPTIONAL — no obvious role in a dependency audit copilot plugins list --kind mcp
Issue-tracker MCP server UNKNOWN — the task opens issues, so it may be the intended path Same
Code-search MCP server UNKNOWN Same
Two user-scope skills UNKNOWN copilot plugins list --kind skill
Memory OPTIONAL — disabled by default in prompt mode; confirm the harness does not enable it Lane profile review

Unbounded or unspecified elements

  • No --model, so the lane inherits a default that can change without review.
  • No --effort, so reasoning depth is unpinned.
  • --allow-all-tools grants full tool permission; there is no visibility restriction at all.
  • No --max-ai-credits, so a single pathological repository has no per-run ceiling.
  • No --no-ask-user, so an unattended run can stall waiting for input.
  • Working directory sits under a parent that carries a long human-oriented instruction file.
  • Advisory output size per repository is unbounded.
  • Plain-text output makes per-run accounting hard; --output-format=json would be machine-readable.

Baseline experiment (example)

  • Probe prompt: Reply with the single word OK.
  • Pinned: one model, --effort low, one working directory, fresh session per run, --no-ask-user, --output-format=json. Do not add -s — it prints only the agent response and suppresses the stats you are trying to measure.
  • Arms: (A) current discovery as-is; (B) identical, plus --disable-builtin-mcps.
  • Repetitions: at least 5 runs per arm; report median and range.
  • Recorded fields: AI credits, input/cached-input/output tokens, latency, outcome, exit status.
  • Second experiment, run separately: repeat the same design with --no-custom-instructions as the single variable. One arm, one variable — never both in the same comparison.
  • Follow-up arm: repeat with 3 representative real repositories to check quality parity before adopting arm B.

Success Criteria

  • ✅ Every contributor is classified REQUIRED, OPTIONAL, or UNKNOWN with a named instrument
  • ✅ At least four unbounded or unspecified elements are identified, including the missing model pin
  • ✅ The baseline experiment changes exactly one variable and specifies repetitions
  • ✅ The plan includes a real-task quality check, not only the trivial probe
  • ✅ No token or credit figure is invented from memory

Lab 2: Design Three Lane Profiles (15 min)

Workshop Section: 2 — Lane Profiles
Objective: Build least-context, least-tool, least-permission profiles and state the evidence required before adopting each reduction.

Starting State

Use the Lane Profile Worksheet (templates/lane-profile-worksheet.md, printable copy in Appendix B). Your fleet has three lanes:

Lane Description
A — Repository audit Read a repository and produce a findings report. Must not modify anything
B — Bounded test fix One failing test named in the work item; a deterministic test command proves success
C — Release-note synthesis Convert a supplied structured changelog into a formatted release note. No repository access required

Steps

  1. (9 min) Complete one worksheet per lane. Fill every field; write UNKNOWN — measure rather than guessing.
  2. (3 min) For each reduction you propose (fewer tools, no MCP servers, no custom instructions, lighter model, lower effort), write the evidence you would require before adopting it in production.
  3. (3 min) Identify the one field in each lane most likely to cause a silent failure if you get it wrong.

Expected Result

Three completed worksheets where every restriction is enforced by a flag, not by prompt wording.

Answer Key

Lane A — Repository audit (read-only)

Field Answer
Tool visibility Read and search tools only, using the tool names your installed CLI reports (verify; do not copy a list)
Tool permission Deny write; deny shell (deny always wins) — this is the enforcement that makes the lane read-only
MCP servers None required; --disable-builtin-mcps unless a finding must be filed through an MCP tool
Custom instructions Only if the report format depends on repository conventions
Model and effort Lighter model, low effort
Credit cap --max-ai-credits set above the CLI minimum of 30
Output --output-format=json plus --share for audit trail (leave -s off anything you measure)
Silent-failure risk A read-only rule stated only in the prompt, or a visibility list whose tool names do not match this version — enforce with --deny-tool

Lane B — Bounded test fix

Field Answer
Tool visibility Read, search, edit, and the specific shell commands the test run needs
Tool permission Allow scoped shell and write; deny shell(git push); deny writes outside the target path
MCP servers Only servers the fix path uses
Custom instructions Yes — the fix must follow repository conventions
Model and effort Mid-tier with a coded escalation rule tied to the deterministic check (one escalation step per fingerprint, recorded in the ledger)
Credit cap Moderate --max-ai-credits (above the CLI minimum of 30); a run that exhausts it is run_cap_exhausted, not an automatic retry
Isolation Isolated worktree or clone per worker, with cleanup
Silent-failure risk Escalation by habit instead of by measured signal; also unverified "fixed" claims without running the test

Lane C — Release-note synthesis

Field Answer
Tool visibility Minimal or none — this is text-to-text
Tool permission Deny write and shell
MCP servers None
Custom instructions Usually none
Model and effort Mid-tier, low effort
Prompt budget Hard cap on changelog size with a visible truncation marker and a context_too_large outcome
Silent-failure risk Unbounded input growth as the changelog accumulates

Evidence required before adopting any reduction

  • A baseline and a reduced arm measured on the same representative task mix.
  • Durable acceptance and human correction time compared, not just tokens or credits.
  • A canary lane, a rollback trigger, and an owner (Lab 6).

Success Criteria

  • ✅ All three worksheets have every field completed or explicitly marked UNKNOWN — measure
  • ✅ Every read-only claim is enforced by a visibility or permission flag
  • ✅ Each proposed reduction has named evidence attached
  • ✅ Lane B specifies an escalation rule that lives in code, not in operator habit
  • ✅ Each lane names its most likely silent-failure field

Lab 3: Two-Watcher Fleet Review (10 min)

Workshop Section: 3 — Isolation, Worktrees, and Concurrent Ownership
Objective: Find inheritance and ownership defects that cause duplicate or misconfigured spend.

Starting State

WATCHER 1: "failing-tests"   — scans all repositories every 10 minutes for failing tests
WATCHER 2: "flaky-tests"     — scans the same repositories every 15 minutes for flaky tests
Both watchers:
  - run as the same automation identity
  - share one checkout at /srv/agents/workspace
  - build the prompt, then invoke Copilot CLI with --allow-all
  - delete the queue item as soon as the CLI exits with status 0
  - have no attempt limit per target
  - were recently moved from /srv/monorepo/tools to /srv/agents to "reduce inherited context"

Steps

  1. (4 min) List every defect you can find. Group them as inheritance, ownership, isolation, or landing defects.
  2. (3 min) For each ownership defect, specify the fingerprint, lease, and dedupe rule that fixes it.
  3. (3 min) Specify the verification step that proves the move to /srv/agents did not silently remove needed configuration.

Expected Result

A defect list with a concrete fix for each, including one verification command.

Answer Key

Defect Category Fix
Both watchers can select the same failing test as a target Ownership Fingerprint on target plus error signature; single-owner time-bounded lease; disjoint scope by construction
No attempt limit per target Ownership Attempt ledger keyed by fingerprint with a hard cap and a parked state
Shared checkout allows workers to corrupt each other's working tree Isolation One worktree or clone per worker with guaranteed cleanup
--allow-all grants full permission for both lanes Isolation / security Replace with explicit --deny-tool rules for everything mutating that the lane must not do, then narrow visibility with --available-tools using tool names verified in this CLI version
The move may have dropped needed MCP servers, instructions, or skills Inheritance Run copilot plugins list from the exact working directory the harness uses and compare against the expected inventory; pass MCP configuration explicitly if it is required
Saved interactive approvals may leak into automation running as the same identity Inheritance Isolate per-lane configuration state (for example, a dedicated COPILOT_HOME per lane — a harness pattern to verify in your environment) and pass permissions per invocation
Deleting the queue item on exit status 0 Landing Acknowledge only after validated, persisted, and consumed output (Section 6); use a distinct signal for "nothing to do"
No per-run credit cap Governance Add --max-ai-credits per lane (minimum 30 in CLI v1.0.79), remembering it is a soft limit in public preview
Shared worktrees or checkouts left behind by killed runs Isolation Unique worktree or clone name per run, cleanup on exit, and a recovery step (git worktree list → git worktree remove → git worktree prune)

Success Criteria

  • ✅ At least six defects identified and categorized
  • ✅ A fingerprint, lease, and dedupe rule specified for the overlap
  • ✅ Per-worker workspace isolation with cleanup specified
  • ✅ The verification step names running the inventory from the harness's actual working directory
  • ✅ The premature acknowledgment defect is identified as a landing problem, not a cost problem

Lab 4: Unsafe Cache-Key Review (15 min)

Workshop Section: 4 — Pre-Spend Gates, Cache Correctness, and Prompt Budgets
Objective: Find cache-key omissions and name the specific wrong result each one can produce.

Starting State

Use the Cache-Key Review Worksheet (templates/cache-key-review-worksheet.md, printable copy in Appendix B). A team ships this cache to avoid re-scoring unchanged files:

CACHE DESIGN v1
  key            = sha256(file_contents)
  value          = { score: int, rationale: string }
  ttl            = none
  negative cache = yes, failures cached like successes
  bypass         = none
  provenance     = none
  invalidation   = manual, by deleting the cache directory
NOTES
  - The scoring rubric lives in prompts/rubric.md and is edited about twice a month
  - The lane recently changed from a lighter model to a mid-tier model
  - Reasoning effort was raised from low to high last week
  - Some entries were written before the team added a "severity" field to the value

Steps

  1. (6 min) List every missing key component and, for each, the specific wrong outcome it can produce.
  2. (5 min) Rewrite the cache design: key components, value schema, provenance, TTL, invalidation, negative-result policy, and bypass.
  3. (4 min) Decide what the system should do when it encounters an entry written before the schema change.

Expected Result

A corrected cache design that a reviewer could approve without further questions.

Answer Key

Missing component Wrong outcome it produces
Fully rendered prompt (including rubric text) After a rubric edit, every unchanged file keeps its old rubric's verdict forever — the most dangerous omission here
Model identifier Verdicts produced by the previous lighter model are served as if produced by the current model
Reasoning effort Low-effort verdicts are served after the lane moved to high effort
Context tier default and long_context results are treated as interchangeable
Tool visibility and permission set A verdict produced without repository access is served for a lane that now has it
MCP configuration Capability differences are invisible in the key
Repository state beyond the single file Verdicts that depend on neighboring files or configuration go stale silently
Harness and CLI version Behavior changes across versions are invisible
TTL Nothing ever expires, so staleness is unbounded
Provenance You cannot audit which configuration produced a stored verdict
Negative-result policy A transient outage is cached as a permanent failure
Bypass No safe way to force a re-run during an incident

Corrected design (example)

CACHE DESIGN v2
  key = sha256(
          rendered_prompt          # includes rubric and template text
        + rubric_version
        + model_id
        + reasoning_effort
        + context_tier
        + tool_visibility_set
        + tool_permission_set
        + mcp_config_hash
        + input_state_hash        # file contents plus relevant neighbors/config
        + harness_version
        + cli_version )
  value       = { schema_version, score, severity, rationale, produced_at, run_id }
  provenance  = { key_components, lane, profile_hash, accepted_later: bool }
  ttl         = 30 days, plus immediate invalidation on any profile change
  negative    = cache deterministic refusals only; never cache service_unavailable
  bypass      = harness --no-cache flag (your runner, not a Copilot CLI option), logged every time it is used
  migration   = entry missing any key component or schema_version -> treat as MISS

Old-schema entries: treat as a miss and re-run. Never infer a missing field, and never serve a value whose schema version is unknown.

Success Criteria

  • ✅ At least eight missing components identified
  • ✅ The rendered-prompt/rubric omission is identified as the highest-severity defect
  • ✅ The corrected key includes model, effort, context tier, tool sets, and versions
  • ✅ Negative caching distinguishes deterministic refusals from transient failures
  • ✅ Missing or unknown key components are treated as a cache miss

Lab 5: Dispatcher Outcome Taxonomy (15 min)

Workshop Section: 5 — Runtime Governance
Objective: Map real run results to outcomes, retry behavior, breaker counting, and queue action.

Starting State

Use the Failure Taxonomy and Breaker Worksheet (templates/failure-taxonomy-worksheet.md, printable copy in Appendix B). Today the dispatcher has exactly two outcomes: ok (exit status 0) and failed (anything else). Failures are retried immediately up to 10 times, and 5 consecutive failures trip a breaker that parks the lane for 7 hours.

Steps

  1. (8 min) Classify each of the nine run results below: outcome name, retry behavior, whether it counts toward the breaker, and queue action.
  2. (4 min) Identify which current behaviors cause a retry storm, a breaker misfire, or silent work loss.
  3. (3 min) Propose the backoff schedule, park window, breaker rule (including how long the breaker stays open), and dead-letter policy you would ship instead.

Run results to classify

  1. The test named in the work item already passes before any model call.
  2. The model edited a file, but the deterministic test still fails.
  3. The CLI returned a permission error because the lane denies write and the task requires it.
  4. The prompt assembler found the diff exceeds the lane's input budget.
  5. The service returned a transient network error after 40 seconds.
  6. The harness budget module refused the call before it was made: the lane's window envelope was already spent.
  7. The lane profile references a model name the CLI does not recognize.
  8. The run succeeded and the report was written, but the consumer directory does not exist.
  9. The run started, consumed nearly all of its per-run --max-ai-credits cap, and stopped mid-task without producing a usable result.

Answer Key

# Outcome Retry Counts toward breaker Queue action
1 already_green No No Acknowledge with reason; record as a free success
2 model_failure Yes, bounded by the attempt ledger Yes Retain, increment attempt
3 policy_denied No No Retain and alert an owner — the profile or the task is wrong
4 context_too_large No — fix the input first No Retain and flag for prompt-budget redesign
5 service_unavailable Yes, with exponential backoff and jitter No Retain
6 budget_refused (pre-spend, no credits used) Not immediately — park the worker No Retain; retry unchanged after the park window; do not increment the attempt counter
7 invalid_config No No Halt the lane and alert; an unrecognized model name is a configuration error to fix, not a condition to retry
8 landing_failed Yes, after the path is resolved No Retain — never acknowledge; this is paid work that did not land
9 run_cap_exhausted (post-spend) Not automatically No Retain; record the spend, increment the attempt counter, and require task decomposition or an explicit reviewed cap decision before another attempt

Current behaviors that break

  • Retry storm: immediate retries with no backoff, plus retrying policy_denied, context_too_large, and invalid_config, which can never succeed on retry.
  • Most expensive retry storm: retrying run_cap_exhausted unchanged — every attempt pays close to the whole cap and lands nothing.
  • Breaker misfire: counting every non-zero exit toward the streak lets routing, budget, and configuration errors trip the breaker and take down a healthy lane.
  • Silent work loss: treating exit status 0 as success acknowledges case 8, where nothing landed.
  • Attempt-ledger corruption: counting case 6 as an attempt eventually dead-letters work that was never actually tried.
  • Throughput loss: a 7-hour park is far longer than most incidents last.

Recommended replacement

  • Backoff: 10m → 20m → 40m with jitter, capped at 40m; maximum 3 attempts per fingerprint.
  • Park on budget_refused for a fixed window (30 minutes is a reasonable start); log one summary line, not one line per item; leave the attempt counter untouched.
  • On run_cap_exhausted: record the spend against the lane, increment the attempt counter, and block further attempts on that fingerprint until the work item is decomposed or the cap is changed by a named owner.
  • Breaker: 5 consecutive model_failure outcomes only; open for 20 minutes, then half-open with exactly one probe item — close on success, reopen for another 20 minutes on failure; alert the lane owner on every trip.
  • Dead-letter after the attempt cap with last outcome, profile hash, and transcript pointer retained.

Success Criteria

  • ✅ All nine results classified with outcome, retry, breaker, and queue action
  • ✅ already_green and context_too_large are excluded from breaker counting
  • ✅ Case 6 and case 9 are given different outcomes, and only case 9 records spend and increments the attempt counter
  • ✅ Case 8 is retained rather than acknowledged
  • ✅ Retry storm, breaker misfire, and silent work loss are each identified with a cause
  • ✅ The proposed backoff, park window, breaker rule (including open duration), and dead-letter policy are specific

Lab 6: Capstone — Fleet Lane Optimization Checklist and Canary Scorecard (12 min)

Workshop Section: 6 — Durable Landing, Telemetry, Canary Rollout, and Capstone
Objective: Produce a canary-ready plan for one real lane, with a quality gate, a rollback trigger, and an owner.

Starting State

Each group picks one anonymized real lane from a member's environment (or Lane A, B, or C from Lab 2 if no real lane is available). You will need your Lab 1–5 outputs.

Steps

  1. (6 min) Complete the Fleet Lane Optimization Checklist section of the canary scorecard (templates/canary-scorecard.md, printable copy in Appendix B) for that lane: profile, gates, governance, landing, telemetry.
  2. (4 min) Complete the Canary Scorecard: the single variable you will change, the baseline you will capture, the quality-parity gate, the cost metric, the rollback trigger, and the owner.
  3. (2 min) Each group reports one line: "Our canary lane is X, our single variable is Y, and we roll back if Z."

Expected Result

One completed scorecard per group, ready to take back to a real backlog.

Answer Key — Model Response

A complete scorecard names all of the following:

  • Canary lane: highest volume with the lowest blast radius and a clear acceptance signal.
  • Single variable: exactly one profile element (for example, disabling two MCP servers that the audit lane never uses).
  • Baseline: median and range for credits, latency, retries, and durable acceptance over a stated window before the change.
  • Quality-parity gate: durable acceptance and human correction time must not regress beyond an agreed tolerance.
  • Cost metric: full cost per durable accepted outcome — not tokens saved.
  • Adversarial review: integration seams, cache-key completeness, flag spelling, exit-code blast radius.
  • Rollback trigger: a specific, pre-agreed threshold and a named person allowed to pull it without a meeting.
  • Deployment verification: restart the worker and confirm the new behavior in live logs.

Success Criteria

  • ✅ The checklist is complete for one specific lane, with unknowns marked UNKNOWN — measure
  • ✅ Exactly one variable is changed in the canary
  • ✅ A quality-parity gate is stated in measurable terms
  • ✅ The cost metric is full cost per durable accepted outcome
  • ✅ A rollback trigger and a named owner are recorded
  • ✅ Deployment verification in live logs is included

Backup Path: Sample Inventory Output (No Product Access)

Use this when the facilitator cannot run copilot plugins list live — no CLI installed, no network, restricted machine, or a demo that failed once. It supports Lab 1 (session-tax inventory) and Lab 3 (verifying what a working directory contributes).

Important: The listing below is illustrative and synthetic. It was written for teaching and is not captured from any customer, production, or personal environment. Real output differs by machine, repository, version, and configuration — never quote counts, names, or costs from it as fact.

Command (illustrative)

$ copilot plugins list

Sample output (illustrative — synthetic, not a real environment)

MCP servers:
  User:
    ✓ issue-tracker     -- http transport
    ✓ wiki-search       -- stdio transport
    ✓ code-search       -- http transport
  Built-in:
    ✗ github-mcp-server -- stdio transport (disabled for this directory)

Skills:
  User:
    ✓ release-notes-formatter  -- Format a structured changelog into release notes.
    ✓ dependency-advisories    -- Summarize dependency advisories for a repository.
  Repository:
    ✓ run-unit-tests           -- Run the repository's unit test command and report failures.
  Built-in:
    ✓ github-pr-media          -- Upload media and embed it in a pull request or comment.

Instructions:
  Repository:
    ✓ .github/copilot-instructions.md
  Working Directory:
    ✓ AGENTS.md
    ✓ team-onboarding.instructions.md

Language servers:
  Repository:
    ✓ typescript-language-server

Plugins:
  User:
    ✓ internal-platform-tools

How to use it in the room

Question to ask What the sample shows
Which of these would a nightly dependency audit actually use? dependency-advisories and possibly issue-tracker; wiki-search, release-notes-formatter, and team-onboarding.instructions.md are candidates for removal
What is grouped by scope, and why does it matter? User scope follows the identity; repository and working-directory scope follow the checkout — moving a worker changes the second group, not the first
What is missing from this inventory? Custom agents and session-scoped hooks are not covered by plugins list; they require a live session
What can this output tell you about cost? Only what is present. It shows no token or credit figures — those must be measured with /context and /usage in your own environment

Note: copilot plugins list performs discovery only and makes no model call, so running it costs nothing when the environment does allow it.


Core Lab Cleanup

Labs 1–6 create no product state. Before leaving:


Core Lab Troubleshooting

Symptom Cause Recovery
A group has no real lane to analyze Audience is pre-automation Use Lane A, B, or C from Lab 2 as the capstone subject
A group argues about exact token overhead numbers Those numbers are environment-specific and unpublished Redirect to the baseline experiment in Lab 1: the answer is measured, not quoted
A group wants to reuse a flag from another agent CLI Different products, different flags Use the "Translating Playbooks From Other Agent CLIs" table in the workshop Appendix
A group finishes early Scenario is smaller than their real system Ask them to add a second lane to the capstone and compare rollback triggers
Disagreement about a flag's current behavior Documentation changes Record it as a verification item; do not settle it by assertion
No CLI, no network, or a live inventory demo fails Environment restriction Switch to Backup Path: Sample Inventory Output above after one attempt; state clearly that the sample is synthetic

Appendix A: Optional Runnable Copilot CLI Probes (45 min)

Optional. Not required for any learning objective. This appendix spends AI credits.

⚠️ Safety and Scope

Rule Why
Use a personal or non-production sandbox repository you own Prevents any change to customer, production, or shared code
Never use a production automation identity Spend and permissions must be attributable to you for this exercise
Confirm spend authorization first This appendix makes a small number of paid calls
Keep every run bounded with --max-ai-credits The cap is a soft limit in public preview — actual usage may slightly exceed it. CLI v1.0.79 rejects values below 30, and GitHub's documentation advises setting limits above 30 because most model calls cost more than 20 AI credits. This appendix uses 40 for every run
Do not grant --allow-all or --yolo These are session-wide permission grants intended for isolated environments only
Treat transcripts as sensitive Session transcripts can contain repository content; store them locally and delete them at cleanup
Do not run --share-gist It publishes a transcript to GitHub.com and is unavailable to EMU and *.ghe.com users
Stop after Exercise A5 The comparison is the objective; do not extend it into real work

Important: Command syntax reflects GitHub documentation verified on 2026-08-12 and copilot help output from CLI v1.0.79. Verify option spellings and values against copilot help for your installed version before running. An unknown option is rejected — the CLI prints error: unknown option '<flag>' and exits non-zero without making a model call. The fail-open risk is a valid flag carrying a wrong or unverified value, which parses cleanly and silently restricts nothing.

Shell note: Commands are given PowerShell-first (Windows), with a bash alternative under each step. Run one or the other consistently — do not mix them in a single run. In PowerShell, output is captured with | Set-Content -Encoding utf8 rather than > so the file encoding is predictable.

Prerequisites Check

Step 1 — Version (proves the CLI is installed; it does not prove authentication)

copilot --version
copilot --version

Step 2 — Authentication (a separate check)

CLI v1.0.79 exposes no non-interactive "auth status" subcommand, so authentication is confirmed either by an interactive login or by the first real run in Exercise A2 failing or succeeding. If you have not authenticated on this machine, do it now:

copilot login
copilot login

Automation-style alternative: export a supported token instead of logging in. The CLI reads COPILOT_GITHUB_TOKEN, then GH_TOKEN, then GITHUB_TOKEN. Never paste a token into a command line that will be captured in a transcript or shell history.

Step 3 — Sandbox repository and clean tree

Set-Location <PATH-TO-YOUR-SANDBOX-REPOSITORY>
git status
cd <PATH-TO-YOUR-SANDBOX-REPOSITORY>
git status

Step 4 — Scratch directory for outputs

New-Item -ItemType Directory -Force -Path .\.module4-probe | Out-Null
mkdir -p ./.module4-probe

Confirm you are in a sandbox repository you own with a clean working tree before continuing.

Setup Checkpoint

  • ✅ copilot --version prints a version (installation confirmed)
  • ✅ You have either completed copilot login or exported a supported token (authentication addressed separately from version)
  • ✅ You are inside a non-production sandbox repository you own, and git status shows a clean tree
  • ✅ You have spend authorization and know your credit cap for this exercise
  • ✅ The scratch directory ./.module4-probe exists

Exercise A1 — Establish the Zero-Cost Inventory (8 min)

Objective: See exactly what this working directory would contribute to a session, without making a model call.

  1. Run the inventory from the directory your automation would use:

    copilot plugins list
    
    copilot plugins list
    
  2. Capture a machine-readable copy:

    copilot plugins list --json | Set-Content -Encoding utf8 .\.module4-probe\inventory-before.json
    
    copilot plugins list --json > ./.module4-probe/inventory-before.json
    
  3. Inspect only MCP servers and instruction sources:

    copilot plugins list --kind mcp --kind instruction
    
    copilot plugins list --kind mcp --kind instruction
    

Expected result: A grouped listing by kind and configuration scope. copilot plugins list performs discovery and does not make a model call. If you cannot run it, use the Backup Path: Sample Inventory Output section earlier in this guide — the sample is illustrative and synthetic.

Checkpoint: You can name every MCP server, skill, plugin, and instruction source this directory would contribute — and identify at least one your automation would not need.

Note: Custom agents and session-scoped hooks are not covered by copilot plugins list; they require a live session. Do not treat this inventory as complete evidence of everything a session loads.

Success criteria

  • ✅ Inventory captured to inventory-before.json
  • ✅ At least one discovered resource identified as unnecessary for a hypothetical audit lane
  • ✅ No model call was made in this exercise

Exercise A2 — Run a Bounded Baseline Probe (12 min)

Objective: Measure a minimal invocation with everything pinned and bounded.

Warning: This step spends AI credits. The cap is set to 40: CLI v1.0.79 rejects anything below 30, and GitHub's documentation advises setting session limits above 30 because most model calls cost more than 20 AI credits. Do not raise it if the run stops — a stop is the control working.

Note: -s (--silent) is deliberately omitted. It prints only the agent response and suppresses run stats, which is the opposite of what a measurement probe needs. Add it only in a production lane where you have proven the JSONL channel carries the fields you depend on.

  1. Run the baseline probe:

    copilot -p "Reply with the single word OK." `
      --no-ask-user `
      --model claude-haiku-4.5 `
      --max-ai-credits 40 `
      --output-format=json `
      --share .\.module4-probe\baseline-transcript.md |
      Set-Content -Encoding utf8 .\.module4-probe\baseline.jsonl
    
    copilot -p "Reply with the single word OK." \
      --no-ask-user \
      --model claude-haiku-4.5 \
      --max-ai-credits 40 \
      --output-format=json \
      --share ./.module4-probe/baseline-transcript.md \
      > ./.module4-probe/baseline.jsonl
    
  2. Inspect the JSONL output:

    Get-Content .\.module4-probe\baseline.jsonl -TotalCount 5
    
    head -n 5 ./.module4-probe/baseline.jsonl
    
  3. Inspect the transcript:

    Get-Content .\.module4-probe\baseline-transcript.md -TotalCount 40
    
    head -n 40 ./.module4-probe/baseline-transcript.md
    
  4. Record what your version actually reports: which fields exist, and whether any of them expose per-call cost.

Expected result: A completed run, a JSONL file, and a Markdown transcript.

Checkpoint: You can state, from evidence rather than assumption, which usage fields your installed CLI emits.

Note: --model values change over time and differ by plan and host. If the model string above is not available in your environment, substitute a lightweight model you know is available and record the substitution. Treat an unrecognized model name as a configuration error to fix — do not assume the CLI substitutes another model for you; that behavior is unverified and sits in the workshop's claim ledger.

Success criteria

  • ✅ The run completed within the credit cap
  • ✅ baseline.jsonl exists and was inspected
  • ✅ A transcript was written locally (not to a gist)
  • ✅ You recorded which usage fields are present, rather than assuming

Exercise A3 — Run a Single-Variable Comparison (12 min)

Objective: Change exactly one factor and observe the difference.

The only difference between this arm and Exercise A2 is --disable-builtin-mcps. Everything else — prompt, model, credit cap, and output format — stays identical, which is what makes the two runs comparable.

  1. Run the same probe with built-in MCP servers disabled:

    copilot -p "Reply with the single word OK." `
      --no-ask-user `
      --model claude-haiku-4.5 `
      --max-ai-credits 40 `
      --disable-builtin-mcps `
      --output-format=json `
      --share .\.module4-probe\reduced-transcript.md |
      Set-Content -Encoding utf8 .\.module4-probe\reduced.jsonl
    
    copilot -p "Reply with the single word OK." \
      --no-ask-user \
      --model claude-haiku-4.5 \
      --max-ai-credits 40 \
      --disable-builtin-mcps \
      --output-format=json \
      --share ./.module4-probe/reduced-transcript.md \
      > ./.module4-probe/reduced.jsonl
    
  2. Compare the first 60 lines of each transcript. Write both extracts to files first — no process substitution, so the same approach works in both shells:

    Get-Content .\.module4-probe\baseline-transcript.md -TotalCount 60 |
      Set-Content -Encoding utf8 .\.module4-probe\baseline-head.txt
    Get-Content .\.module4-probe\reduced-transcript.md -TotalCount 60 |
      Set-Content -Encoding utf8 .\.module4-probe\reduced-head.txt
    Compare-Object (Get-Content .\.module4-probe\baseline-head.txt) (Get-Content .\.module4-probe\reduced-head.txt)
    
    head -n 60 ./.module4-probe/baseline-transcript.md > ./.module4-probe/baseline-head.txt
    head -n 60 ./.module4-probe/reduced-transcript.md > ./.module4-probe/reduced-head.txt
    diff ./.module4-probe/baseline-head.txt ./.module4-probe/reduced-head.txt
    
  3. Record credits, latency, and any visible context differences for both arms.

Expected result: Two runs that differ by exactly one configuration element.

Checkpoint: You can state what changed between arms and what you still cannot see from this evidence.

Important: This comparison measures session tax on a trivial prompt only, and one run per arm is an anecdote — the workshop's baseline design calls for repetitions with median and range. It is not evidence that the reduced profile solves real tasks. Adopting it in production requires the quality-parity gate from Lab 6.

Note: Testing a second reduction (for example --no-custom-instructions) requires another arm run separately. Changing two things at once produces a result nobody can attribute — that is the defect this exercise exists to prevent. If time allows and you have spend authorization, run it as an additional arm and record it separately; otherwise write it down as a follow-up.

Success criteria

  • ✅ Exactly one factor changed between the A2 and A3 arms
  • ✅ Both runs used identical model, cap, and output format
  • ✅ Both runs stayed within their credit caps
  • ✅ Differences recorded as observations, not conclusions
  • ✅ You stated explicitly what this evidence does not prove

Exercise A4 — Verify a Permission Restriction Empirically (8 min)

Objective: Prove that a restriction you configured is actually in effect — using permission denial, which uses identifiers the CLI itself documents.

The run below keeps the same model, cap, and output format as A2 and A3 so its output is comparable with them. Reasoning effort remains a lane-profile decision, but this probe does not set it because support varies by model.

  1. Ask the agent to describe its tools while write and shell are denied:

    copilot -p "List the names of the tools you can use. Do not use any tool to answer." `
      --no-ask-user `
      --model claude-haiku-4.5 `
      --max-ai-credits 40 `
      --deny-tool 'write' --deny-tool 'shell' `
      --output-format=json `
      --share .\.module4-probe\exclusion-transcript.md |
      Set-Content -Encoding utf8 .\.module4-probe\exclusion.jsonl
    
    copilot -p "List the names of the tools you can use. Do not use any tool to answer." \
      --no-ask-user \
      --model claude-haiku-4.5 \
      --max-ai-credits 40 \
      --deny-tool 'write' --deny-tool 'shell' \
      --output-format=json \
      --share ./.module4-probe/exclusion-transcript.md \
      > ./.module4-probe/exclusion.jsonl
    
  2. Compare the response and transcript against your intent.

  3. Optional, visibility layer: if you want to test --available-tools, first discover the tool names your installed version actually uses (from this run's output or an interactive session), then add --available-tools '<NAME>,<NAME>' with those exact names. Do not copy a tool list from a slide or another product — an unmatched name parses fine and restricts nothing.

Expected result: Evidence about which tools the model reports as available under your restriction.

Checkpoint: You have first-hand evidence rather than a belief about your restriction.

Important: A model's self-report is corroborating evidence, not proof. The authoritative check is the enforcement behavior itself: a denied tool cannot run, and deny always wins over allow, --allow-all, and saved approvals. Treat any mismatch between intent and observation as a configuration bug to investigate, and verify option spelling and values with copilot help.

Success criteria

  • ✅ The run completed within its credit cap
  • ✅ The run used the same model, effort, cap, and output format as A2 and A3
  • ✅ You compared the observed tool list against your intended restriction
  • ✅ Any tool name you used with --available-tools came from your own environment, not from a copied list
  • ✅ Any mismatch was recorded as a follow-up, not explained away

Exercise A5 — Record Findings and Stop (5 min)

  1. Write four lines in your notes:
    • What the inventory showed that you did not expect.
    • What the baseline arm cost and how long it took.
    • What changed in the reduced arm.
    • What you still cannot determine without a real-task comparison.
  2. Add any documentation mismatch you found to your team's verification backlog.
  3. Stop here. Do not extend these probes into real work in this session.

Success criteria

  • ✅ Four findings recorded
  • ✅ At least one open verification question written down
  • ✅ No further paid runs started

Appendix A Cleanup

  1. Remove local transcripts and outputs:

    Remove-Item -Recurse -Force .\.module4-probe
    
    rm -rf ./.module4-probe
    
  2. Confirm no repository changes were made:

    git status
    
    git status
    
  3. Check for stray Git worktrees. These exercises do not create any, but a killed run in your own automation can, and worktrees are shared Git state that outlives the process:

    git worktree list
    Get-ChildItem -Directory -Filter "*.worktrees" -Path .. -ErrorAction SilentlyContinue
    
    git worktree list
    ls -d ../*.worktrees 2>/dev/null
    

    If an abandoned worktree appears, remove it and prune the metadata (add --force only when you are certain no process is using it):

    git worktree remove <PATH-TO-WORKTREE>
    git worktree prune
    
    git worktree remove <PATH-TO-WORKTREE>
    git worktree prune
    
  4. Confirm no session artifacts were published externally (you did not run --share-gist).

  5. Confirm your total spend against your authorized cap.

Cleanup success criteria

  • ✅ ./.module4-probe removed
  • ✅ git status shows a clean working tree
  • ✅ git worktree list shows only the worktrees you expect
  • ✅ No gist or external share was created
  • ✅ Spend reconciled against the cap you agreed before starting

Appendix A Troubleshooting

Symptom Likely cause Recovery
copilot: command not found / The term 'copilot' is not recognized CLI not installed or not on PATH Install Copilot CLI, or skip the appendix — it is optional
The run stops citing the credit limit The soft cap was reached This is the control working. Do not raise the cap; record the observation as run_cap_exhausted and note that credits were spent
Use at least 30 AI credits A --max-ai-credits value below the CLI minimum Use the appendix value of 40; the minimum accepted by CLI v1.0.79 is 30
Authentication error Not logged in, or the wrong host for your enterprise Run copilot login (add --host https://<your-host> for data residency), or export COPILOT_GITHUB_TOKEN; never paste a token into a command line
error: unknown option '<flag>' Option names differ in your installed version The CLI rejects unknown options and makes no model call. Run copilot help, use the current spelling, and record the discrepancy as a documentation-drift finding
The restriction appears to have no effect A valid flag with an unmatched value (tool name, pattern, or server name) Re-check the value against your environment, not the documentation alone; prefer --deny-tool 'write' / --deny-tool 'shell' for enforcement and record the mismatch
Error or unexpected behavior when pinning reasoning effort Configurable reasoning is available only for supported models Remove --effort, or choose a model documented to support configurable reasoning; record which model you used
Model string not available Model availability changes over time and by plan and host Substitute a lightweight model available to you and record the substitution; treat an unrecognized model name as a configuration error, not as something the CLI will silently work around
The run reports it cannot use tools in non-interactive mode Non-interactive runs need an explicit tool-permission grant in some versions These probes need no tool. If your version requires a grant, use --allow-all-tools together with --deny-tool 'write' --deny-tool 'shell' (deny always wins) — never --allow-all or --yolo
Output file is empty Redirection, encoding, or format mismatch Re-run without redirection to see the output in the terminal, then re-add flags one at a time. In PowerShell prefer | Set-Content -Encoding utf8 <path> over >
PowerShell reports a parsing error on a multi-line command Backtick line continuations require no trailing spaces Paste the command as a single line, or re-copy it; do not mix bash \ continuations into PowerShell
The agent asks a clarifying question --no-ask-user omitted Cancel, add --no-ask-user, and re-run
A worktree or scratch directory is left behind after a cancelled run Cleanup did not execute Follow the cleanup steps above: remove ./.module4-probe, then git worktree list → git worktree remove → git worktree prune

Appendix B: Printable Templates

Why this appendix exists: the published site renders this lab guide but does not publish the templates/ folder. The four worksheets are therefore reproduced here in full so that every learner — including anyone reading the published lab without repository access — can print or copy them. The files in templates/ remain the editable sources; the copies below must be kept identical to them.

Template Used in Source file
B1 — Lane Profile Worksheet Lab 2 templates/lane-profile-worksheet.md
B2 — Cache-Key Review Worksheet Lab 4 templates/cache-key-review-worksheet.md
B3 — Failure Taxonomy and Breaker Worksheet Lab 5 templates/failure-taxonomy-worksheet.md
B4 — Fleet Lane Optimization Checklist and Canary Scorecard Lab 6 capstone templates/canary-scorecard.md

Note: Appendix B is reference material. It adds no time to the 77-minute core lab total or to the optional 45-minute Appendix A.


B1 — Lane Profile Worksheet

Used in: Lab 2 — one copy per lane. Source file: templates/lane-profile-worksheet.md.

Complete one worksheet per lane. Write UNKNOWN — measure rather than guessing. Every restriction must be enforced by a flag or harness control, never by prompt wording alone.


Lane name: ___________________________________

Owner: ___________________________________ Review date: _______________

Verified against Copilot CLI docs on: _______________


1. Purpose

Field Value
Task shape (one shape per lane)
Definition of done (stop condition)
Deterministic check that proves success
Invocation volume per window
Blast radius if this lane misbehaves

2. Model and Reasoning

Field Control Value Justification
Model --model / COPILOT_MODEL (auto carries a documented 10% model-cost discount on paid plans)
Reasoning effort --effort / --reasoning-effort (none, minimal, low, medium, high, xhigh, max in CLI v1.0.79)
Context window tier --context (default | long_context)
Escalation rule (in code, on a measured signal) Harness
Escalation ceiling (steps per fingerprint) and where it is recorded Harness ledger

3. Tools and Permissions

Visibility (--available-tools / --excluded-tools) controls what the model can choose from, and its values are version- and configuration-specific — verify the tool names in your own environment. Permission (--allow-tool / --deny-tool) controls what may run. Deny always wins, and it is the enforcement layer for any "must not modify" rule.

Field Control Value
Tools visible to the model (names verified in this CLI version ☐) --available-tools
Tools excluded --excluded-tools
Tools permitted without prompting --allow-tool
Tools denied outright --deny-tool
Directory scope -C, --add-dir
URL scope --allow-url, --deny-url
Temp directory --disallow-temp-dir

Read-only claim check: Is every "must not modify" statement enforced by a flag? ☐ Yes ☐ No


4. Context Sources

Field Control Value Evidence it is needed
MCP servers enabled --disable-builtin-mcps, --disable-mcp-server, --additional-mcp-config
GitHub MCP tool scope --add-github-mcp-toolset, --add-github-mcp-tool
Custom instructions --no-custom-instructions, COPILOT_CUSTOM_INSTRUCTIONS_DIRS
Memory --enable-memory (off by default in prompt mode)
Discovered inventory verified from the harness working directory copilot plugins list ☐ Yes ☐ No

5. Spend and Fan-Out Controls

Field Control Value
Per-run credit cap (soft limit, public preview; minimum 30 in CLI v1.0.79) --max-ai-credits
Subagent concurrency cap Harness scheduler (no supported CLI environment variable listed in v1.0.79 help)
Subagent depth cap Harness scheduler
Run wait timeout / watchdog Harness
Parallel workers per lane Harness
Attempts per fingerprint Harness attempt ledger
Behavior when a run exhausts its cap (run_cap_exhausted) Harness — record spend, increment attempt, require decomposition or a reviewed cap change

6. Isolation

Field Control Value Status note
Working directory -C Documented
Configuration/state directory COPILOT_HOME Documented variable; per-lane use is a harness pattern
Worktree isolation --worktree Experimental (not listed in v1.0.79 top-level help) — fallback:
Shell sandbox --sandbox Experimental — fallback (generic engineering practice, not a Copilot control):
Secret redaction --secret-env-vars Documented
Cleanup rule and owner Harness
Stray-worktree recovery step (git worktree list → remove → prune) Runbook

7. Output and Interaction Contract

Field Control Value
Output format --output-format=json (-s suppresses stats — keep it off measurement runs)
Transcript capture and retention --share=PATH
External sharing (default: none) --share-gist — avoid; unavailable to EMU and *.ghe.com
No clarifying questions --no-ask-user
Exit-status contract (success / no-op / failure) Harness

8. Reduction Log

Record every reduction from the current profile and the evidence required before adoption.

Reduction Expected saving Evidence required Canary lane Decision

9. Sign-Off

Check Status
Every field completed or marked UNKNOWN — measure ☐
Every restriction enforced by a control, not prompt text ☐
Flag values (tool names, patterns, server names) verified in this environment, not copied ☐
Preview/experimental controls have a stated fallback ☐
Permission changes reviewed as security changes ☐
Profile committed with the code that references it ☐

Reviewer: ___________________________________ Date: _______________



B2 — Cache-Key Review Worksheet

Used in: Lab 4 — one copy per cache. Source file: templates/cache-key-review-worksheet.md.

A cache that omits an input which can change the answer will confidently serve a wrong result, and the failure looks like a saving in cost reporting. Review every cache in front of a paid call with this worksheet.


Cache name: ___________________________________

Lane(s) served: ___________________________________

Reviewer: ___________________________________ Date: _______________


1. Key Completeness

Component Included? If missing, the specific wrong result it can produce
Fully rendered prompt (template, rubric, and instruction text) ☐
Instruction / rubric version ☐
Model identifier ☐
Reasoning effort ☐
Context window tier (default / long_context) ☐
Tool visibility set ☐
Tool permission set ☐
MCP server configuration ☐
Relevant repository/input state (commit SHA or content hash) ☐
Harness version ☐
Copilot CLI version ☐
Other lane-specific inputs: ____________________ ☐

Highest-severity omission found: ___________________________________


2. Value and Provenance

Field Present? Notes
Value schema version ☐
Result payload fully specified ☐
Produced-at timestamp ☐
Run ID ☐
Lane and profile hash ☐
Later accepted / rejected flag ☐

3. Lifecycle Policy

Policy Decision
TTL
Invalidation triggers (profile change, rubric change, version bump)
Behavior when a key component is missing from an old entry Must be cache miss — confirm ☐
Behavior when the value schema version is unknown Must be cache miss — confirm ☐
Negative-result policy: deterministic refusals
Negative-result policy: transient failures (must not be cached) Confirm ☐
Documented bypass flag (implemented in your harness, not a Copilot CLI option)
Bypass usage logged every time Confirm ☐

4. Gate Ladder Placement

Where does this cache sit relative to the other pre-spend gates?

Order Gate Present in this lane? Notes
1 Configuration validation ☐
2 Ownership lease ☐
3 Skip-if-done ☐
4 Baseline probe ☐
5 Attempt ledger ☐
6 Result cache ☐
7 Budget check (pre-spend — refusal is budget_refused, no credits spent) ☐

Is any gate optimistic (assumes done when uncertain)? ☐ Yes ☐ No — if yes, fix it to fail toward spending.


5. Prompt Budget Review (same input path)

Check Status
Every growing field has a hard cap ☐
Truncation is visible in the prompt (...[truncated]) ☐
Trim-to-budget drops sections in a defined priority order ☐
Oversized input produces a distinct context_too_large outcome instead of a call ☐
Files are referenced by path rather than inlined where the lane can read them ☐
Tool-output size behavior reviewed (documented default: output over 20 KiB is written to a file and previewed) ☐
Harness-level input caps defined, independent of any CLI threshold variable ☐

6. Corrected Design

CACHE DESIGN v__
  key         =
  value       =
  provenance  =
  ttl         =
  negative    =
  bypass      =
  migration   =

7. Sign-Off

Check Status
Every key component reviewed with a stated failure mode ☐
Missing or unknown components treated as a miss ☐
Transient failures excluded from negative caching ☐
Bypass exists and is logged ☐
Change reviewed as a correctness change, not an optimization ☐


B3 — Failure Taxonomy and Breaker Worksheet

Used in: Lab 5 — one copy per lane. Source file: templates/failure-taxonomy-worksheet.md.

Most dispatcher defects come from one mistake: treating every non-success as "the model failed." Use this worksheet to classify outcomes and to size retries, parking, breakers, and dead-lettering.


Lane name: ___________________________________

Owner: ___________________________________ Date: _______________


1. Outcome Map

Fill one row per outcome your dispatcher can produce. The first ten are the recommended baseline set. Note that a pre-spend refusal and a post-spend cap exhaustion are different outcomes with different consequences.

Outcome Detected by Retry? Backoff Counts toward breaker? Attempt counter Queue action Alert?
success No — No — Acknowledge and remove No
already_done / already_green No — No — Acknowledge with reason No
model_failure Bounded Exponential + jitter Yes Increment Retain, increment attempt On breaker trip
context_too_large No — No — Retain, flag for redesign Yes
policy_denied No — No — Retain, alert owner Yes
service_unavailable Yes Exponential + jitter No — Retain On sustained failure
budget_refused (pre-spend; no credits used) After park window Fixed park No Do not increment Retain One summary line
run_cap_exhausted (post-spend; credits used) Not automatically — requires decomposition or a reviewed cap change Blocked, not timed No Increment Retain, blocked until the work or cap changes Yes — to the lane owner
invalid_config No — No — Halt lane Yes
landing_failed Yes, after fix Exponential No Increment Retain — never acknowledge Yes
Other: ______________

Spend accounting check: does every run_cap_exhausted outcome record the credits actually consumed against the lane? ☐ Yes ☐ No


2. Retry and Backoff Design

Parameter Value Rationale
Maximum attempts per fingerprint
Backoff schedule
Jitter
Backoff cap
Park window on budget refusal (pre-spend)
Required change before retrying after run_cap_exhausted (decompose / re-lane / reviewed cap change)
Log volume per park event (target: one summary line)

3. Breaker Design

Parameter Value
Outcomes counted toward the streak (should be model_failure only)
Consecutive failures to trip
Open duration (a defensible default is 20 minutes — long enough to clear a blip, short enough to protect throughput)
Half-open probe policy (exactly one item; close on success, reopen for another full window on failure)
Reset condition
Who is alerted when it trips

Check: Could a routing, policy, budget, cap-exhaustion, configuration, or already-done outcome trip this breaker? ☐ Yes ☐ No If yes, the breaker will punish the model for the dispatcher's mistakes — fix before shipping.


4. Dead-Letter Policy

Field retained with a dead-lettered item Present?
Last outcome and error detail ☐
Attempt history ☐
Lane and profile hash ☐
Transcript pointer ☐
Fingerprint and lease history ☐
Owner responsible for triage ☐

Rule: an item that exhausts its attempts is moved, never deleted. Confirm ☐


5. Layered Budget Check

Layer Control Configured value Enforced by
Enterprise / organization / cost center Spending budgets, user-level budgets GitHub
Fleet envelope Credits per lane per window Harness check() before every paid call
Run --max-ai-credits (soft, public preview, minimum 30 in CLI v1.0.79) Copilot CLI
Fan-out Subagent concurrency and depth caps Harness scheduler (no supported CLI environment variable in v1.0.79 help)
Worker concurrency Parallel workers per lane Scheduler
Retries Attempts per fingerprint Attempt ledger

Honest accounting check: when one task fans out into N model calls, does the ledger record N? ☐ Yes ☐ No


6. Failure-Mode Review

Risk Present today? Mitigation
Retry storm (immediate retries, or retrying non-retryable outcomes) ☐
Automatic retry after run_cap_exhausted (pays the cap again and lands nothing) ☐
Breaker misfire (non-model outcomes counted) ☐
Attempt-ledger corruption (pre-spend refusals counted as attempts) ☐
Silent work loss (acknowledging on ambiguous success) ☐
Refusal log flood (per-item refusal logging) ☐
Invisible spend (a lane that bypasses the budget module) ☐
Park window longer than typical incident duration ☐


B4 — Fleet Lane Optimization Checklist and Canary Scorecard

Used in: Lab 6 capstone — one copy per lane. Source file: templates/canary-scorecard.md.

Use Part 1 to confirm a lane is ready to change. Use Part 2 to run the change like a production deployment.


Lane name: ___________________________________

Owner: ___________________________________ Date: _______________


Part 1 — Fleet Lane Optimization Checklist

1.1 Measurement
Check Status Evidence
Session tax contributors inventoried for the harness working directory ☐
Baseline captured with median and range (not a single run) ☐
Baseline includes a representative real-task arm, not only a trivial probe ☐
Recorded fields include credits, tokens, latency, retries, outcome ☐
1.2 Lane Profile
Check Status
Model, effort, and context tier pinned explicitly ☐
Tool visibility restricted to what the lane needs ☐
Tool permissions least-privilege; deny rules present for anything the lane must never do ☐
MCP servers and instruction sources justified or disabled ☐
Memory intentionally decided (off by default in prompt mode) ☐
Per-run credit cap set (soft limit, public preview; minimum 30 in CLI v1.0.79) ☐
--no-ask-user set for unattended runs ☐
Flag values (tool names, patterns, MCP server names) verified in this environment ☐
Preview/experimental controls have a documented fallback ☐
1.3 Isolation and Ownership
Check Status
Working directory and configuration paths resolved relative to the harness ☐
Per-worker workspace isolation with a unique name, a cleanup rule, and an owner ☐
Work fingerprint defined ☐
Single-owner lease with expiry ☐
Scopes disjoint by construction ☐
Attempt ledger with a hard cap ☐
1.4 Pre-Spend Gates
Check Status
Configuration validation before spend ☐
Skip-if-done with an explicit force override ☐
Baseline probe runs before the paid call ☐
Cache key complete and reviewed ☐
Prompt budget enforced with visible truncation and a context_too_large outcome ☐
Gates fail toward spending when uncertain ☐
1.5 Runtime Governance
Check Status
Every paid call passes through one budget check() and record() ☐
Fan-out recorded honestly (N calls recorded as N) ☐
Outcome taxonomy implemented, including separate budget_refused (pre-spend) and run_cap_exhausted (post-spend) outcomes ☐
Backoff with jitter; no immediate retries; no automatic retry after run_cap_exhausted ☐
Breaker counts model failures only, with a stated open duration and single-probe half-open ☐
Refusals park the worker and log one summary line ☐
Dead-letter retains context ☐
1.6 Landing and Telemetry
Check Status
Output validated before acknowledgment ☐
Atomic write or verified merge ☐
Distinct signal for success, no-op, and failure ☐
Exit-code changes traced through every caller ☐
Downstream consumer confirmed to read the output ☐
Provenance recorded (lane, run ID, profile hash, model, cache status) ☐
Durable acceptance recorded after the stabilization period ☐
Worker restarted and new behavior confirmed in live logs ☐

Part 2 — Canary Scorecard

2.1 Change Definition
Field Value
Canary lane (highest volume, lowest blast radius, clear acceptance signal)
Single variable being changed
Everything explicitly held constant
Expected effect and mechanism
Reviewer for the change
2.2 Baseline (before the change)
Metric Median Range Window
AI credits per invocation
Latency per invocation
Retries per accepted outcome
Human correction time per accepted outcome
Durable acceptance rate
Full cost per durable accepted outcome
2.3 Canary Result (after the change)
Metric Median Range Delta vs. baseline
AI credits per invocation
Latency per invocation
Retries per accepted outcome
Human correction time per accepted outcome
Durable acceptance rate
Full cost per durable accepted outcome
2.4 Gates
Gate Pass condition Result
Baseline captured Median and range recorded before the change ☐ Pass ☐ Fail
Single variable Exactly one profile element changed ☐ Pass ☐ Fail
Quality parity Durable acceptance and human correction do not regress beyond tolerance: ______ ☐ Pass ☐ Fail
Cost improvement Full cost per durable accepted outcome improves ☐ Pass ☐ Fail
Adversarial review Integration seams, cache-key completeness, flag spelling and flag values, exit-code blast radius all reviewed ☐ Pass ☐ Fail
Deployed and verified New behavior confirmed in live logs after restart ☐ Pass ☐ Fail
2.5 Rollback
Field Value
Rollback trigger (specific, pre-agreed threshold)
Person allowed to roll back without a meeting
Rollback procedure and expected time to restore
How the rollback is verified
2.6 Expansion
Field Value
Next lane to receive the change
Minimum observation window before expanding
Who signs off on expansion
Re-verification date for preview/experimental controls used

Report line: "Our canary lane is __________, our single variable is __________, and we roll back if __________."




Lab guide for GitHub Copilot AI Credits Optimization — Optional Module 4: Agent Fleet Efficiency and Cost Governance (optional; not counted in the 7-hour-10-minute core curriculum)