-
----
-
-# Useful Sandboxes
-
-## Safe by design, Useful by default
-
-> The best developer tools protect you from catastrophe while letting you build something real
-
----
-
-# From Scratch to MakeCode
-
-## Kid dev environments got here first
-
-- **Scratch** — Block-based coding (MIT) — can't break anything important
-- **MakeCode / pxt** — Hardware + game programming for beginners
-- **BASIC** — First language for a generation of developers
-
-These environments share one superpower:
-
-> Protected from catastrophe — still building something **real and delightful**
-
----
-
-# Agentic Sandbox for Enterprise
-
-## Safe by default
-
-- **Containers**: Isolated GitHub Actions Jobs
-
-- **Firewall**: Network Control
-
-- **Minimal Permissions**: Read-only by default
-
-- **MCP Gateway**: Secure tool access
-
-- **Threat Detection**: Agentic detection of threats
-
-- **Safe Outputs**: Deterministic, guardrailed outputs
-
-- **Plan / Check / Act**: Human in the loop
-
----
-
-# Safe Outputs
-
-```yaml
----
-on:
- pull_request:
- types: [opened]
-permissions:
- contents: read
-safe-outputs:
- create-issue:
----
-Check for breaking changes in package.json and create an issue.
-```
-
-**Security:** AI agents cannot directly write to GitHub. Safe-outputs validate AI responses and execute actions in isolated containers.
-
----
-
-# Staged Mode
-
-## Preview before you deploy
-
-```yaml
----
-on:
- issues:
- types: [opened]
-safe-outputs:
- staged: true # Preview only — no writes
- create-issue:
----
-Analyze issue and suggest follow-up tasks.
-```
-
-> See exactly what a workflow _would_ create — before it does
-
----
-
-# Network Permissions
-
-```yaml
----
-on:
- pull_request:
-network:
- allowed:
- - defaults # Basic infrastructure
- - node # NPM ecosystem
-tools:
- web-fetch:
----
-Fetch latest TypeScript docs and report findings in a comment.
-```
-
-> Control external access for security
-
----
-
-# Safe Outputs → Copilot Handoff
-
-```yaml
----
-on:
- issues:
- types: [opened]
-safe-outputs:
- create-issue:
- assignees: ["copilot"]
----
-Analyze issue and break down into implementation tasks
-```
-
-> Triage agent → Creates tasks → @copilot implements → Review
-
----
-
-# AI Engines
-
-## Multiple AI providers supported
-
-- **GitHub Copilot CLI** (default, recommended)
-- **Claude Code**
-- **OpenAI Codex**
-- **Google Gemini CLI**
-- **Crush** / **OpenCode** — experimental multi-provider AI coding agents
-
-```yaml
-engine: copilot # sensible defaults
-```
-
-> GitHub Copilot offers MCP support and conversational workflows
-
----
-
-# MCP Servers Configuration
-
-
-```yaml
-# GitHub MCP (recommended: use toolsets)
-tools:
- github:
- toolsets: [default] # context, repos, issues, pull_requests
-
-# Custom MCP servers
-mcp-servers:
- bundle-analyzer:
- command: "node"
- args: ["path/to/mcp-server.js"]
- allowed: ["*"]
-```
-
-**MCP:** Extend AI with [Model Context Protocol](https://modelcontextprotocol.io/)
-
----
-
-# Containerized, Firewalled MCPs
-
-```yaml
-mcp-servers:
- web-scraper:
- container: mcp/fetch
- network:
- allowed: ["npmjs.com", "*.jsdelivr.com"]
- allowed: ["fetch"]
-```
-
-**Defense in depth:** Container + network + permissions
-
----
-
-# Monitoring & Optimization
-
-```sh
-# View recent runs
-gh aw logs
-
-# Filter by date range
-gh aw logs --start-date -1w accessibility-review
-
-# Cross-run analysis report
-gh aw logs --format markdown --count 10
-
-# Audit a specific workflow run
-gh aw audit 123456
-
-# Generate the lock file for a workflow
-gh aw compile
-```
-
-> Lock files (`.lock.yml`) ensure reproducibility and auditability
-
----
-
-# OpenTelemetry Distributed Tracing
-
-```yaml
----
-on:
- pull_request:
- types: [opened]
-observability:
- otlp:
- endpoint: "${{ secrets.OTLP_ENDPOINT }}"
- headers: "${{ secrets.OTLP_HEADERS }}"
----
-Analyze this pull request for security issues.
-```
-
-**Export spans** to Honeycomb, Grafana Tempo, or Sentry — every job emits setup and conclusion spans, MCP tool calls are correlated under the same trace ID
-
----
-
-# Cache & Persistent Memory
-
-## Speed up workflows and maintain context
-
-```yaml
----
-on:
- pull_request:
- types: [opened]
-tools:
- cache-memory: # AI remembers across runs
----
-Review this PR with context from previous reviews:
-- Check for repeated issues
-- Track improvement trends
-- Reference past discussions
-```
-
-**Benefits:** Faster builds + contextual AI analysis
-
----
-
-# Playwright + Upload Assets
-
-```yaml
----
-on:
- pull_request:
- types: [ready_for_review]
-tools:
- playwright: # Headless browser automation
-safe-outputs:
- create-issue:
- upload-asset: # Attach screenshots to artifacts
----
-Test the web application:
-1. Navigate to the preview URL
-2. Take screenshots of key pages
-3. Check for visual regressions and responsive design
-4. Create issue with findings and screenshots
-```
-
-**Use cases:** Visual regression, accessibility audits, E2E validation for SPAs
-
----
-
-# Sanitized Context & Security
-
-## Protect against prompt injection
-
-```yaml
----
-on:
- issues:
- types: [opened]
-permissions:
- contents: read
- actions: read
-safe-outputs:
- add-comment:
----
-# RECOMMENDED: Use sanitized context
-Analyze this issue content (safely sanitized):
-"${{ steps.sanitized.outputs.text }}"
-```
-
-**Auto-sanitization:** @mentions neutralized, bot triggers blocked, URIs filtered
-
----
-
-# Security Architecture
-
-## Multi-layered defense in depth
-
-- Container isolation for all components
-- Network firewall controls at every layer
-- Minimal permissions by default
-- Separation of concerns (agent, tools, outputs)
-
----
-
-# Security Architecture Diagram
-
-
-flowchart TB
- subgraph ActionJobVM["Action Job VM"]
- subgraph Sandbox1["Sandbox"]
- Agent["Agent Process"]
- end
-
- Proxy1["Proxy / Firewall"]
- Gateway["Gateway<br/>(mcpg)"]
-
- Agent --> Proxy1
- Proxy1 --> Gateway
-
- subgraph Sandbox2["Sandbox"]
- MCP["MCP Server"]
- end
-
- subgraph Sandbox3["Sandbox"]
- Skill["Skill"]
- end
-
- Gateway --> MCP
- Gateway --> Skill
-
- Proxy2["Proxy / Firewall"]
- Proxy3["Proxy / Firewall"]
-
- MCP --> Proxy2
- Skill --> Proxy3
- end
-
- Service1{{"Service"}}
- Service2{{"Service"}}
-
- Proxy2 --> Service1
- Proxy3 --> Service2
-
-
----
-
-# Security Layer 1: Coding Agent Sandbox
-
-**Agent sandbox** — isolated container, read-only by default, limited system access
-
-**Primary proxy/firewall** — filters outbound traffic, controls MCP Gateway access, enforces network allowlists
-
----
-
-# Security Layer 2: MCP Gateway
-
-**MCP Gateway (mcpg)** — central routing between agents and services
-
-- Validates tool invocations and enforces permission boundaries
-- Single point of control — no direct agent-to-service access
-- Full audit trail for tool calls
-
----
-
-# Security Layer 3: Tool Sandboxes
-
-**MCP servers & skills** — each runs in its own container, non-root, dropped capabilities
-
-**Secondary proxies** — egress filtering, domain allowlists, defense against data exfiltration
-
----
-
-# Security Layer 4: Service Access
-
-External services accessed only through proxies — multiple controls before reaching any service
-
-> Defense in depth: if one layer is compromised, additional controls remain in place
-
----
-
-# Security Features Summary
-
-| Layer | Protection |
-|---|---|
-| **Containers** | VMs + sandboxes for agent, MCP servers, skills |
-| **Network** | Proxy/firewall at every layer, domain allowlisting |
-| **Permissions** | Read-only default, safe outputs for writes |
-| **Supply Chain** | Pinned action SHAs, protected CI/CD files |
-| **Integrity** | `min-integrity`, access & integrity metadata |
-| **Monitoring** | Threat detection, audit logs, run analysis |
-
----
-
-# Best Practices: Human in the Loop
-
-**Manual Approval Gates:**
-
-```yaml
----
-on:
- issues:
- types: [labeled]
- manual-approval: production
-safe-outputs:
- create-pull-request:
----
-Analyze issue and create implementation PR
-```
-
-**Plan / Check / Act:** plan (read-only) → review & approve → execute via safe outputs
-
----
-
-# Learn More About Security
-
-**Documentation:**
-
-- Security Best Practices Guide
-- Threat Detection Configuration
-- Network Configuration Reference
-- Safe Outputs Reference
-
-**Visit:**
-
----
-
-# Getting Started (Agentically)
-
-```sh
-# Install GitHub Agentic Workflows extension
-gh extension install github/gh-aw
-gh aw init
-
-# Agentic setup with Copilot CLI (optional)
-npx --yes @github/copilot -i "activate https://raw.githubusercontent.com/github/gh-aw/refs/heads/main/install.md"
-```
-
-> Built with AI agents in mind from day 0
-
-> Quick Start:
-
----
+version https://git-lfs.github.com/spec/v1
+oid sha256:6dff7f23b04f978e62d3477279efb1ff7712e51495f0c54f3616daef510c2574
+size 10889
diff --git a/pkg/cli/README.md b/pkg/cli/README.md
index 8e025388b83..b10c44e1482 100644
--- a/pkg/cli/README.md
+++ b/pkg/cli/README.md
@@ -571,7 +571,7 @@ This appendix is generated from the current non-test Go source files in this pac
| `audit_cross_run.go` | `DomainRunStatus` | `type DomainRunStatus struct { RunID int64 `json:"run_id"` Status string `json:"status"` // "allowed", "denied", "mixed", "absent" Allowed int `json:"allowed"` Blocked int `json:"blocked"` }` | DomainRunStatus records the status of a domain in a single run. |
| `audit_cross_run.go` | `ErrorTrendData` | `type ErrorTrendData struct { RunsWithErrors int `json:"runs_with_errors"` TotalErrors int `json:"total_errors"` AvgErrorsPerRun float64 `json:"avg_errors_per_run"` RunsWithWarnings int `json:"runs_with_warnings"` TotalWarnings int `json:"total_warnings"` }` | ErrorTrendData summarizes error and warning patterns across runs. |
| `audit_cross_run.go` | `MCPServerCrossRunHealth` | `type MCPServerCrossRunHealth struct { ServerName string `json:"server_name"` RunsConnected int `json:"runs_connected"` // Runs where server was used (appeared in tool usage) TotalRuns int `json:"total_runs"` TotalCalls int `json:"total_calls"` TotalErrors int `json:"total_errors"` ErrorRate float64 `json:"error_rate"` // 0.0–1.0 Unreliable bool `json:"unreliable"` // True if error_rate > 0.10 or connected < 75% of runs }` | MCPServerCrossRunHealth describes the health of a single MCP server across runs. |
-| `audit_report.go` | `JobStepData` | `type JobStepData struct { Name string `json:"name"` Status string `json:"status,omitempty"` Conclusion string `json:"conclusion,omitempty"` }` | JobStepData contains information about an individual workflow job step. |
+| `audit_report.go` | `JobStepData` | `type JobStepData = JobStep` | JobStepData is an alias for JobStep (see logs_models.go). |
| `audit_report.go` | `MCPServerStats` | `type MCPServerStats struct { ServerName string `json:"server_name" console:"header:Server"` // RequestCount is kept for backward-compatible report schemas that label per-server // request volume; in MCP usage summaries this currently mirrors ToolCallCount. RequestCount int `json:"request_count" console:"header:Requests"` ToolCallCount int `json:"tool_call_count" console:"header:Tool Calls"` TotalInputSize int `json:"total_input_size" console:"header:Total Input,format:number"` TotalOutputSize int `json:"total_output_size" console:"header:Total Output,format:number"` AvgDuration string `json:"avg_duration,omitempty" console:"header:Avg Duration,omitempty"` ErrorCount int `json:"error_count,omitempty" console:"header:Errors,omitempty"` }` | MCPServerStats contains server-level statistics |
| `audit_report.go` | `OverviewDisplay` | `type OverviewDisplay struct { RunID int64 `console:"header:Run ID"` Workflow string `console:"header:Workflow"` Status string `console:"header:Status"` Duration string `console:"header:Duration,omitempty"` Event string `console:"header:Event"` Branch string `console:"header:Branch"` URL string `console:"header:URL"` Files string `console:"header:Files,omitempty"` Experiment string `console:"header:Experiment,omitempty"` }` | OverviewDisplay is a display-optimized version of OverviewData for console rendering |
| `audit_report_experiments.go` | `ExperimentData` | `type ExperimentData struct { // Assignments maps each experiment name to the variant selected for this run. // e.g. {"caveman": "yes", "style": "concise"} Assignments map[string]string `json:"assignments"` // CumulativeCounts maps each experiment name to a per-variant invocation counter. // e.g. {"caveman": {"yes": 3, "no": 2}} CumulativeCounts map[string]map[string]int `json:"cumulative_counts,omitempty"` }` | ExperimentData represents the A/B experiment assignments for a single workflow run. |
diff --git a/pkg/cli/audit_report.go b/pkg/cli/audit_report.go
index a4937bdedbb..30b8ecaec0a 100644
--- a/pkg/cli/audit_report.go
+++ b/pkg/cli/audit_report.go
@@ -125,12 +125,9 @@ type JobData struct {
Steps []JobStepData `json:"steps,omitempty"`
}
-// JobStepData contains information about an individual workflow job step.
-type JobStepData struct {
- Name string `json:"name"`
- Status string `json:"status,omitempty"`
- Conclusion string `json:"conclusion,omitempty"`
-}
+// JobStepData is an alias for JobStep, kept to avoid renaming the existing
+// "Data" suffixed usages of this type within this package.
+type JobStepData = JobStep
// FileInfo contains information about downloaded artifact files
type FileInfo struct {
@@ -383,9 +380,7 @@ func buildAuditJobs(jobDetails []JobInfoWithDuration) []JobData {
Name: jobDetail.Name,
Status: jobDetail.Status,
Conclusion: jobDetail.Conclusion,
- Steps: sliceutil.Map(jobDetail.Steps, func(step JobStep) JobStepData {
- return JobStepData(step)
- }),
+ Steps: jobDetail.Steps,
}
if jobDetail.Duration > 0 {
job.Duration = timeutil.FormatDuration(jobDetail.Duration)