Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8e43588
feat: add review skill for blog posts
vitorvasc Apr 10, 2026
5d2b59a
feat: add otel-issue-draft skill
vitorvasc Apr 10, 2026
49f1ec3
feat: add otel-pr-review skill
vitorvasc Apr 10, 2026
3ce688a
feat: add otel-triage skill
vitorvasc Apr 10, 2026
3eab61e
remove 'contributor' folder, fix format
vitorvasc Apr 10, 2026
4ac1d03
add Bloomberg OSS mentorship evaluation criteria
vitorvasc Apr 10, 2026
0195f15
Merge branch 'main' into site_agentic-skills
vitorvasc Apr 23, 2026
984b474
chore(skills): enhance argument handling
vitorvasc Apr 23, 2026
495920f
Merge branch 'main' into site_agentic-skills
vitorvasc Apr 23, 2026
b8fcbdc
chore: rename review-blog-post skill
vitorvasc Apr 23, 2026
15de35e
chore: rename draft-issue skill
vitorvasc Apr 23, 2026
756422a
chore: rename review-pull-request skill
vitorvasc Apr 23, 2026
6e7dc34
chore: rename triage-issue skill
vitorvasc Apr 23, 2026
1bce79b
chore: add Polish language support to repo configuration
vitorvasc Apr 23, 2026
d8cd6a3
chore: address code review suggestions
vitorvasc Apr 23, 2026
8342181
Merge branch 'main' into site_agentic-skills
vitorvasc Apr 23, 2026
8480fbd
chore: improve error handling in frontmatter-check script and update …
vitorvasc Apr 23, 2026
f51b3a1
fix refcache
vitorvasc Apr 23, 2026
d4f1337
chore(schema): simplify examples for verdict labels in triage profiles
vitorvasc Apr 23, 2026
b07f64c
Results from /fix directive
otelbot[bot] Apr 23, 2026
7a5af3a
feat(frontmatter-check): replace bash script with node.js validation …
vitorvasc Apr 23, 2026
26800c7
update tests to use describe block and improve readability
vitorvasc Apr 23, 2026
36cfce0
fix refcache
vitorvasc Apr 23, 2026
9540d6b
npm run fix:format
vitorvasc Apr 23, 2026
eb7f3cd
migrate validation script and tests to scripts/validate/front-matter-…
vitorvasc Apr 23, 2026
f614530
chore(triage-issue): reduce skill size; add reference files
vitorvasc Apr 23, 2026
a447d96
chore(review-pull-request): reduce skill size; add reference files
vitorvasc Apr 23, 2026
2eae4e7
fix(triage-issue): clarify read-only behavior and link formatting in …
vitorvasc Apr 23, 2026
c07ba12
chore: add automation note for front matter rules enforcement
vitorvasc Apr 23, 2026
fc2d197
Results from /fix directive
otelbot[bot] Apr 23, 2026
bcecd90
fix(triage-issue): update command block omission rule and add new ver…
vitorvasc Apr 28, 2026
89a0ae3
fix(label-taxonomy): update and expand label taxonomy; remove duplica…
vitorvasc Apr 28, 2026
e4c2b71
chore: refactor otel-issue-triager agent, add instructions to read fr…
vitorvasc Apr 28, 2026
28b0e8b
fix(otel-issue-triager): update agent name to match naming conventions
vitorvasc Apr 28, 2026
2262678
chore: add comment to clarify path traversal in hook configuration
vitorvasc Apr 28, 2026
bceb1b3
chore: clarify source of truth for label taxonomy and usage instructions
vitorvasc Apr 28, 2026
7de665b
chore: clean up and reorganize documentation for review-pull-request …
vitorvasc Apr 28, 2026
9dab0fb
chore(review-pull-request): update step references in documentation
vitorvasc Apr 28, 2026
4ec2f17
chore(review-pull-request): remove redundant external references
vitorvasc Apr 28, 2026
7b92013
chore: defer triage-issue subsystem to a follow-up PR
vitorvasc Apr 28, 2026
e6bfe03
chore(draft-issue): defer label taxonomy and template structures to u…
vitorvasc Apr 28, 2026
3d6c8fa
chore(review-blog-post): trim mechanical rules and review checklist
vitorvasc Apr 28, 2026
7628ae3
chore(review-pull-request): inline content-review and drop deleted-da…
vitorvasc Apr 28, 2026
73a8ed7
chore(refcache): drop entry for removed triage-issue skill page
vitorvasc Apr 28, 2026
94b5733
chore: apply prettier formatting to trimmed skills
vitorvasc Apr 28, 2026
0ab1e1d
Merge branch 'main' into site_agentic-skills
vitorvasc Apr 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .claude/hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"_comment": "Path traversal is intentional: hook config lives in .claude/, source lives under scripts/validate/ as a repo-level tool.",
"command": "printf '%s' \"$TOOL_INPUT\" | node ${PLUGIN_DIR}/../scripts/validate/front-matter-check/index.mjs"
}
]
}
]
}
}
127 changes: 127 additions & 0 deletions .claude/skills/draft-issue/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
name: draft-issue
description: >-
Draft GitHub issues for opentelemetry.io following the real issue templates
under `.github/ISSUE_TEMPLATE/`, the contributing guide, and the repo's live
label taxonomy. Use when creating issue drafts from investigation findings or
conversation context.
argument-hint: '<description of issue to draft>'
allowed-tools: Read Grep Bash
effort: low
---

# Draft Issue

Drafts ready-to-paste GitHub issues for `open-telemetry/opentelemetry.io`. The
templates under `.github/ISSUE_TEMPLATE/` and the live label set are the sources
of truth — when this skill drifts from them, trust the source.

## Arguments {#arguments}

- If `$ARGUMENTS` is empty, infer context from the conversation. If there is
insufficient context, ask the user what issue to draft.
- Otherwise, treat the full `$ARGUMENTS` string as the description. There are no
flags.

## When to use

- After investigating a problem in the OTel site codebase.
- When a conversation reveals a bug, docs gap, or feature need.
- When drafting a blog post proposal for OTel.

## Issue types {#issue-types}

The repo has five issue templates. Auto-detect type from context, or accept an
explicit type from the user.

| Template file | Title prefix | Use for |
| --------------------- | ----------------- | ---------------------------------------------------- |
| `DOCS_UPDATE.yml` | `[Docs]: ` | Documentation errors, missing content, outdated info |
| `ISSUE_REPORT.yml` | `bug: ` | Site bugs, broken functionality, CI/workflow issues |
| `FEATURE_REQUEST.yml` | `feat: ` | New site features, tooling improvements |
| `BLOG_POST.yml` | `blog: ` | Blog post proposals (auto-applies `blog` label) |
| `PAGE_FEEDBACK.yml` | `page feedback: ` | Feedback from the "was this page helpful?" widget |

When drafting, read the chosen template under `.github/ISSUE_TEMPLATE/` and
mirror its section labels verbatim so GitHub maps the body back to template form
fields. Required fields are marked in the template.

For writing or reviewing the post itself after a `blog:` proposal lands, see the
`review-blog-post` skill.

## Drafting rules

From `content/en/docs/contributing/issues.md`:

- **Be specific.** Describe what is missing, out of date, wrong, or needs
improvement. "Fix the security docs" is too broad; "Add details to the
'Restricting network access' topic" is actionable.
- **Right-size the scope.** One issue = one reasonable unit of work; break broad
problems into smaller, reviewable issues.
- **Search first.** Check existing issues for duplicates before filing.
- **Reference related issues and PRs** with `#1234` for the same repo, or the
full URL for cross-repo references.
- **Concise, actionable** descriptions; no filler.
- Wrap body prose at 80 characters (convention, not enforced).

## Labels {#labels}

The repo's labels evolve; do not maintain a copy in this skill. Discover the
live set with:

```bash
gh label list --repo open-telemetry/opentelemetry.io --limit 200
```

Path-based auto-labeling (e.g. `blog`, `registry`, `i18n`, `lang:*`, several
`sig:*`) is defined in `.github/component-label-map.yml` and applies on PRs
only. You can still suggest these on issues manually.

Governance for the `triage:*`, `type:*`, `priority:*`, and `sig:*` families
lives in `content/en/docs/contributing/sig-practices.md`. Skip `type:discussion`
— its own label description says "Do not use, convert discussion issues into
real Discussions."

## Output format

Produce a fenced block with title, suggested labels, and body. Labels are
comma-separated so they can be passed directly to
`gh issue create --label "<comma,separated>"`.

```
**Title**: `bug: pr-approval-labels workflow adds ready-to-be-merged despite requested changes`

**Labels**: `CI/infra`, `Github actions`, `p2-medium`

---

### What happened?

The `pr-approval-labels` workflow currently adds the `ready-to-be-merged`
label when a PR receives an approving review, but it does not check whether
other reviewers have requested changes.

### What did you expect would happen?

The workflow should skip adding the `ready-to-be-merged` label if any
reviewer has a pending "changes requested" status on the PR.

### Name + path of the page

.github/workflows/pr-approval-labels.yml

### Additional context

Related to #1234.
```

## References {#references}

- `.github/ISSUE_TEMPLATE/*.yml` — five real templates; mirror their section
labels verbatim.
- `content/en/docs/contributing/issues.md` — user-facing guidance on filing
great issues.
- `content/en/docs/contributing/sig-practices.md` — label and triage governance.
- `.github/component-label-map.yml` — path-based PR auto-labeling.
- `gh label list --repo open-telemetry/opentelemetry.io --limit 200` — live
label set.
201 changes: 201 additions & 0 deletions .claude/skills/review-blog-post/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
---
name: review-blog-post
description: >-
Review OpenTelemetry blog posts for front matter compliance, content
conventions, GitHub link stability (`gh-url-hash`), spelling, and OTel
terminology. Use when reviewing a PR or draft under `content/en/blog/`.
argument-hint: '<blog post path or PR number>'
allowed-tools: Read Grep Glob Bash
model: sonnet
effort: medium
---

# Review Blog Post

Review workflow for OpenTelemetry blog posts. The repo tooling — the
front-matter-check hook, prettier, markdownlint (`gh-url-hash`), cSpell, and the
publish-labels workflow — enforces the mechanical rules; this skill covers the
judgment layer those tools cannot check.

## Arguments {#arguments}

- If `$ARGUMENTS` is empty, ask for a file path or PR number.
- If `$ARGUMENTS` contains `/` or ends in `.md`, treat it as a repo-relative
file path.
- If `$ARGUMENTS` is a GitHub URL containing `/pull/`, extract the PR number
after `/pull/`.
- If `$ARGUMENTS` is a bare number or starts with `#`, treat it as a PR number.
- Otherwise, stop and ask for a valid file path or PR number.

## Location

Blog posts live under `content/en/blog/YYYY/`. Use a single `short-name.md` when
there are no images, or a `short-name/index.md` directory when there are.
`short-name` is kebab-case — no dates, no special characters.

Scaffold from the archetype with Hugo:

```sh
npx hugo new content/en/blog/$(date +%Y)/short-name.md # no images
npx hugo new content/en/blog/$(date +%Y)/short-name/index.md # with images
```

## Front matter

A `PreToolUse` hook on `Write`/`Edit`
([`scripts/validate/front-matter-check/`][fm-check]) blocks any
`content/en/blog/**/*.md` change whose front matter is missing `title`,
`linkTitle`, `date` (must be `YYYY-MM-DD`), or `author` (must be a Markdown
link), or that introduces an H1 in the body. When reviewing an existing PR where
the hook didn't run, double-check those fields against
[`archetypes/blog.md`][archetype].

Judgment calls beyond the hook:

- **`title`** — sentence case is typical; a few proper-noun-heavy posts use
Title Case. Keep it descriptive.
- **`author`** — single-author posts use a single-line Markdown link; multi-
author posts must use the YAML folded form (`>-`) because the list spans
lines. The trailing `(Organization)` suffix is optional but common.

```yaml
author: '[Juraci Paixao Krohling](https://github.com/jpkrohling) (OllyGarden)'
```

```yaml
author: >-
[Johanna Öjeling](https://github.com/johannaojeling) (Grafana Labs),
[Juliano Costa](https://github.com/julianocosta89) (Datadog), [Tristan
Sloughter](https://github.com/tsloughter) (community)
```

- **`draft: true`** — work-in-progress; required for future-dated posts.
- **`canonical_url`** — set when the post is a cross-post; points to the
original. Preferred over the older `crosspost_url`.
- **`body_class: otel-with-contributions-from`** — set when secondary
contributors are credited in the intro paragraph (see
[Authoring rules](#authoring-rules)).
- **`issue`** — optional; only ~15% of recent posts set this.
- **`sig`** — sponsoring SIG (e.g. `Developer Experience SIG`). When present,
the PR should carry a matching `sig:<name>` label.
- **`cSpell:ignore`** — see [Spelling](#spelling).

## Submission prerequisites

From [`content/en/docs/contributing/blog.md`][contrib-blog]:

- Non-commercial, broadly relevant; no vendor product pitches.
- Prefer CNCF projects in examples (Jaeger for traces, Prometheus for metrics).
- A pre-submission issue is required; a SIG sponsor is strongly recommended
(ideally from a different company than the author).
- "Call for Contributors" posts follow the project-management process in
`open-telemetry/community`.

## Authoring rules {#authoring-rules}

- Start headings at `##` (no H1; the H1 is auto-generated from `title`) and
don't skip levels.
- Wrap prose at 80 columns (`npm run format`, prettier with
`proseWrap: always`). Don't hand-wrap — run the formatter. Skip URLs, code
blocks, and front matter values.
- Place images beside `index.md`; descriptive kebab-case filenames; always
include meaningful alt text.
- Always tag fenced code blocks with a language.
- Credit secondary contributors who aren't in the `author` field in the intro:
_"With contributions from [Name](https://github.com/username), …"_ and set
`body_class: otel-with-contributions-from`.
- Prefer active voice. Link external tools and OTel concepts on first mention
only — don't over-link.

## GitHub links (`gh-url-hash`)

A blog-only markdownlint rule
([`scripts/_md-rules/gh-url-hash/index.mjs`][gh-rule], enabled via
`content/en/blog/.markdownlint.yaml`) blocks default-branch links
(`main`/`master`) and short commit hashes in GitHub `blob`/`tree` URLs. Tags,
release refs, and full 40-character SHAs are allowed.

Run `npm run fix:markdown` to auto-fix default-branch links by resolving the
current HEAD commit. Auto-fix needs network access; on rate-limit or unreachable
failures, fix manually with a full SHA or a release tag.

## Spelling {#spelling}

Spell-checking uses cSpell (`.cspell.yml`). Repo-wide additions go in
`.cspell/en-words.txt`; post-local words go in the `cSpell:ignore` front matter
field. Add `# prettier-ignore` immediately above `cSpell:ignore` only when the
line is long enough that the formatter would wrap it:

```yaml
# prettier-ignore
cSpell:ignore: jpkrohling Krohling logdedup OllyGarden OTTL Paixao telemetrygen
```

## OTel terminology

- **OpenTelemetry** is one word; **OTel** is acceptable shorthand only after the
first full mention.
- Signal names are lowercase: traces, metrics, logs.
- Component names are cased: SDK, API, Collector.
- Proper nouns: Jaeger, Zipkin, Prometheus, Kubernetes.
- Semantic-convention attribute names should match the current names in
[`docs/specs/semconv/`](https://opentelemetry.io/docs/specs/semconv/).

## Publish timing

- The `date` field drives publication. Use `draft: true` while the date is in
the future.
- A daily workflow ([`blog-publish-labels.yml`][publish-workflow], 7 AM UTC)
adds `ready-to-be-merged` only when **all** hold: docs-approver approval,
SIG/component-owner approval, and `date:` is in the past or today. The
workflow only labels — a human still merges.

## Cross-posting

Decide which version is canonical (typically the original OpenTelemetry post).
On any external copy, mention the original, link back to it, and set the
platform's canonical-URL tag if available. When the OTel post is the copy, set
`canonical_url` in its front matter.

## Reviewing a PR

Walk the post top-to-bottom against the sections above. The mechanical checks
below are what humans most often miss after the hook + linters pass:

1. Run `npm run format` (wrap), `npm run fix:markdown` (`gh-url-hash`),
`npm run check:spelling`. All must be clean.
2. Author front matter: single-line vs. folded `>-` form correct?
`(Organization)` accurate?
3. Multi-author intro credits + `body_class: otel-with-contributions-from` set
if needed.
4. `gh-url-hash`: no `main`/`master` or short SHAs; tags or full SHAs only.
5. Submission prerequisites: non-commercial, CNCF tools preferred, SIG sponsor
identified.
6. OTel terminology consistent throughout.
7. `date` and `draft` set so the publish workflow gates the merge as intended.

## References

- [`archetypes/blog.md`][archetype] — canonical front matter template.
- [`content/en/docs/contributing/blog.md`][contrib-blog] — submission process,
cross-posting, `gh-url-hash` rationale.
- `content/en/blog/.markdownlint.yaml` — enables `gh-url-hash` for blog posts.
- [`scripts/_md-rules/gh-url-hash/index.mjs`][gh-rule] — authoritative rule
behavior.
- [`scripts/validate/front-matter-check/`][fm-check] — write-time hook source +
tests.
- [`.github/workflows/blog-publish-labels.yml`][publish-workflow] — publish date
and approval gating.
- `.cspell.yml`, `.cspell/en-words.txt` — spell-check configuration.
- `package.json` — `prettier.proseWrap: always` drives 80-char wrapping.

[archetype]:
https://github.com/open-telemetry/opentelemetry.io/blob/main/archetypes/blog.md
[contrib-blog]:
https://github.com/open-telemetry/opentelemetry.io/blob/main/content/en/docs/contributing/blog.md
[fm-check]:
https://github.com/open-telemetry/opentelemetry.io/tree/main/scripts/validate/front-matter-check
[gh-rule]:
https://github.com/open-telemetry/opentelemetry.io/blob/main/scripts/_md-rules/gh-url-hash/index.mjs
[publish-workflow]:
https://github.com/open-telemetry/opentelemetry.io/blob/main/.github/workflows/blog-publish-labels.yml
Loading