Skip to content

Add Agentic skills: draft-issue, review-blog-post, review-pull-request#9626

Merged
vitorvasc merged 46 commits intoopen-telemetry:mainfrom
vitorvasc:site_agentic-skills
Apr 30, 2026
Merged

Add Agentic skills: draft-issue, review-blog-post, review-pull-request#9626
vitorvasc merged 46 commits intoopen-telemetry:mainfrom
vitorvasc:site_agentic-skills

Conversation

@vitorvasc
Copy link
Copy Markdown
Member

@vitorvasc vitorvasc commented Apr 10, 2026

Summary

Contributes to #9397.

Introduces 3 agentic skills under .claude/skills/ to assist contributors working on this repo:

  • draft-issue - draft issues against the real .github/ISSUE_TEMPLATE/ templates
  • review-blog-post - review blog PRs/drafts for frontmatter, conventions, gh-url-hash, and OTel terminology
  • review-pull-request - review PRs against CI checks, CLA/approval workflow, refcache, and content conventions

All content introduced in this PR is an initial proposal. Iteration on the scope, prompts, and conventions are expected before merging. Feedback is always welcome :)

Usage

/review-pull-request

Arguments:

/review-pull-request <PR number or URL>

Examples:

/review-pull-request 9614
/review-pull-request https://github.com/open-telemetry/opentelemetry.io/pull/9614

/review-blog-post

Arguments:

/review-blog-post <blog post path or PR number>

Examples:

/review-blog-post content/en/blog/2026/my-new-post/index.md
/review-blog-post 9580

/draft-issue

Arguments:

/draft-issue <description of issue to draft>

Examples:

/draft-issue the Kubernetes getting-started page references a deprecated flag
/draft-issue feature: add a copy-to-clipboard button on code samples
/draft-issue blog: proposal for a post about exemplars in Prometheus

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
@otelbot-docs otelbot-docs Bot added the missing:docs-approval Co-owning SIG has provided approval, PR needs approval from docs maintainer label Apr 10, 2026
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Copy link
Copy Markdown
Member

@theletterf theletterf left a comment

Choose a reason for hiding this comment

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

Interesting! How are arguments parsed?

@vitorvasc
Copy link
Copy Markdown
Member Author

Interesting! How are arguments parsed?

@theletterf, Claude interprets them semantically, so I haven't been explicitly documenting that in the instructions. It's worked fine so far, but given our recent threads on Slack and @chalin's experience while using Copilot to interpret agent skills, I think it's worth being explicit about the expected arguments.

I'll update the skills to make it clearer. :)

vitorvasc and others added 2 commits April 23, 2026 09:17
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
@vitorvasc vitorvasc marked this pull request as ready for review April 23, 2026 12:17
@vitorvasc vitorvasc requested a review from a team as a code owner April 23, 2026 12:17
Copilot AI review requested due to automatic review settings April 23, 2026 12:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an initial set of contributor-focused “agentic skills” and supporting assets under .claude/ to help draft issues, review PRs/blog posts, and batch-triage GitHub issues for the OpenTelemetry website repo (and optionally other repos), including a triage sub-agent, schemas, and a frontmatter validation hook.

Changes:

  • Introduces 4 skills: otel-triage, otel-pr-review, otel-issue-draft, otel-blog-review.
  • Adds an otel-issue-triager sub-agent plus triage profile/state JSON schemas and repo-specific triage profiles.
  • Adds a .claude PreToolUse hook intended to validate blog frontmatter on Write/Edit operations.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
.claude/skills/otel-triage/SKILL.md Defines the batch issue triage workflow, report/state format, and profile merge behavior.
.claude/skills/otel-pr-review/SKILL.md Documents PR review workflow and CI check semantics for opentelemetry.io.
.claude/skills/otel-issue-draft/SKILL.md Guides drafting issues aligned to repo templates and label taxonomy.
.claude/skills/otel-blog-review/SKILL.md Documents blog post review rules (frontmatter, gh-url-hash, terminology, etc.).
.claude/agents/otel-issue-triager.md Sub-agent spec for per-issue deep triage analysis and dossier generation.
.claude/schemas/triage-state.schema.json JSON schema for triage run state tracking.
.claude/schemas/triage-profiles.schema.json JSON schema for triage profiles (repo config + evaluation criteria).
.claude/data/opentelemetry-website.yml Repo profile for open-telemetry/opentelemetry.io (keywords, taxonomy, templates).
.claude/data/bloomberg-mentorship.yml Evaluation profile for Bloomberg mentorship suitability.
.claude/hooks/hooks.json Registers a pre-tool hook for Write/Edit actions.
.claude/hooks/frontmatter-check.sh Hook script to validate blog post frontmatter and heading rules.

Comment thread .claude/data/opentelemetry-website.yml Outdated
Comment thread .claude/skills/review-pull-request/SKILL.md Outdated
Comment thread .claude/hooks/frontmatter-check.sh Outdated
Comment thread .claude/hooks/frontmatter-check.sh Outdated
Comment on lines +74 to +76
# Check for H1 headings in content (after frontmatter)
BODY=$(echo "$CONTENT" | awk 'BEGIN{n=0} /^---$/{n++; next} n>=2{print}')
if echo "$BODY" | grep -qE '^# [^#]'; then
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

The H1 check scans the entire body with a simple grep '^# ', which will also match shell comments or other lines inside fenced code blocks (common in blog posts), causing false failures. Consider tracking fenced-code state (``` / ~~~) and only flagging # headings outside code fences, or using a markdown-aware parser.

Suggested change
# Check for H1 headings in content (after frontmatter)
BODY=$(echo "$CONTENT" | awk 'BEGIN{n=0} /^---$/{n++; next} n>=2{print}')
if echo "$BODY" | grep -qE '^# [^#]'; then
# Check for H1 headings in content (after frontmatter), ignoring fenced code blocks
BODY=$(echo "$CONTENT" | awk 'BEGIN{n=0} /^---$/{n++; next} n>=2{print}')
if echo "$BODY" | awk '
BEGIN {
in_fence = 0
fence_char = ""
}
/^[[:space:]]*```/ {
if (!in_fence) {
in_fence = 1
fence_char = "`"
next
}
if (fence_char == "`") {
in_fence = 0
fence_char = ""
next
}
}
/^[[:space:]]*~~~/ {
if (!in_fence) {
in_fence = 1
fence_char = "~"
next
}
if (fence_char == "~") {
in_fence = 0
fence_char = ""
next
}
}
!in_fence && /^# [^#]/ {
found = 1
exit
}
END {
exit found ? 0 : 1
}
'; then

Copilot uses AI. Check for mistakes.
Comment thread .claude/skills/triage-issue/SKILL.md Outdated
Comment thread .claude/skills/triage-issue/SKILL.md Outdated
Comment thread .claude/schemas/triage-state.schema.json Outdated
Comment thread .claude/schemas/triage-state.schema.json Outdated
Comment thread .claude/data/opentelemetry-website.yml Outdated
Comment thread .claude/data/opentelemetry-website.yml Outdated
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented Apr 23, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
@vitorvasc vitorvasc force-pushed the site_agentic-skills branch from 730820e to d8cd6a3 Compare April 23, 2026 13:04
vitorvasc and others added 3 commits April 23, 2026 10:05
…skill references

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
@vitorvasc vitorvasc changed the title [WIP] Agentic skills: contributor Add Agentic skills: draft-issue, review-blog-post, review-pull-request, triage-issue Apr 23, 2026
Copy link
Copy Markdown
Contributor

@chalin chalin left a comment

Choose a reason for hiding this comment

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

Thanks for the updates. My main concern is that it feels like non-DRY docs to have so much content under the references subfolders, but I could be wrong. WDYT?

Included below is a review from Claude, with some focus on DRY-ness.

Review: Quality, Consistency, DRYness, Test Coverage

Overall assessment

The branch has evolved materially since my earlier reviews. Notably:

  • The bash hook was rewritten as Node (scripts/validate/front-matter-check/index.mjs) with a pure validate() function and unit tests.
  • triage-issue was decomposed into an orchestrator SKILL.md + 6 references/*.md files (progressive disclosure).
  • review-pull-request got the same treatment with 6 references/*.md files.
  • content/en/site/skills/_index.md now documents both skills and the new hook.

This is a big improvement. Most of my prior suggestions (progressive disclosure, collocating the hook as code+tests, self-consistency with existing conventions like test:local-tools) have been addressed. The issues below are what remains.


🔴 Blocking / correctness issues

1. triage-profiles.schema.jsonverdict_labels schema is internally inconsistent

"verdict_labels": {
  "required": ["recommended", "maybe", "not_suitable"],
  "additionalProperties": false,
  "properties": { "recommended": {  } }   // ← only `recommended` defined
}

With additionalProperties: false, the three required keys maybe and not_suitable are simultaneously required and disallowed. No value can validate — any call in triage-issue Phase 0.3 ("validate against schema, abort on failure") will always fail.

2. bloomberg-mentorship.yml is missing two required verdict_labels

verdict_labels:
  recommended: 'mentorship:bloomberg'

Even after fixing (1), this file lacks maybe and not_suitable. Consequence: when a reviewer runs /triage-issue --profile bloomberg-mentorship, profile load fails (or the skill silently skips validation, which is also a bug).

Fix: either mark only recommended as required in the schema, or add sensible defaults/empty strings for maybe / not_suitable in the YAML.


🟡 DRY / mutual consistency issues

3. Label taxonomy duplicated between draft-issue/SKILL.md and .claude/data/opentelemetry-website.yml

The draft-issue skill maintains a handwritten label taxonomy in prose. The opentelemetry-website.yml profile maintains a structured label taxonomy. They've already drifted:

Label In draft-issue SKILL.md In opentelemetry-website.yml
analytics+observability, IA, metadata-quality, dependencies, blocked
contribfest, mentorship:bloomberg
docs:mobile, docs:blog, docs:registry, docs:javascript, docs:vendor-list
sig:collector:refactor
triage:rejected, triage:rejected:duplicate, etc.

triage-issue/references/label-taxonomy.md explicitly says draft-issue is the source of truth, but the YAML schema says labels must come from PROFILE.repo.label_taxonomy. Pick one:

  • Recommended: make the YAML the source of truth; have draft-issue/SKILL.md point to it (keep the "PR-only labels" warning inline since that's editorial guidance, not a label list).

4. Action tokens / confidence tiers / close-reason mapping duplicated

Three files all carry the same tables with explicit "mirror when editing" notes:

  • .claude/agents/otel-issue-triager.md (488 lines, embeds everything)
  • .claude/skills/triage-issue/references/analysis-checklist.md
  • .claude/skills/triage-issue/references/gh-commands.md

The subagent file is the only version actually executed by the subagent at runtime; the orchestrator references are read by the human/main agent. You cannot trivially remove the duplication, but you can:

  • Refactor otel-issue-triager.md the same way triage-issue was refactored — move the checklist / tables into triage-issue/references/*.md and have the subagent file Read those files at runtime instead of inlining them. That makes the reference files truly the single source of truth.

5. Comment templates exist in three places

  • .claude/data/opentelemetry-website.ymlcomment_templates: (5 templates)
  • .claude/skills/triage-issue/references/comment-templates.md (fallback variants)
  • .claude/agents/otel-issue-triager.md## Comment Templates (fallback variants, again)

The last two are near-identical fallbacks. Pick one and reference it from the other.

6. Staleness tiers table duplicated verbatim

Same 4-row table (Critical / High / Medium / Low with day thresholds) in:

  • .claude/agents/otel-issue-triager.md §3
  • .claude/skills/triage-issue/references/analysis-checklist.md §3

🟡 Documentation self-consistency nits

7. _index.md says "covered by *.test.mjs files" (plural) — only one exists today

Pure logic lives in `index.mjs` and is covered by `*.test.mjs` files in the same
folder (`npm run test:local-tools` to run them).

The phrasing copies content/en/site/build/ci-workflows.md (which covers multiple tools), but here there's a single index.test.mjs. Acceptable as-is (the glob still works for future additions), but could read "is covered by index.test.mjs" for accuracy.

8. The "Pure logic lives in …" paragraph is under ## Hooks but is only about the one hook

Visually it reads as a generic section-level note. If you add a second hook later without tests, this paragraph becomes misleading. Consider moving it into the bullet for the blog front-matter hook.

9. .claude/hooks/hooks.json reaches outside the plugin directory

"command": "printf '%s' \"$TOOL_INPUT\" | node ${PLUGIN_DIR}/../scripts/validate/front-matter-check/index.mjs"

${PLUGIN_DIR}/.. traverses out of .claude/ and relies on the plugin being embedded in this repo (i.e., not installed as a stand-alone Claude plugin). This is intentional per the content/en/site/skills/_index.md split — hook config in .claude/, hook source under scripts/validate/. Worth a one-line comment in hooks.json (or a note in the site docs) so future maintainers don't "fix" the path.

10. .claude/agents/otel-issue-triager.md frontmatter name: OpenTelemetry Issue Triager

Noted in the earlier review — still the case on this branch. Rename to otel-issue-triager (matching file name and kebab-case convention) to avoid confusion with skill naming rules.


🟢 Test coverage — mostly good, a few gaps

scripts/validate/front-matter-check/index.test.mjs has 9 focused tests exercising validate() directly. Solid.

Not covered (suggest adding):

Gap Why it matters
content vs new_string fallback (Edit vs Write tool) This logic is in main() not validate(), so the behavior Edit tool calls depend on is untested. Could be covered by refactoring the precedence into a helper and testing it, or by spawning the script in a subprocess test.
CRLF line endings lines[0] !== '---' would be false ('---\r'); the hook silently no-ops on Windows-style input.
Missing closing --- (unterminated frontmatter) Current code returns [] (silent pass). Confirm this is intended and lock it in with a test.
H1-looking text inside a fenced code block /^# [^#]/m would match # comment inside a ```bash block and falsely flag. Non-trivial to fix without a real Markdown parser, but at minimum document the limitation or test that it's accepted as a known limitation.
Author with surrounding single quotes '[Jane](https://…)' The AUTHOR_LINK_RE allows it, but it's not in the tests, and it's the idiomatic form in the repo per review-blog-post/SKILL.md.
YAML block scalar variants >+, ` ,
Schema validation tests No tests validate bloomberg-mentorship.yml or opentelemetry-website.yml against triage-profiles.schema.json. A 10-line test with ajv would have caught issues 1 & 2 above.

Minor code nits:

  • valueOf() uses replace(/^['"]|['"]$/g, '') which strips quotes independently — "foo' becomes foo. Fine for well-formed input, but imprecise.
  • find() uses startsWith('${key}:'), so a literal line like title: x (indented) is skipped — acceptable, but worth a comment.
  • The // Run only when invoked directly guard import.meta.url === \file://${process.argv[1]}`will break on Windows (paths use backslashes, nofile://prefix inargv[1]`). Since the repo is Unix-first, not a blocker.

✅ What's done well on this branch

  • Pure-function architecture of index.mjs makes testing trivial and matches the existing scripts/gh/specs/pick-branch/ convention — good DRY-in-conventions.
  • triage-issue progressive disclosure is nicely executed: each references/*.md starts with a clear "When to read:" callout.
  • review-pull-request references/ split shrunk the SKILL.md from 454 → 205 lines while preserving all substantive detail.
  • Cross-skill links (labels.mdprocess-rules.md#stale-handling) keep the references network navigable.
  • _index.md site docs are consistent with the rest of content/en/site/ (same phrasing patterns as ci-workflows.md).
  • Refcache updates include all new publicly linked paths (hooks.json, scripts/validate/…, each SKILL.md).
  • Test file naming (index.test.mjs) matches test:local-tools glob without any package.json change.

Actionable summary

Blocking

  1. Fix triage-profiles.schema.json: either drop maybe/not_suitable from verdict_labels.required, or add them to properties. The current schema rejects every input.
  2. Fix bloomberg-mentorship.yml: add maybe and not_suitable entries under verdict_labels (or leave them empty if allowed by the fixed schema).

DRY / consistency (pick one canonical source)

  1. Label taxonomy: consolidate — likely make opentelemetry-website.yml the source and have draft-issue/SKILL.md defer to it; then audit the ~15 labels currently only in one of the two.
  2. Refactor .claude/agents/otel-issue-triager.md to read the same triage-issue/references/*.md files the orchestrator uses — eliminating the duplicated action tokens, confidence tiers, staleness table, close-reason mapping, and comment templates.
  3. Delete either triage-issue/references/comment-templates.md or the equivalent section in otel-issue-triager.md.

Test coverage

  1. Add an ajv-based schema validation test that loads every .claude/data/*.yml against triage-profiles.schema.json. This catches issues like (2) in CI.
  2. Add front-matter-check tests for: CRLF line endings, missing closing ---, Edit-tool new_string path, single-quoted single-line author, H1 inside fenced code block (either fix or document as known limitation).

Docs nits

  1. In content/en/site/skills/_index.md, move the "Pure logic lives in index.mjs …" paragraph under the blog front-matter hook bullet (it's per-hook, not section-wide). Consider singular "index.test.mjs".
  2. Add a brief comment in .claude/hooks/hooks.json (or adjacent docs) explaining the ${PLUGIN_DIR}/../scripts/validate/... traversal is intentional for this monorepo layout.
  3. Rename .claude/agents/otel-issue-triager.md frontmatter name: value from OpenTelemetry Issue Triagerotel-issue-triager.

Items 1, 2, and 6 are the only hard blockers — everything else is improvement.

…dict categories

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
…te instructions for labels

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
…om the triage-issue/references skill

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
@vitorvasc
Copy link
Copy Markdown
Member Author

/fix:format

@otelbot-docs
Copy link
Copy Markdown
Contributor

otelbot-docs Bot commented Apr 28, 2026

fix:format applied successfully in run 25069384208.

@vitorvasc vitorvasc force-pushed the site_agentic-skills branch from 6944f6d to 6b7265f Compare April 28, 2026 18:15
…skill

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Removes the triage-issue skill and its supporting infrastructure (subagent,
profile/state schemas, repo and Bloomberg-mentorship profiles) so this PR
focuses on the website-specific skills: draft-issue, review-blog-post, and
review-pull-request. The triage subsystem is generic (works on any repo via
--repo) and addresses scope/DRY concerns raised in review.

The deferred work is preserved on a local site_agentic-skills_triage branch.

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
…pstream

Replaces the inline label taxonomy with a pointer to `gh label list`,
`.github/component-label-map.yml`, and `sig-practices.md`. Replaces the five
inline issue-template body structures with a one-line directive to mirror the
real `.github/ISSUE_TEMPLATE/*.yml` section labels verbatim. Single source of
truth, fewer drift risks, ~half the lines.

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Drops front matter rules already enforced by the front-matter-check hook,
prettier, markdownlint (gh-url-hash), and cSpell — keeps only the judgment
layer those tools cannot check (multi-author folded form, sentence vs title
case, optional field semantics, OTel terminology, publish-timing gating,
cross-posting). Compresses the 72-line review checklist into a tight 7-item
walkthrough that complements the body. From 377 to ~180 lines.

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
…ta pointer

Inlines the 72-line references/content-review.md into the workflow steps and
final-pass checklist (single SKILL.md, no references/ subfolder). Drops the
bullet pointing at the now-deleted .claude/data/opentelemetry-website.yml.
Consolidates the two trailing References sections into one, and the duplicate
"Bundled references"/"References" headers into a single source-of-truth list.

Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
Signed-off-by: Vitor Vasconcellos <vvasconcellos1@gmail.com>
@vitorvasc vitorvasc force-pushed the site_agentic-skills branch from 2344bf6 to 94b5733 Compare April 28, 2026 19:09
Copy link
Copy Markdown
Contributor

@chalin chalin left a comment

Choose a reason for hiding this comment

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

TY @vitorvasc! ✨
Let's give this a spin, and incrementally improve. I think you've removed the triage skill (if so update the opening comment). Looking forward to seeing that land as well in a followup PR, if that's what you choose.

@otelbot-docs otelbot-docs Bot removed the missing:docs-approval Co-owning SIG has provided approval, PR needs approval from docs maintainer label Apr 29, 2026
@vitorvasc vitorvasc changed the title Add Agentic skills: draft-issue, review-blog-post, review-pull-request, triage-issue Add Agentic skills: draft-issue, review-blog-post, review-pull-request Apr 30, 2026
@vitorvasc
Copy link
Copy Markdown
Member Author

@chalin - that's correct! Just updated the title and description, and I'll raise the follow-up PR for the triaging skill as soon as I get back to it. :)

Let me know if you run into any issues with the skills in this PR.

@vitorvasc vitorvasc added this pull request to the merge queue Apr 30, 2026
Merged via the queue into open-telemetry:main with commit 805e163 Apr 30, 2026
25 checks passed
@vitorvasc vitorvasc deleted the site_agentic-skills branch April 30, 2026 10:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants