Skip to content

feat: data bootstrap + health check + Codex P1 regression tests - #9

Merged
codowave merged 4 commits into
mainfrom
claude/data-bootstrap-health-check
May 23, 2026
Merged

feat: data bootstrap + health check + Codex P1 regression tests#9
codowave merged 4 commits into
mainfrom
claude/data-bootstrap-health-check

Conversation

@codowave

Copy link
Copy Markdown
Owner

目的

「データなし=故障」という誤解を潰す。利用者から見て unavailable が故障に見える危険を除去する。

追加内容

1. scripts/bootstrap_morph_data.sh

morphhb(ヘブライ語形態論 XML)と morphgnt(ギリシャ語形態論)を data/ 配下に配置する導線。

  • morphhb: sparse clone(wlc/ のみ取得、全履歴不要)
  • morphgnt: 通常クローン
  • データがなくてもアプリは正常動作する(このスクリプトは任意実行)

2. GET /api/lexicon/health

{
  "morphhb": {"status": "missing", "path": "...", "xml_files": 0},
  "morphgnt": {"status": "missing", "path": "...", "txt_files": 0},
  "correspondence_index": {"entry_count": 18},
  "verify_verse_status": "degraded",
  "verify_verse_detail": "morphhb missing — verify_verse returns unavailable (expected behavior)",
  "note": "morphhb/morphgnt missing は故障ではない。..."
}
  • データ未配置でも 常に 200 を返す
  • verify_verse_status: operational(morphhb あり + サニティチェック通過)/ degraded(データなし)
  • note フィールドで「missing ≠ 故障」を明示

データ配置後の期待値:

{
  "morphhb": {"status": "available", "xml_files": 39},
  "morphgnt": {"status": "available", "txt_files": 27},
  "verify_verse_status": "operational",
  "verify_verse_detail": "Gen.3.5/H3045 → found ✓"
}

3. tests/test_lexicon_health.py (22 tests)

Codex P1 回帰防止が主目的。

テストクラス 内容
TestVerseVerifyUnavailable morphhb 未配置時に contains=NoneFalse ではない)を固定
TestVerseVerifyBadRef 不正 ref フォーマットが unavailable を返すことを固定
TestLookupWord Strong's 辞書(同梱 JSON)の動作確認
TestCorrespondenceLookup found/not_found/unavailable の三状態を固定
TestHealthEndpoint /api/lexicon/health の HTTP 応答を固定
22 passed in 0.79s  (データ未配置環境)

Codex P1 の核心を固定するテスト:

def test_contains_is_none(self):
    result = verify_verse("Gen.3.5", "H3045")
    assert result["contains"] is None  # False ではない
    # contains=False は「照合済みの不在」。データ未配置を False で返すと
    # 「Gen.3.5 に H3045 は存在しない」と Claude に権威付きで伝わる(Codex P1 バグ)。

4. README_DATA.md

  • 三状態の意味(found/not_found/unavailable)
  • 「データなし ≠ 故障」「unavailable ≠ not_found」の明記
  • bootstrap 手順
  • データライセンス(morphhb: CC BY 4.0 / morphgnt: CC BY-SA 3.0)

変更なし

  • app.py ロジック変更なし
  • biblical_lexicon.py 変更なし
  • 既存のすべての挙動は維持

実行方法

# テスト(データ不要)
cd biblical_correspondence
python -m pytest tests/test_lexicon_health.py -v --override-ini="addopts="

# データ配置(任意)
bash scripts/bootstrap_morph_data.sh

# ヘルスチェック確認
curl http://localhost:8000/api/lexicon/health

https://claude.ai/code/session_017WKYFbVsWhWZA3M8Jc1eKs


Generated by Claude Code

1. scripts/bootstrap_morph_data.sh
   morphhb (sparse clone, wlc/ only) と morphgnt を data/ 配下に配置する。
   データなしでもアプリは正常動作する(unavailable を返すのが正しい挙動)。

2. GET /api/lexicon/health
   morphhb/morphgnt の配置状態、correspondence_index のエントリ数、
   verify_verse のサニティチェック結果を返す。
   データ未配置でも 200 — "missing" は故障ではなく状態の記述。

3. biblical_correspondence/tests/test_lexicon_health.py (22 tests)
   - verify_verse が unavailable 時に contains=None を返すことを固定(Codex P1 回帰防止)
   - not_found と unavailable が混在しないことを各ケースで確認
   - correspondence_lookup の三状態(found/not_found/unavailable)を固定
   - /api/lexicon/health エンドポイントの HTTP 応答を固定
   全 22 テスト、データ未配置環境でパス。

4. README_DATA.md
   「データなし ≠ 故障」「unavailable ≠ not_found」を明記。
   三状態の意味・bootstrap 手順・ライセンスを記載。

https://claude.ai/code/session_017WKYFbVsWhWZA3M8Jc1eKs

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a robust data management and health monitoring system for biblical morphological data. Key additions include a /health endpoint for status tracking, a bootstrap script for automated data acquisition, and documentation clarifying the 'three-state' logic for data availability. Feedback suggests optimizing the /health endpoint by moving imports to the top level and improving the efficiency of entry counting in the correspondence index. Additionally, the reviewer recommended safer directory copying in the shell script to prevent nested paths and better error handling to avoid silent failures.

operational — morphhb が存在し、サニティチェック(Gen.3.5/H3045)が found を返す
degraded — morphhb 未配置(unavailable を返す正常動作)
"""
from pathlib import Path

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

関数内でのインポートは、実行時のオーバーヘッドを避けるために通常はファイル上部で行うべきです。特別な理由がない限り、from pathlib import Path はファイルの冒頭に移動することを検討してください。

Comment on lines +54 to +58
try:
with open(corr_index_path, encoding="utf-8") as f:
corr_entry_count = len(json.load(f).get("entries", []))
except Exception:
pass

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

JSONファイルを全件メモリに読み込んでエントリ数をカウントするのは、インデックスが肥大化した際にヘルスチェックのレスポンスを低下させる原因となります。また、except Exception: pass は予期せぬエラーを隠蔽するため避けるべきです。ログを出力するか、特定の例外をキャッチするように変更してください。

git sparse-checkout set "$MORPHHB_SUBDIR"
)

cp -r "$TMPDIR_HEB/morphhb/$MORPHHB_SUBDIR" "$MORPHHB_DEST"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

cp -r は、コピー先ディレクトリが既に存在する場合に意図せず階層が深くなる(wlc/wlc になる)可能性があります。mkdir -p でディレクトリを作成した上で、中身のみをコピーする(例: cp -r src/. dest/)方法がより安全です。同様の箇所が 73 行目にもあります。

Suggested change
cp -r "$TMPDIR_HEB/morphhb/$MORPHHB_SUBDIR" "$MORPHHB_DEST"
mkdir -p "$MORPHHB_DEST"
cp -r "$TMPDIR_HEB/morphhb/$MORPHHB_SUBDIR/." "$MORPHHB_DEST/"

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 44bdd8b670

ℹ️ 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".

trap 'rm -rf "$TMPDIR_GRK"' EXIT

git clone --depth 1 "$MORPHGNT_REPO" "$TMPDIR_GRK/morphgnt"
cp -r "$TMPDIR_GRK/morphgnt" "$MORPHGNT_DEST"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Copy dataset contents without nesting destination directories

This cp -r call copies the entire cloned morphgnt directory into data/morphgnt when data/morphgnt already exists, producing data/morphgnt/morphgnt/... instead of files at data/morphgnt/*.txt. In that state, MORPHGNT_PATH.glob("*.txt") finds nothing, so Greek data remains effectively unavailable even though bootstrap reports success. This is reproducible whenever a stale/empty destination directory exists from a prior partial setup.

Useful? React with 👍 / 👎.

Comment on lines +24 to +25
os.environ.setdefault("MORPHHB_PATH", str(_BC_DIR / "data" / "__nonexistent_morphhb__"))
os.environ.setdefault("MORPHGNT_PATH", str(_BC_DIR / "data" / "__nonexistent_morphgnt__"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Force test data paths instead of honoring pre-set environment

Using setdefault here makes these regression tests depend on external environment state: if MORPHHB_PATH/MORPHGNT_PATH are already set (for example by a developer shell or CI job), the tests run against real data and assertions expecting status == "unavailable" will fail. That makes the new safety suite non-deterministic and can hide or spuriously report regressions.

Useful? React with 👍 / 👎.

claude added 3 commits May 23, 2026 23:30
cp -r src/wlc dest/wlc は dest/wlc が既存の場合 dest/wlc/wlc/ になる。
mkdir -p + cp -r src/wlc/. dest/wlc/ 形式に統一し、
実行回数・dest の存在状態に依らず冪等にする。morphgnt も同様。

https://claude.ai/code/session_017WKYFbVsWhWZA3M8Jc1eKs
setdefault は環境変数が既に設定されていると上書きしない。
実環境に morphhb が配置済みの場合、Codex P1 回帰テストが
unavailable ではなく found を返し、バグを見逃す。

os.environ["MORPHHB_PATH"] / ["MORPHGNT_PATH"] の強制代入に変更し、
このテストファイルを外部環境から完全に独立させる。
回帰防止テストは、環境依存をゼロにしないと意味がない。

https://claude.ai/code/session_017WKYFbVsWhWZA3M8Jc1eKs
except Exception: pass はログも状態フラグもなく全エラーを飲む。
JSON パースエラーとファイル読み取りエラーを別々に捕捉し、
ログに記録した上でレスポンスの correspondence_index.error に含める。
entry_count=0 のまま通過するが、原因が response で可視になる。

https://claude.ai/code/session_017WKYFbVsWhWZA3M8Jc1eKs
@codowave
codowave merged commit 2b56987 into main May 23, 2026
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.

2 participants