From db826a802f8836f1a8501a126b4d48f52ffb8f25 Mon Sep 17 00:00:00 2001 From: yktsnet Date: Fri, 23 Oct 2026 22:22:34 +0900 Subject: [PATCH 1/4] chore(issues): open 08_sessions-fail-loud.md --- issues/08_sessions-fail-loud.md | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 issues/08_sessions-fail-loud.md diff --git a/issues/08_sessions-fail-loud.md b/issues/08_sessions-fail-loud.md new file mode 100644 index 0000000..19ec111 --- /dev/null +++ b/issues/08_sessions-fail-loud.md @@ -0,0 +1,42 @@ +## 例の拡張 sessions は、セッションを1本も読めなければ生成を止める +id: 08 +branch-slug: sessions-fail-loud +status: open +type: fix +対象: examples/plugins/sessions.py, tests/test_example_sessions.py, docs/guarantees.md +内容: 例の拡張 `examples/plugins/sessions.py` は、`ccreel` が無いときや、すべての config dir で `list` が失敗したときも、警告を1行出すだけで生成を続ける。定期実行の `PATH` に ccreel が無いと、`publish --if-changed` はセッションのページが無いサイトを黙って配信する。ccreel の `list --json` の形が変わって要る項目が欠けた場合も、同じ結果になる。すべての config dir で読めなかったときは生成を始める前に止め、前回の配信を残す。 +対象外: 本体(`codeview/` 配下)の変更。ccreel 側で JSON の形を固定するテスト。`show` の失敗の扱い(今のまま、そのセッションだけ `Could not read this session`)。一部の config dir だけが失敗したときの扱い(今のまま、警告して飛ばす) +仮定: 「止める」は、`codeview build` が `error:` を出して非0で終わり、`public/` に触れないこととする。本体は拡張の `css()` の呼び出しで起きた `PluginError` / `ConfigError` だけを `error:` にして生成前に止めるので、一覧の取得を `css()` の時点で済ませる(設定の検査を `css()` で行っているのと同じ理由)。`publish` は指紋を取る時点で同じ例外が上がり、push せずに非0で終わる(本体を変えないので、こちらは `error:` ではなくトレースバックになってよい)。`list` が成功して0件を返すのは正常で、止めない +確認: `nix develop -c pytest -q` が通る。新しいテストは既存の `tests/test_example_sessions.py` と同じく、`site` フィクスチャで生成器を別プロセスで呼び、偽の `ccreel` で確かめる +人が見るもの: なし + +--- + +### 保証 +- 新たに宣言する保証(例の拡張 `examples/plugins/sessions.py`): + - `ccreel` が無いとき、またはすべての config dir で `list` が失敗したときは、`codeview build` が `error:` と失敗した理由(config dir と ccreel の標準エラーか例外の文)を出して非0で終わり、`public/` を作らない + - `list` の1行に `id`・`repo`・`title`・`prompts`・`started`・`updated` のどれかが欠けていれば、その config dir の `list` の失敗として扱う(すべての config dir がそうなら上と同じく止まる) + - 上の場合、`codeview publish --if-changed` は push せずに非0で終わる + - `list` が成功して0件のときは止めず、セッションのページを書かずに生成を終える(今の振る舞い) +- 変更する保証(台帳 §5): + - 「`ccreel` が無いとき、またはいずれかの config dir で `list` が失敗したときは、警告を出してそこを飛ばし、生成は止めない」を、「一部の config dir で `list` が失敗したときは、警告を出してそこを飛ばし、生成は止めない。すべての config dir で失敗したとき(`ccreel` が無いときを含む)は止める」に改める +- 維持する保証: 台帳 §5 のほかの項目すべて(`show` に失敗したセッションのページ、設定の誤りで `error:`、指紋、使い回し、相対リンク など)。台帳 §1 の「拡張を設定しなければ…」「読み込めない拡張を設定したときは…」。本体に触れないので、§1〜§4 のテストはそのまま通る + +### examples/plugins/sessions.py + +- `_sessions()` で、config dir ごとの失敗を集める。成功した config dir が1つも無ければ、`codeview.plugins.PluginError` を上げる。メッセージは英文で、失敗した config dir ごとの理由を含める(`ConfigError` / `PluginError` のメッセージは、そのまま利用者に出す英文にする規約) +- 行の検査: 上の6項目が無い行があれば、その config dir の失敗にする。今は `updated` と `started` の `KeyError` だけを拾っている +- `css()` で `_sessions(ctx)` を呼び、生成前に失敗を表に出す。`_cache` があるので、`side()` / `build()` / `fingerprint()` で二度は呼ばない +- モジュールと `_sessions()` の docstring の「生成は止めない」を、新しい振る舞いに合わせて直す + +### tests/test_example_sessions.py + +- `test_build_survives_missing_ccreel` は、止まることを確かめるテストに置き換える(`error:`・非0・`public/` が無い) +- すべての config dir で `list` が失敗する(不正な JSON・非0で終わる)場合と、要る項目が欠けた行の場合を足す +- `list` が0件のときに止まらないことを足す +- `publish --if-changed` が push しないことは、`tests/test_publish.py` の既存の作り(配信先のリモートと `site.run("-m", "codeview", "publish", "--if-changed")`)を参考に、このファイルの中で確かめる +- `test_build_survives_one_failing_config_dir` はそのまま残す + +### docs/guarantees.md + +§5 の箇条と表を、上の「新たに宣言する保証」と「変更する保証」に合わせて直す。 From 777bf820638dc1abe5bad56a0324b8bdd908c592 Mon Sep 17 00:00:00 2001 From: yktsnet Date: Fri, 23 Oct 2026 22:26:50 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=E4=BE=8B=E3=81=AE=E6=8B=A1=E5=BC=B5?= =?UTF-8?q?=20sessions=20=E3=81=AF=E3=80=81=E3=82=BB=E3=83=83=E3=82=B7?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E3=82=921=E6=9C=AC=E3=82=82=E8=AA=AD?= =?UTF-8?q?=E3=82=81=E3=81=AA=E3=81=91=E3=82=8C=E3=81=B0=E7=94=9F=E6=88=90?= =?UTF-8?q?=E3=82=92=E6=AD=A2=E3=82=81=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 変更内容 - `_sessions()` が config dir ごとの失敗を集め、成功した config dir が1つも無ければ `PluginError` を上げる。メッセージは失敗した config dir ごとの理由を含む英文 - `list --json` の行に `id`・`repo`・`title`・`prompts`・`started`・`updated` のどれかが欠けていれば、その config dir の失敗として扱う(オブジェクトでない行も同じ) - `css()` で `_sessions(ctx)` を呼び、生成前に `error:` で止める(`publish` は指紋の時点で同じ例外が上がり、push せずに非0で終わる) - 一部の config dir だけの失敗は、今までどおり警告して飛ばす。`list` が0件は止めない - モジュールと `_sessions()` の docstring を新しい振る舞いに合わせた ## 保証 - 全 config dir で `list` が失敗・`ccreel` が無い → `error:`・非0・`public/` 無し: tests/test_example_sessions.py `test_build_stops_without_ccreel`、`test_build_stops_when_every_list_fails` - 行の項目が欠ければ config dir の失敗: `test_build_stops_when_a_list_row_lacks_a_field`(6項目それぞれ) - `publish --if-changed` は push しない: `test_publish_if_changed_does_not_push_when_list_fails` - 0件は止めない: `test_build_with_empty_list_is_not_an_error` - 一部の失敗は警告して続ける(維持): `test_build_survives_one_failing_config_dir` - 台帳 §5 を上に合わせて更新 ## 静的確認結果 - `nix develop -c pytest -q`: 81 passed。新しいテストは旧実装で失敗することを確かめた - 本体(`codeview/`)は変更なし。`build.main` / `publish.main` は `css()` / 指紋の例外を既存どおり扱う - git diff --name-only --cached: docs/guarantees.md examples/plugins/sessions.py tests/test_example_sessions.py --- docs/guarantees.md | 8 +++-- examples/plugins/sessions.py | 57 +++++++++++++++++++++++++--------- tests/test_example_sessions.py | 50 ++++++++++++++++++++++++++--- 3 files changed, 95 insertions(+), 20 deletions(-) diff --git a/docs/guarantees.md b/docs/guarantees.md index cbc6033..af2a8f7 100644 --- a/docs/guarantees.md +++ b/docs/guarantees.md @@ -144,7 +144,8 @@ - `[plugins.sessions]` の `config_dirs` ごとに `ccreel list --json --limit 0 --since d --config-dir ` を呼び、全部をまとめて新しい順に `public/sessions/index.html` へ一覧を書く。各セッションの本文を `ccreel show --json` から `public/sessions/.html` に書く - 本文のページには発言と応答のテキストを出し、応答の Markdown は生の HTML・`