Skip to content

test(e2e): Phase D 敵対的パック (AI 一括投入検出 + proof 偽造) + insertParagraph 検出漏れ修正 - #118

Merged
shinyaoguri merged 4 commits into
developfrom
feat/e2e-phase-d
Jun 17, 2026
Merged

test(e2e): Phase D 敵対的パック (AI 一括投入検出 + proof 偽造) + insertParagraph 検出漏れ修正#118
shinyaoguri merged 4 commits into
developfrom
feat/e2e-phase-d

Conversation

@shinyaoguri

Copy link
Copy Markdown
Owner

概要

E2E ハーネス Phase D。敵対的シナリオ (AI コード一括投入の検出 / proof 偽造の負のオラクル) を追加し、AI 一括投入の検出漏れを発見・修正した。

🐛 発見・修正した検出漏れ (重要)

Copilot/Cursor が「コード全体を 1 編集で一気に投入」すると検出を素通りしていた (fix(shared))。

AI が executeEdits で複数行コードを 1 編集で投入すると Monaco は insertParagraph で記録する。Phase A の bulk 検出は insertText/insertReplacementText/replaceContent のみを対象にしていたため、この insertParagraph 経路を素通りし、Pure Typing: YES のまま AI 一括投入を見逃していた。Phase D の敵対的 E2E で発覚。

修正:

  • insertParagraph を bulk 検出対象に追加。空白のみ (auto-indent) は benign、コードを含めば bulk。
  • 内部ペーストの罠: 自分のコードの内部コピペも実挿入は複数行 insertParagraph になり AI と区別できない。insertFromInternalPaste 監査マーカーと同一内容を許可リスト化して 3 経路 (verification / processSummary / pureTypingAnalyzer) で除外。
  • isPureTyping を複数行 bulk でも崩すよう更新。bulkInsertEvents 申告メタデータ照合・valid (暗号的合否) は不変で後方互換。

E2E シナリオ (Phase D: 3本・全 green。累計 16本 green)

  • ai-bulk-insert (2): 単一編集での複数行コード投入 → Pure Typing: NO / 外部入力 / bulk insertion として検出。対照として同じコードの打鍵は Pure Typing: YES (一括投入と区別される)
  • proof-forgery: export 済み proof への 5 種の偽造 (nonce/fingerprint 改ざん、イベント複製=リプレイ、順序入替=切り貼り、末尾切り詰め) を verify-cli がすべて exit 1 で拒否

インフラ

  • editor/main.ts に dev 限定テストフック __tcTestInsertBlock を追加 (executeEdits で単一編集の複数行投入を再現)。通常のキー入力 API では Monaco が 1 文字ずつに分解し再現できないため。import.meta.env.DEV ガードで本番ビルドからは除去される
  • app.ts: injectCodeBlock。

テスト

  • E2E 16 シナリオ全 green (ローカル)
  • shared 388 / editor 95 ユニットテスト pass、全ワークスペース typecheck pass

🤖 Generated with Claude Code

shinyaoguri and others added 4 commits June 16, 2026 01:43
Phase D の敵対的 E2E で、AI が executeEdits で「コード全体を 1 編集で一気に投入」すると
Monaco が insertParagraph で記録し、従来の bulk 検出 (insertText/insertReplacementText/
replaceContent のみ対象) を素通りして Pure Typing: YES のまま見逃す穴が判明した。

- structuralEdit: EDITOR_INTERNAL_INSERT に insertParagraph を追加。空白のみ (auto-indent)
  は benign、コードを含めば bulk。
- 内部ペースト (自分のコードのコピペ = 許可) の実挿入も複数行なら insertParagraph になり
  AI 一括投入と区別できないため、insertFromInternalPaste 監査マーカーと同一内容を許可リスト化
  する isFlaggedBulkInsert / collectInternalPasteContents を新設し、verification /
  processSummary / pureTypingAnalyzer の 3 経路で内部ペーストを除外。
- isPureTyping は複数行 bulk でも崩れるよう導出を更新 (insertParagraph は従来 suspicious
  判定に載らないため)。bulkInsertEvents の申告メタデータ照合は不変で後方互換。valid 不変。

editor/main.ts: dev 限定テストフック __tcTestInsertBlock (executeEdits で単一編集の複数行
投入を再現)。通常のキー入力 API では Monaco が 1 文字ずつに分解し再現できないため。
import.meta.env.DEV ガードで本番ビルドからは除去される。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- ai-bulk-insert: Copilot/snippet 相当の単一編集での複数行コード投入を再現し、proof に
  痕跡が残り Pure Typing: NO / 外部入力 / bulk insertion として検出されることを実証。
  対照として同じコードの打鍵は Pure Typing: YES (一括投入と区別される) を確認。
  この経路で insertParagraph 検出漏れを発見・修正した (別コミット)。
- proof-forgery: export 済み proof への 5 種の偽造 (nonce/fingerprint 改ざん、イベント
  複製=リプレイ、順序入替=切り貼り、末尾切り詰め) を verify-cli がすべて exit 1 で拒否
  することを確認 (1 回の export に複数偽造を適用)。

app.ts: injectCodeBlock (dev フック __tcTestInsertBlock 経由で executeEdits を 1 回適用)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6 種の偽造はすべて root/チェーン/メタの破綻で PoSW 無関係なため fast (改ざん耐性のみ) で
検出できる。CI ランナーで full PoSW 再計算を 6 回直列実行すると test timeout (300s) を
超えていた (8 分超 × retry) ため fast に切替。ローカル 2.1m→20s。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Name URL
Preview https://f9b59896.typedcode.pages.dev

Deployed from commit ee5bce8
API: staging Workers

@shinyaoguri
shinyaoguri merged commit e5cf65f into develop Jun 17, 2026
7 checks passed
@shinyaoguri
shinyaoguri deleted the feat/e2e-phase-d branch June 17, 2026 13:31
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.

1 participant