chore: v0.23 release gate governanceを追加 - #594
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 035f56f9fe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if not re.search( | ||
| r"\b(no|not|without|does not|do not|is not|not a|forbidden|does not approve)\b", | ||
| prefix + " " + sentence_prefix, | ||
| ): |
There was a problem hiding this comment.
Reject positive claims after unrelated negations
When a release issue or notes draft says something like Not production ready; public sync ready. or No production-ready claim; AI chat ready., this regex sees the earlier unrelated negation in sentence_prefix and suppresses the later positive forbidden claim, so the gate can still return release_go=true with an overclaim present. The negation check needs to be scoped to the same clause/phrase being matched rather than the whole sentence prefix.
Useful? React with 👍 / 👎.
| AGENTS.md @YoneRai12 | ||
| .github/workflows/* @YoneRai12 | ||
| clients/cli/yonerai_cli/services/realtime_sync_client_service.py @YoneRai12 | ||
| docs/contracts/* @YoneRai12 |
There was a problem hiding this comment.
Cover nested contract files in CODEOWNERS
docs/contracts contains nested contract artifacts under paths like docs/contracts/schemas/... and docs/contracts/fixtures/..., but the docs/contracts/* CODEOWNERS pattern only covers direct children. Changes to those nested schemas/fixtures therefore won't request the owner review this governance file is adding for contract changes; use a recursive directory pattern instead.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Code Review
This pull request introduces a release gate checker script (scripts/yonerai_release_gate.py) along with its corresponding unit tests and updates the .github/CODEOWNERS file. The review feedback highlights three key issues: a bug in _status_failures where currently running checks may be ignored in favor of older completed checks; a violation of the ASCII-safety rule due to the use of ensure_ascii=False when dumping JSON; and a logic flaw in scan_overclaim_text where negation checks can cross sentence boundaries and cause false negatives.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| current_time = _parse_time(str(current.get("completedAt") or "")) if current else None | ||
| check_time = _parse_time(str(check.get("completedAt") or "")) | ||
| if current is None or (check_time and (current_time is None or check_time >= current_time)): | ||
| latest_by_name[name] = check |
There was a problem hiding this comment.
_status_failures 内の最新のチェックを判定するロジックにおいて、現在実行中のチェック(completedAt が存在せず check_time が None になるもの)がある場合、すでに完了した古いチェック(current)が存在すると、check_time が None(Falsy)であるために条件式 current is None or (check_time and ...) が False となり、実行中の最新チェックが無視されてしまいます。
これにより、古い成功したチェックのステータスが誤って採用され、現在実行中のチェック(または未完了のチェック)があるにもかかわらずリリースゲートを通過してしまう可能性があります。
実行中のチェック(check_time is None)を最新として扱うように条件を修正することをお勧めします。
| current_time = _parse_time(str(current.get("completedAt") or "")) if current else None | |
| check_time = _parse_time(str(check.get("completedAt") or "")) | |
| if current is None or (check_time and (current_time is None or check_time >= current_time)): | |
| latest_by_name[name] = check | |
| current_time = _parse_time(str(current.get("completedAt") or "")) if current else None | |
| check_time = _parse_time(str(check.get("completedAt") or "")) | |
| if current is None: | |
| latest_by_name[name] = check | |
| elif check_time is None: | |
| latest_by_name[name] = check | |
| elif current_time is not None and check_time >= current_time: | |
| latest_by_name[name] = check |
| Blocker(PUBLIC_REPO, "github_access", "p1", str(exc), "").as_dict(), | ||
| ], | ||
| } | ||
| print(json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True)) |
There was a problem hiding this comment.
General Rulesに「Keep ensure_ascii=True when dumping JSON in CLI commands to ensure ASCII-safety and prevent cp932 decoding issues in Windows/PowerShell subprocesses」とあります。現在、ensure_ascii=False が指定されているため、Windows環境やPowerShellのサブプロセスでcp932デコードエラーが発生する可能性があります。ensure_ascii=True に変更するか、デフォルト値(True)を使用するようにしてください。
| print(json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True)) | |
| print(json.dumps(report, ensure_ascii=True, indent=2, sort_keys=True)) |
References
- Keep
ensure_ascii=Truewhen dumping JSON in CLI commands to ensure ASCII-safety and prevent cp932 decoding issues in Windows/PowerShell subprocesses.
| prefix = lowered[max(0, index - 36) : index] | ||
| sentence_start = max(lowered.rfind(".", 0, index), lowered.rfind("\n", 0, index), lowered.rfind(":", 0, index)) | ||
| sentence_prefix = lowered[sentence_start + 1 : index] | ||
| if not re.search( | ||
| r"\b(no|not|without|does not|do not|is not|not a|forbidden|does not approve)\b", | ||
| prefix + " " + sentence_prefix, | ||
| ): |
There was a problem hiding this comment.
scan_overclaim_text において、prefix(対象フレーズの手前36文字)と sentence_prefix(文頭から対象フレーズまで)を結合した文字列に対して否定語の検索を行っています。
しかし、prefix は文の境界(ピリオドや改行)を考慮せずに機械的に手前36文字を切り取るため、前の文に含まれる否定語(例: "This is not ready. It is production ready." における "not")が現在の文の肯定的な主張を誤って打ち消してしまい、検出漏れ(偽陰性)が発生します。
否定語の検索は、文の境界で区切られた sentence_prefix のみに対して行うように修正することで、この問題を回避できます。
sentence_start = max(lowered.rfind(".", 0, index), lowered.rfind("\n", 0, index), lowered.rfind(":", 0, index))
sentence_prefix = lowered[sentence_start + 1 : index]
if not re.search(
r"\b(no|not|without|does not|do not|is not|not a|forbidden|does not approve)\b",
sentence_prefix,
):035f56f to
228bb15
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 228bb15441
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| later = [ | ||
| item | ||
| for item in tags | ||
| if item.get("tag") in ROLLBACK_OR_BLOCKER_TAGS and item.get("created_at") and item["created_at"] > passed["created_at"] | ||
| ] |
There was a problem hiding this comment.
Reject stale ready tags after rollback
When issue #552 contains a blocker/rollback tag after the ready markers but before the eventual [WEB-TO-CLI-E2E-PASSED], this filter only looks for blockers later than the pass marker, so check_issue_552() returns no blocker and release_go can be true while using stale readiness evidence. I inspected AGENTS.md's release-window rule, which explicitly forbids using old window evidence after rollback; reset the window on any rollback/blocker between the readiness tags and the pass.
Useful? React with 👍 / 👎.
228bb15 to
bceba47
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bceba472c6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "[WEB-TO-CLI-E2E-PASSED]", | ||
| ) | ||
|
|
||
| ROLLBACK_OR_BLOCKER_TAGS = ( |
There was a problem hiding this comment.
Treat documented blocker tags as blockers
When issue #552 contains a standalone blocker tag such as [AWS-PUBLIC-ALLOWLIST-BLOCKER] (documented in docs/codex/checkpoints/public_sync.md:138 as the latest effective blocker) or [AWS-E2E-SUPPORT-BLOCKED], issue_comment_tags() records it but this hard-coded tuple never matches it, so check_issue_552() can still accept stale ready/pass markers and return release_go=true; include the documented *-BLOCKED/*-BLOCKER coordination tags or match them generically.
Useful? React with 👍 / 👎.
| "security", | ||
| } | ||
|
|
||
| OVERCLAIM_PATTERNS = ( |
There was a problem hiding this comment.
Block all forbidden release overclaims
When the v0.23 release issue or a draft release note says a forbidden positive claim like Discord restored, Google login complete, Tools/MCP complete, or v7.8 started, scan_overclaim_text() returns no finding because this denylist only covers five phrases. Those claims are explicitly banned by AGENTS.md:16 and release governance, so the new release gate can report release_go=true for an overclaim it is meant to block.
Useful? React with 👍 / 👎.
bceba47 to
9b08d38
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9b08d38963
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| clause_start = max(sentence_start, lowered.rfind(",", 0, index)) | ||
| clause_prefix = lowered[clause_start + 1 : index] | ||
| local_negation = re.search(r"\b(no|not|without|does not|do not|is not|not a)\b", clause_prefix) |
There was a problem hiding this comment.
Split negation scope on conjunctions
Fresh evidence after this update: the scanner still only narrows negation scope at commas, so common release-note wording such as No production-ready claim and public sync ready. or Not production ready but AI chat ready. makes local_negation match the earlier negative phrase and suppresses the later positive forbidden claim. That lets the v0.23 gate report no overclaim for text the AGENTS/release governance rules explicitly forbid; include conjunctions like and/but/however in the clause boundary or otherwise bind the negation to the matched phrase.
Useful? React with 👍 / 👎.
| tests/test_verify_version.py \ | ||
| tests/test_release_workflow_prerelease.py \ | ||
| tests/test_release_gate.py \ | ||
| tests/test_yonerai_release_gate.py \ |
There was a problem hiding this comment.
Run the new release gate in CI
Adding the new test file to the release-gate job only exercises unit tests; the job below still invokes scripts/release_gate.py and never executes scripts/yonerai_release_gate.py --fail-on-blockers, and the tag release workflow is likewise unchanged. As a result, the new #552/cross-repo blocker checks and release_go decision can be completely bypassed during CI/release, so a v0.23 release path can pass without consulting this governance gate.
Useful? React with 👍 / 👎.
9b08d38 to
d19e815
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d19e815c6f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| --artifact "${PRODUCT_NAME}-${ORA_VERSION}.zip" \ | ||
| --github-prerelease "${ORA_PRERELEASE}" | ||
| python scripts/yonerai_release_gate.py \ | ||
| --release-issue 592 \ |
There was a problem hiding this comment.
Do not hard-code the v0.23 gate issue
This workflow runs for every pushed tag matching v*, but the new gate always checks issue #592. Once v0.23 has passed or a later release has its own gate issue, non-v0.23 releases will still be governed by stale #592 checklist/state instead of the release being built, and --fail-on-blockers can abort them for that unrelated issue; pass the issue number from release metadata/input or scope this hard-coded check to the v0.23 tag only.
Useful? React with 👍 / 👎.
| ], | ||
| } | ||
| print(json.dumps(report, ensure_ascii=True, indent=2, sort_keys=True)) | ||
| if args.fail_on_blockers and report.get("blockers"): |
There was a problem hiding this comment.
Fail only when the release gate is false
When the report contains only non-release-blocking P2 items, build_report() still sets release_go to true, but this exit check returns failure for any entry in blockers. Since the release workflow invokes --fail-on-blockers, a P2 such as an unreadable sibling AGENTS.md or a closed gate issue can abort the release even though the JSON says it is safe; base the exit status on release_go or make those severities release-blocking consistently.
Useful? React with 👍 / 👎.
概要
.github/CODEOWNERSを追加し、AGENTS.md / workflows / realtime sync receiver / docs/contracts を owner review対象にしました。scripts/yonerai_release_gate.pyを追加しました。gh --repo明示の読み取り専用cross-repo release gate checkerで、issue coord: Web-to-CLI realtime sync contract v1 #552、v0.23 Release Gate issue、Public/AWS/Web open PR、AWS PR chore(deps): update transformers requirement from >=4.48.0 to >=5.9.0 #150、AGENTS.md presence、release note overclaimをJSONで返します。Fresh truth / release gate
[YONERAIWEB-SYNC-CLIENT-READY]/[PUBLIC-SYNC-CLIENT-READY]/[WEB-TO-CLI-E2E-PASSED]が存在します。python scripts/yonerai_release_gate.py --release-issue 592は現在release_go=falseを返します。主な理由は AWS PR chore(deps): update transformers requirement from >=4.48.0 to >=5.9.0 #150/chore(deps): update discord-py requirement from <3.0,>=2.3 to >=2.7.1,<3.0 #151 と #592の未完了checklistです。GitHub governance
YonerAI Launch Controlはgh projectがread:project/projectscope不足で操作不能でした。Project作成は権限ブロッカーとして報告します。検証
python -m pytest tests/test_yonerai_release_gate.py tests/test_release_gate.py tests/test_quality_wall_workflow.py -qpython -m ruff check scripts/yonerai_release_gate.py tests/test_yonerai_release_gate.pypython -m compileall -q scripts/yonerai_release_gate.py tests/test_yonerai_release_gate.pygit diff --checkgit diff --cached --checkpython scripts/ci_quality_scans.py --changedpython scripts/yonerai_release_gate.py --release-issue 592境界
src/cogs/ora.pyとreference_clawdbotは触っていません。docs/codex/checkpoints/public_sync.md差分はこのPRに含めていません。