Skip to content

feat(workflow): ワークフロー自動化 13 件 — skill 4 + pre-commit hook 6 + pre-push gate - #496

Merged
ayutaz merged 9 commits into
devfrom
feat/workflow-automation-skills
May 16, 2026
Merged

feat(workflow): ワークフロー自動化 13 件 — skill 4 + pre-commit hook 6 + pre-push gate#496
ayutaz merged 9 commits into
devfrom
feat/workflow-automation-skills

Conversation

@ayutaz

@ayutaz ayutaz commented May 16, 2026

Copy link
Copy Markdown
Owner

Summary

開発ワークフローで recurring に発生していた drift / cycle-of-shame パターンを fail-fast 化するため、 Claude Code skill 5 件 + pre-commit hook 6 件 + opt-in pre-push stage 1 件 + skill auto-chain 1 件 + cmake drift 解消 1 件 を追加 (9 コミット、16 ファイル、+2214 / -9 行)。各 hook は conservative 設計 (既存コードは ALLOWLIST or 検出ロジック緩和で通過、新規発生のみ block)。auto-invocation 可能な skill (/watch-pr, /reply-review, /create-pr, /check-review-backlog --pr <N>) は LLM が文脈判断で自動発動、 PR 作成時は /create-pr/check-review-backlog --pr/watch-pr の 3 段 auto-chain が連鎖。

新規 / 拡張機能

PR レビュー支援 (skill)

skill 動作 解決する問題 auto
/watch-pr <PR> gh pr checks を polling + 失敗を format drift / test fail / build error / flake / contract drift に分類 CI 待ちの手動 refresh、 失敗原因の都度判定。 PR #419 で起きた silent skip パターンも検出
/reply-review <PR> --stale-check comment の originalCommit.oidgit log で HEAD と比較し、 該当ファイルが解決済みかを判定 Copilot が古い commit を指摘し続けて、 解決済みなのに review thread が closed されない問題 (memory feedback_copilot_stale_review)
/reply-review <PR> --skip-copilot-style ^Consider (using|renaming) ^Optional: \bnit\b 等の Copilot 定型ノイズ regex を skip。 human reviewer には適用しない 人間の判断が要る指摘と Copilot の自動 nitpick の混在による集中度低下
/check-review-backlog [--days N] [--author X] 全 open PR の isResolved=false thread を GraphQL で集計、 N 日 (default 7) 経過したものを表化。 read-only レビュー対応漏れの可視化。 30 日超 unresolved の PR の active/abandoned 判定

PR 作成支援 (skill)

skill 動作 解決する問題 auto
/create-pr [base-branch] push 済みブランチに対し、 機能カテゴリ別の表 + 設計判断 + Test plan を含む構造化 PR 本文を生成。 マイルストーン非付与、 auto-merge 非使用、 時系列フェーズ表記禁止を強制。 既存 PR は gh pr edit --body-file で本文書き換え PR body の構造が PR ごとにバラバラ、 reviewer が読みづらい / 後から振り返れない問題。 マイルストーン誤付与・auto-merge 誤起動の予防

PR 作成後の auto-chain (3 skill 連鎖)

/create-pr 完了直後に明示確認なしで 3 段連鎖。 PR #496 で「PR 作成後に review チェックを発動しなかった結果、 5 件の未対応 Copilot review に気づくのが遅れた」事例を再発防止する仕組み。

Step skill 動作
6.1 /check-review-backlog --pr <N> 単一 PR モードで全未解決 review を即時表示 (PR 更新時の bot review 早期検出)
6.2 /watch-pr <N> 5 秒待機後 CI 状態 polling、 red なら失敗 job のログ分類
6.3 (集約報告) PR URL + review 件数 + CI status を 1 メッセージにまとめ、 次のアクション提案

skip 条件: ユーザ明示拒否 / feature → feature の PR / dry-run。

cmake drift 解消

commit 変更 理由
3fe4112b cmake/ExternalDeps.cmake の pyopenjtalk-plus URL を 0.4.1.post70.4.1.post8 に bump (SHA256 も 555fdf86...f4dfbfbe...) src/python_run/requirements.txt: pyopenjtalk-plus>=0.4.1.post8 との range constraint drift を、 強化された check_openjtalk_version_sync.py が検出したため解消。 Python / C++ で同じ OpenJTalk dict / behavior を共有する設計意図に従い PyPI 最新 (post8) に揃える

(auto ✓ = disable-model-invocation: false、 LLM が「PR を作って」「review に返信」「PR の CI を見て」等の文脈で自動発動。 auto — = 明示呼び出しのみ、 周期実行向け or 誤起動リスク回避)

リリース・ドキュメント整合性 (skill)

skill 動作 解決する問題
/sync-docs Agent 7 追加 既存 6 並列 agent に「Version Drift 監査」を追加。 docs/spec/release-versions.toml canonical で CLAUDE.md ランタイム表 / docs/spec の version comment / CHANGELOG [Unreleased] 残留 / README Feature Matrix を一括照合 リリース時の 9 manifest 間の version 同期漏れ。 release-versions.toml mode="warn" の段階で drift 検出を網羅化
/release-prep [runtime] [--target-version X.Y.Z] 9 manifest の現 version 一覧 → release-versions.tomlexpected_prefix 照合 → CHANGELOG [Unreleased][X.Y.Z] 移行 markdown 生成 → PyPI / crates.io / NuGet / npm / Maven Central の最新公開 version 取得 → ローカル/公開/canonical 3-way 差分表を出力 リリース時の forensic check の手動性。 「local では bump 済みだが publish されてない」状態の即発見

Commit 時の drift gate (pre-commit hook)

.pre-commit-config.yaml に追加。 git commit 時点で staged files に対して fire。

hook files filter 検出内容
language-parity docker/webui/app.py, docker/python-inference/{inference,test_openai_api}.py WebUI SAMPLE_TEXTS keys / CLI --language choices / FastAPI test 期待値の 3-way 不一致 (AST 解析)
changelog-unreleased-cleanup CHANGELOG.md, docs/spec/release-versions.toml [Unreleased] 内の release-style 見出し (### [vX.Y.Z]) 残留 検出 (conservative: 構造見出しのみ、 prose は flag しない)
secret-path-reference *.{py,sh,yml,toml,rs,go,cs,...} 全 executable 拡張子 /data/piper/.env 等ホスト固有 secret env パスが executable code に漏洩していないか (CLAUDE.md / docs/ は exempt、 ALLOWLIST で legacy 許容)
openjtalk-version-sync cmake/ExternalDeps.cmake, **/pyproject.toml cmake URL の pyopenjtalk_plus-X.Y.Z pin と pyproject.toml の == / ~= 制約の同期検証 (bare name は warn-only)
pytest-skip-reason src/**/tests/**/*.py @pytest.mark.skip / pytest.skip() / skipifreason= または positional arg が空でないか (AST、 f-string / 式 / kwarg すべて accept)
gofmt *.go (vendor / *.pb.go 除外) Go format drift。 scripts/run_gofmt_check.shgofmt -l の出力を exit code 化

Push 前の最終確認 (opt-in pre-push stage)

.pre-commit-config.yamlstages: [pre-push]pre-commit install --hook-type pre-push で初めて有効化、 default では install されない。 git push 直前に full-repo で 4 contract gate (loanword / PUA / language parity / CHANGELOG unreleased) を実行 (~20-30 秒)。 commit 時に SKIP=... で hook を bypass しても push 前に drift を検出。

設計判断 / トレードオフ

  • conservative changes: 既存 Rust source に rustfmt drift が pre-existing のため rustfmt hook は別 PR に deferral。 既存 prepare_*.py の docstring 内の /data/piper/ 参照は ALLOWLIST 化 (legacy 許容)。 既存の 20 件 pytest skip は f-string / 式 reason 検出で通過 (新規 reason-less skip のみ block)
  • 誤検出回避: secret-path-reference は executable 拡張子のみ、 doc は exempt。 changelog-unreleased-cleanup は構造見出しのみ flag、 prose は除外。 openjtalk-version-sync は明示的 == / ~= 不一致のみ error、 bare name は warn-only
  • bypass 経路: 全 hook は SKIP=hook-id git commit で個別 bypass 可。 pre-push stage は pre-commit install --hook-type pre-push を実行しなければそもそも fire しない
  • CI mirror: 既存 .github/workflows/pre-commit.ymlpre-commit run --all-files を PR 時に実行するため、 install 忘れでも PR で drift を検出
  • read-only skill: /check-review-backlog は GraphQL の query のみ実行、 POST / mutation 一切なし。 /release-prep の CHANGELOG 移行も markdown diff 提示のみ、 Edit 適用は明示確認後

Test plan

実装時に通過確認済み (各 commit の pre-commit hook で gate)

CI 側で要確認 (本 PR で初めて gate 化される項目)

  • cmake post8 bump 後の C++ build (Linux / macOS / Windows) が SHA256 mismatch / 構造変更で失敗しないこと — cpp-tests / C++ Release & Debug × macos-latest / windows-latest / ubuntu-24.04 全 6 組 + cpp-coverage + test-cpp-unit-tests + test-cpp-inference + iOS / macOS arm64 build が全件 pass
  • .github/workflows/pre-commit.yml で 6 新規 hook 全件が PR 時に通過 — pre-commit run --all-files job が pass
  • pre-push opt-in stage: pre-commit install --hook-type pre-push 後の git push で 4 contract gate が 20-30 秒で完走 (ローカル検証のみ可、 副作用あり)

skill chain の動作確認

Copilot レビュー対応検証 (commit b7e71c8a 関連)

  • run_gofmt_check.sh: set -uo pipefail + rc=$? の明示捕捉で gofmt exit 2 (syntax error) が silent abort しない
  • check_openjtalk_version_sync.py: packaging.SpecifierSet== ~= >= <= > < != 全制約形式判定、 requirements*.txt も scan 対象に追加
  • .pre-commit-config.yaml files filter: (^|/)(CMakeLists\.txt|Dockerfile|Makefile)$ で sub-directory の同名ファイルも検査対象 / .*requirements.*\.txt を openjtalk-version-sync filter に追加

参考

ayutaz added 5 commits May 16, 2026 01:43
…y hook

PR 後の手動 CI polling、Copilot の stale review 検出、WebUI/CLI/FastAPI
テストの 3-way 言語リスト drift を fail-fast 化するワークフロー自動化 3 点:

- `.claude/skills/watch-pr/SKILL.md`: PR の CI checks を `gh pr checks` で
  1 回ポーリングし失敗 job を分類 (format drift / test fail / flake /
  contract drift)。`/loop /watch-pr <PR>` で継続監視。
- `.claude/skills/reply-review/SKILL.md`: `--stale-check` 追加。コメントの
  originalCommit と HEAD を `git log -- <path>` で比較し、コメント以降に
  該当ファイルが更新済なら stale 候補として flag (memory
  `feedback_copilot_stale_review` の二重対応防止)。
- `scripts/check_language_parity.py` + pre-commit hook: WebUI
  SAMPLE_TEXTS / CLI --language choices / FastAPI test assertion の 3 個を
  AST で抽出して set 比較。PR #2f4efaf9 で起きた WebUI 7 言語 vs CLI 6 言語
  drift の再発防止。
A 級施策 2 件を反映。A5 (未統合 contract script の gate 化) は再調査の結果、
候補 3 スクリプトはすべて既に gate 化済みだったため不要 (Agent 5 調査が
古かった)。

- `.claude/skills/reply-review/SKILL.md`: `--skip-copilot-style` オプション
  追加。Copilot bot (`copilot-pull-request-reviewer` または `*[bot]`) の
  定型ノイズ (Consider using / Optional: / nit: / style: prefer 等) を
  regex で検出し、対応対象から除外。誤検出防止のため human レビュアーの
  コメントは除外しない。
- `.claude/skills/sync-docs/SKILL.md`: Agent 7 (Version Drift 監査) 追加。
  `docs/spec/release-versions.toml` を canonical truth として、CLAUDE.md
  ランタイム別パッケージ表 / docs/spec/*.toml 内 version comment /
  CHANGELOG.md `[Unreleased]` 残留 / README Feature Matrix の 4 観点を
  cross-check。memory `feedback_data_asset_distribution` を補強。
…e-push)

- `.claude/skills/check-review-backlog/SKILL.md`: 全 open PR の未解決
  review thread を gh api graphql で集計、N 日 (デフォルト 7) 以上未対応の
  thread を backlog として表示する read-only skill。`/loop` で週次監視可能。
- `scripts/check_changelog_unreleased.py` + pre-commit hook
  `changelog-unreleased-cleanup`: `[Unreleased]` 内の release-style
  sub-heading (`### [X.Y.Z]`) が release-versions.toml::expected_prefix と
  major.minor 一致した場合に検出。release 後の section 移動漏れを fail-fast。
  conservative 設計で prose cross-reference は flag しない。
- `.pre-commit-config.yaml` pre-push stage: opt-in (`pre-commit install
  --hook-type pre-push` で有効化) で full-repo の contract gate 4 個
  (loanword / PUA / language parity / changelog unreleased) を ~20-30s
  並列実行。`SKIP=...` で commit gate を bypass しても push 前に drift
  検出可能。CLAUDE.md に install 手順を追記。

A5 (未統合 contract script の gate 化) は再調査の結果すべて gate 化済み
だったため不要。
15 エージェント並列調査で浮上した recurring drift パターンを commit 時点で
fail-fast 化する 4 hook を新規追加。各々 conservative 設計 (既存コードは
allowlist or 検出ロジック緩和で通過、新規発生のみ block):

- secret-path-reference: ホスト固有 secret env パスが executable code
  (sources / workflows / configs) に漏洩していないか検出。CLAUDE.md と
  docs/ 等のドキュメントは exempt、guard-bash.sh と prepare_*.py の
  docstring example は ALLOWLIST で legacy 許容
- openjtalk-version-sync: cmake/ExternalDeps.cmake の pyopenjtalk-plus
  tarball URL pin (現 0.4.1.post7) と全 pyproject.toml の version
  constraint の同期を tomllib で検証、 == / ~= の明示的 mismatch のみ
  error (bare name は warn-only)
- pytest-skip-reason: tests/ 配下の skip / skipif で AST 経由 reason
  存在検証、f-string / 式 / kwarg すべて accept (既存 reason 付きは通過)
- gofmt: Go 第 7 ランタイムの format drift を commit 時点で検出
  (scripts/run_gofmt_check.sh で exit code を整形)

rustfmt は既存 Rust source に pre-existing format drift があり別 PR が
必要なため deferral (config コメントで明示)。15 エージェントが指摘した
他の中インパクト項目 (WASM RTF baseline 初期化、JA phoneme rules contract
gate、auto-label workflow 等) も別 PR で個別検討予定。
リリース作業の forensic check と CHANGELOG [Unreleased] 昇格を 1 skill に
集約。docs/spec/release-versions.toml を canonical source として 6 phase:

1. 9 manifest (VERSION / Cargo.toml / 2 csproj / 2 package.json /
   Package.swift / gradle.properties) の現 version 一覧
2. expected_prefix との照合 (warn → fail flip 判定材料)
3. CHANGELOG.md [Unreleased] → [X.Y.Z] 移行 markdown 生成 (承認後 Edit)
4. PyPI / crates.io / NuGet / npm / Maven Central の最新公開 version 取得
5. ローカル vs 公開 vs canonical の 3-way 差分表 (verdict 付き)
6. verdict 別の推奨 next action

15 エージェント調査 (Agent 5: Release ritual gap) で「manifest version
分散の多重化チェック欠落」を Critical と判定したのを踏まえ実装。
/sync-docs Agent 7 (version drift 監査) と相補的: drift 検出 + 解消支援。
変更は markdown diff として提示、Edit 適用は明示確認後 (memory
feedback_merge_caution.md 準拠)。
Copilot AI review requested due to automatic review settings May 16, 2026 01:57
@ayutaz ayutaz self-assigned this May 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds local automation to catch recurring workflow drift earlier through pre-commit/pre-push gates and Claude Code skills, fitting into the repo’s existing contract-check and multi-runtime consistency tooling.

Changes:

  • Adds new Python/Bash pre-commit helper scripts for language parity, changelog cleanup, secret-path detection, OpenJTalk version sync, pytest skip reasons, and gofmt checks.
  • Extends .pre-commit-config.yaml with new commit-time hooks and an opt-in pre-push contract gate.
  • Adds/updates Claude skill documentation for PR watching, review replies, release prep, review backlog checks, and docs sync version-drift auditing.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
scripts/run_gofmt_check.sh Adds gofmt wrapper for pre-commit failures.
scripts/check_test_skip_reason.py Adds AST-based pytest skip reason checker.
scripts/check_secret_path_reference.py Adds host-specific secret path reference detector.
scripts/check_openjtalk_version_sync.py Adds CMake vs Python OpenJTalk dependency sync checker.
scripts/check_language_parity.py Adds WebUI/CLI/FastAPI language list parity checker.
scripts/check_changelog_unreleased.py Adds CHANGELOG [Unreleased] release-heading drift checker.
CLAUDE.md Documents opt-in pre-push contract gates.
.pre-commit-config.yaml Registers new hooks and opt-in pre-push gate.
.gitignore Unignores new check scripts.
.claude/skills/watch-pr/SKILL.md Adds CI polling/triage skill.
.claude/skills/sync-docs/SKILL.md Adds version-drift audit agent.
.claude/skills/reply-review/SKILL.md Adds stale-check and Copilot-style filtering guidance.
.claude/skills/release-prep/SKILL.md Adds release preparation helper skill.
.claude/skills/check-review-backlog/SKILL.md Adds unresolved review-thread backlog skill.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/run_gofmt_check.sh
Comment thread scripts/check_openjtalk_version_sync.py Outdated
Comment thread scripts/check_openjtalk_version_sync.py Outdated
Comment thread .pre-commit-config.yaml Outdated
Comment thread .pre-commit-config.yaml Outdated
ayutaz added 4 commits May 16, 2026 11:04
…on 化

LLM が「PR を作って」「review に返信」「CI 監視」の文脈で skill を
自動発動できるよう disable-model-invocation を false 化、description に
トリガキーワード (push 直後 / merge 前確認 / review thread resolve 等) を
追加。

/create-pr は PR 本文の標準フォーマットを強制:
- 機能カテゴリ別の表 (PR レビュー支援 / リリース整合性 / Commit drift
  gate / Push 前確認 等)
- 時系列フェーズ表現 (Phase 1/S 級 等) 禁止 — 後から読んで意味が薄い
- マイルストーン非付与 (memory feedback_pr_no_milestones)
- auto-merge 禁止 (memory feedback_merge_caution)
- 既存 PR は body 書き換え (memory feedback_pr_body_over_comments)
- guard hook が誤検出する文字列は body-file 経由で渡す

release-prep / check-review-backlog は明示呼び出し維持 (誤起動リスク /
周期実行向け)。
- run_gofmt_check.sh: set -euo pipefail を set -uo pipefail に変更し
  rc=$? で gofmt の exit code を明示捕捉、parse error (exit 2) を
  command substitution で silent abort せず propagate するよう変更
- check_openjtalk_version_sync.py: packaging.SpecifierSet で全制約形式
  (== ~= >= <= > < !=) を判定、requirements*.txt も scan 対象に追加。
  既存 drift (requirements.txt の pyopenjtalk-plus>=0.4.1.post8 vs
  cmake 0.4.1.post7) を range violation として WARN 報告で露呈。
  明示 pin 違反のみ error、range 違反は warn (意図的 bound を尊重)
- .pre-commit-config.yaml: secret-path-reference の files filter で
  CMakeLists.txt / Dockerfile / Makefile を (^|/) prefix で path 任意
  位置の basename match に対応。openjtalk-version-sync の files filter
  に .*requirements.*\.txt を追加し dynamic deps 経路もカバー
…t 解消)

cmake/ExternalDeps.cmake の URL pin (post7) と src/python_run/requirements.txt
の制約 (>=0.4.1.post8) の drift を解消。Python/C++ で同じ OpenJTalk 辞書 /
behavior を共有する設計意図 (file header コメント参照) を踏まえ、 PyPI
最新 (post8) に揃える方向で bump。

変更:
- URL: pyopenjtalk_plus-0.4.1.post7.tar.gz → pyopenjtalk_plus-0.4.1.post8.tar.gz
- SHA256: 555fdf86... → f4dfbfbe... (2 箇所、 同一 tarball 参照)

検証: scripts/check_openjtalk_version_sync.py で WARN (range constraint
violation) が消え、 OK ステータス。 PR #496 の review 対応 (Copilot 指摘
#2, #5) で本 drift が露呈、 本 commit で解消。
PR #496 で「PR 作成後にレビュー確認 skill を発動しなかった結果、 5 件の
未対応 Copilot review に気づくのが遅れた」事例を踏まえ、 /create-pr 完了
時に review + CI 確認を自動連鎖させる chain を組み込む。

変更内容:

- /check-review-backlog: 引数に `--pr <N>` 単発モード追加。 既存の全 PR
  backlog 監視 (週次運用) と並列で、 PR 作成直後の単一 PR review 即時
  確認を可能化。 disable-model-invocation: false 化、 description に
  「PR 作成直後の review チェック」文脈を明記
- /create-pr: フェーズ 6 を「自動 follow-up 提案」から「auto chain 自動
  実行」に強化。 Step 6.1 (Skill check-review-backlog --pr <N>) → 5秒
  待ち → Step 6.2 (Skill watch-pr <N>) → Step 6.3 (集約報告) の 3 段。
  feature → feature PR や dry-run は chain skip
- /watch-pr: description に「PR 作成後の auto chain (/create-pr の
  フェーズ 6.2 から発動)」を明記、 LLM auto-invocation の文脈強化

これで「PR 作って」要求 → /create-pr 発動 → push + PR 作成 → 自動で
review チェック + CI 監視 が 1 ユーザ要求で完結する。
@ayutaz
ayutaz merged commit 1163a60 into dev May 16, 2026
56 checks passed
@ayutaz
ayutaz deleted the feat/workflow-automation-skills branch May 16, 2026 04:22
ayutaz added a commit that referenced this pull request May 16, 2026
…ed ~155 件 (#498)

* feat(pre-commit): メタ regex coverage / yamllint / shellcheck / 14 既存 CI-only contract gate を hook 化

PR #496 で再発した file-path regex over-matching と、 CI-only だった 14 contract
gate (ssml / streaming-api / swift-g2p / migration-changelog-parity 等) を
commit 時点で検出するよう pre-commit に統合。 重い toolchain hook の SKIP
省略デフォルトを維持し、 cycle of shame (PR #401) を再発防止する。

* feat(contract): japanese-n-variant / chinese-tone cross-runtime gate を追加

15 エージェント調査で「ん」 4 allophone (N_m/N_n/N_ng/N_uvular) と Mandarin
tone1-5 が cross-runtime drift gate 未整備と判明。 drift = silent acoustic
regression のため、 canonical Python の trigger 集合と各 runtime source の
symbol literal / PUA codepoint 存在を pre-commit / pre-push で gate する。

* feat(skills): prepare-release / publish-model / bump-deps / watch-ci-patterns / skill-health を追加

15 エージェント調査で未カバーと判明した「リリースサイクル / モデル公開 /
依存関係 bump / CI failure 分類 / skill 自身の health check」 を 5 skill に
集約。 すべて read-mostly 既定 (--apply 明示でのみ Edit) で memory
feedback_merge_caution を遵守し、 既存 release-prep / watch-pr / commit /
sync-docs と連鎖可能なよう設計。

* feat(ci): golangci-lint @v7 を semver pin、 16 workflow に最小権限 permissions、 Trivy container scan を追加

セキュリティ監査の指摘 (sliding-tag ref / 暗黙の write 権限 / Docker image 未 scan)
を一括対応。 golangci-lint-action@v7 は v7.0.1 へ pin、 lint/test/report 系
16 workflow に `permissions: contents: read` を明示、 3 Dockerfile を Trivy で
image scan (CRITICAL のみ block、 fixed-only) する weekly + PR trigger を追加。

* feat(deps,test): NuGet packages.lock.json と pytest-xdist `-n auto` を有効化

NuGet `.csproj` に `RestorePackagesWithLockFile=true` を共通設定で追加し
reproducible build + CVE 監査基盤を確立 (security-audit.yml の nuget-audit と
連携)。 pytest は `pytest.ini` の addopts に `-n auto` を追加し、 既存 dep
`pytest-xdist` を python_run/pyproject.toml にも明示。 Python test 全体で
15-25% の wall-clock 短縮を狙う。

* docs: CLAUDE.md ↔ .claude/README.md 相互参照 + breaking sync / 廃止 API gate (warning) を追加

CLAUDE.md に Automation セクションを追加し全 skill 一覧を `.claude/README.md`
へリンク (skill discovery が CLAUDE.md だけで完結する状態に)。 加えて多言語
README breaking banner sync gate と、 廃止 API (Flask/HiFi-GAN/--mb-istft 等)
が docs/ に archived 注釈なしで残存しないか warning モードで検出する gate
を追加。 false positive を許容するため non-strict、 翻訳遅延を妨げない。

* fix(ci,rule): C# build / Trivy / shellcheck の初回 CI failure 対応 + PR 作成 skill 経由ルール

PR #498 初回 CI で 13 件失敗の原因解消:
- Directory.Build.props のコメント内に XML 違反な `--locked-mode` 表現を含んで
  いて SDK が reject (Line 29、 XML comment cannot contain `--`)。 reword で
  回避。
- aquasecurity/trivy-action@0.28.0 は GHSA-69fq-xp46-6x23 (supply chain
  compromise)。 patched 版 0.36.0 に bump。
- shellcheck severity warning は既存 .claude/hooks/*.sh に SC2034/SC2046/
  SC2221 等の warning が多数あり一括修正困難。 severity=error に下げて新規
  hook の guard と既存 rot 防止のバランス。
- editorconfig-checker は .claude/hooks/*.sh の 2-space indentation を
  4-space 必須 として reject。 exclude に追加 (既存スタイル尊重)。

加えて memory feedback_pr_create_skill_only を導入し、 PR 作成は /create-pr
skill 経由を強制。 .claude/hooks/guard-bash.sh で gh の直接 PR 作成を block
(commit message 内の文字列で誤発動しないよう command 先頭 / `&&` / `;`
直後のみマッチ)。 PR #498 でユーザが「監視 skill が動いてない」 と指摘した
事例の再発防止。

* feat(skill): watch-pr に unresolved review thread 集計 + stale check を統合

ユーザー指摘 (PR #498) で「ループ監視 skill にレビュー対応も含まれているか」と
質問を受け、 現状 watch-pr が CI status のみで review thread を見ていない事を
確認。 同 skill 内に新フェーズ「Unresolved review thread 集計」 を追加し、
GraphQL で reviewThreads を取得して reviewer 別 / stale flag 付きで提示。
自動 reply / resolve は行わない (memory feedback_pr_body_over_comments 遵守);
/reply-review skill 起動を提案する形で連携する。 これで `/loop /watch-pr <PR>`
が CI + review の両方を毎 iteration でカバーする。

* feat(skill): watch-pr → reply-review --auto-safe chain で SAFE 系 review thread を自動 reply + resolve

ユーザー指摘 (PR #498) で「ループ監視で review の自動判断 + 対応 + reply + resolve
まで」 要望を受け、 2 つの skill を連携:

- reply-review: 新 flag `--auto-safe` を追加。 stale check + Copilot ノイズ regex
  を内部で自動有効化し、 各 thread を SAFE-stale / SAFE-copilot-style /
  REVIEW-human / REVIEW-copilot-blocker の 4 カテゴリに分類。 SAFE 系のみ
  自動 reply + resolve、 REVIEW 系は user 提示のみ。
- watch-pr: フェーズ 5.5 で `/reply-review <PR> --auto-safe` を Skill tool で
  chain 起動。 unresolved 1 件以上なら毎 iteration で SAFE 系を解消し、 残った
  REVIEW 系を user に提示。

自動境界は memory 整合:
- feedback_pr_body_over_comments: PR body 改変ルール → review thread reply には
  適用外 (異なる surface)
- feedback_merge_caution: merge ≠ resolve、 resolve は user 介入不要
- feedback_copilot_stale_review: stale 検出が auto-safe の core 判定材料

logic / security / API 系の指摘 (REVIEW-copilot-blocker) と人間 reviewer 指摘
(REVIEW-human) は自動コード修正の影響大のため user 判断に残す。

* fix(review-498): Copilot 15 件 review コメント全て対応 — regex 堅牢化 / 多言語化 / Trivy DRY / pytest -n auto 撤回

PR #498 で Copilot bot が指摘した 15 unresolved review thread の logic / 設計
指摘に全て対応:

scripts/:
- check_readme_breaking_sync: BANNER_RE を 7 言語の "breaking" 相当語に拡張
  (ZH 重大变更 / FR Changements incompatibles / KO 주요 변경사항 等)
- check_skill_health: TRIGGER_FRAGMENT_RE の capturing / non-capturing 混在を
  named group 2 つに統一、 findall の tuple 戻り値で安全に分岐
- check_precommit_file_regex: block-scalar の inner indent を first non-empty
  line から動的検出 (hard-coded `+2` を撤回)
- check_deprecated_api_lingering: substring → 単語境界 regex に変更
  (`flask` 部分一致や `HTS` 誤検出を排除)
- check_readme_code_examples: ALLOWLIST `None` 重複を除去 + stdlib/typing/
  JS-Rust 共通名を追加、 `git grep` に `-F -w` (literal + word boundary) で
  metachar / 部分一致誤判定を抑止
- check_chinese_tone_contract: `_normalize_codepoint` を新設、 int / `0x...`
  / `U+...` / bare hex の全形式を正規化してから比較
- check_japanese_n_variant_contract: narrow regex を撤回、 関数 body 内の
  variant assignment から walk-back で `in (...)` / `in CONST` / `case ...`
  を探す堅牢パーサに刷新 (refactor 耐性向上)

config:
- src/{python,python_run}/pytest.ini: `-n auto --dist=loadgroup` を addopts
  から削除。 single-test run / 各 worker の model load による OOM を防ぐため
  ローカルは on-demand、 CI は workflow で明示有効化する形に運用変更
- src/csharp/Directory.Build.props: lockfile 初回 generate を CI 側で
  許容する 2 段階 rollout の旨をコメントに追記 (撤回はせず repo-wide enable
  維持、 csharp-ci.yml で `--force-evaluate` 等を別途調整予定)
- .pre-commit-config.yaml: shellcheck files regex を `(\.(sh|bash))$` に
  グルーピングして anchor 強化 (`.bash.sample` 等の中途 suffix を除外)
- .yamllint.yaml: ignore block の alternation を撤回し gitignore-style の
  glob を行単位で列挙 (yamllint の ignore は gitignore syntax)
- .github/workflows/trivy-container-scan.yml: Trivy invocation を 3 回 →
  1 回に削減 (SARIF 1 回生成 + Python で parse して CRITICAL gate)。
  build_target matrix 列を追加して multi-stage Dockerfile に備える

* fix(ci): aquasecurity/trivy-action tag を `v` 付き (v0.36.0) に修正

upstream の tag 形式は `v<X.Y.Z>` のみ (v 無しの `0.36.0` tag は存在せず)、
前 commit (0.28.0 → 0.36.0 bump) で v 接頭辞を落としていたため CI が
「Unable to resolve action」 で fail していた。 ` gh api repos/.../tags` で
全 20 tags 全てが `v` 付きであることを確認。

* fix(ci): Trivy scan matrix から python-train を除外 — runner disk OOM 回避

PR #498 で python-train image (torch + cuDNN + ML deps、 ~10GB+) を Trivy
で image scan しようとして GitHub-hosted runner が `no space left on device`
で fail。 training image は本番 deploy されない (`piper_train` モジュールは
checkpoint export 用) ため image vulnerability scan の優先度は低く、 free-
disk-space cleanup を要する大規模 image は別途 scheduled job で扱う TODO。

残り python-inference / cpp-dev の 2 image で日常 PR scan を継続。

* feat(workflow): Wave 3 P0 — lockfile / retention / meta-gate / Renovate / commitlint

15 エージェント並列調査 (Wave 3) の P0 13 件のうち以下 11 件を実装:

- T1 lockfile / 再現性: Android dependencyLocking 有効化 (subprojects に
  STRICT mode)、 10 runtime の lockfile consistency gate (scripts +
  pre-commit hook)。 C# packages.lock.json は既存 RestorePackagesWithLockFile=true
  で CI 初回 restore で生成、 soft-required 扱い。
- T2 artifact retention: 中途半端な 14 日を 7 日に統一 (csharp-ci /
  cli-help-docs-sync / go-ci / clang-tidy)、 docs/spec/artifact-retention-contract.toml
  で ephemeral(1d)/pr-debug(7d)/regression-baseline(30d)/release-publish(90d)
  の 4 カテゴリを宣言。
- T3 pre-commit meta-gate 拡張: check_precommit_file_regex.py に
  exclude regex compile 検証を追加、 benchmark JSON sanity gate
  (NaN/Inf/負値/out-of-bounds)、 README H2 parity gate (8 言語 ±20%
  tolerance、 warn-only)。
- T4 Renovate regex-manager: renovate.json で ruff 6 箇所 + ORT 7
  runtime + OpenJTalk の cross-runtime grouped bump を補完。 dependabot
  と共存 (Renovate は regex-manager 専用、 通常 dependency は dependabot)。
- T5 PR title + commitlint: pr-title-check.yml で Conventional Commits
  type regex (feat|fix|chore|...) を PR 編集時に検査、 commitlint.yml +
  .commitlintrc.json で全 PR commits を wagoid/commitlint-github-action@v6.2.1
  で検査。 PR #498 wave2 では title formatter は /create-pr skill のみ
  だったが、 GitHub UI 直接編集の安全網として CI 側にも gate を追加。

15 エージェント調査結果 (75 提案) のうち、 残り T6-T16 (P0 残り 2 件 +
P1 15 件 + P2 13 件) を後続 commit で順次対応する。 user 明示で C 案
(全部 wave3 に押し込み) 採用。

* feat(workflow): Wave 3 batch 2 - spec meta / release scripts / templates / model publish

T6 spec TOML schema: 24 spec に [meta].forward_compat_policy 統一付与
T7 Version drift gate (S-4): check_version_manifest_sync + 10 polyglot manifest
T8 CHANGELOG 自動昇格 (S-3): promote_changelog + archive_changelog
T9 Issue/PR template: g2p-language-issue + PR template Risk Level + Contract Impact
T10 Model publish: auto_update_model_manifest + generate_hf_model_card
T11 Test flake retry (phase 1): pytest-rerunfailures + test-flake-retry-contract.toml

* feat(workflow): Wave 3 batch 3 - Trivy heavy / cosign / release-please / deferred proposals

T12 Trivy 拡張 + cosign signing: trivy-container-scan.yml に scan-heavy job、 cosign-release-artifacts.yml
T13 release-please 本格導入 (S-1): config + manifest + workflow
T14-T16 (deferred): docs/spec/wave3-deferred-proposals.toml に 12 proposal を canonical 化

* fix(workflow): lockfile gate から src/wasm/g2p/package-lock.json を除外

src/wasm/g2p/ は .gitignore で package-lock.json を意図的に除外している
('regenerated by npm install' 方針)。 一方 openjtalk-web は WASM ビルド
再現性のため committed。 両者の policy 差を尊重し、 lockfile-consistency
gate は openjtalk-web のみを hard-required にする。

CI fail: pre-commit run --all-files step で lockfile-consistency が
'missing (required): npm (g2p)' で fail していた。 5 lockfile (uv /
cargo / go × 2 / openjtalk-web npm) を hard-required、 4 soft-required
(C# × 2 / Android × 2) という最終構成に。

* fix(scripts): migrate_spec_meta — CodeQL 'unused assignment' 修正

scripts/migrate_spec_meta.py:92 で insert_at = start + 1 を代入後、
直後の last_field_line ループで再代入していた (CodeQL のは1979 指摘)。
最初の代入は不要なので削除。 機能影響なし (再代入が必ず走る path)。

CodeQL alert: 'Variable defined multiple times' (review thread の対応)。

* fix(android): dependencyLocking を STRICT → DEFAULT に降格 (2 段 rollout)

CI fail (Publish AAR + Analyze (kotlin)) の原因:
  MissingLockStateException: Configuration ':piper-plus-g2p:androidApis' is
  locked but does not have lock state.

LockMode.STRICT は gradle.lockfile が必須だが、 Wave 3 では lockfile 生成
step を CI に組み込んでいなかった。

修正方針 (2 段 rollout):
  Phase 1 (本 commit): lockMode を comment-out (DEFAULT mode)。
    lockAllConfigurations() は残し、 lockfile が存在すれば検証する形に。
    既存 build を破壊せず、 lockfile 不在でも build 成功。
  Phase 2 (別 PR): release-kotlin-g2p workflow に
    './gradlew :piper-plus-g2p:dependencies --write-locks' step を追加 →
    gradle.lockfile 生成 → commit。 landed したら本 file の LockMode.STRICT
    を有効化。

memory feedback_conservative_changes に整合 (影響大きい変更を分割)。

* feat(workflow): Wave 4 batch 1 — flake retry / stale auto-close / PR body validate + T17-T19 deferred

Wave 4 (15 並列 agent 調査、 45 提案) のうち低リスク 3 件を即実装、 残り
17 件は wave3-deferred-proposals.toml の T17 (test/coverage/golden) /
T18 (DevEx) / T19 (supply chain / security / cache / API surface) に集約。

Why: PR #498 が既に Wave 3 で 13 commit 規模、 中・大規模 item を追加すると
review 不能 (memory feedback_conservative_changes)。 低リスク 3 件のみ
本 batch に含め、 残りは個別 PR 化。

含まれる変更:
- python-tests.yml: --reruns 1 --reruns-delay 1 を 3 invocation に追加
  (runtime phonemization / runtime full / G2P package)。 一過性 flake を
  retry で吸収、 永続 flake は @pytest.mark.flaky で個別 quarantine。
  pytest-rerunfailures>=14.0 を install step に追加 (Wave 3 で
  src/python_run/pyproject.toml に追加済 dep を CI で actual 使用)。
- stale.yml: 90 日 stale + 7 日 close の Issue/PR auto-close (actions/
  stale@v9.1.0)。 pinned/blocked/wip/security/dependencies 等 label で
  exempt、 model-request backlog 蓄積を防止。
- pr-body-validate.yml: ## Test Plan / Risk Level / Affected Components
  / Type の必須 section が空のまま merge されるのを CI で gate。 bot PR
  (dependabot/renovate/release-please) と skip-pr-body-validate label
  で bypass 可。
- wave3-deferred-proposals.toml: T17 (8 sub-proposals — CLI snapshot /
  exit-code / behavioral parity / coverage threshold / untested-public-API
  / audio WAV golden / speaker encoder xruntime / flake catalog) +
  T18 (5 sub-proposals — devcontainer / dev-env-sync / CODEOWNERS-from-spec
  / stale-codeowners-path / auto-label) + T19 (10 sub-proposals — SPDX
  header / license CI / NOTICES.md / secret rotation / env-scoped secrets
  / cache key drift / ccache for C++ / API surface dump / release smoke
  test / HF model verify / code block lint / README freshness)。

* feat(workflow): Wave 5 — workflow 自動化 12 件 (Tier A) + T20-T23 deferred 28 件

Why: 15 並列 agent 第 3 弾調査 (15 領域 × ~8 件 = 119 提案) のうち、 既存 gate
  と非重複・S 工数・false positive 低の Tier A 12 件を実装。 残 100+ 件
  (M/L 工数 + 中-高 risk) は wave3-deferred-proposals.toml の T20-T23
  (G2P / モデル / error / meta + 学習) として canonical 化、 個別 PR で着手。
  Tier A は全 hook が warning-only / regression-only ゲートで既存 commit を
  block しない保守的設計。

Wave 5 Tier A 12 件:
  - 5-1  test-parametrize-hint     for-loop >=3 iter + assert を parametrize 推奨 (warn)
  - 5-4  cargo-lock-duplicates     22 既存 duplicate を baseline 化、 新規のみ fail
  - 5-4  lockfile-size-regression  uv.lock / Cargo.lock の +20% / +50% gate
  - 5-6  readme-latency-freshness  README 最終 commit >=90d で stale warn
  - 5-6  asymmetric-latency-gate   short/medium P50 ratio >=2.0 で DP unstable warn
  - 5-9  rust-unwrap-density       5 crate の unwrap density budget 化
  - 5-10 todo-age-check            git blame で >=180d の TODO を warn
  - 5-11 commitlint references     Closes/Fixes/Refs #NNN trailer を warn 化
  - 5-13 workspace-python-parity   6 pyproject.toml の requires-python pin
  - 5-14 training-template-drift   CLAUDE.md Template A/B vs argparse 同期
  - 5-15 actionlint                rhysd/actionlint v1.7.7 を pre-commit 統合
  - 5-3  cpp-lint paths             既存対応済 (確認のみ、 .yml 変更なし)

Deferred T20-T23 (28 件) — wave3-deferred-proposals.toml で canonical 化:
  - T20 G2P cross-runtime contract 拡張 (phonemize API shape / unknown phoneme /
    SSML golden / variant fixture mirror / phoneme timing mirror / dialect ctx)
  - T21 モデル ライフサイクル拡張 (embedding dim / naming / emb_lang unify /
    config roundtrip / checkpoint archive / HF sync / submission manifest /
    dataset license matrix)
  - T22 Error observability + 静的解析 (exit code / HTTP status / log level /
    RUF lints / errorlint / clang-tidy bugprone / C# naming / short-text /
    phonemizer fallback log / root pyproject floor)
  - T23 Meta-workflow + 学習 (skill meta.toml / cross-runtime DRY / hook profile /
    local-CI act / dry-run enforce / doc link / memory cleanup / training log /
    seed everything / resume determinism / ONNX sanity / dataset balance /
    val_audio_log_relation)

* fix(workflow): actionlint pre-commit を CI 等価化 (shellcheck OFF + workflow-only)

Why: Wave 5 で追加した actionlint pre-commit hook が既存 56 workflow YAML 内の
  SC2086 / SC2129 shellcheck violations を大量検出し、 CI `pre-commit
  run --all-files` を block した。 一方 .github/workflows/actionlint.yml
  は `continue-on-error: true` で運用しており、 pre-commit 側が strict
  すぎる drift だった。 actionlint の core function (workflow syntax /
  job-needs / step types) を維持しつつ、 shellcheck integration を OFF にして
  既存 CI 運用と等価に。 加えて .github/actions/**/action.yml (composite
  action 形式) は別 schema のため誤検知の対象から除外。 段階的 shellcheck
  修正は別 PR (T22) で実施。

* feat(workflow): Wave 6 — workflow 自動化 6 件 (Tier A) + T24-T28 deferred ~80 件

15 並列 agent 第 5 弾調査 (15 領域 × 7-10 件 = 119 提案) のうち、 既存 gate と
非重複・ 純粋追加型・ rollback 容易な Tier A 6 件を本 commit で実装。 残り ~80 件
(M/L 工数 + spec 設計 / cross-runtime 同期 / admin UI 必要) は
docs/spec/wave3-deferred-proposals.toml の T24-T28 に集約、 個別 PR で着手する。

## Tier A 実装内容

- **CI parallelism (6-1.1)**: 長時間 4 workflow に timeout-minutes 明示
  (deploy-huggingface 30 / model-quality-gate 15 / build-phonemize-wheels
  build 60 + test 20) — cost overrun 抑制。
- **Action security (6-13.1)**: 11 workflow に top-level permissions:
  contents: read 追加 (least-privilege)。 該当: docker-build / npm-publish /
  build-piper / wasm-build / deploy-huggingface / csharp-build-all-platforms /
  e2e-issue-426 / _build-test-cpp / build-phonemize-wheels /
  build-wasm-reusable / build-all-platforms。
- **Cache optimization (6-12.6)**: pre-commit.yml の cache key に uv.lock を
  hashFiles に追加 + 2-stage restore-keys。 uv.lock 更新で stale uv env を
  流用する race を防止 (check_*.py が ImportError で fail するリスク回避)。
- **SAST coverage (6-9.8)**: license-check.yml を新規追加 (cargo-deny
  licenses + go-licenses report)。 dependency-review-action (PR 時) との
  補完で transitive cascade を weekly audit。 forbidden mode 移行は T26
  deferred。
- **Issue triage (6-8.4)**: security-issue-routing.yml で security label
  付与 issue に needs-triage + roadmap label を auto-add + 初回 comment で
  SECURITY.md private flow に escalation 経路を提示 (conservative)。
- **Wave 6 deferred (T24-T28)**: wave3-deferred-proposals.toml に 5 sections
  (~80 提案) を append。

## Tier A から除外 (deferred 化した理由)

- 14.1 ORT drift detector を Rust ort crate 拡張: 既存 check_ort_versions.py
  の docstring で Rust ort は明示的に out-of-scope (RC 系 2.0.0-rc.X は
  upstream ORT と 1:1 対応せず) → T28 deferred。
- 15.3 commitlint references-empty を warn→error: 本 PR の既存 commit が
  Closes #N trailer を持たないため retroactively fail する → T28 deferred。

## Verification

uvx pre-commit run --files <16 files> で全 hook pass (actionlint v1.7.7 /
spec-meta-schema / editorconfig-checker / yamllint / taplo fmt 含む 20+ hook)。

* fix(license-check): CDLA-Permissive-2.0 を deny.toml allowlist に追加

Wave 6-9.8 で追加した license-check.yml workflow が cargo-deny で fail
(PR #498 run 25970354116)。 webpki-roots v0.26.11 (ureq 2.x 経由) と v1.0.6
(ureq 3.x → ort-sys → ort 経由) が CDLA-Permissive-2.0 を使用、 既存
allowlist に未登録のため reject。

CDLA-Permissive-2.0 (Community Data License Agreement Permissive 2.0) は
Linux Foundation approved の permissive OSS license で、 BSD-3-Clause と
同等の copyleft 影響なし。 rustls チームの webpki-roots は OSS で広く使われる
canonical な certificate roots crate (rustls 系 transitive dep)。

また array indent を editorconfig (*.{rs,toml} indent_size=4) に揃えるため
2-space → 4-space に統一 (cargo-deny は両 indent 受理、 taplo fmt も pass)。
ayutaz added a commit that referenced this pull request May 17, 2026
PR #505 で発覚した 2 点に対応:
- create-pr が生成する PR 本文が pull_request_template.md の必須
  セクション (## Test Plan / ## Risk Level / ## Affected Components)
  を欠き、validate-pr-body CI ゲートで必ず落ちていた
- /create-pr→/watch-pr→/reply-review の skill 間 handoff が散文指示
  のため工程が抜けることがあった (PR #496 / #505 で発生)

create-pr/SKILL.md を全面改訂し、push / PR 作成 (template 準拠本文) /
CI 監視ループ / review thread 返信+resolve を inline フェーズとして
1 skill に集約。skill 間 handoff をゼロにした。watch-pr / reply-review /
check-review-backlog は単体利用のため存続。
ayutaz added a commit that referenced this pull request May 17, 2026
* fix(gitattributes): 全ファイルを eol=lf に正規化する catch-all を追加

拡張子の個別列挙で *.go / *.rs / *.kt 等が漏れ、Windows で CRLF
チェックアウトされて gofmt と byte-for-byte sync ゲートが壊れていた。
`* text=auto eol=lf` の catch-all で現在/将来のソース種別を全カバー。
QA finding F1。

* fix(scripts): 契約ゲートを非 UTF-8 コンソールで実行可能にする

契約ゲートは — / ✓ / ↔ / ≥ 等を print するため Windows の
cp932/cp1252 コンソールで UnicodeEncodeError でクラッシュしていた。
platform_utils.force_utf8_output() を追加し対象 15 スクリプトが
import 時に stdout/stderr を UTF-8 へ reconfigure。check_todo_age は
git subprocess 出力の decode も UTF-8 明示に修正。
QA finding F6。

* fix(scripts): check_secret_path_reference を Windows 対応にする

rel パスを as_posix() で正規化(backslash パスが ALLOWLIST/docs 除外
と不一致だった)。manual scan を rglob から git ls-files へ変更し
gitignore 対象の build/ 誤走査による false positive を解消。
QA finding F7。

* fix(deps): preprocess extra の piper-phonemize に macOS marker を付与

piper-phonemize 1.1.0 は macOS x86_64 wheel のみ配布のため
`uv sync --all-extras` が非 macOS で失敗していた。sys_platform ==
'darwin' marker を付与。uv.lock を同期更新。
QA finding F5。

* test(g2p): Korean 欠落テストを g2p_en 非依存に堅牢化する

test_multilingual_ko_segment_raises_when_g2pk2_missing は混在入力の
ため g2p_en 未導入時に英語側が別 ImportError を投げ g2pk2 エラーを
隠していた。規則ベースで依存のないスペイン語セグメントに変更。
QA finding F3。

* fix(wasm): openjtalk-web eslint をレガシー CommonJS テストに対応

test/*.js のレガシーテストランナーは require()/__dirname を使う
CommonJS だが flat config が module 扱いで no-undef を多発させて
いた。CommonJS 用 config ブロックを追加。
QA finding F2(部分 — ソース本体の lint 債務は別途対応)。

* ci: 契約・sync ゲートを Windows / macOS でも実行する

契約・lint・sync ゲートは 100% ubuntu-latest のみで実行され、
Windows 固有バグ(非 UTF-8 コンソール / CRLF / パス区切り)を CI が
検出できなかった。今回のローカル QA で発覚した複数バグの根本原因。
contract-gates-extended / zh-en-loanword-sync / pua-consistency を
3 OS マトリクスへ拡張。

* fix: PR #505 の Copilot / CodeQL レビュー指摘に対応

- pyproject.toml: preprocess extra の marker に `platform_machine ==
  'x86_64'` を追加。`sys_platform == 'darwin'` だけでは Apple Silicon
  (arm64) でなお piper-phonemize の install が試行され失敗する
  (Copilot 指摘)。uv.lock を同期。
- scripts/platform_utils.py: force_utf8_output() の空 except 節に
  挙動を説明するコメントを追加(CodeQL empty-except 指摘)。

* fix: preprocess extra marker に python_version 制約を追加

Copilot レビュー指摘の残部に対応。piper-phonemize 1.1.0 の wheel は
cp311/cp312 のみ(cp313 wheel 無し)のため、marker に
`python_version < '3.13'` を追加。これで macOS x86_64 + Python
3.11/3.12 以外では install が試行されない。uv.lock 同期。

* chore(skills): create-pr を end-to-end 化 (push→PR→CI監視→review対応)

PR #505 で発覚した 2 点に対応:
- create-pr が生成する PR 本文が pull_request_template.md の必須
  セクション (## Test Plan / ## Risk Level / ## Affected Components)
  を欠き、validate-pr-body CI ゲートで必ず落ちていた
- /create-pr→/watch-pr→/reply-review の skill 間 handoff が散文指示
  のため工程が抜けることがあった (PR #496 / #505 で発生)

create-pr/SKILL.md を全面改訂し、push / PR 作成 (template 準拠本文) /
CI 監視ループ / review thread 返信+resolve を inline フェーズとして
1 skill に集約。skill 間 handoff をゼロにした。watch-pr / reply-review /
check-review-backlog は単体利用のため存続。

* chore(ci): dictionary-consistency ゲートを 3 OS マトリクス化

byte-for-byte sha256 ミラーチェックは zh-en-loanword-sync /
pua-consistency と同型の sync ゲートだが、同じ QA バッチで 3 OS 化
されず ubuntu-only のまま残っていた漏れを解消。Windows の CRLF
チェックアウト由来の byte 不一致を CI が検出できるようにする。
_mirror_check.py は UTF-8 reconfigure 済みのためスクリプト改修不要。

* chore(ci): python-tests job の到達不能な OS 分岐を削除

ci.yml の python-tests job は matrix.os が [ubuntu-24.04] 固定
だが、macOS / Windows 専用の条件ステップ (brew / choco / MSVC
ビルド) と "Run Python tests" の Windows 分岐が残っており、
いずれも実行されないデッドコードだった。3 OS × 3 Python の
pytest カバレッジは standalone の python-tests.yml が担う
(本 job のコメントも明示委譲)。単一 OS job として runner.os
条件をすべて除去。

* build(csharp): packages.lock.json を全 5 プロジェクトに追加

src/csharp/Directory.Build.props で RestorePackagesWithLockFile=true
が設定されているのに packages.lock.json がリポジトリに含まれて
おらず、NuGet 復元の再現性が担保されていなかった。Core / Cli /
Core.Tests / Cli.Tests / Bench の 5 プロジェクト分の lock file を
追跡対象に追加する。

* docs: リリース QA デバッグチェックリストを追加

全 7 ランタイムを対象としたローカル QA のデバッグ項目
チェックリスト (11 フェーズ) と本リリース QA の実行結果
サマリ。finding F1〜F7 を発見した際の作業ドキュメント。

* fix(ci): QA 副産物コミットの lint drift を修正

packages.lock.json コミットと QA checklist コミットが CI lint を
2 件落としていた:
- markdownlint MD038: QA-RELEASE-CHECKLIST.md の不可視文字
  (BOM / ゼロ幅) を含むコードスパンを named code point 表記へ置換
- end-of-file-fixer: NuGet 生成の packages.lock.json 5 件に
  末尾改行がなく fail。他 lockfile (uv/Cargo/npm) と同じく
  LF 終端へ統一
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants