Skip to content

⚡ Copilot Token Optimization2026-07-02 — Test Coverage Improver #5808

Description

@github-actions

Target Workflow: test-coverage-improver

Source report: Most recent 📊 Copilot Token Usage Report (label: token-usage-report)
Estimated AIC per run: 197.78 (highest of all 50 runs analyzed)
Run duration: 19.6 minutes (action minutes: 20)
Model: claude-haiku-4-5
GitHub API calls: 10
Most recent run: 28578573634

Note: Raw token counts are unavailable (only the usage artifact was downloaded). AIC is the composite AI Credits metric covering both compute and LLM inference. At 9.9 AIC/min vs a 2.8 AIC/min fleet average, ~72% of cost is LLM inference.

Current Configuration

Setting Value
Tools loaded 5 bash commands (node:*, jest:*, eslint:*, cat:jest.config.js, cat:jest.config.ts); github: toolsets: [repos]
Network groups github only ✅
Pre-agent steps Yes — npm ci, npm run build, npm run test:coverage, coverage extraction, file injection
npm ci cache Missingtest-coverage-reporter.md uses actions/cache, this workflow does not
Coverage cache Missing — coverage is re-computed from scratch every daily run
Target file selection ⚠️ Includes barrel re-exportsdocker-manager.ts (577 bytes, re-export only) and cli.ts (425 bytes) are always selected
Prompt size 3,110 chars (777 tokens base) + ~5,100 chars injected context
Timeout 25 min — only 5.4 min headroom above typical 19.6 min duration

Recommendations

1. Add npm dependency caching (same pattern as test-coverage-reporter.md)

Estimated savings: ~6–8 AIC/run (~3–4%) — 2–3 minutes off npm ci

The sibling workflow test-coverage-reporter.md already caches npm. test-coverage-improver.md runs npm ci in pre-agent steps without any caching, downloading ~500 MB of packages on every daily run.

Change: In .github/workflows/test-coverage-improver.md, add before the Install dependencies step:

steps:
  - name: Cache npm dependencies
    uses: actions/cache
    with:
      path: ~/.npm
      key: npm-${{ hashFiles('package-lock.json') }}
      restore-keys: npm-

  - name: Install dependencies
    run: npm ci

2. Cache coverage results keyed to source hash

Estimated savings: ~20–40 AIC/run average (~10–20%) — skips npm run test:coverage (~5–7 min) on days with no source changes

npm run test:coverage (= jest --coverage) re-instruments all 135 tests every day, even when no .ts files have changed. Most daily runs have no code changes.

Change: Add a actions/cache step wrapping the coverage run:

  - name: Cache coverage results
    id: coverage-cache
    uses: actions/cache
    with:
      path: |
        coverage/coverage-summary.json
        COVERAGE_SUMMARY.md
      key: coverage-${{ hashFiles('src/**/*.ts', 'tests/**/*.ts', 'jest.config.js', 'package-lock.json') }}

  - name: Install dependencies
    run: npm ci

  - name: Build
    run: npm run build

  - name: Run coverage
    id: coverage
    run: |
      if [[ "${{ steps.coverage-cache.outputs.cache-hit }}" == "true" ]]; then
        echo "✅ Using cached coverage results (source unchanged)"
      else
        npm run test:coverage 2>&1 | tail -10
      fi

3. Fix target file selection — avoid barrel re-export stubs

Estimated savings: ~30–50 AIC/run (~15–25%) — eliminates 2–3 extra tool turns per run

The current priority list always selects src/docker-manager.ts (577 bytes, a pure re-export barrel). The agent receives this tiny stub as SOURCE_CONTENT, then must make additional node:* calls to understand the underlying implementations (host-env.ts, config-writer.ts, container-lifecycle.ts, container-cleanup.ts). This wastes 2–3 turns and significant tokens before any test is written.

Coverage data confirms the problem: docker-manager.ts shows 18% coverage of 250 statements — but the file itself has only 24 lines. The 250 statements are the re-exported modules being tracked under the barrel's name.

Change: Replace the priority list in the Select target file and inject content step:

// BEFORE — contains stub barrel files:
const priority = [
  'src/docker-manager.ts',   // 577 bytes, pure re-export — agent gets useless context
  'src/cli.ts',              // 425 bytes, entry point stub — 0% coverage but untestable directly
  'src/host-iptables.ts',
  'src/squid-config.ts',
  'src/domain-patterns.ts'
];

// AFTER — real implementation files with actual code to test:
const priority = [
  'src/host-iptables.ts',         // 83.63% stmt coverage, 55% branch — real iptables logic
  'src/container-lifecycle.ts',   // core container lifecycle (~14 KB of actual code)
  'src/config-writer.ts',         // config generation logic (~12 KB)
  'src/services/agent-service.ts', // agent service setup (~17 KB)
  'src/option-parsers.ts',        // option parsing logic (~11 KB)
];

This ensures the agent always receives a meaningful source file and can write impactful tests on the first try.

4. Remove stale static coverage table from prompt

Estimated savings: ~200 tokens/turn × 3 turns ≈ 600 tokens per run (~1%)

The prompt body contains a hardcoded table:

| File | Expected Coverage | Priority |
|------|-------------------|----------|
| `src/docker-manager.ts` | <20% | High (container lifecycle) |
| `src/cli.ts` | 0% | High (entry point) |
| `src/host-iptables.ts` | ~84% | Medium (edge cases) |

This is duplicated by the dynamically injected ${{ steps.low-coverage.outputs.LOW_COVERAGE }}. As coverage improves, the static table becomes stale and misleading. Remove the entire "Current Coverage Status" static table section.

5. Increase timeout to prevent near-deadline failures

Estimated savings: Reliability (prevents 25-min timeout kills on slow days)

The workflow runs in 19.6 minutes against a 25-minute timeout — only 5.4 minutes of headroom. If npm run test:coverage takes slightly longer or the agent needs one extra jest rerun, the workflow times out and wastes the full 25 compute-minutes.

Change: Increase timeout-minutes from 25 to 35:

timeout-minutes: 35

After applying recommendations 1–2 (caching), expected runtime drops to ~12–14 min on cache-hit days, making 35 min very safe.

Expected Impact

Metric Current Projected Savings
AIC/run 197.78 ~130 ~34%
Monthly AIC (30 runs/mo) ~5,934 ~3,900 ~2,034
Run duration (cache hit) 19.6 min ~12 min ~38%
Run duration (cache miss) 19.6 min ~17 min ~13%
LLM turns wasted on barrel files 2–3 0 100%

Cache hit rate estimate: ~60% of daily runs have no source changes (weekends + unchanged days).

Implementation Checklist

  • Add npm cache step before Install dependencies in steps: (Rec 1)
  • Add coverage cache step wrapping Run coverage in steps: (Rec 2)
  • Replace priority list in Select target file step with implementation files (Rec 3)
  • Remove static coverage table from prompt body (Rec 4)
  • Update timeout-minutes: 35 (Rec 5)
  • Recompile: gh aw compile .github/workflows/test-coverage-improver.md
  • Verify CI passes on a test PR
  • Compare AIC on next daily run vs 197.78 baseline

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

Generated by Daily Copilot Token Optimization Advisor · 152.4 AIC · ⊞ 6.4K ·

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions