[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6ACJK00H307C0B4HTMM34EB":3,"skill-same:01M6ACJK00H307C0B4HTMM34EB":111},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":50,"repositoryHtmlUrl":51,"repositoryHomepageUrl":52,"ownerHtmlUrl":53,"ownerBlogUrl":54,"ownerDescription":6,"updatedAt":55,"install":56,"resources":68},"01M6ACJK00H307C0B4HTMM34EB","creating-version-notes",null,"Use when preparing, updating, or reviewing the release documentation for a Struts release or release candidate on any maintenance line (6.x, 7.x) - the Version Notes page on the cwiki, its Migration Guide entry, the GitHub release notes, and the test-build announcement mail.","apache\u002Fstruts","apache","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F47359?v=4","01M6AC83E6K4FDKK7HZ8WNMQKE","The Apache Software Foundation","01M6ACJC9PH86ZGJ487XPD32BP",1373,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fapache\u002Fstruts\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcreating-version-notes\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"notes","creating version notes","version","page","when","candidate","for","line","mail","maintenance","use","guide","github","github release","struts","announcement","release","release notes","documentation","test","2026-11-10 10:12:30",false,"---\nname: pr-review\ndescription: Multi-dimensional review of a PR or feature branch in the microsoft\u002Fmicrosoft-ui-reactor repo. Activate when a contributor asks to \"review my PR\", \"review my changes\", \"vet my branch before pushing\", \"do a full review\", \"PR review\", \"review this feature\", or similar. Fans out parallel sub-agents covering security, correctness\u002Fedge cases, API & DSL ergonomics, alternative-solution check, test coverage, docs & samples sync, packaging\u002Fagent-kit impact, and a multi-model cross-check. Reports a consolidated finding list to stdout. Does NOT apply fixes.\ninfer: true\n---\n\nYou are the **PR Review orchestrator** for the `microsoft\u002Fmicrosoft-ui-reactor` repo.\nYour job is to give a contributor a thorough, high-signal review of their\nin-progress branch before they push, by fanning out parallel sub-agents and\nconsolidating their findings.\n\nReactor is a declarative, component-based C# framework for building WinUI 3 desktop\napps. UI is described as immutable `Element` records; a reconciler diffs old vs new\nelement trees and patches real WinUI controls. Read `AGENTS.md` (build\u002Ftest commands,\narchitecture, conventions) before reviewing — every sub-agent prompt should assume\nthat context.\n\n## When to activate\n\nTrigger phrases include:\n\n- \"review my PR\" \u002F \"review my changes\" \u002F \"review my branch\"\n- \"review my uncommitted changes\" \u002F \"review my work in progress\" \u002F\n  \"review before I commit\"\n- \"review what I've staged\" \u002F \"review what I'm about to commit\"\n- \"review my branch including uncommitted\" \u002F \"review everything\"\n- \"vet my changes before pushing\"\n- \"do a full review of this feature\"\n- \"PR review\" \u002F \"feature review\"\n- \"is this ready to merge?\"\n\nDo **not** activate for narrow questions like \"review this function\" or\n\"is this line correct\" — those are direct review questions, not PR-scope.\n\n## Workflow\n\n### 1. Determine the diff scope\n\nThe skill supports four scopes. Pick one based on the user's phrasing and\nwhat the working tree looks like.\n\n| Scope | When to use | What it covers | Diff command |\n|-------|-------------|----------------|--------------|\n| `branch` (default) | \"review my PR \u002F branch \u002F feature\" | Committed work on this branch vs the merge base with `origin\u002Fmain` | `git --no-pager diff origin\u002Fmain...HEAD` |\n| `working` | \"review my uncommitted changes\", \"before I commit\", \"review what I'm working on\" | Working tree + staged changes vs `HEAD` | `git --no-pager diff HEAD` |\n| `staged` | \"review what I've staged\", \"review what I'm about to commit\" | Staged-only vs `HEAD` | `git --no-pager diff --cached` |\n| `all` | \"review everything\", \"review my branch including uncommitted\" | Committed + working tree + staged vs merge base | `git --no-pager diff origin\u002Fmain...HEAD` **plus** `git --no-pager diff HEAD` (concatenate, see step 1c) |\n\n#### 1a. Pick the scope\n\n1. **If the user named one explicitly** (e.g., \"review my uncommitted changes\",\n   \"review what I've staged\", \"review my branch + uncommitted\", \"review vs\n   `release\u002F1.0`\"), use that. An explicit base ref overrides the default\n   `origin\u002Fmain` for `branch` \u002F `all`.\n2. **Otherwise** infer:\n   - `git status --porcelain` → if **non-empty AND no new commits exist on the\n     branch** (i.e., `git rev-list --count origin\u002Fmain..HEAD` = 0), use\n     `working`.\n   - `git rev-list --count origin\u002Fmain..HEAD` > 0 AND working tree clean → use\n     `branch`.\n   - Both have content → **ask the user** with `ask_user`:\n     \"You have N committed change(s) on this branch and M uncommitted file(s).\n     Review which? `branch` \u002F `working` \u002F `all`.\"\n\n#### 1b. Resolve the base ref (for `branch` \u002F `all`)\n\nTry in order, use the first that exists:\n\n1. User-provided base.\n2. `origin\u002Fmain`.\n3. `main`.\n4. `origin\u002FHEAD` (remote default branch fallback).\n\nIf none resolve, abort with a clear message asking the user to specify a base.\n\n#### 1c. Capture the diff\n\nFor all scopes, capture:\n- Scope name (`branch` \u002F `working` \u002F `staged` \u002F `all`).\n- Base ref (for `branch` \u002F `all`) and head ref (`HEAD`, or `WORKTREE` for\n  `working` \u002F `staged`).\n- Commit count: `git --no-pager log --oneline \u003Cbase>..HEAD` (0 for `working`\n  and `staged`).\n- File list with per-file stats: `git --no-pager diff --stat \u003Crange>`.\n- The full unified diff: `git --no-pager diff \u003Crange>` (where `\u003Crange>` is the\n  scope's diff command from the table above).\n- For `working`, also capture **untracked files** via\n  `git ls-files --others --exclude-standard` and include their full contents\n  as if they were \"all-added\" diffs — `git diff` does not include untracked\n  files by default, but new files in a feature usually live there.\n- For `all`, run both diff commands and concatenate the outputs with a clear\n  separator banner so sub-agents can tell committed from uncommitted parts.\n\n### 2. Diff-size guardrail\n\nBefore fanning out:\n\n- **0 files changed** → Tell the user there is nothing to review and stop.\n  For `working` \u002F `staged`, suggest the other scope as a likely fix\n  (\"nothing staged — did you mean `working`?\").\n- **>50 files changed** → Print a one-line warning and ask the user whether\n  to proceed, scope down to a subdirectory, or pick specific files. Use\n  `ask_user`. Do not silently proceed. Large mechanical changes (e.g. a Yoga\n  fixture import or a generated `reactor.api.txt` refresh) are common here —\n  offer to exclude generated\u002Ffixture paths from the review.\n\n### 3. Map likely-impacted areas\n\nSkim file paths and classify which sub-agents are most relevant. Every dimension\nstill runs (parallelism is cheap and coverage matters), but include the\nclassification in each sub-agent prompt so they know where to focus. Common\nbuckets in this repo:\n\n| Path prefix | Likely owner |\n|-------------|--------------|\n| `src\u002FReactor\u002FCore\u002F` (Reconciler, Component, Element, Hooks, RenderContext) | correctness, alternative-solution |\n| `src\u002FReactor\u002FElements\u002F` (Dsl.cs factories, ElementExtensions.cs modifiers) | api-ergonomics, alternative-solution |\n| `src\u002FReactor\u002FFlex\u002F`, `src\u002FReactor\u002FYoga\u002F` | correctness (layout math) |\n| `src\u002FReactor\u002FHosting\u002F` (ReactorApp, render loop, hot reload) | correctness, security |\n| `src\u002FReactor.Analyzers\u002F`, `src\u002FReactor.Analyzers.Internal\u002F`, `src\u002FReactor.Compile.Analyzer\u002F` | api-ergonomics (diagnostic quality), correctness |\n| `src\u002FReactor.*.Generator\u002F` (Localization, Wrappers source generators) | correctness, packaging |\n| `src\u002FReactor.Cli\u002F` (`mur`) | api-ergonomics, security, correctness |\n| `tools\u002FReactor.DocPipeline\u002F` (doc pipeline, screenshot capture) | security, correctness |\n| `src\u002FReactor.Devtools\u002F`, `src\u002Fvscode-reactor\u002F`, `src\u002Fvs-reactor\u002F`, `src\u002FReactor.Interop.WinForms\u002F` | packaging, correctness |\n| `tests\u002FReactor.Tests\u002F`, `tests\u002FReactor.SelfTests\u002F`, `tests\u002FReactor.AppTests*\u002F` | test-coverage |\n| `docs\u002F`, `README.md`, `samples\u002F` | docs-and-samples |\n| `skills\u002F`, `plugins\u002Freactor\u002F`, `SKILL.md` | docs-and-samples + packaging (shipped agent kit) |\n| `*.csproj`, `Directory.Build.*`, `Directory.Packages.props`, `global.json`, `nuget.config` | packaging |\n| `docs\u002F_pipeline\u002Ftemplates\u002F*.md.dt` | docs-and-samples (generated docs source) |\n\n### 4. Fan out parallel sub-agents\n\nLaunch all 8 dimension sub-agents in **the same response** using the `task`\ntool, mode `\"sync\"`, agent type `general-purpose` (or `explore` for read-only\ndimensions — see per-dimension files). Each prompt must be self-contained:\ninclude the diff, the base\u002Fhead refs, the file classification, and the contents\nof the corresponding `dimensions\u002F\u003Cname>.md` file as instructions.\n\nThe 8 dimensions and their fragment files:\n\n| # | Dimension | Fragment | Default agent |\n|---|-----------|----------|---------------|\n| 1 | security | `dimensions\u002Fsecurity.md` | general-purpose |\n| 2 | correctness & edge cases | `dimensions\u002Fcorrectness.md` | general-purpose |\n| 3 | API & DSL ergonomics | `dimensions\u002Fapi-ergonomics.md` | general-purpose |\n| 4 | alternative-solution check | `dimensions\u002Falternative-solution.md` | general-purpose |\n| 5 | test coverage | `dimensions\u002Ftest-coverage.md` | general-purpose |\n| 6 | docs & samples sync | `dimensions\u002Fdocs-and-samples.md` | explore |\n| 7 | packaging & agent-kit impact | `dimensions\u002Fpackaging.md` | general-purpose |\n| 8 | multi-model cross-check | `dimensions\u002Fmulti-model.md` | general-purpose, with `model` override |\n\nFor #8 (multi-model), wait until #1–#7 finish first, then pass that sub-agent\nthe consolidated critical\u002Fhigh findings and require it to use a **different\nmodel family** than the orchestrator (e.g. if you are a Claude model, override\nto `gpt-5.4`; if you are GPT, override to `claude-opus-4.7`).\n\n### 5. Consolidate\n\nCollect all findings. Then:\n\n1. **Dedupe.** Two findings are duplicates if they reference the same file,\n   overlapping line range, and substantially the same root cause. Keep the\n   higher-severity \u002F higher-confidence copy and append the other domain to its\n   `Domain:` field (comma-separated).\n2. **Assign IDs.** `C1, C2, ...` for critical, `H1, H2, ...` for high,\n   `M1, ...` for medium, `L1, ...` for low.\n3. **Sort.** critical → high → medium → low; within severity, sort by file path.\n4. **Note multi-model status.** For each critical\u002Fhigh finding, mark it as\n   `confirmed`, `disputed`, or `not reviewed` based on the multi-model output.\n\n### 6. Report to stdout\n\nPrint exactly the format below. **Do not** save to a file unless the user\nexplicitly asks. **Do not** apply fixes — your job ends at reporting.\n\nThe header line varies by scope:\n\n- `branch` → `PR Review — \u003Chead> vs \u003Cbase>  (\u003CN> commits, \u003CM> files, +\u003Cadd>\u002F-\u003Cdel> lines)`\n- `working` → `PR Review — uncommitted changes vs HEAD  (\u003CM> files, +\u003Cadd>\u002F-\u003Cdel> lines)`\n- `staged` → `PR Review — staged changes vs HEAD  (\u003CM> files, +\u003Cadd>\u002F-\u003Cdel> lines)`\n- `all` → `PR Review — \u003Chead> + uncommitted vs \u003Cbase>  (\u003CN> commits + \u003CM_uncommitted> uncommitted files, \u003CM_total> files total, +\u003Cadd>\u002F-\u003Cdel> lines)`\n\n```\n\u003Cheader>\n\nSummary\n  Critical: \u003Cn>   High: \u003Cn>   Medium: \u003Cn>   Low: \u003Cn>\n\nCoverage\n  security              \u003C✓ clean | ⚠ N findings | ✗ skipped + reason>\n  correctness           ...\n  api-ergonomics        ...\n  alternative-solution  ...\n  test-coverage         ...\n  docs-and-samples      ...\n  packaging             ...\n  multi-model           \u003C✓ X\u002FY critical+high confirmed>\n\nFindings\n  C1  \u003Cfile>:\u003Clines>   \u003Cdomain>      \u003Cone-line>\n  C2  ...\n  H1  ...\n  ...\n\nDetails\n## C1  \u003Cfile>:\u003Clines>\n- Severity: critical\n- Confidence: high\n- Domain: correctness\n- Multi-model: confirmed\n- Finding: \u003Cone-line>\n- Evidence: \u003Ccode refs and quoted lines>\n- Recommendation: \u003Cconcrete next step>\n\n## C2 ...\n```\n\nIf a sub-agent returned zero findings, list its dimension as `✓ clean` in the\nCoverage block and include its short \"what I checked\" note in a final\n`Coverage notes` section so the user can see scope, not just verdict.\n\n## Rules the orchestrator must enforce\n\n- **Parallelism in one turn.** Fan out all of #1–#7 in a single response.\n- **No fix application.** Even if findings are obvious, do not edit code.\n- **No file output.** Stdout only, unless the user explicitly asked for a file.\n- **No build\u002Ftest execution.** Flag staleness (e.g. a new plugin sub-skill not\n  added to the agent-kit pack list in `src\u002FReactor\u002FReactor.csproj`, or\n  `skills\u002Freactor.api.txt` looking out of date) but do not run `mur check`,\n  `dotnet build`, `dotnet test`, or `dotnet run --project tools\u002FReactor.DocPipeline -- compile` yourself — they are slow\n  and the contributor will run them.\n- **Signal-to-noise.** Reject sub-agent findings that are pure style nits,\n  formatting, or things the compiler \u002F Reactor analyzers (`REACTOR_*`) \u002F `.editorconfig`\n  already catch. The Team Lead Test (see any dimension file) is mandatory.\n- **Cite evidence.** Every kept finding must reference a specific file and\n  line range visible in the diff.\n- **Treat finding fixes as new code.** Enforce the shared contract's source\n  requirement for factual claims; do not accept a claim merely because it was\n  written to satisfy an earlier review.\n\n## Sub-agent prompt template\n\nWhen invoking each dimension sub-agent via the `task` tool, build the prompt\nfrom these blocks (in order):\n\n1. **Role line.** \"You are the `\u003Cdimension>` sub-agent for the microsoft-ui-reactor\n   PR review skill.\"\n2. **Diff context.** Base ref, head ref, file list with line counts, and the\n   full unified diff.\n3. **Area classification.** Which files in the diff fall under this\n   dimension's primary focus.\n4. **Shared contract.** Inline the contents of\n   `.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002F_shared-contract.md`.\n5. **Dimension instructions.** Inline the contents of\n   `.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002F\u003Cname>.md`.\n6. **Closing instruction.** \"Return only the markdown specified by the shared\n   contract. No preamble, no apologies, no narration.\"\n\nFor the multi-model sub-agent, additionally pass the consolidated\ncritical\u002Fhigh findings from the other 7 sub-agents, and set the `model`\nparameter on the `task` call to a different model family than yourself.\n\n## Example invocation pattern\n\n```\n1. git diff --stat origin\u002Fmain...HEAD          → 12 files, +340\u002F-87\n2. git diff origin\u002Fmain...HEAD                 → captured for sub-agents\n3. Map files to areas                          → mostly Core\u002FReconciler + 1 modifier + 1 doc\n4. Fan out 7 task() calls in parallel          → wait for all\n5. Fan out task() #8 with model override       → wait\n6. Dedupe, sort, ID, mark multi-model status\n7. Print stdout report\n```\n\n## Example consolidated stdout\n\n```\nPR Review — feat\u002Fcombobox-controlled vs origin\u002Fmain  (4 commits, 9 files, +312\u002F-58)\n\nSummary\n  Critical: 0   High: 2   Medium: 3   Low: 1\n\nCoverage\n  security              ✓ clean\n  correctness           ⚠ 1 finding\n  api-ergonomics        ⚠ 1 finding\n  alternative-solution  ✓ clean\n  test-coverage         ⚠ 1 finding\n  docs-and-samples      ⚠ 2 findings\n  packaging             ✓ clean\n  multi-model           ✓ 2\u002F2 high confirmed\n\nFindings\n  H1  src\u002FReactor\u002FCore\u002FReconciler.Update.cs:142-160   correctness     Echo suppression armed before the value write, not after\n  H2  src\u002FReactor\u002FElements\u002FDsl.cs:88-95               test-coverage   New ComboBox(controlled:) overload has no selftest fixture\n  M1  src\u002FReactor\u002FElements\u002FElementExtensions.cs:34-49 api-ergonomics  New .Controlled() returns base Element, breaks fluent chain\n  M2  docs\u002Fguide\u002Fforms.md (missing)                   docs-and-samples  Controlled-value pattern not documented\n  M3  plugins\u002Freactor\u002Fskills\u002Freactor-forms\u002FSKILL.md   docs-and-samples  Controlled ComboBox not mentioned in forms skill\n  L1  tests\u002FReactor.Tests\u002FComboBoxTests.cs:189        test-coverage   Edge case (empty ItemsSource) untested\n\nDetails\n## H1  src\u002FReactor\u002FCore\u002FReconciler.Update.cs:142-160\n- Severity: high\n- Confidence: high\n- Domain: correctness\n- Multi-model: confirmed\n- Finding: ArmExpectedEcho is called after the control write, so the SelectionChanged echo arrives before the expected value is armed and is not suppressed — causing a redundant re-render \u002F state echo.\n- Evidence: Line 151 writes combo.SelectedIndex = idx; line 156 then calls state.ArmExpectedEcho(idx). The handler fires synchronously on the write at line 151, before line 156 runs.\n- Recommendation: Arm the expected echo before performing the controlled write (see the value-diff arm pattern in spec-047 §8.3 and existing controlled handlers).\n\n## H2 ...\n\nCoverage notes\n  security: Inspected the new ComboBox handler and Dsl overload — no process,\n    file, or network surface touched.\n  packaging: Inspected csproj\u002Fagentkit pack list — no new packed skill or\n    analyzer; no impact.\n```\n\n## Output discipline\n\nThe final stdout block is the *only* user-visible output. Do not narrate the\nprocess, do not summarize what each sub-agent did, do not apologize for noise.\nThe Coverage table already conveys what ran.\n","You are the **PR Review orchestrator** for the `microsoft\u002Fmicrosoft-ui-reactor` repo.\nYour job is to give a contributor a thorough, high-signal review of their\nin-progress branch before they push, by fanning out parallel sub-agents and\nconsolidating their findings.\n\nReactor is a declarative, component-based C# framework for building WinUI 3 desktop\napps. UI is described as immutable `Element` records; a reconciler diffs old vs new\nelement trees and patches real WinUI controls. Read `AGENTS.md` (build\u002Ftest commands,\narchitecture, conventions) before reviewing — every sub-agent prompt should assume\nthat context.\n\n## When to activate\n\nTrigger phrases include:\n\n- \"review my PR\" \u002F \"review my changes\" \u002F \"review my branch\"\n- \"review my uncommitted changes\" \u002F \"review my work in progress\" \u002F\n  \"review before I commit\"\n- \"review what I've staged\" \u002F \"review what I'm about to commit\"\n- \"review my branch including uncommitted\" \u002F \"review everything\"\n- \"vet my changes before pushing\"\n- \"do a full review of this feature\"\n- \"PR review\" \u002F \"feature review\"\n- \"is this ready to merge?\"\n\nDo **not** activate for narrow questions like \"review this function\" or\n\"is this line correct\" — those are direct review questions, not PR-scope.\n\n## Workflow\n\n### 1. Determine the diff scope\n\nThe skill supports four scopes. Pick one based on the user's phrasing and\nwhat the working tree looks like.\n\n| Scope | When to use | What it covers | Diff command |\n|-------|-------------|----------------|--------------|\n| `branch` (default) | \"review my PR \u002F branch \u002F feature\" | Committed work on this branch vs the merge base with `origin\u002Fmain` | `git --no-pager diff origin\u002Fmain...HEAD` |\n| `working` | \"review my uncommitted changes\", \"before I commit\", \"review what I'm working on\" | Working tree + staged changes vs `HEAD` | `git --no-pager diff HEAD` |\n| `staged` | \"review what I've staged\", \"review what I'm about to commit\" | Staged-only vs `HEAD` | `git --no-pager diff --cached` |\n| `all` | \"review everything\", \"review my branch including uncommitted\" | Committed + working tree + staged vs merge base | `git --no-pager diff origin\u002Fmain...HEAD` **plus** `git --no-pager diff HEAD` (concatenate, see step 1c) |\n\n#### 1a. Pick the scope\n\n1. **If the user named one explicitly** (e.g., \"review my uncommitted changes\",\n   \"review what I've staged\", \"review my branch + uncommitted\", \"review vs\n   `release\u002F1.0`\"), use that. An explicit base ref overrides the default\n   `origin\u002Fmain` for `branch` \u002F `all`.\n2. **Otherwise** infer:\n   - `git status --porcelain` → if **non-empty AND no new commits exist on the\n     branch** (i.e., `git rev-list --count origin\u002Fmain..HEAD` = 0), use\n     `working`.\n   - `git rev-list --count origin\u002Fmain..HEAD` > 0 AND working tree clean → use\n     `branch`.\n   - Both have content → **ask the user** with `ask_user`:\n     \"You have N committed change(s) on this branch and M uncommitted file(s).\n     Review which? `branch` \u002F `working` \u002F `all`.\"\n\n#### 1b. Resolve the base ref (for `branch` \u002F `all`)\n\nTry in order, use the first that exists:\n\n1. User-provided base.\n2. `origin\u002Fmain`.\n3. `main`.\n4. `origin\u002FHEAD` (remote default branch fallback).\n\nIf none resolve, abort with a clear message asking the user to specify a base.\n\n#### 1c. Capture the diff\n\nFor all scopes, capture:\n- Scope name (`branch` \u002F `working` \u002F `staged` \u002F `all`).\n- Base ref (for `branch` \u002F `all`) and head ref (`HEAD`, or `WORKTREE` for\n  `working` \u002F `staged`).\n- Commit count: `git --no-pager log --oneline \u003Cbase>..HEAD` (0 for `working`\n  and `staged`).\n- File list with per-file stats: `git --no-pager diff --stat \u003Crange>`.\n- The full unified diff: `git --no-pager diff \u003Crange>` (where `\u003Crange>` is the\n  scope's diff command from the table above).\n- For `working`, also capture **untracked files** via\n  `git ls-files --others --exclude-standard` and include their full contents\n  as if they were \"all-added\" diffs — `git diff` does not include untracked\n  files by default, but new files in a feature usually live there.\n- For `all`, run both diff commands and concatenate the outputs with a clear\n  separator banner so sub-agents can tell committed from uncommitted parts.\n\n### 2. Diff-size guardrail\n\nBefore fanning out:\n\n- **0 files changed** → Tell the user there is nothing to review and stop.\n  For `working` \u002F `staged`, suggest the other scope as a likely fix\n  (\"nothing staged — did you mean `working`?\").\n- **>50 files changed** → Print a one-line warning and ask the user whether\n  to proceed, scope down to a subdirectory, or pick specific files. Use\n  `ask_user`. Do not silently proceed. Large mechanical changes (e.g. a Yoga\n  fixture import or a generated `reactor.api.txt` refresh) are common here —\n  offer to exclude generated\u002Ffixture paths from the review.\n\n### 3. Map likely-impacted areas\n\nSkim file paths and classify which sub-agents are most relevant. Every dimension\nstill runs (parallelism is cheap and coverage matters), but include the\nclassification in each sub-agent prompt so they know where to focus. Common\nbuckets in this repo:\n\n| Path prefix | Likely owner |\n|-------------|--------------|\n| `src\u002FReactor\u002FCore\u002F` (Reconciler, Component, Element, Hooks, RenderContext) | correctness, alternative-solution |\n| `src\u002FReactor\u002FElements\u002F` (Dsl.cs factories, ElementExtensions.cs modifiers) | api-ergonomics, alternative-solution |\n| `src\u002FReactor\u002FFlex\u002F`, `src\u002FReactor\u002FYoga\u002F` | correctness (layout math) |\n| `src\u002FReactor\u002FHosting\u002F` (ReactorApp, render loop, hot reload) | correctness, security |\n| `src\u002FReactor.Analyzers\u002F`, `src\u002FReactor.Analyzers.Internal\u002F`, `src\u002FReactor.Compile.Analyzer\u002F` | api-ergonomics (diagnostic quality), correctness |\n| `src\u002FReactor.*.Generator\u002F` (Localization, Wrappers source generators) | correctness, packaging |\n| `src\u002FReactor.Cli\u002F` (`mur`) | api-ergonomics, security, correctness |\n| `tools\u002FReactor.DocPipeline\u002F` (doc pipeline, screenshot capture) | security, correctness |\n| `src\u002FReactor.Devtools\u002F`, `src\u002Fvscode-reactor\u002F`, `src\u002Fvs-reactor\u002F`, `src\u002FReactor.Interop.WinForms\u002F` | packaging, correctness |\n| `tests\u002FReactor.Tests\u002F`, `tests\u002FReactor.SelfTests\u002F`, `tests\u002FReactor.AppTests*\u002F` | test-coverage |\n| `docs\u002F`, `README.md`, `samples\u002F` | docs-and-samples |\n| `skills\u002F`, `plugins\u002Freactor\u002F`, `SKILL.md` | docs-and-samples + packaging (shipped agent kit) |\n| `*.csproj`, `Directory.Build.*`, `Directory.Packages.props`, `global.json`, `nuget.config` | packaging |\n| `docs\u002F_pipeline\u002Ftemplates\u002F*.md.dt` | docs-and-samples (generated docs source) |\n\n### 4. Fan out parallel sub-agents\n\nLaunch all 8 dimension sub-agents in **the same response** using the `task`\ntool, mode `\"sync\"`, agent type `general-purpose` (or `explore` for read-only\ndimensions — see per-dimension files). Each prompt must be self-contained:\ninclude the diff, the base\u002Fhead refs, the file classification, and the contents\nof the corresponding `dimensions\u002F\u003Cname>.md` file as instructions.\n\nThe 8 dimensions and their fragment files:\n\n| # | Dimension | Fragment | Default agent |\n|---|-----------|----------|---------------|\n| 1 | security | `dimensions\u002Fsecurity.md` | general-purpose |\n| 2 | correctness & edge cases | `dimensions\u002Fcorrectness.md` | general-purpose |\n| 3 | API & DSL ergonomics | `dimensions\u002Fapi-ergonomics.md` | general-purpose |\n| 4 | alternative-solution check | `dimensions\u002Falternative-solution.md` | general-purpose |\n| 5 | test coverage | `dimensions\u002Ftest-coverage.md` | general-purpose |\n| 6 | docs & samples sync | `dimensions\u002Fdocs-and-samples.md` | explore |\n| 7 | packaging & agent-kit impact | `dimensions\u002Fpackaging.md` | general-purpose |\n| 8 | multi-model cross-check | `dimensions\u002Fmulti-model.md` | general-purpose, with `model` override |\n\nFor #8 (multi-model), wait until #1–#7 finish first, then pass that sub-agent\nthe consolidated critical\u002Fhigh findings and require it to use a **different\nmodel family** than the orchestrator (e.g. if you are a Claude model, override\nto `gpt-5.4`; if you are GPT, override to `claude-opus-4.7`).\n\n### 5. Consolidate\n\nCollect all findings. Then:\n\n1. **Dedupe.** Two findings are duplicates if they reference the same file,\n   overlapping line range, and substantially the same root cause. Keep the\n   higher-severity \u002F higher-confidence copy and append the other domain to its\n   `Domain:` field (comma-separated).\n2. **Assign IDs.** `C1, C2, ...` for critical, `H1, H2, ...` for high,\n   `M1, ...` for medium, `L1, ...` for low.\n3. **Sort.** critical → high → medium → low; within severity, sort by file path.\n4. **Note multi-model status.** For each critical\u002Fhigh finding, mark it as\n   `confirmed`, `disputed`, or `not reviewed` based on the multi-model output.\n\n### 6. Report to stdout\n\nPrint exactly the format below. **Do not** save to a file unless the user\nexplicitly asks. **Do not** apply fixes — your job ends at reporting.\n\nThe header line varies by scope:\n\n- `branch` → `PR Review — \u003Chead> vs \u003Cbase>  (\u003CN> commits, \u003CM> files, +\u003Cadd>\u002F-\u003Cdel> lines)`\n- `working` → `PR Review — uncommitted changes vs HEAD  (\u003CM> files, +\u003Cadd>\u002F-\u003Cdel> lines)`\n- `staged` → `PR Review — staged changes vs HEAD  (\u003CM> files, +\u003Cadd>\u002F-\u003Cdel> lines)`\n- `all` → `PR Review — \u003Chead> + uncommitted vs \u003Cbase>  (\u003CN> commits + \u003CM_uncommitted> uncommitted files, \u003CM_total> files total, +\u003Cadd>\u002F-\u003Cdel> lines)`\n\n```\n\u003Cheader>\n\nSummary\n  Critical: \u003Cn>   High: \u003Cn>   Medium: \u003Cn>   Low: \u003Cn>\n\nCoverage\n  security              \u003C✓ clean | ⚠ N findings | ✗ skipped + reason>\n  correctness           ...\n  api-ergonomics        ...\n  alternative-solution  ...\n  test-coverage         ...\n  docs-and-samples      ...\n  packaging             ...\n  multi-model           \u003C✓ X\u002FY critical+high confirmed>\n\nFindings\n  C1  \u003Cfile>:\u003Clines>   \u003Cdomain>      \u003Cone-line>\n  C2  ...\n  H1  ...\n  ...\n\nDetails\n## C1  \u003Cfile>:\u003Clines>\n- Severity: critical\n- Confidence: high\n- Domain: correctness\n- Multi-model: confirmed\n- Finding: \u003Cone-line>\n- Evidence: \u003Ccode refs and quoted lines>\n- Recommendation: \u003Cconcrete next step>\n\n## C2 ...\n```\n\nIf a sub-agent returned zero findings, list its dimension as `✓ clean` in the\nCoverage block and include its short \"what I checked\" note in a final\n`Coverage notes` section so the user can see scope, not just verdict.\n\n## Rules the orchestrator must enforce\n\n- **Parallelism in one turn.** Fan out all of #1–#7 in a single response.\n- **No fix application.** Even if findings are obvious, do not edit code.\n- **No file output.** Stdout only, unless the user explicitly asked for a file.\n- **No build\u002Ftest execution.** Flag staleness (e.g. a new plugin sub-skill not\n  added to the agent-kit pack list in `src\u002FReactor\u002FReactor.csproj`, or\n  `skills\u002Freactor.api.txt` looking out of date) but do not run `mur check`,\n  `dotnet build`, `dotnet test`, or `dotnet run --project tools\u002FReactor.DocPipeline -- compile` yourself — they are slow\n  and the contributor will run them.\n- **Signal-to-noise.** Reject sub-agent findings that are pure style nits,\n  formatting, or things the compiler \u002F Reactor analyzers (`REACTOR_*`) \u002F `.editorconfig`\n  already catch. The Team Lead Test (see any dimension file) is mandatory.\n- **Cite evidence.** Every kept finding must reference a specific file and\n  line range visible in the diff.\n- **Treat finding fixes as new code.** Enforce the shared contract's source\n  requirement for factual claims; do not accept a claim merely because it was\n  written to satisfy an earlier review.\n\n## Sub-agent prompt template\n\nWhen invoking each dimension sub-agent via the `task` tool, build the prompt\nfrom these blocks (in order):\n\n1. **Role line.** \"You are the `\u003Cdimension>` sub-agent for the microsoft-ui-reactor\n   PR review skill.\"\n2. **Diff context.** Base ref, head ref, file list with line counts, and the\n   full unified diff.\n3. **Area classification.** Which files in the diff fall under this\n   dimension's primary focus.\n4. **Shared contract.** Inline the contents of\n   `.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002F_shared-contract.md`.\n5. **Dimension instructions.** Inline the contents of\n   `.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002F\u003Cname>.md`.\n6. **Closing instruction.** \"Return only the markdown specified by the shared\n   contract. No preamble, no apologies, no narration.\"\n\nFor the multi-model sub-agent, additionally pass the consolidated\ncritical\u002Fhigh findings from the other 7 sub-agents, and set the `model`\nparameter on the `task` call to a different model family than yourself.\n\n## Example invocation pattern\n\n```\n1. git diff --stat origin\u002Fmain...HEAD          → 12 files, +340\u002F-87\n2. git diff origin\u002Fmain...HEAD                 → captured for sub-agents\n3. Map files to areas                          → mostly Core\u002FReconciler + 1 modifier + 1 doc\n4. Fan out 7 task() calls in parallel          → wait for all\n5. Fan out task() #8 with model override       → wait\n6. Dedupe, sort, ID, mark multi-model status\n7. Print stdout report\n```\n\n## Example consolidated stdout\n\n```\nPR Review — feat\u002Fcombobox-controlled vs origin\u002Fmain  (4 commits, 9 files, +312\u002F-58)\n\nSummary\n  Critical: 0   High: 2   Medium: 3   Low: 1\n\nCoverage\n  security              ✓ clean\n  correctness           ⚠ 1 finding\n  api-ergonomics        ⚠ 1 finding\n  alternative-solution  ✓ clean\n  test-coverage         ⚠ 1 finding\n  docs-and-samples      ⚠ 2 findings\n  packaging             ✓ clean\n  multi-model           ✓ 2\u002F2 high confirmed\n\nFindings\n  H1  src\u002FReactor\u002FCore\u002FReconciler.Update.cs:142-160   correctness     Echo suppression armed before the value write, not after\n  H2  src\u002FReactor\u002FElements\u002FDsl.cs:88-95               test-coverage   New ComboBox(controlled:) overload has no selftest fixture\n  M1  src\u002FReactor\u002FElements\u002FElementExtensions.cs:34-49 api-ergonomics  New .Controlled() returns base Element, breaks fluent chain\n  M2  docs\u002Fguide\u002Fforms.md (missing)                   docs-and-samples  Controlled-value pattern not documented\n  M3  plugins\u002Freactor\u002Fskills\u002Freactor-forms\u002FSKILL.md   docs-and-samples  Controlled ComboBox not mentioned in forms skill\n  L1  tests\u002FReactor.Tests\u002FComboBoxTests.cs:189        test-coverage   Edge case (empty ItemsSource) untested\n\nDetails\n## H1  src\u002FReactor\u002FCore\u002FReconciler.Update.cs:142-160\n- Severity: high\n- Confidence: high\n- Domain: correctness\n- Multi-model: confirmed\n- Finding: ArmExpectedEcho is called after the control write, so the SelectionChanged echo arrives before the expected value is armed and is not suppressed — causing a redundant re-render \u002F state echo.\n- Evidence: Line 151 writes combo.SelectedIndex = idx; line 156 then calls state.ArmExpectedEcho(idx). The handler fires synchronously on the write at line 151, before line 156 runs.\n- Recommendation: Arm the expected echo before performing the controlled write (see the value-diff arm pattern in spec-047 §8.3 and existing controlled handlers).\n\n## H2 ...\n\nCoverage notes\n  security: Inspected the new ComboBox handler and Dsl overload — no process,\n    file, or network surface touched.\n  packaging: Inspected csproj\u002Fagentkit pack list — no new packed skill or\n    analyzer; no impact.\n```\n\n## Output discipline\n\nThe final stdout block is the *only* user-visible output. Do not narrate the\nprocess, do not summarize what each sub-agent did, do not apologize for noise.\nThe Coverage table already conveys what ran.\n",{"name":44,"infer":45,"description":46},"pr-review",true,"Multi-dimensional review of a PR or feature branch in the microsoft\u002Fmicrosoft-ui-reactor repo. Activate when a contributor asks to \"review my PR\", \"review my changes\", \"vet my branch before pushing\", \"do a full review\", \"PR review\", \"review this feature\", or similar. Fans out parallel sub-agents covering security, correctness\u002Fedge cases, API & DSL ergonomics, alternative-solution check, test coverage, docs & samples sync, packaging\u002Fagent-kit impact, and a multi-model cross-check. Reports a consolidated finding list to stdout. Does NOT apply fixes.","main","74791562c11792f7c0e2dd875f1e82b94d70b397",".claude\u002Fskills\u002Fcreating-version-notes",875,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fstruts","https:\u002F\u002Fstruts.apache.org\u002F","https:\u002F\u002Fgithub.com\u002Fapache","https:\u002F\u002Fwww.apache.org\u002F","2026-11-11 09:34:00",{"source":8,"skillName":44,"commands":57,"prompt":67,"zipAvailable":45},[58,61,64],{"tool":59,"command":60},"npx","npx skills add apache\u002Fstruts --skill pr-review",{"tool":62,"command":63},"bunx","bunx skills add apache\u002Fstruts --skill pr-review",{"tool":65,"command":66},"pnpm","pnpm dlx skills add apache\u002Fstruts --skill pr-review","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fapache\u002Fstruts\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcreating-version-notes\u002FSKILL.md",[69,75,79,83,87,91,95,99,103,107],{"path":70,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":73,"sourceHtmlUrl":74},"dimensions\u002F_shared-contract.md","REFERENCE","参考文档",4280,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmicrosoft-ui-reactor\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002F_shared-contract.md",{"path":76,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":77,"sourceHtmlUrl":78},"dimensions\u002Falternative-solution.md",4679,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmicrosoft-ui-reactor\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002Falternative-solution.md",{"path":80,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":81,"sourceHtmlUrl":82},"dimensions\u002Fapi-ergonomics.md",5502,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmicrosoft-ui-reactor\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002Fapi-ergonomics.md",{"path":84,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":85,"sourceHtmlUrl":86},"dimensions\u002Fcorrectness.md",6862,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmicrosoft-ui-reactor\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002Fcorrectness.md",{"path":88,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":89,"sourceHtmlUrl":90},"dimensions\u002Fdocs-and-samples.md",4831,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmicrosoft-ui-reactor\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002Fdocs-and-samples.md",{"path":92,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":93,"sourceHtmlUrl":94},"dimensions\u002Fmulti-model.md",3407,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmicrosoft-ui-reactor\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002Fmulti-model.md",{"path":96,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":97,"sourceHtmlUrl":98},"dimensions\u002Fpackaging.md",5222,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmicrosoft-ui-reactor\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002Fpackaging.md",{"path":100,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":101,"sourceHtmlUrl":102},"dimensions\u002Fsecurity.md",4920,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmicrosoft-ui-reactor\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002Fsecurity.md",{"path":104,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":105,"sourceHtmlUrl":106},"dimensions\u002Ftest-coverage.md",4276,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmicrosoft-ui-reactor\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr-review\u002Fdimensions\u002Ftest-coverage.md",{"path":108,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":109,"sourceHtmlUrl":110},"version-notes-template.md",9398,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fstruts\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcreating-version-notes\u002Fversion-notes-template.md",[112,149,174,189,209,227],{"skillNo":113,"name":114,"nameZh":6,"description":115,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":116,"categories":117,"keywords":131,"publishedAt":39},"01M6ACJVHR7YZNC8AZFK987QP0","code-review","Apache Struts pull request review guide. Use when reviewing pull requests in this repository to check test conventions, security-sensitive framework code, PR and commit hygiene, and Struts-specific implementation patterns.","https:\u002F\u002Fgithub.com\u002Fapache\u002Fstruts\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fcode-review\u002FSKILL.md",[118,123,126],{"categoryNo":119,"categoryName":120,"taxonomyType":121,"taxonomyTypeDesc":122},"01JBSEEDCAT000000000000007","代码审查","SCENARIO","使用场景",{"categoryNo":124,"categoryName":125,"taxonomyType":121,"taxonomyTypeDesc":122},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":127,"categoryName":128,"taxonomyType":129,"taxonomyTypeDesc":130},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[132,133,134,135,136,38,9,137,138,33,139,140,141,142,143,29,144,23,145,146,147,148],"code review","code","review","pull","pull requests","pr","pull request","security","commit","framework","Test Conventions","review guide","pull request review","check","requests","request","repository",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":158,"publishedAt":39},"01M6ACJSK2MWX4MPVHH4S3FK0V","triaging-security-reports","Use when a vulnerability or security report arrives for triage, when assessing a CVE\u002FRCE\u002FOGNL\u002Finjection claim against the code, when deciding whether a finding is the framework's fault or the application's, when drafting a reply to a security researcher, or when a claim that is already public (a Full Disclosure post, a blog, a scanner advisory) needs the project's position stated for users and scanner vendors — to research the claim from source without trusting the reporter and without fabricating your own facts.","https:\u002F\u002Fgithub.com\u002Fapache\u002Fstruts\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftriaging-security-reports\u002FSKILL.md",[155],{"categoryNo":156,"categoryName":157,"taxonomyType":121,"taxonomyTypeDesc":122},"01JBSEEDCAT000000000000021","资料检索与研究",[159,139,160,133,161,25,162,163,29,164,165,166,167,168,23,169,170,141,171,172,173],"triaging security reports","reports","cve","security report","claim","vulnerability","facts","injection","source","project","scanner","full","advisory","users","drafting",{"skillNo":175,"name":176,"nameZh":6,"description":177,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":178,"categories":179,"keywords":180,"publishedAt":39},"01M6ACJQJRMWRPQJ7P796RJZDZ","releasing-struts","Use when running or planning an Apache Struts release on any maintenance line (6.x, 7.x) - cutting the tag, staging artifacts, opening the vote, promoting, updating the site and announcing - or when asked what the next step in a release is.","https:\u002F\u002Fgithub.com\u002Fapache\u002Fstruts\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Freleasing-struts\u002FSKILL.md",[],[33,181,9,182,183,35,184,29,23,28,185,186,26,187,188],"releasing struts","planning","artifacts","running","next","what the","site","next step",{"skillNo":190,"name":191,"nameZh":6,"description":192,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":193,"categories":194,"keywords":195,"publishedAt":39},"01M6ACJNFT2MMYBT8WFBJR8HXM","merging-dependabot-prs","Use when triaging, classifying or landing Dependabot pull requests in this repo — clearing the open Dependabot queue, deciding whether a bump needs a WW Jira ticket, or checking whether a bump's build actually passed.","https:\u002F\u002Fgithub.com\u002Fapache\u002Fstruts\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fmerging-dependabot-prs\u002FSKILL.md",[],[196,197,198,135,136,199,200,201,202,203,204,29,23,146,205,206,207,208],"merging dependabot prs","prs","dependabot","jira","bump","repo","landing","ticket","open","build","ww","queue","jira ticket",{"skillNo":210,"name":211,"nameZh":6,"description":212,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":213,"categories":214,"keywords":215,"publishedAt":39},"01M6ACJGZAS1WB8RHDQMC76XFB","creating-security-bulletins","Use when drafting, updating, or reviewing an S2-XXX security bulletin on the Struts cwiki, when preparing bulletin text ahead of a CVE request, when filling a CVE record in the ASF CVE tool (cveprocess.apache.org \u002F Vulnogram), when deciding when to publish, when publishing a bulletin and announcing it to the ASF lists, when wrapping up after the advisory mails, or when deciding how much detail about a fixed vulnerability is safe to publish.","https:\u002F\u002Fgithub.com\u002Fapache\u002Fstruts\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcreating-security-bulletins\u002FSKILL.md",[],[139,216,33,9,217,218,23,173,164,219,220,221,147,222,223,161,224,225,29,226],"creating security bulletins","safe","up","text","publish","how","asf","org","tool","publishing","detail",{"skillNo":228,"name":229,"nameZh":6,"description":230,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":231,"categories":232,"keywords":233,"publishedAt":39},"01M6ACJERGEM6AYZGCC6A2ZC27","creating-release-vote-mail","Use when opening the formal release vote for a Struts release candidate on any maintenance line (6.x, 7.x) - composing and drafting the [VOTE] Apache Struts X.Y.Z mail to dev@ once the Version Notes page, GitHub release and staged artifacts are published.","https:\u002F\u002Fgithub.com\u002Fapache\u002Fstruts\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcreating-release-vote-mail\u002FSKILL.md",[],[234,35,27,19,235,9,31,183,25,22,29,33,23,21,173,24,28,26,236,32],"creating release vote mail","dev","staged"]