テスト: .md の文言を照合するテストを削り、書かない方針を規約にする(#885) - #918
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
ファイルごと消したテストは 20 本、混在するファイルからは関数単位で外した。 参照の実在は check-markdown-links.py が失敗を返すことを確かめてから削った。 retrospective/tests が無くなるため、test_root_conftest.py の一覧の外の束を playwright-kit-ops/tests へ差し替えた。 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | codex | REQUEST_CHANGES
文書内の実行手順と、文書から本番判定へ複製される契約は、文言固定テストの削除対象から外し、振る舞いまたは整合性を自動検証してください。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | kiro | REQUEST_CHANGES
本 PR は自らが新設する方針(tdd-cycle/references/test-quality.md の例 8 の表)で「参照切れは検査スクリプトが見る」「スクリプトが実行時に読む形式はそのスクリプトを通すテストで見る」と定めている。しかし削除したテストの一部は、その表で『残す』側に当たる (a) 実行時に読むシェル定数と文書表の整合、(b) 実ファイル群が索引に漏れなく載る参照切れ、を見ていた。AC19b の検査スクリプトへの寄せ替え(check-markdown-links.py)はいずれも検知できない方向のため、置き換えなしで保護が失われている。削除対象を『.md 文言照合』と『機械が読む契約・参照切れ』へ分け直し、後者は検査スクリプトへ寄せるか、寄せられないものは PR 本文にその旨を明記することを推奨する。
- test_skill_bg_wait.py から誤って消えた test_critique_round_monitors_with_the_critique_phase を test_critiques.py へ移して戻す(.md ではなく scripts/critique-round.sh を読む検査) - ndf-documentation-mode.md のテスト観点「形が 9 つあり、索引が実ファイルと一致する」の確かめ方を、 削除済みのテストではなく文書を読んで確かめる形へ直す Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
🔧 /ndf:fix サマリ | round 1 | commit 786e558対応件数: critical=0 / major=1 / minor=1(合計 2 件) |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | claude | REQUEST_CHANGES
文言照合ではない検査(release/SKILL.md の 365 行の上限)が分類の規則の外で消えており、削除したテスト関数を指す仕様書の行も 2 本残っている。
差分の外を指す指摘
docs/specifications/ndf-cleanup-and-bundle-closing.md:252[major] [major / 正確性]test_completion_check.pyからtest_the_skill_md_stays_within_its_budget(release/SKILL.md≤ 365 行)が消えたが、これは.mdの文言照合ではなく分量の上限で、設計の「分類の規則」のどの削る行にも当たらず PR 本文でも触れていない。500 行はcheck-skill-frontmatter.py/check-doc-line-limit.pyが見るが 365 行を見る検査は他に無いので、この関数を戻す(残す)か、上限を捨てる判断を本文に書いたうえで本行とndf-instruction-files-check.md:315の確かめ方を直す。docs/specifications/ndf-cleanup-and-bundle-closing.md:249[minor] [minor / ドキュメント整合] 確かめ方が削除済みのtest_only_progress_tracking_closes_issues/test_the_gates_stay_twoを指し、次の行(250)の「同上(…release_verification_templateを名前に持つテスト)」も削除済みの 3 関数を含む。他の 9 本と同じく「文書を読んで確かめる(照合していたテストは #885 で削除)」へ直し、250 行は残るclosing_step/record_readerのテストだけを挙げる。docs/specifications/ndf-agent-layers-unattended-run.md:265[minor] [minor / ドキュメント整合] 「同上」の先が「文書を読んで確かめる」に変わったのに、265 行と 267 行は削除済みのtest_cross_review_defines_main_as_the_driving_supervisor/test_the_three_layer_docs_drop_the_old_wordsを括弧で挙げたまま。括弧の関数名を外して「同上」だけにする。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | kiro | REQUEST_CHANGES
本 PR が新設した方針(tdd-cycle/references/test-quality.md 例 8)は「参照切れを見ていたテストは、検査スクリプトが同じ参照で失敗を返すことを確かめてから削る」と明記している。release/tests/test_completion_check.py から削られた test_the_form_index_links_to_every_form_file は、distribution-forms.md の索引が実在する form-*.md(9 本)を全て指すことを確かめる網羅性検査だったが、この網羅性を代替するスクリプトが存在しない(check-markdown-links.py は既存リンクの解決のみで、索引に無い form ファイルを検知しない)。方針自身が要求する代替の確認を通さずに削除されている点だけを直せば良い。他の削除(WF_STAGE_MATRIX と SKILL.md 表の突き合わせ等)は、対象の振る舞いが test_workflow_guard.py / test_stage_check.py / test_workflow_units.py に残るため方針どおりで、指摘しない。
- test_the_skill_md_stays_within_its_budget(release/SKILL.md <= 365 行)を戻す - test_the_form_index_links_to_every_form_file を、実在する form-*.md との網羅の検査として戻す(固定の 9 名の一覧は使わない) - 仕様のテスト観点の表から削除済みのテスト名を外し、残るテストを関数名で指す Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
🔧 /ndf:fix サマリ | round 2 | commit 79ffb98対応件数: critical=0 / major=2 / minor=2(合計 4 件) |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 3 | claude | REQUEST_CHANGES
残した関数の分類(AC19a)に、分類の規則では「削る」に当たる関数が P1 として混ざっている。本文の表の件数と合わせて直す。
差分の外を指す指摘
scripts/tests/test_base_branch_consistency.py:234[major] [major / 正確性]test_remote_default_branch_is_not_hardcodedとtest_commands_do_not_hardcode_default_branch(242 行)はSKILL.mdを読んでorigin/mainやmainの字面の有無を見るだけで、埋め込んだ bash を実行していない。設計の「分類の規則」の「文書の中のコマンドの形を照合する → 削る」に当たるため、2 関数(と使われなくなるLITERAL_SKILLS・COMMAND_LITERAL)を削り、PR 本文の P1 の行のtest_base_branch_consistency.py(8) を (6) に直してほしい。plugins/ndf/skills/cross-refactoring/tests/test_removed_review_phase.py:40[minor] [minor / 一貫性]test_the_review_prompt_is_goneは消したprompts/review.mdが無いことだけを見ており、分類の規則の「消した名前のファイルが無いこと → 削る」(test_agy_naming.pyのlaunch-gemini.shと同じ形)に当たる。この PR でtest_agy_naming.pyの同じ形を削っているのと揃えて削るか、残すなら PR 本文の分類表に残す理由を書いてほしい。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 3 | codex | APPROVE
修正必須の指摘はありません。
- test_base_branch_consistency.py: SKILL.md の origin/main / main の字面を照合するだけの test_remote_default_branch_is_not_hardcoded と test_commands_do_not_hardcode_default_branch、 それでしか使わない LITERAL_SKILLS・COMMAND_LITERAL、モジュール docstring の該当文を削る - test_removed_review_phase.py: 消した prompts/review.md の不在だけを見る test_the_review_prompt_is_gone を削る Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
🔧 /ndf:fix サマリ | round 3 | commit 8713fe1対応件数: critical=0 / major=1 / minor=1(合計 2 件) |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 4 | codex | APPROVE
修正が必要な指摘はありません。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 4 | kiro | REQUEST_CHANGES
AC24(uv run ... pytest . -q -n 4)は手元で 4641 passed を確認。本番コード変更(workflow-common.sh のコメント、test_root_conftest.py の OUTSIDE_BUNDLE 差し替え)と部分削除は全体テストで裏付けられており、機能退行は見当たらない。残る指摘は、この PR が新設した方針(test-quality.md 例 8)と、方針適用後に残ったテスト・補助関数の整合の 2 点で、いずれも minor。
差分の外を指す指摘
plugins/ndf/skills/worktree/tests/test_scripts_reference.py:170[minor] [minor / 一貫性]test_no_undefined_variableは doc の code block から変数使用を集め、received_tableが読む.mdの表の宣言と突き合わせるだけで、bash を実行しない。これは本 PR が新設した方針(test-quality.md 例 8 「.md の文言・表・語の有無を照合するテストを書かない」)に当たる.md構造照合であり、同じファイルの bash 実行テスト(test_*_layout_resolves_worktree_setup)とは別扱いのはず。削除するか、機械が読む契約(変数宣言表)としてスクリプト側で検査する経路へ寄せるか、PR 本文の分類表で残す理由を明示する。plugins/ndf/skills/worktree/tests/test_scripts_reference.py:141[minor] [minor / 保守性]received_tableはtuple[set[str], int]を返すが、trim 後の唯一の呼び出し(173 行)はdeclared, _ = received_table(path)で第 2 要素 index を捨てている。index を使っていたnext_content_line/test_bundling_is_recommended_after_the_tableは削除済み。戻り値をset[str]に減らし、未使用の index 計算を落とす(plan Task 2 の「使われなくなった補助の関数・定数・import を消す」に沿う)。
…le の戻り値を減らす Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
🔧 /ndf:fix サマリ | round 4 | commit c42d3f8対応件数: critical=0 / major=1 / minor=1(合計 2 件) |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | codex | APPROVE
修正が必要な新規指摘はありません。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | kiro | REQUEST_CHANGES
AC24 は手元で確認済み(uv run ... pytest . -q -n 4 で 4641 passed、SHARD 0/1 でも 1835+2806=4641 passed)。本番コード変更(workflow-common.sh のコメント、test_root_conftest.py の OUTSIDE_BUNDLE 差し替え)と大量のテスト削除は全体テストで裏付けられ、機能退行は見当たらない。ラウンド 4 の CI: FAILURE は手元(フル・シャード両方・collect-only)では再現せず、worktree からは CI ログを確認できないため原因を特定できなかった(pytest.yml の必須検査は緑、pr-body-decisions は必須外との注記あり)。残る指摘は 1 件のみ。この PR が編集して 207→12 行へ切り詰めた test_skill_layout.py に、方針(例 8)と同じ字面照合の関数が 1 つ残っている点。
🔧 /ndf:fix サマリ | commit (なし)対応件数: critical=0 / major=0 / minor=0(合計 0 件) |
#895 の中継テスト(AC23)は残し、#885 で削除した文言テスト 2 本 (test_workflow_skill_handover_rule / test_readme_runtime_table)は戻さない。 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
Summary
Closes #885
リポジトリで追跡している
.mdの文言を照合する pytest を削り、書かない方針をテストを書く規約へ入れた。設計 PR #911(関門 1 承認済み)で分けた 2 本のうちの PR 1。PR 2(#880 #883 #494 #723、cross-refactoring の是正)は別に進んでいる。issues/issue-880-885-design.md(「テストと規約(F10・F11)」「テスト: .md の文言を固定するテストを削除し、置かない方針を規約にする #885 の棚卸」)issues/issue-885-plan.mdretrospective_helpers.py)。一覧は下の「分類」tdd-cycle/references/test-quality.mdに### 8. .md の文言を照合するを足し、「削除してよいテスト」に 1 行。quality-gates/SKILL.mdの「受け入れ条件との対応」に、文書の文言照合を検証手段にしないと 1 段落。AGENTS.mdの DON'T に 1 行scripts/tests/test_root_conftest.pyのOUTSIDE_BUNDLEをplugins/playwright-kit/skills/playwright-kit-ops/testsへ差し替えた(retrospective/testsが無くなるため。条件の「一覧に無く、シェルスクリプトを起動しない束」を満たす)。削除したテストを検証手段として指していたdocs/specifications/の 9 本・workflow-common.shのコメント 1 行・docstring 2 か所を直した全体テストの件数: 5365 → 4641(レビューで戻した 3 関数と削り足した 3 関数を含む)。
構造改善: 飛ばした。利用者の指示で当面省略している(#880 ほか)うえ、本番コードの差分がない(
.shの変更はコメント 1 行だけ。refactor.py assessはまだ無いため、設計の「実装の分け方と順序」の条件に当たることをここに書く)分類(AC19a)
判定の問いは「その
.mdをスクリプトが実行時に読むか、テストがその中のコードを実行するか」で、どちらでもなければ削った(設計の「分類の規則」)。洗い出しの方法: 次の 2 つの和を取った。
.mdを開いたかを記録する.mdのパスのリテラルを、定数・補助モジュール・fixture まで追う実行時の記録はキャッシュ経由の読み取りを取りこぼし、AST は一時ファイルの同名を誤検知するため、和を取ってから関数の本文を読んで分類した。
削除した後に残った関数(実行時にリポジトリの
.mdを開くもの 84 関数)test_projects_scripts_lookup.py(13)・test_base_branch_consistency.py(6)・test_completion_check.py(9)・test_scripts_reference.py(6)・test_issue_target.py(5)・test_related_skills_characterization.py(4)・test_workflow_hooks.py(3)・test_declaration_check.py(2)・test_issue_upkeep_layout.py(2)・test_base_branch.py(2)・test_package_plugin_examples.py(2)test_assert_changes.py(2)test_vocabulary_single_source.py(3)・test_vocabulary_source.py(1)。test_apply_rounds.py・test_merge_apply.py・test_abandon_items.pyの各 1 はvocabulary.pyの import がvocabulary.mdを読む(テストは.mdを見ていない)test_workflow_hooks.py(8)・test_worker_agent.py(1)test_notion_writing_backticks.py(1)、test_scripts_reference.py::test_no_undefined_variable(埋め込み bash の未定義変数の静的検査)test_external_ai_codistribution.py(2)(/ndf:external-aiを指す Skill が manifest で一緒に配られるか)test_completion_check.py(2)(下の「レビューで戻したもの」)test_cross_skill_refs.py(2)・test_lock_common.py(2)・test_kiro_installer_project.py(2)AST の走査にだけ出た関数: 実行時には追跡中の
.mdを開かない。一時ディレクトリに同名のファイル(README.md・SKILL.mdなど)を作ってスクリプトへ渡すテストで、規則の「入力」に当たる。例はtest_instructions_check.py・test_doc_staleness.py・test_workflow_guard.py。P2' に残したもの: スクリプトが実行時に生成した
*-prompt.mdを見る関数は残した(test_critiques.py・test_propose_prompt.py・test_test_round_prompt.pyほか)。このうち雛形の説明の文言だけを見る 4 関数は削る側とも読める。今回は規則どおり残した。ファイルごと削除したもの
test_agent_layers_doc.py・test_approval_gates.py・test_parallel_work_bounds.py・test_stage_values.py・test_workflow_stage_matrix.py(development-workflow)、test_execution_plan_doc.py(issue-plan-strategy)、test_skill_terms.py・test_monitor_phase_calls.py(cross-refactoring)、test_agy_naming.py・test_procedure_eval_exit_code.py・test_skill_bg_wait.py・test_writes_by_conductor_docs.py(cross-review)、test_design_definition_ownership.py・test_documentation_read_order.py(design)、test_context_window_section.py・test_record_target.py・retrospective_helpers.py(retrospective)、test_run_metrics_docs.py(ndf/scripts)工程表と定数の一致を見ていたテスト
test_stage_values.py・test_workflow_stage_matrix.pyは、SKILL.mdの工程表と、実行時に使うシェルの定数(workflow-common.shのWF_STAGE_MATRIX・projects-common.shのPJ_STAGES)の一致を見ていた。検査スクリプトへは寄せずに削った。SKILL.mdの工程表を実行時に読むスクリプトは無く、設計の「分類の規則」の「2 つの文書の表の並びが一致する」と P3'(スクリプトが読まない文書の値とコードの定数の一致)に当たる。工程表と定数の食い違いはレビューで見る。WF_STAGE_MATRIXの中の並びと特定のセルはtest_document_restructuring_stage.pyが引き続き見る。設計の棚卸と違ったところ
retrospective_helpers.pyは残らなかった。設計は「共有の補助モジュールは残る」としていたが、import するのはtest_record_target.pyだけで、そのファイルに残す関数が無かったtest_document_restructuring_stage.pyから削ったのは 1 関数だけだった(設計の概数は 8)。残りの関数は.shの定数と manifest を読んでいるtest_workflow_stage_matrix.pyはファイルごと消した(設計は「残す 1」)。残す候補だった関数は、削る関数だけが使う補助の自己検査だったtest_token_guard.py(7 関数)とtest_vocabulary_single_source.py(2 関数。どのスクリプトも読まないcode-smells.mdの語の有無を見ていた)からも削ったrelease/SKILL.mdの配布の記録の例など)は削った。P1 の読み取りを通していなかったため参照切れの寄せ先(AC19b)
リンクの参照を見ていた関数は、参照先を 1 つずつ消した写しで
python3 scripts/check-markdown-links.py --root .を実行し、どれも exit=1 と参照元の行が出ることを確かめてから削った(元の状態では exit=0)。issue-upkeep/SKILL.md→references/no-work.md・milestones.md・grouping.mdissue-upkeep/SKILL.md: missing link target: references/no-work.mdほかdevelopment-workflow/SKILL.md→references/operation-run.mdoperation-run.mdSKILL.mdの 5 か所を検出release/SKILL.md→references/completion-check.mdcompletion-check.mdrelease/references/distribution-forms.md→form-*.mdform-package-plugin.mddevelopment-workflow/SKILL.md→references/stage-completeness.mdstage-completeness.mdout-of-scope/SKILL.md・retrospective/SKILL.md→issue-target.mdissue-target.mdcross-review/SKILL.md→docs/03-review-output.md・docs/04-contracts.md、docs/01-state-and-review.md→04-contracts.mdexternal-ai/SKILL.md→references/cli-agy.mdcli-agy.mdSKILL.md→references/execution-plan.md・parallel-work.md・agent-layers.md・context-window.md(ファイルごと消したテストの配線の照合)検査スクリプトへ判定を足さずに削ったもの: いずれも参照の実在を見るテストではなかった。
launch-agy.sh・git-credential.shを指す語の照合: リンクではない語を照合していた。前者は改名の後始末の確認で、役目を終えている残したもの:
/ndf:external-aiを指す Skill が一緒に配られるかと、manifest が指す Skill の実在の 2 つ。配布の構造であり、.mdの文言ではない。レビューで戻したもの(cross-review):
release/tests/test_completion_check.pyのtest_the_form_index_links_to_every_form_file: 実在するform-*.mdのすべてをdistribution-forms.mdの索引が指すか。check-markdown-links.pyは逆向き(索引に無いファイル)を見ないため。固定の 9 名の一覧は使わず、globの結果と比べる形にしたtest_the_skill_md_stays_within_its_budget(release/SKILL.mdは 365 行まで): 文言ではなく分量の上限。365 行を見る検査が他に無いcross-review/tests/test_critiques.pyのtest_critique_round_monitors_with_the_critique_phase:.mdではなくscripts/critique-round.shを読むテストで、削る対象ではなかった(test_skill_bg_wait.pyから移した)レビューで削り足したもの(cross-review):
scripts/tests/test_base_branch_consistency.pyのtest_remote_default_branch_is_not_hardcoded・test_commands_do_not_hardcode_default_branch(SKILL.mdの字面を見るだけで bash を実行しない=「文書の中のコマンドの形を照合する」)と、cross-refactoring/tests/test_removed_review_phase.pyのtest_the_review_prompt_is_gone(消したファイルの不在を見る=「消した名前のファイルが無いこと」)規約(AC19c)
文書を読んで確かめる(文言を固定するテストは書かない)。
plugins/ndf/skills/tdd-cycle/references/test-quality.mdの「### 8..mdの文言を照合する」と、「削除してよいテスト」の 1 行plugins/ndf/skills/quality-gates/SKILL.mdの「受け入れ条件との対応」の段落AGENTS.mdの「DON'T(非推奨)」の 1 行やらないこと
refactor_lib・workflow-modes.md・stage-notes.md(PR 2 が扱う)issues/issue-880-885-design.md)の棚卸の概数の更新。上の「設計の棚卸と違ったところ」を記録として残す実装レビュー(cross-review)
codex / kiro / claude の 2 席ずつで通算 5 ラウンド(agy は収束ループで止まるため
--exclude agy)。4 ラウンド目の後、test_instructions_check.py::test_ac44_refresh_writes_nothingの flaky(.git/objects/maintenance.lock)で CI が落ちて一度中断し、直した後に状態を作り直した 1 ラウンドで収束した(codex=APPROVE、kiro の指摘 1 件は範囲外)。最終スイープ後の未解決の指摘は 0 件(GitHub 側で確認)。範囲外として起票: #923(
test_ac18_check_writes_nothingも同じ flaky の形)、#924(スクリプトに埋め込んだプロンプトの文言を照合するテストの扱い)。Test plan
uv run --project plugins/playwright-kit/skills/playwright-kit-ops --with pytest pytest . -q -n 4→ exit=0(4641 passed。c42d3f89、2026-09-23 14:18)check-markdown-links.pyが exit=1python3 scripts/check-markdown-links.py --root .→ exit=0python3 scripts/check-doc-line-limit.py→ exit=0python3 scripts/check-skill-frontmatter.py→ exit=0python3 scripts/check-skill-repo-assumptions.py→ exit=0(test-quality.mdの表にあったこのリポジトリのスクリプトのパスは、一般の語に直した)python3 scripts/check-cross-skill-refs.py/check-skill-shell-vars.py/check-doc-staleness.py→ exit=0python3 plugins/ndf/scripts/instructions-check.py --root .→ exit=0bash scripts/build-runtime-plugins.sh→ exit=0(生成物の差分なし)、bash scripts/validate-runtime-plugins.sh→ exit=0claude plugin validate .→ exit=0🤖 Generated with Claude Code
https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy