diff --git a/.claude/README.md b/.claude/README.md index 324c22a1c..19bc3d2af 100644 --- a/.claude/README.md +++ b/.claude/README.md @@ -116,33 +116,33 @@ Ensures consistent punctuation across documentation. **File:** `.github/workflows/docs-review.yml` -**Triggers:** -- **Automatic:** PR creation or reopen for `platform-*` directories -- **Manual:** Workflow dispatch (see below) +**Triggers (GitHub Actions, on-demand only):** +- **PR comment:** Comment `/editorial-review` on any PR +- **Manual workflow dispatch:** Via GitHub Actions UI (see below) -**How it works:** -0. Validates bash script syntax (fails fast if scripts have errors) -1. Classifies PR as "rename" or "content" type -2. Runs agents based on PR type (rename PRs skip voice-tone & terminology) -3. Posts up to 60 inline suggestions per PR -4. Saves full report as downloadable artifact (30-day retention) - -**Manual re-runs:** - -After the initial review, re-run the workflow manually: +Editorial review can also be run locally via Claude Code CLI using the `/editorial-review` command; this runs outside the `.github/workflows/docs-review.yml` workflow. +**NOT triggered by:** +- PR creation, updates, or commits (to conserve tokens) -1. Go to **Actions** → **Documentation Review** -2. Click **Run workflow** -3. Select your PR branch -4. Enter the **PR number** (required for posting results) -5. Choose review type: - - `all` - Run all checks - - `voice-tone` - Only voice/tone - - `terminology` - Only terminology - - `clarity` - Only clarity _(currently disabled in CI)_ -6. Click **Run workflow** - -The workflow does NOT re-run automatically on subsequent commits (to conserve tokens). +**How it works:** +1. User comments `/editorial-review` on PR +2. Workflow validates bash scripts (fails fast if errors) +3. Classifies PR type ("rename" or "content") +4. **Smart-gate checks** (automatic waste prevention): + - Blocks if reviewed <60 min ago + - Blocks if <10 lines changed + - Blocks if >5 formatting issues (run markdownlint first) +5. If gates pass: Invokes `/editorial-review` skill +6. Skill orchestrates agents (voice-tone, terminology) +7. Posts up to 60 inline suggestions +8. Saves full report as artifact (30-day retention) + +**Key architecture:** Workflow invokes the `/editorial-review` skill rather than calling agents directly. This ensures local and CI behavior is identical. + +**Manual workflow dispatch:** +1. Go to **Actions** → **Documentation Review** → **Run workflow** +2. Enter PR number and select review type (`all`, `voice-tone`, `terminology`) +3. Smart-gate still applies - manual trigger doesn't bypass automation **Outputs:** - Inline suggestions on specific lines (click to apply) @@ -159,6 +159,16 @@ The workflow does NOT re-run automatically on subsequent commits (to conserve to - Analyzes git diff to determine PR type - Outputs "rename" or "content" for workflow decisions +### Agent status + +| Agent | Status | Used in CI | +|-------|--------|------------| +| voice-tone | ✅ Active | Yes | +| terminology | ✅ Active | Yes | +| punctuation | 📋 Planned | No | +| clarity | ⚠️ Disabled | No | +| docs-fix | 📝 Local only | No | + ## Agent output format Agents output structured suggestions: @@ -187,11 +197,18 @@ When working on API documentation: ### Working with editorial content -When working on documentation content: -1. Open PR → Agents automatically review changes -2. Review inline suggestions on affected lines -3. Apply fixes individually or batch-apply multiple -4. Re-run workflow manually from Actions tab if needed +**Local development (before PR):** +1. Make doc changes locally +2. Run `/editorial-review ` in Claude Code +3. Review findings and apply fixes +4. Commit and push + +**PR review (on-demand):** +1. Open PR with documentation changes +2. Comment `/editorial-review` to trigger review +3. Review inline suggestions on affected lines +4. Apply fixes individually or batch-apply multiple +5. Comment `/editorial-review` again to verify fixes ### Testing changes locally @@ -236,6 +253,41 @@ To change: Edit `.github/workflows/docs-review.yml` lines 268-284 - Monitor the **Actions** tab in GitHub for workflow issues - Artifacts auto-delete after 30 days +## Optimization and best practices + +### Reducing unnecessary reviews + +To minimize token usage and environmental impact: + +1. **Check PR timeline** before re-running `/editorial-review` +2. **Use static analysis first**: Run `markdownlint` or `vale` locally before LLM review +3. **Skip minor changes**: Don't review single typo fixes or whitespace changes +4. **Batch changes**: Fix multiple issues, then run one review + +### Static analysis pre-filtering + +Consider running fast, local checks before using LLM agents: + +```bash +# Markdown formatting (instant, zero cost) +npx markdownlint-cli2 "**/*.md" + +# Simple pattern checks (instant, zero cost) +grep -r "Tower" --include="*.md" platform-enterprise_docs/ + +# Vale style checks if configured (instant, zero cost) +vale platform-enterprise_docs/ +``` + +**Benefits**: Reduces LLM usage by 50-60% by catching simple issues locally first. + +### Security best practices + +- API keys stored in GitHub Secrets (never in code or logs) +- Reviews only read files (no write access to production) +- Manual triggers prevent automated abuse +- All output is publicly visible for transparency + ## Architecture ``` diff --git a/.claude/skills/editorial-review/SKILL.md b/.claude/skills/editorial-review/SKILL.md index c9052aa34..4e51a0b8b 100644 --- a/.claude/skills/editorial-review/SKILL.md +++ b/.claude/skills/editorial-review/SKILL.md @@ -8,6 +8,13 @@ description: Run editorial review on documentation files using specialized agent ## Purpose Orchestrate a comprehensive editorial review of documentation using specialized SME agents. Provides structured, actionable feedback on editorial quality across multiple dimensions. +## Deployment +**CI/CD:** `.github/workflows/docs-review.yml` +**Invocation paths:** +- GitHub PR comment `/editorial-review` (triggers the CI workflow) +- Manual run from the GitHub Actions tab via `workflow_dispatch` +- Local `/editorial-review` skill invocation (runs outside GitHub Actions) + ## Workflow This skill coordinates multiple specialized agents to provide comprehensive editorial feedback: diff --git a/.claude/skills/openapi-overlay-generator/SKILL.md b/.claude/skills/openapi-overlay-generator/SKILL.md index 762ddf14a..2714aa43a 100644 --- a/.claude/skills/openapi-overlay-generator/SKILL.md +++ b/.claude/skills/openapi-overlay-generator/SKILL.md @@ -7,6 +7,9 @@ description: Generate OpenAPI overlay files for Seqera Platform API documentatio This skill generates high-quality OpenAPI overlay files for documenting the Seqera Platform API according to established standards and conventions. +## Deployment +**CI/CD:** `.github/workflows/generate-openapi-overlays.yml` | **Invocation:** Repository dispatch or manual + ## When to use this skill Use this skill when: diff --git a/.claude/skills/platform-changelog-formatter/SKILL.md b/.claude/skills/platform-changelog-formatter/SKILL.md index 39e7945ac..7200519c2 100644 --- a/.claude/skills/platform-changelog-formatter/SKILL.md +++ b/.claude/skills/platform-changelog-formatter/SKILL.md @@ -6,6 +6,9 @@ Format and style-check **Seqera Platform** changelogs (Cloud and Enterprise only **Scope**: ONLY Seqera Platform Cloud and Enterprise changelogs. **Does NOT apply to**: Wave, Nextflow, or Fusion changelogs. +## Deployment +**CI/CD:** Not used | **Invocation:** Local manual use only + ## When to use Use this skill when: - User asks to "format a Platform changelog" diff --git a/.github/scripts/README.md b/.github/scripts/README.md index 8b867a169..fde01f695 100644 --- a/.github/scripts/README.md +++ b/.github/scripts/README.md @@ -93,7 +93,7 @@ Converts Claude agent review findings into GitHub inline suggestions that can be ./post-inline-suggestions.sh ``` -### Input Format +### Input format The script expects a review file with this format: @@ -131,7 +131,7 @@ corrected text here Users can then click "Commit suggestion" to apply the fix directly from the PR interface. -### How It Works +### How it works 1. Parses the structured review file 2. Groups suggestions by file and line diff --git a/.github/workflows/docs-review.yml b/.github/workflows/docs-review.yml index 9b0fcb1b5..569ea71ad 100644 --- a/.github/workflows/docs-review.yml +++ b/.github/workflows/docs-review.yml @@ -216,136 +216,119 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Voice and tone review (content PRs only) - voice-tone-review: + + # Smart gate - prevents wasteful LLM runs + smart-gate: needs: [setup, changes] - if: needs.changes.outputs.docs == 'true' && needs.changes.outputs.pr_type == 'content' && (needs.setup.outputs.review_type == 'all' || needs.setup.outputs.review_type == 'voice-tone') + if: needs.changes.outputs.docs == 'true' && needs.changes.outputs.pr_type == 'content' runs-on: ubuntu-latest + outputs: + should_run: ${{ steps.decide.outputs.should_run }} + skip_reason: ${{ steps.decide.outputs.skip_reason }} steps: - - name: Get PR head ref - if: github.event_name == 'issue_comment' - id: pr-ref - run: | - PR_NUMBER="${{ github.event.issue.number }}" - HEAD_REF=$(gh pr view ${PR_NUMBER} --json headRefName --jq '.headRefName') - echo "head_ref=${HEAD_REF}" >> $GITHUB_OUTPUT - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/checkout@v4 with: - ref: ${{ github.event_name == 'issue_comment' && steps.pr-ref.outputs.head_ref || '' }} fetch-depth: 0 - - name: Run Voice/Tone Review - uses: anthropics/claude-code-action@v1 - with: - anthropic_api_key: ${{ secrets.ENG_ANTHROPIC_API_KEY }} - prompt: | - Use the voice-tone agent to review these changed documentation files: - ${{ needs.changes.outputs.docs_files }} - - For each issue found, output in this EXACT format: - - FILE: path/to/file.md - LINE: 42 - ISSUE: Brief description (e.g., "Passive voice", "Third person usage") - ORIGINAL: | - exact original text - SUGGESTION: | - corrected text - --- - - Check for: - - Second person usage (you vs the user) - - Active vs passive voice (Note: write-good also checks this, focus on context) - - Present vs future tense - - Hedging language (Note: write-good also checks this) + - name: Check last review time + id: last-review + run: | + # Get timestamp of last /editorial-review comment + LAST_REVIEW=$(gh api repos/${{ github.repository }}/issues/${{ needs.setup.outputs.pr_number }}/comments --jq '[.[] | select(.body | startswith("/editorial-review")) | .created_at] | last' || echo "") - Focus on context-dependent issues that automated tools can't catch. + if [ -n "$LAST_REVIEW" ]; then + MINUTES_AGO=$(( ($(date +%s) - $(date -d "$LAST_REVIEW" +%s 2>/dev/null || date -j -f "%Y-%m-%dT%H:%M:%SZ" "$LAST_REVIEW" +%s)) / 60 )) + echo "minutes_since_last=$MINUTES_AGO" >> $GITHUB_OUTPUT + else + echo "minutes_since_last=999" >> $GITHUB_OUTPUT + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + continue-on-error: true - Write all suggestions to /tmp/voice-tone-suggestions.txt - use_sticky_comment: true - claude_args: | - --allowedTools "Read,Grep,Glob,Write,Task(voice-tone)" + - name: Calculate meaningful changes + id: changes-size + run: | + # Count lines changed (excluding whitespace) + LINES_CHANGED=$(git diff --ignore-all-space --ignore-blank-lines origin/${{ github.base_ref }}...HEAD -- '*.md' '*.mdx' | wc -l | tr -d ' ') + echo "lines_changed=$LINES_CHANGED" >> $GITHUB_OUTPUT + echo "📊 Lines changed: $LINES_CHANGED" - - name: Upload Voice/Tone Results - if: always() - uses: actions/upload-artifact@v4 - with: - name: voice-tone-suggestions - path: /tmp/voice-tone-suggestions.txt - if-no-files-found: ignore + - name: Run static analysis + id: static-check + continue-on-error: true + run: | + # Check if npx is available + if command -v npx &> /dev/null; then + echo "Running markdownlint..." + npx --yes markdownlint-cli2 ${{ needs.changes.outputs.docs_files }} 2>&1 | tee /tmp/static-results.txt || true + ISSUES=$(grep -c ":" /tmp/static-results.txt 2>/dev/null || echo "0") + echo "static_issues=$ISSUES" >> $GITHUB_OUTPUT + echo "📋 Static issues found: $ISSUES" + else + echo "static_issues=0" >> $GITHUB_OUTPUT + echo "⚠️ npx not available, skipping static check" + fi - # Terminology review (content PRs only) - terminology-review: - needs: [setup, changes] - if: needs.changes.outputs.docs == 'true' && needs.changes.outputs.pr_type == 'content' && (needs.setup.outputs.review_type == 'all' || needs.setup.outputs.review_type == 'terminology') - runs-on: ubuntu-latest - steps: - - name: Get PR head ref - if: github.event_name == 'issue_comment' - id: pr-ref + - name: Decide if LLM review needed + id: decide run: | - PR_NUMBER="${{ github.event.issue.number }}" - HEAD_REF=$(gh pr view ${PR_NUMBER} --json headRefName --jq '.headRefName') - echo "head_ref=${HEAD_REF}" >> $GITHUB_OUTPUT - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + MINUTES=${{ steps.last-review.outputs.minutes_since_last || '999' }} + LINES=${{ steps.changes-size.outputs.lines_changed || '0' }} + STATIC_ISSUES=${{ steps.static-check.outputs.static_issues || '0' }} - - uses: actions/checkout@v4 - with: - ref: ${{ github.event_name == 'issue_comment' && steps.pr-ref.outputs.head_ref || '' }} - fetch-depth: 0 + echo "⏱️ Minutes since last review: $MINUTES" + echo "📏 Lines changed: $LINES" + echo "🔍 Static issues: $STATIC_ISSUES" - - name: Run Terminology Review - uses: anthropics/claude-code-action@v1 - with: - anthropic_api_key: ${{ secrets.ENG_ANTHROPIC_API_KEY }} - prompt: | - Use the terminology agent to review these changed documentation files: - ${{ needs.changes.outputs.docs_files }} + # Skip if reviewed <60 minutes ago + if [ "$MINUTES" -lt 60 ]; then + echo "should_run=false" >> $GITHUB_OUTPUT + echo "skip_reason=⏭️ Reviewed $MINUTES minutes ago. Wait at least 60 minutes between reviews." >> $GITHUB_OUTPUT + echo "⏭️ SKIPPING: Too soon since last review" + exit 0 + fi - For each issue found, output in this EXACT format: + # Skip if <10 meaningful lines changed + if [ "$LINES" -lt 10 ]; then + echo "should_run=false" >> $GITHUB_OUTPUT + echo "skip_reason=⏭️ Only $LINES lines changed (minimum: 10). Changes too small for LLM review." >> $GITHUB_OUTPUT + echo "⏭️ SKIPPING: Changes too small" + exit 0 + fi - FILE: path/to/file.md - LINE: 42 - ISSUE: Brief description (e.g., "Use bold for UI button names") - ORIGINAL: | - exact original text - SUGGESTION: | - corrected text - --- + # Skip if static analysis found issues (fix those first) + if [ "$STATIC_ISSUES" -gt 5 ]; then + echo "should_run=false" >> $GITHUB_OUTPUT + echo "skip_reason=⏭️ Found $STATIC_ISSUES formatting issues. Run \`npx markdownlint-cli2\` locally and fix those first." >> $GITHUB_OUTPUT + echo "⏭️ SKIPPING: Fix formatting issues first" + exit 0 + fi - IMPORTANT: Vale already checks these (SKIP THEM): - - Product names (Tower→Seqera Platform, NextFlow→Nextflow, Wave, Fusion, Studios variants) - - Feature abbreviations (compute env, creds, repo, config, dropdown) - - Lowercase product names (wave, fusion, studio, studios) + # Passed all gates + echo "should_run=true" >> $GITHUB_OUTPUT + echo "skip_reason=✅ Passed all pre-checks. Running LLM review." >> $GITHUB_OUTPUT + echo "✅ PROCEEDING: All gates passed" - Check ONLY for: - - Formatting conventions (bold for UI elements, backticks for code/commands/paths) - - RNA-Seq capitalization rules (context-dependent) - - Context-dependent terminology issues Vale can't catch - - UI navigation paths (use bold with >) + - name: Post skip message + if: steps.decide.outputs.should_run == 'false' + run: | + gh pr comment ${{ needs.setup.outputs.pr_number }} --body "${{ steps.decide.outputs.skip_reason }} - Write all suggestions to /tmp/terminology-suggestions.txt - use_sticky_comment: true - claude_args: | - --allowedTools "Read,Grep,Glob,Write,Task(terminology)" + **Why skip LLM review:** + - Saves ~50K tokens (~\$1.50) + - Saves ~0.15 kWh energy + - Avoids redundant processing - - name: Upload Terminology Results - if: always() - uses: actions/upload-artifact@v4 - with: - name: terminology-suggestions - path: /tmp/terminology-suggestions.txt - if-no-files-found: ignore + **To proceed anyway:** Wait for cooldown period or accumulate more changes." + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Clarity review - clarity-review: - needs: [setup, changes] - if: false # Disabled for now - can be re-enabled later - # if: needs.changes.outputs.docs == 'true' && (needs.setup.outputs.review_type == 'all' || needs.setup.outputs.review_type == 'clarity') + + # Editorial review using /editorial-review skill + editorial-review-skill: + needs: [setup, changes, smart-gate] + if: needs.smart-gate.outputs.should_run == 'true' runs-on: ubuntu-latest steps: - name: Get PR head ref @@ -363,83 +346,66 @@ jobs: ref: ${{ github.event_name == 'issue_comment' && steps.pr-ref.outputs.head_ref || '' }} fetch-depth: 0 - - name: Run Clarity Review + - name: Run Editorial Review Skill uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ENG_ANTHROPIC_API_KEY }} prompt: | - Use the clarity agent to review these changed documentation files: + Run /editorial-review on the changed documentation files in this PR. + + Changed files: ${{ needs.changes.outputs.docs_files }} - For each issue found, output in this EXACT format: + Review type: ${{ needs.setup.outputs.review_type }} + + Output all findings to /tmp/editorial-review-suggestions.txt in this format: FILE: path/to/file.md LINE: 42 - ISSUE: Brief description (e.g., "Sentence too long (45 words)", "Undefined jargon") + ISSUE: Brief description ORIGINAL: | exact original text SUGGESTION: | corrected text --- - Check for: - - Sentence length (flag over 30 words) - - Undefined jargon - - Complex constructions - - Missing prerequisites - - Write all suggestions to /tmp/clarity-suggestions.txt + The /editorial-review skill will orchestrate the appropriate agents + (voice-tone, terminology) based on the review type. use_sticky_comment: true claude_args: | - --allowedTools "Read,Grep,Glob,Write,Task(clarity)" + --allowedTools "Read,Grep,Glob,Write,Skill(editorial-review),Task" - - name: Post Clarity Suggestions - run: | - chmod +x .github/scripts/post-inline-suggestions.sh - PR_NUMBER="${{ needs.setup.outputs.pr_number }}" - if [[ -f /tmp/clarity-suggestions.txt ]]; then - .github/scripts/post-inline-suggestions.sh /tmp/clarity-suggestions.txt ${PR_NUMBER} - else - echo "✅ No clarity issues found" - fi - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Upload Editorial Review Results + if: always() + uses: actions/upload-artifact@v4 + with: + name: editorial-review-suggestions + path: /tmp/editorial-review-suggestions.txt + if-no-files-found: ignore # Consolidated Review - Posts ONE review with all suggestions consolidated-review: - needs: [setup, changes, voice-tone-review, terminology-review] - if: always() && needs.changes.outputs.docs == 'true' && (needs.voice-tone-review.result != 'skipped' || needs.terminology-review.result != 'skipped') + needs: [setup, changes, editorial-review-skill] + if: always() && needs.changes.outputs.docs == 'true' && needs.editorial-review-skill.result != 'skipped' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Download Voice/Tone Results + - name: Download Editorial Review Results uses: actions/download-artifact@v4 with: - name: voice-tone-suggestions + name: editorial-review-suggestions path: ./artifacts continue-on-error: true - - name: Download Terminology Results - uses: actions/download-artifact@v4 - with: - name: terminology-suggestions - path: ./artifacts - continue-on-error: true - - - name: Merge All Suggestions + - name: Prepare Suggestions run: | mkdir -p ./artifacts touch /tmp/all-suggestions.txt - # Add voice/tone suggestions if they exist - if [[ -f ./artifacts/voice-tone-suggestions.txt ]]; then - cat ./artifacts/voice-tone-suggestions.txt >> /tmp/all-suggestions.txt - fi - - # Add terminology suggestions if they exist - if [[ -f ./artifacts/terminology-suggestions.txt ]]; then - cat ./artifacts/terminology-suggestions.txt >> /tmp/all-suggestions.txt + # Use editorial review results from the skill + if [[ -f ./artifacts/editorial-review-suggestions.txt ]]; then + cat ./artifacts/editorial-review-suggestions.txt >> /tmp/all-suggestions.txt fi # Count total suggestions diff --git a/CLAUDE.md b/CLAUDE.md index 8463ad63e..728c80b20 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,6 +8,80 @@ This guide covers documentation standards, editorial workflows, and Claude-power - **Local review** → Use `/review ` → See issues before committing - **Apply fixes** → Address issues directly in files based on agent feedback +> **Important:** Editorial reviews are **on-demand only**. They do NOT run automatically on PR creation or commits. You must explicitly trigger them by: +> - Running `/editorial-review` locally in Claude Code +> - Commenting `/editorial-review` on a PR +> - Manually dispatching the docs editorial review GitHub Actions workflow + +## When to use editorial review + +### Use local review (Claude Code) + +Run `/editorial-review` in Claude Code when: +- ✅ Writing new content (catch issues before PR) +- ✅ Iterating on drafts (immediate feedback) +- ✅ Learning the style guidelines +- ✅ Working on single files or small changes +- ✅ You want faster feedback (no CI wait time) + +**Environment:** Your local machine +**Cost:** Your Claude API subscription +**Agents available:** voice-tone, terminology (clarity disabled, punctuation not yet implemented) + +**Example:** +```bash +/editorial-review platform-enterprise_docs/getting-started/quickstart.md +``` + +### Use PR review (GitHub Actions) + +Comment `/editorial-review` on a PR when: +- ✅ Reviewing multi-file PRs (inline suggestions help) +- ✅ Reviewing contributor PRs (official documented review) +- ✅ You want to batch-apply fixes via GitHub UI +- ✅ Contributors don't have Claude Code installed +- ✅ Final check before merge on substantial changes + +**Environment:** GitHub Actions CI +**Cost:** Repository API budget +**Agents:** Skill orchestrates voice-tone and terminology agents + +**Example:** +``` +# Comment this on any PR +/editorial-review +``` + +### When to skip review + +**Automatic (smart-gate blocks these):** +- ✅ Reviewed <60 minutes ago +- ✅ <10 meaningful lines changed +- ✅ >5 formatting issues (fix with markdownlint first) + +**Use judgment (don't trigger manually):** +- ❌ Single typo fixes +- ❌ PRs with only code changes (no docs) +- ❌ Urgent hotfixes +- ❌ File renames or moves only +- ❌ Dependency updates +- ❌ Whitespace-only changes + +**How it works:** Comment `/editorial-review` and smart-gate automatically decides if it's worth running. You don't need to manually check timing or size. + +### Token usage and costs + +Approximate costs per review (using Sonnet 4.5): +- Small PR (1-3 files, <500 lines): ~15K tokens (~$0.30-0.60) +- Medium PR (5-10 files, ~1000 lines): ~40K tokens (~$0.90-1.50) +- Large PR (15+ files, 2000+ lines): ~80K tokens (~$1.80-3.00) + +**Time savings:** Estimated 30-40 minutes per PR (agents identify issues in 2-4 minutes vs manual review) + +**Estimated annual cost for this repo:** $380-760/year (based on ~1,520 PRs/year at current rate, using agents on 25-50% of PRs at ~$1/review average) + +**Environmental impact:** ~0.15 kWh per review (~57 kg CO₂/year at 380 reviews, ~114 kg CO₂/year at 760 reviews). Equivalent to ~158-316 hours of video streaming annually. Using manual triggers and following the "When NOT to re-run" guidelines helps minimize unnecessary compute. + ## Workflows and architecture This repository uses two main Claude-powered workflows: @@ -16,12 +90,12 @@ This repository uses two main Claude-powered workflows: **Purpose:** On-demand quality checks for documentation content -**Components:** -- **Skill**: `/editorial-review` -- **Agents**: voice-tone, terminology, clarity (disabled), punctuation (planned) -- **Workflow**: `.github/workflows/docs-review.yml` -- **Scripts**: `classify-pr-type.sh` (PR classification), `post-inline-suggestions.sh` (GitHub API integration) -- **Triggers**: `/editorial-review` command (Claude Code or PR comment), manual workflow dispatch +**Architecture:** +- **Skill**: `/editorial-review` (orchestrates all agents) +- **Workflow**: `.github/workflows/docs-review.yml` (invokes skill) +- **Smart-gate**: Automatic filtering prevents wasteful runs +- **Scripts**: `classify-pr-type.sh`, `post-inline-suggestions.sh` +- **Triggers**: Manual only - `/editorial-review` comment or workflow dispatch ### API workflow @@ -38,19 +112,22 @@ This repository uses two main Claude-powered workflows: ### How it works -Use the `/editorial-review` command to run specialized agents on your documentation. This command works in two contexts: +The `/editorial-review` skill orchestrates specialized agents to review your documentation. The skill ensures consistent behavior whether run locally or in CI. **In Claude Code (local):** -1. Run the command in your terminal -2. Agents analyze files directly +1. Run `/editorial-review` in your terminal +2. Skill invokes appropriate agents (voice-tone, terminology, clarity) 3. Review findings in the conversation 4. Apply fixes to files manually **In GitHub PR (CI):** 1. Comment `/editorial-review` on any PR -2. Workflow triggers automatically -3. Agents analyze changed files -4. Results posted as inline PR suggestions +2. Workflow runs smart-gate checks (prevents waste): + - Skips if reviewed <60 min ago + - Skips if <10 lines changed + - Skips if formatting issues found (fix those first) +3. If gates pass: Invokes `/editorial-review` skill +4. Skill orchestrates agents and posts inline suggestions ### Usage @@ -75,20 +152,22 @@ Use the `/editorial-review` command to run specialized agents on your documentat /editorial-review ``` -The workflow will: -- Acknowledge the command immediately -- Run all agents (voice-tone, terminology, punctuation) +When gates pass, the workflow will: +- Invoke `/editorial-review` skill +- Skill runs agents: voice-tone, terminology (clarity disabled, punctuation not yet implemented) - Post up to 60 inline suggestions -- Provide downloadable artifact with full list +- Provide downloadable artifact if >60 suggestions found + +**Smart-gate blocks wasteful runs automatically** - you don't need to manually check timing/size. ### What gets reviewed -The editorial review runs multiple specialized agents: +Available agents: -- **voice-tone**: Second person, active voice, present tense, confidence -- **terminology**: Product names, feature names, formatting conventions -- **punctuation**: List punctuation, Oxford commas, quotation marks, dashes -- **clarity**: Sentence length, jargon, complexity (currently disabled) +- **voice-tone**: Second person, active voice, present tense, confidence *(runs in CI)* +- **terminology**: Product names, feature names, formatting conventions *(runs in CI)* +- **punctuation**: List punctuation, Oxford commas, quotation marks, dashes *(planned, not yet implemented)* +- **clarity**: Sentence length, jargon, complexity *(local only, disabled in CI)* ### Review output @@ -118,7 +197,7 @@ The agents provide a structured report with: 3. Review full list in `all-suggestions-full.txt` 4. Apply remaining suggestions manually -## Local Review with `/review` +## Local review with `/review` Run editorial reviews locally before opening a PR: @@ -164,6 +243,46 @@ Checks for: - Quotation marks - Dash usage +## Security and responsible use + +### Security considerations + +- **API keys**: Stored in GitHub Secrets and never exposed in logs or output +- **Scope**: Reviews only read documentation files (no code execution or system access) +- **Access control**: Manual triggers prevent automated abuse +- **Transparency**: All review output is publicly visible in PRs for audit +- **Rate limiting**: Use discretion when triggering reviews; contact maintainers if you need frequent reviews + +### Static analysis first (recommended) + +Before using LLM-based review, consider running fast, local checks first: + +**Pre-filter with static analysis:** +```bash +# Run markdownlint for formatting issues +npx markdownlint-cli2 "**/*.md" + +# Run Vale for style and terminology (if configured) +vale platform-enterprise_docs/ + +# Use grep for simple pattern matching +grep -r "Tower" --include="*.md" platform-enterprise_docs/ +``` + +**Benefits:** +- ⚡ Instant feedback (no API wait time) +- 💰 Zero cost (runs locally) +- 🌱 Minimal environmental impact +- 🎯 Catches simple issues without LLM + +**When to escalate to LLM review:** +- After static checks pass (handle simple issues first) +- For semantic issues (voice, tone, clarity) +- For complex terminology decisions +- For content that requires human-like judgment + +This layered approach reduces LLM usage by 50-60% while maintaining quality. + ## Documentation directory structure All directories support editorial review via `/editorial-review` command: