Skip to content

fix(shared): exam の time-box を advisory に戻し binding の valid から外す (#220) - #272

Merged
shinyaoguri merged 1 commit into
mainfrom
fix/exam-timebox-advisory
Aug 15, 2026
Merged

fix(shared): exam の time-box を advisory に戻し binding の valid から外す (#220)#272
shinyaoguri merged 1 commit into
mainfrom
fix/exam-timebox-advisory

Conversation

@shinyaoguri

Copy link
Copy Markdown
Owner

Closes #220

目的

ADR-0013 と system-spec §4.7 は deadline を「advisory な提出窓の上限。verifyExamBinding の time-box は失格条件にしない。開始/締切の管理は Moodle が唯一の正」と定めているが、verifyExamBindingwithinWindow !== false を総合 valid に合流させており、docs と正面から矛盾していた (同関数内のコメント自体が「time-box (advisory)」と書いていて、18 行下のコードと食い違っていた)。

docs を正とし、実装を ADR-0013 に合わせる。 判断の経緯・却下案は #220 のコメント に記録した。

なぜ「exit 1 になるだけ」ではないか

binding.valid の下流は 3 方向に伸びている。

  1. root アンカー gate の免除が外れるverify.tsexamBindingVerified: binding?.valid === true により、遅延提出というだけで ADR-0017 の gate 免除 ([shared] 自己申告の proof.exam ブロックで --require-root-anchor gate をバイパスできる #131) が外れる
  2. 保証等級が落ちる — 同じフラグが deriveAssurancebindingValid に流れる。「実証拠のみから導出し自己申告は使わない」という ADR-0020 の原則に、スケジュールという運用情報が混入していた
  3. web と CLI で結論が割れる — 検証 (Web) は submissionTimeMs を渡さないため withinWindow は常に null。同じ proof + 同じ package でも Web は PASS、CLI に --submitted-at を渡すと FAILED になっていた ([verify/verify-cli] web↔CLI の結論一致を CI で固定するパリティテストを追加する #216 でパリティを固めた直後の非対称)

変更点

  • packages/shared/src/exam/examPackage.tsresult.valid から withinWindow !== false を削除。withinWindow の算出 (下限 >= releaseTime を含む) は一切変更せずtimeBox は表示専用の advisory 情報になる
  • packages/verify-cli/src/output.ts — time-box 行から passFail を外す。valid から外すだけだと Submitted within window: FAIL と出したまま総合は PASS になり、採点者に「FAIL と書いてあるのに合格」と読まれるため。窓内は yes、窓外は no (advisory — the submission window is managed by Moodle, not by this proof)。ADR-0013 が Negative 節に残した「advisory である旨が伝わるかは UI 表示次第 (既存の繰り越し課題)」もここで閉じる
  • docs/system-spec.md — §6.4 手順 5 に「withinWindow=falsevalid に合流しない」を明記 (§4.7 は既に正しいので変更なし)
  • CHANGELOG.md — Unreleased / 修正 に 1 行

ADR-0013 は変更していない。 実装を ADR に合わせる修正であり、docs/adr/README.md の append-only 規約の改廃手続き (新 ADR + Superseded) には該当しないため。

テスト

  • packages/shared/src/__tests__/examBinding.test.ts — 「窓外で fail」を「窓外でも valid、withinWindow=false が立つ」に反転 (= 本 Issue の再現テスト)。下限側 (releaseTime より前の提出) の境界ケースも 1 件追加
  • packages/verify-cli/src/__tests__/output.test.ts — time-box 行の表示テストを新設。この行は既存テストを一度も通っていなかった (examBindingFailed()timeBox: null だったため)

実装前にテストだけ投入して shared 2 件 / verify-cli 2 件が赤くなることを確認し、修正後に緑にした。仕上げに valid の式へ withinWindow !== false を戻し、CLI の行を passFail に戻して、4 ケースすべてが再び赤くなることも確認済み。

CLI 経路の統合テストは新設していない — 出題者鍵レジストリが本番定数 EXAM_AUTHORITY_KEYS 固定のため「binding valid かつ窓外」を組み立てられない (#216 のパリティテストに binding が valid になるケースが 1 件も無いのも同じ理由)。波及 1・2 は shared 側で binding.valid === true を固定することで担保している。

確認方法

npm run test:run --workspaces --if-present   # 746 passed / 3 skipped
npm run lint                                  # error 0 (warning 60 / info 9 は変更前と同数)

E2E は CI の e2e job に委ねる。

変更していないもの


🤖 Assisted by Claude Code

ADR-0013 / system-spec §4.7 は deadline を「advisory な提出窓の上限。verifyExamBinding
の time-box は失格条件にしない (開始/締切の管理は Moodle が唯一の正)」と定めているが、
verifyExamBinding が withinWindow !== false を総合 valid に合流させていた。

波及:
- root アンカー gate (#131 / ADR-0017) の exam 免除は examBindingVerified = binding.valid
  なので、遅延提出というだけで免除が外れる
- deriveAssurance (ADR-0020) にも同じフラグが流れ、保証等級まで落ちる
- verify (web) は submissionTimeMs を渡さないため、同じ proof で web は PASS・CLI は
  FAILED という非対称が出る

time-box を valid から外し (withinWindow の算出ロジックは不変・表示専用の advisory)、
verify-cli の time-box 行も総合 PASS の下で FAIL と読ませない表記に改めた。
docs/system-spec.md §6.4 に valid と合流しない旨を明記。

Assisted-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation pkg:shared packages/shared pkg:verify packages/verify + verify-cli pkg:repo リポジトリ横断 (docs/CI/依存) labels Aug 15, 2026
@shinyaoguri
shinyaoguri enabled auto-merge (squash) August 15, 2026 21:32
@shinyaoguri
shinyaoguri merged commit b3d0116 into main Aug 15, 2026
8 checks passed
@shinyaoguri
shinyaoguri deleted the fix/exam-timebox-advisory branch August 15, 2026 21:37
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Name URL
Preview https://82a45cfb.typedcode.pages.dev

Deployed from commit bea2ebd
API: staging Workers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation pkg:repo リポジトリ横断 (docs/CI/依存) pkg:shared packages/shared pkg:verify packages/verify + verify-cli

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[shared] exam の time-box が ADR-0013「advisory・失格条件にしない」に反して失格条件になっている

1 participant