Skip to content

Track skill usage in audit artifacts - #63688

Merged
pelikhan merged 6 commits into
mainfrom
copilot/task-9919-1036865607-ca3f0885-26de-462e-8253-7d4ecc7be8ae
Sep 26, 2026
Merged

pelikhan merged 6 commits into
mainfrom
copilot/task-9919-1036865607-ca3f0885-26de-462e-8253-7d4ecc7be8ae

Conversation

Copilot AI commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Skill invocations were only available in full agent traces, preventing lightweight audit analysis. This change aggregates named skill usage into compact usage artifacts and exposes it through audit output.

  • Usage collection

    • Detect skill tool calls in Copilot session events.
    • Aggregate invocation and failure counts with first/last timestamps.
  • Audit integration

    • Backfill skill activations from compact usage data.
    • Report named skills as skill:<name> tools.
    • Preserve aggregates through cached audit summaries.
  • Schema

    • Add invocation_count and failed_count to audit and JSONL skill activation records.
{
  "skills": {
    "total_invocations": 2,
    "unique_skills": 1,
    "items": [{
      "name": "documentation",
      "invocation_count": 2,
      "failed_count": 0
    }]
  }
}

Branch refresh requested by pr-sous-chef run https://github.com/github/gh-aw/actions/runs/36277822788

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 16.5 AIC · ⌖ 8.7 AIC · ⊞ 9.7K · ◷
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI requested a review from pelikhan September 26, 2026 22:43
@pelikhan
pelikhan marked this pull request as ready for review September 26, 2026 22:47
Copilot AI balanced review requested due to automatic review settings September 26, 2026 22:47
@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Generated by Ponytail Reviewer for #63688

@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ponytail pass complete: one meaningful simplification opportunity found in tool-usage merging logic; everything else looks appropriately scoped.

net: -12 lines possible.

Generated by ✂️ Ponytail Reviewer for #63688 · codex · gpt53codex · 4.4 AIC · ⌖ 2.76 AIC · ⊞ 12.5K
Comment /ponytail to run again

Comments that could not be inline-anchored

pkg/cli/audit_report.go:64

pkg/cli/audit_report.go:L64: shrink: two-pass merge/delete for skill counts in buildAuditToolUsage. append per activation directly to usage map/slice in one pass, then materialize once.

@github-actions

Copy link
Copy Markdown
Contributor
🏗️ ADR required

An ADR was required for this PR because it adds 169 lines in default business-logic directories, exceeding the 100-line enforcement threshold.

Evidence reviewed

  • PR title: Track skill usage in audit artifacts
  • PR description: introduces compact skill-usage aggregation and audit exposure
  • Changed implementation files include pkg/cli/audit_report.go, pkg/cli/logs_usage_activity.go, and actions/setup/js/generate_usage_activity_summary.cjs
  • Existing ADR reviewed: docs/adr/63664-surface-awf-steering-counters-in-compact-usage-data.md

Gate result

  • No existing ADR in the PR body or branch was found for this decision.
  • I drafted and added docs/adr/63688-track-skill-usage-in-audit-artifacts.md to this PR branch.

Next action

  • Review and refine the new draft ADR so it accurately captures the intended decision and trade-offs before merge.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · pi · gpt54 · 18 AIC · ⌖ 10.5 AIC · ⊞ 9.9K · ◷
Comment /review to run again

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Fresh audit paths lose compact skill aggregates, while no-ID failures and cross-file timestamps are recorded incorrectly.

Review effort: Balanced
Findings: 4 Medium severity

Open (4)
What changed in this PR

Adds compact skill-usage aggregation and exposes invocation metrics in audit output.

Changes:

  • Aggregates named skill invocations, failures, and timestamps.
  • Backfills audit activations and reports skill:<name> tool usage.
  • Extends schemas, cache preservation, and tests.
File Description
actions/​setup/​js/​generate_usage_activity_summary.cjs Aggregates skill activity from session events.
actions/​setup/​js/​generate_usage_activity_summary.test.cjs Tests skill aggregation.
pkg/​cli/​logs_usage_activity.go Loads and applies compact skill aggregates.
pkg/​cli/​logs_usage_activity_test.go Tests skill backfilling.
pkg/​cli/​logs_models.go Adds invocation and failure counts.
pkg/​cli/​audit_report.go Adds named skills to tool usage.
pkg/​cli/​audit_run_pipeline.go Preserves cached skill activations.
pkg/​cli/​audit_summary_build_test.go Tests audit integration.
schemas/​audit.schema.json Extends audit activation schema.
schemas/​logs-jsonl.schema.json Extends cached JSONL schema.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +394 to +395
aggregate.invocation_count += 1;
aggregate.last_timestamp = String(entry.timestamp || aggregate.last_timestamp);
Comment on lines +397 to +399
if (data.toolCallId) {
pendingSkills.set(String(data.toolCallId), skillName);
}
Comment thread pkg/cli/audit_report.go
errors := extractAuditErrors(run)
downloadedFiles := extractDownloadedFiles(run.LogsPath)
toolUsage := buildAuditToolUsage(metrics, mcpToolUsage)
toolUsage := buildAuditToolUsage(metrics, mcpToolUsage, processedRun.SkillActivations)
MissingData: summary.MissingData,
Noops: summary.Noops,
MCPFailures: summary.MCPFailures,
SkillActivations: summary.SkillActivations,
@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-09-26T22:49:58Z
review_event: COMMENT
top_themes:
  - skill timestamp aggregation is order-dependent
files_reviewed:
  - actions/setup/js/generate_usage_activity_summary.cjs
  - actions/setup/js/generate_usage_activity_summary.test.cjs
  - pkg/cli/audit_report.go
  - pkg/cli/audit_run_pipeline.go
  - pkg/cli/audit_summary_build_test.go
  - pkg/cli/logs_models.go
  - pkg/cli/logs_usage_activity.go
  - pkg/cli/logs_usage_activity_test.go
  - schemas/audit.schema.json
  - schemas/logs-jsonl.schema.json
comment_count: 1

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 61 AIC · ⌖ 7.07 AIC · ⊞ 20.2K · ◷
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

Non-blocking overall, but the new skill-usage aggregation now records order-dependent provenance timestamps.

Theme
  • first_timestamp / last_timestamp are taken from directory traversal order instead of min/max event time, so the audit summary can report the wrong window for a skill invocation.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 61 AIC · ⌖ 7.07 AIC · ⊞ 20.2K
Comment /review to run again

last_timestamp: String(entry.timestamp || ""),
};
aggregate.invocation_count += 1;
aggregate.last_timestamp = String(entry.timestamp || aggregate.last_timestamp);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These timestamps are derived from filesystem iteration order rather than event time, so first_timestamp/last_timestamp can be wrong as soon as the run has multiple events.jsonl files or readdir returns a different order; that makes the new audit artifact lie about when a skill first or last ran.

💡 Why this matters and how to fix it

findFiles() just walks directories in readdirSync() order, and this code initializes first_timestamp from the first file it happens to see while blindly overwriting last_timestamp on every later match. That means a later-processed older event can move last_timestamp backwards, and an earlier event discovered late can never fix first_timestamp.

Please compare timestamps and keep the minimum as first_timestamp and the maximum as last_timestamp instead of relying on traversal order.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

pr-sous-chef
@copilot There is still forward progress needed on this PR.

  • Please address the latest code-quality feedback about order-dependent skill timestamp aggregation and any related follow-up review items.
  • A branch refresh was requested from sous-chef for this run: https://github.com/github/gh-aw/actions/runs/36277822788
  • After addressing the feedback, run the pr-finisher skill and return the PR to maintainer-ready state.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 16.5 AIC · ⌖ 8.7 AIC · ⊞ 9.7K · ◷
Comment /souschef to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /tdd and /codebase-design — requesting changes for a test-coverage gap in new logic.

📋 Key Themes & Highlights

Key Themes

  • Test coverage gap: the "create new SkillActivation from usage summary" branch in applyUsageActivitySkills (pkg/cli/logs_usage_activity.go) is untested — only the enrichment-of-existing-activation path has a test.
  • Fragile assumption: the JS aggregator hard-codes input.skill as the only recognized argument key for the skill tool, with no fallback or documented contract.
  • Docs drift: docs/src/content/docs/reference/audit.md still describes skill_activations without the new invocation_count/failed_count fields or usage_summary source.
  • Minor: backfillUsageActivityMCPMetrics was refactored from pointer-based to copy-and-reassign loops for usage.Summary/usage.Servers. This looks unrelated to skill tracking — worth double-checking it wasn't an accidental side-effect of the diff, though it appears behavior-preserving.

Positive Highlights

  • ✅ Clean, minimal aggregation logic in generate_usage_activity_summary.cjs (skills/pendingSkills maps keyed correctly on toolCallId).
  • ✅ Good use of omitempty and schema updates (audit.schema.json, logs-jsonl.schema.json) kept in sync with the new fields.
  • ✅ Solid existing test for the enrichment path and for the JS-side aggregation (generate_usage_activity_summary.test.cjs).

@copilot please address the review comments above.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 181.3 AIC · ⌖ 14.6 AIC · ⊞ 10K
Comment /matt to run again

}
enriched = append(enriched, activation)
}
for _, skill := range skills.Items {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] The "new skill activation" branch (lines 250-268, creating a SkillActivation for a skill not already in result.SkillActivations) has no test coverage. TestApplyUsageActivitySkillsEnrichesDetailedActivations only exercises the enrichment-of-existing-activation path.

💡 Suggested test
func TestApplyUsageActivitySkillsAddsNewActivation(t *testing.T) {
    result := DownloadResult{}
    summary := &usageActivitySummary{
        Skills: &usageActivitySkills{
            Items: []usageActivitySkillItem{{Name: "new-skill", InvocationCount: 3, FailedCount: 1, FirstTimestamp: "2026-01-01T00:00:00Z"}},
        },
    }
    applyUsageActivitySummaryToResult(summary, &result, true)
    require.Len(t, result.SkillActivations, 1)
    assert.Equal(t, "usage_summary", result.SkillActivations[0].Source)
}

Without this, a regression that silently drops usage-only skills (e.g. a stray continue/delete ordering bug) would go unnoticed.

@copilot please address this.

.toLowerCase() === "skill"
) {
const input = data.input && typeof data.input === "object" ? data.input : data.arguments && typeof data.arguments === "object" ? data.arguments : {};
const skillName = String(input.skill || "").trim();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] input.skill hard-codes the assumption that the built-in skill tool's argument key is literally named skill. If this ever changes in the Copilot CLI (or differs across engine versions), this silently stops aggregating without any error signal.

💡 Suggested hardening

Consider falling back to a couple of plausible keys (similar to how extractStructuredToolInput in tool_call_details.cjs tries input/arguments/parameters/args), e.g. input.skill || input.name || input.skillName, and/or add a code comment pinning the exact tool-call shape this depends on (with a link to where the Copilot CLI's skill tool emits { skill: <name> }) so future changes to the tool schema are easier to catch.

@copilot please address this.

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Copilot AI and others added 3 commits September 26, 2026 23:20
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Sep 26, 2026

Copy link
Copy Markdown
Contributor Author

pr-sous-chef
@copilot There is still forward progress needed on this PR.
...

Addressed the skill aggregation and fresh audit-path feedback in 3112f47. The requested base refresh was checked; the branch was already current with main.

Copilot AI requested a review from gh-aw-bot September 26, 2026 23:26
@pelikhan
pelikhan merged commit e66d8d5 into main Sep 26, 2026
43 checks passed
@pelikhan
pelikhan deleted the copilot/task-9919-1036865607-ca3f0885-26de-462e-8253-7d4ecc7be8ae branch September 26, 2026 23:41
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.89.22

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants