Skip to content

親の前提が未達なら contains の集約で達成にしない - #13

Merged
MotimotiNotch merged 1 commit into
mainfrom
fix/issue-7-cascade-requires
Sep 12, 2026
Merged

MotimotiNotch merged 1 commit into
mainfrom
fix/issue-7-cascade-requires

Conversation

@MotimotiNotch

Copy link
Copy Markdown
Owner

Fixes #7

症状

cascadeSatisfyContainsParents() が親を自動達成にする条件で contains しか見ておらず、requirescontains を両方持つノードが前提未達のまま達成済みになる。さらに cascadeSatisfyRequires() がそこから遡るので、未達だった前提まで芋づるに書き換わる

resolveState() は一貫してそのノードを BLOCKED と判定しており、カスケード側だけが別の質問をしていた。

姉妹プロジェクト(Sirube、同じ engine を移植したもの)が2026-09-02に実データで踏んだ。目的ノードが requirescontains を同時に持った瞬間に出て、目的が勝手に達成済みになり前提7件が巻き込まれた。

直し方

  1. 判定に requires を足す
  2. 集約の引き金を requiredBy 側にも広げるcontains を持つ親には固有の作業が無いので、最後に埋まったのが前提側でも「もうやることが無い」ことに変わりはない。contains を持たない親は弾くので requires の意味は変わらない

1 だけ直すと、最後に前提を満たしたときに集約が走らず親が永久に立たなくなる。 Sirube側がテストで踏んだ落とし穴。

テスト

既存テスト1件(cascadeSatisfyContainsParents also cascades the newly-satisfied parent's own requires)が修正前の挙動をそのまま固定していた——子が揃えば親の requires が未達でも親が立ち、その前提も巻き込む、という内容。バグを仕様として書いてあったので、親の前提が満たされている形に書き換えた。

回帰テスト4件を追加:

  • 前提未達なら親を立てない/前提を巻き込まない
  • 最後に埋まったのが前提側でも集約する
  • requires だけの依存ノードは立てない(引き金を広げても requires の意味は変わらない)
  • カスケードの判定は resolveState と食い違わない

typecheck clean / 108 tests green(+4)。

既存データの被害

scratch/scan-issue-7-damage.ts(新規、読み取り専用)で走査し、0件。実データ・devデータとも requirescontains を両方持つノードがそもそも1件も無く、このリポジトリでは踏んでいなかった。

実機確認

テスト用の目標(contains 2件 + requires 1件)をdevデータに作り、UIから確認済み:

  1. 子2件を達成にしても親は未達のまま、前提も巻き込まれない
  2. 続けて前提を達成にすると、その瞬間に親が自動で達成になる

のっちの実機UXチェック済み。

🤖 Generated with Claude Code

https://claude.ai/code/session_01GK23a3A9J1eeGHFKaYgpga

cascadeSatisfyContainsParents が親を自動達成にする条件で `contains` しか
見ておらず、`requires` と `contains` を両方持つノードが前提未達のまま
satisfied になっていた。さらに cascadeSatisfyRequires がそこから遡るので、
未達だった前提まで芋づるに書き換わる。resolveState は一貫してそのノードを
BLOCKED と判定しており、カスケード側だけが別の質問をしていた。

姉妹プロジェクト(Sirube、同じ engine を移植したもの)が2026-09-02に実データで
踏んだ。目的ノードが requires と contains を同時に持った瞬間に出て、目的が
勝手に達成済みになり前提7件が巻き込まれた。

判定に requires を足し、あわせて集約の引き金を requiredBy 側にも広げた。
contains を持つ親には固有の作業が無いので、最後に埋まったのが前提側でも
「もうやることが無い」ことに変わりはない。contains を持たない親は弾くので
requires の意味は変わらない。条件だけ直して引き金を広げないと、最後に前提を
満たしたときに集約が走らず親が永久に立たなくなる。

既存テスト1件は修正前の挙動(前提未達でも親が立ち、前提を巻き込む)を
そのまま固定していたので、親の前提が満たされている形に書き換えた。回帰
テスト4件を追加: 前提未達なら立てない/前提を巻き込まない、最後に埋まったのが
前提でも集約する、requires だけの依存ノードは立てない、カスケードの判定は
resolveState と食い違わない。

既存データの被害は scratch/scan-issue-7-damage.ts で確認して0件。実データ・
devデータとも requires と contains を両方持つノードが1件も無く、このリポジトリ
では踏んでいなかった。

Fixes #7

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GK23a3A9J1eeGHFKaYgpga
@MotimotiNotch
MotimotiNotch merged commit afbc2e6 into main Sep 12, 2026
1 check passed
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.

cascadeSatisfyContainsParents が親の requires を見ておらず、前提未達でも達成済みにする

1 participant