From 0d2b7c758c72f0b140c4c59fbe72244992cfa828 Mon Sep 17 00:00:00 2001 From: taminororo <169162271+taminororo@users.noreply.github.com> Date: Thu, 1 Oct 2026 09:48:51 +0700 Subject: [PATCH 1/2] =?UTF-8?q?docs:=20=E8=A8=98=E6=86=B6=E3=81=AB?= =?UTF-8?q?=E3=81=A0=E3=81=91=E6=AE=8B=E3=81=A3=E3=81=A6=E3=81=84=E3=81=9F?= =?UTF-8?q?=E3=83=81=E3=83=BC=E3=83=A0=E3=81=AE=E6=B1=BA=E3=81=BE=E3=82=8A?= =?UTF-8?q?=E3=82=92=E3=80=81workflow.md=E3=83=BBdeploy.md=E3=83=BBonboard?= =?UTF-8?q?ing.md=20=E3=81=AA=E3=81=A9=E3=81=AB=E8=B6=B3=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #599。セキュリティの問題を直す issue・PR の書き方、追跡から外すファイルの前の決まりの理由、CodeRabbit の実害の例と親子の issue、DB の変更の有無の確かめ方、Flutter の版を書く3か所と版上げを混ぜない理由、言語ごとの lint、トークンを AI のツールの会話に貼らないこと。automation-design.md に残っていた前の決まりも直した。 --- docs/development/manual-html-operations.md | 14 ++++++++++++++ docs/development/onboarding.md | 5 ++++- docs/development/workflow.md | 8 +++++--- docs/operations/deploy.md | 6 ++++++ .../manual-proposal-v4-slides/automation-design.md | 2 +- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/docs/development/manual-html-operations.md b/docs/development/manual-html-operations.md index 93c3e7f3..f66cf0c6 100644 --- a/docs/development/manual-html-operations.md +++ b/docs/development/manual-html-operations.md @@ -225,6 +225,20 @@ curl -X PUT "https://seeft-api.nutfes.net/manuals/en-nichi" -H "Authorization: B 作業が終わったらターミナルを閉じる。環境変数はそのウィンドウにしか残らないため、閉じれば消える。 +### AI のツールに頼むとき + +Claude などの AI のツールに作業を頼むときも、トークンを会話に貼らない。会話のログに平文で残るためである。自分のターミナルで、入力を表示しない形で読み、自分だけが読めるファイルに保存する。 + +```bash +mkdir -p ~/.config/seeft && chmod 700 ~/.config/seeft && printf 'アップロードトークンを貼り付けてEnter: ' && read -rs t && echo && (umask 077 && printf '%s' "$t" > ~/.config/seeft/manual-upload-token) && unset t +``` + +ツールには、そのファイルを環境変数に読み込んでから実行するように頼む。トークンそのものは会話に出てこない。 + +```bash +MANUAL_UPLOAD_TOKEN="$(cat ~/.config/seeft/manual-upload-token)" python3 scripts/automation/upload_manual.py --id en-nichi --doc-url "https://docs.google.com/document/d/xxxx/edit" docs/manuals/45th_企画マニュアル_縁日 +``` + ### レスポンス 成功すると `201 Created` で、次のJSONが返る。 diff --git a/docs/development/onboarding.md b/docs/development/onboarding.md index d8c332f4..36bfa22a 100644 --- a/docs/development/onboarding.md +++ b/docs/development/onboarding.md @@ -322,7 +322,9 @@ for rows.Next() { // 行を1つずつ読む **何か。** Flutter は Google の UI フレームワークで、言語は Dart です。1つのコードから Android / iOS / Web などを作れますが、**SeeFT は Web としてだけ動かしています。** 参加者はアプリをインストールせず、スマホのブラウザで URL を開きます。`mobile/` の下に `android/`・`ios/`・`macos/`・`windows/` も残っていますが、使っていません。 -**Flutter のバージョンは [fvm](https://fvm.app/) で固定しています**(`mobile/.fvmrc` で 3.27.3)。`flutter` コマンドは必ず `fvm flutter ...` の形で打ってください。素の `flutter` を打つと、手元に入っている別のバージョンが動き、依存ライブラリの解決やビルド結果が変わります。Flutter 自体を上げる作業は、他の変更と混ぜず、専用のブランチで行います(#514)。 +**Flutter のバージョンは [fvm](https://fvm.app/) で固定しています**(`mobile/.fvmrc` で 3.27.3)。`flutter` コマンドは必ず `fvm flutter ...` の形で打ってください。素の `flutter` を打つと、手元に入っている別のバージョンが動き、依存ライブラリの解決やビルド結果が変わります。バージョンを書いている場所は3か所あり、正は `mobile/.fvmrc` です。本番のコンテナのビルド(`mobile/Dockerfile` の `FLUTTER_VERSION`)と CI(`.github/workflows/flutter-lint.yml` の `flutter-version`)は fvm を使わず、それぞれに同じ値を書いています。上げるときは3か所を同時に上げてください。1か所だけ上げると、手元・CI・本番で別のバージョンが動きます。 + +Flutter 自体を上げる作業は、lint の導入や機能の追加などのほかの変更と混ぜず、専用のブランチで行います(#514)。3.27 から 3.35 のように大きく上げると、壊れたときに、原因がバージョンなのか一緒に入れた変更なのかを切り分けられなくなるためです。 **画面は Widget の木です。** 画面のすべて(文字、ボタン、余白、並べ方)が Widget で、Widget の中に Widget を入れて画面を組み立てます。 @@ -515,6 +517,7 @@ cd mobile && fvm flutter test - `mobile/` を変えたとき:`flutter analyze --fatal-infos`(`flutter-lint.yml`。最も軽い info レベルの指摘でも落ちる)。**テスト(`flutter test`)は走りません。** mobile を変えたら、10節のコマンドで手元で実行してください。45th では、別々の PR で変わったボタンの文言とテストが食い違ったまま develop に入り、マージ後に気づきました(#516) - `gas/` を変えたとき:GAS のコードを検査するものは走らない - どの PR でも:ADR(`docs/decisions/`)に書いた前提のファイルや関数がまだあるかの点検(`docs-refcheck.yml`) +- **lint は言語ごとに選んでいます。** Go は golangci-lint、Dart は `flutter analyze`(flutter_lints のルール)です。ESLint は JavaScript 専用なので、Go や Dart には使えません。GAS(JavaScript)には今は lint がありません(`gas/package.json` に入っているのは clasp だけです)。入れるなら ESLint ですが、`gas/` はある時点の写しなので([ADR 0007](../decisions/0007-gas-live-is-source.md))、clasp でライブの版を取ってきてから、それに対して実行します。 - **CodeRabbit**:PR に AI がレビューコメントを付けます。指摘は参考です。すべてに従う必要はなく、スコープ外のものは理由を書いて見送って構いません。 - **Git**:issue を立て、`種類/名前/issue番号/内容` のブランチで作業し、PR を出します。種類は `feat`(機能)・`fix`(修正)・`docs`(文書)です。コミットメッセージは日本語で、`feat:` / `fix:` / `docs:` を付けます。PR はスカッシュマージ(コミットを1つにまとめる)で develop に入り、マージするのは PM です。詳しくは [開発の進め方](workflow.md)。 diff --git a/docs/development/workflow.md b/docs/development/workflow.md index 9a32b790..769836a4 100644 --- a/docs/development/workflow.md +++ b/docs/development/workflow.md @@ -44,6 +44,8 @@ SeeFT で、課題に気づいてから本番に反映するまでの仕事の - **セキュリティの問題は、公開の issue にしません。** 公開の issue に書くと、手口がそのまま公開されます。 - admin 権限がある人(PM など)は、リポジトリの Security タブ → Advisories から、非公開のセキュリティアドバイザリ(下書き)として記録します。 - admin 権限がない人は、Security タブからは報告できません(外部からの非公開の報告機能は無効にしてあります)。見つけたことを、PM に Slack の DM で知らせてください。タスクの割り振りはチャンネルで行いますが(12節)、セキュリティの問題だけは例外です。 + - 直すための issue と PR も、問題の中身に触れない書き方で出します。「使われていない処理を消す」「入力の検査を足す」のように、変更そのものだけを書きます。差分は公開されるので変更の中身は隠せませんが、どこを狙えばよいかを説明する文章は書かずに済むためです。中身はアドバイザリにだけ書きます。 + - 秘密の値(トークンや Web アプリの URL など)がすでにコミットされていたときは、コードから消しても git の履歴に残ります。消しただけで片付いたとはせず、どう扱うかをアドバイザリの中で決めます。 ## 3. ブランチ @@ -51,7 +53,7 @@ SeeFT で、課題に気づいてから本番に反映するまでの仕事の - 名前は `種類/名前/issue番号/内容` です。種類は `feat`(機能)・`fix`(修正)・`docs`(文書)です。例:`feat/{名前}/123/show-break-card`。 - **main は使っていません。** 2025 年 8 月から更新されておらず、本番は develop を動かしています([deploy.md](../operations/deploy.md))。 - **PoC(作ってみないと分からないもの)は、試作用のブランチで自由に試します**。形が見えないうちに develop 向けのブランチで書くと、本番と同じ品質を早い段階から求められすぎて、試作が進まないためです。完成形が見えたら、develop から新しいブランチを切り、要るファイルだけを `git checkout <試作用のブランチ> -- <パス>` で持ち込んで PR にします。試行錯誤のコミットは develop の履歴に入れません。持ち込む時期の目安は、本番に入れると確信できたとき、または試作用のブランチが2か月を超えたときです。 -- **git の追跡から外したいファイルは、ほかの人も同じものを作るかで置き場所を決めます。** 誰が作業しても出る生成物(マニュアルの変換の出力など)は、理由のコメントを付けて `.gitignore` に書きます。自分だけの作業ファイルは、手元の `.git/info/exclude` に書きます。`.git/info/exclude` はリポジトリに入らないので、みんなが作る生成物をここに書くと、ほかの人の手元では追跡されていないファイルとして溜まり続けます(PR #491 で `.gitignore` に移しました)。 +- **git の追跡から外したいファイルは、ほかの人も同じものを作るかで置き場所を決めます。** 誰が作業しても出る生成物(マニュアルの変換の出力など)は、理由のコメントを付けて `.gitignore` に書きます。自分だけの作業ファイルは、手元の `.git/info/exclude` に書きます。`.git/info/exclude` はリポジトリに入らないので、みんなが作る生成物をここに書くと、ほかの人の手元では追跡されていないファイルとして溜まり続けます(PR #491 で `.gitignore` に移しました)。前は「特定のブランチでしか作らない生成物は `.git/info/exclude` に書く」という決まりでしたが、これは1人で開発している間しか成り立ちませんでした。ほかの人が同じブランチで作業すると、その人の手元の exclude には何も書かれていないためです。 ## 4. コミット @@ -97,9 +99,9 @@ develop には、**承認1件と、PR 上の会話がすべて解決している PR には AI のレビュー(CodeRabbit)が付きます。 - 指摘は参考です。スコープ外のものは、理由を書いて見送って構いません。 -- **指摘は「その PR が持ち込んだか」と「実害があるか」の2つで振り分けます。** CodeRabbit は PR で触った行を見るので、元からあった問題も、その PR が作ったように見えます。実害は、動かしたときの不具合・ビルドが壊れること・情報が漏れることのどれかです。 +- **指摘は「その PR が持ち込んだか」と「実害があるか」の2つで振り分けます。** CodeRabbit は PR で触った行を見るので、元からあった問題も、その PR が作ったように見えます。実害は、動かしたときの不具合・ビルドが壊れること・情報が漏れることのどれかです。たとえば、Flutter や依存ライブラリを上げると使えなくなる非推奨の API(`deprecated_member_use`。PR #343 で直した)は、今は動いていても実害があるものとして扱います。 - その PR が持ち込んだもの:その PR で直す - - 元からあって、実害があるもの:PR のスコープ外として、別の issue に切る + - 元からあって、実害があるもの:PR のスコープ外として、別の issue に切る。範囲が広いときは、親の issue を1つ立て、直す単位ごとに子の issue に分ける(例:mobile の lint の違反は、親の #286 の下にルールごとの子の issue を立てた) - 元からあって、見た目や書き方の揃え方だけのもの:スコープ外だと返信して、スレッドを閉じる - 無料枠のため、**レビューは1時間に1回まで**です。枠を超えると自動では走らず、PR の要約コメントに「Review limit reached」と出ます。枠が戻ってから、PR に `@coderabbitai review` とコメントすると頼めます。 - **指摘を直したあとの再レビューは、必要なときだけ頼みます**。直し方が提案どおりで、境目のケースをテストで確かめてあるなら、頼みません。1時間に1回の枠は、まだ誰も見ていない PR のために取っておきます。直し方が提案から大きく外れたとき、ほかの場所にも手を入れたとき、テストで確かめられていないときに頼みます。 diff --git a/docs/operations/deploy.md b/docs/operations/deploy.md index e650917a..b424bd5c 100644 --- a/docs/operations/deploy.md +++ b/docs/operations/deploy.md @@ -70,6 +70,12 @@ git diff --name-only HEAD..origin/develop | `postgresql/` | **この手順ではない。** DB の変更を伴うので、中身を確かめてから別に計画する | | `gas/` | コンテナとは関係ない。`clasp` で反映する([gas/README.md](../../gas/README.md)) | +**DB の変更があるか(`postgresql/` の行に当たるか)は、PR の最終版の差分で確かめる。** ほかの人や AI のツールの「DB の変更は無い」という説明を、そのまま信じない。途中のコミットで足したファイルを、最後のコミットで消している PR もある(45th の #546 は、途中でテーブルを足すファイルを入れ、最後に消していた)。PR ごとに、最終版で変わるファイルの一覧を見る。 + +```bash +gh pr view --json files --jq '.files[].path' +``` + ### 2. ディスクの空きを確かめる ```bash diff --git a/docs/proposals/manual-proposal-v4-slides/automation-design.md b/docs/proposals/manual-proposal-v4-slides/automation-design.md index eb04a973..e5e7c3a3 100644 --- a/docs/proposals/manual-proposal-v4-slides/automation-design.md +++ b/docs/proposals/manual-proposal-v4-slides/automation-design.md @@ -156,7 +156,7 @@ sheets_client.read_row(manual_name) - git の事故防止(誤コミットで認証情報が公開される事態を避ける) - 新 PM 引き継ぎ時に「このディレクトリをコピーすれば動く」状態にできる -- メモリ `project/ignore_convention.md` の「ブランチ依存生成物は `.git/info/exclude` に寄せる」原則を、認証情報には拡張適用 +- 認証情報は、追跡から外すだけでなく、リポジトリの中に置かない(追跡から外すファイルの置き場所の決まりは `docs/development/workflow.md` の「3. ブランチ」) ### 5-3. 初回起動フロー From 9b7694d57ec3a487949deb164658a932ec94a52c Mon Sep 17 00:00:00 2001 From: taminororo <169162271+taminororo@users.noreply.github.com> Date: Thu, 1 Oct 2026 12:08:48 +0700 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20=E3=82=A2=E3=83=83=E3=83=97?= =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=83=89=E3=81=AE=E9=80=81=E3=82=8A=E5=85=88?= =?UTF-8?q?=E3=82=92=20--base-url=20=E3=81=A7=E6=98=8E=E7=A4=BA=E3=81=97?= =?UTF-8?q?=E3=80=81PR=20=E3=81=AE=E5=A4=89=E6=9B=B4=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=82=92=E3=83=9A=E3=83=BC=E3=82=B8=E3=82=92?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E5=8F=96=E3=81=A3=E3=81=A6=E8=A6=8B=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeRabbit の指摘2件への対応。upload_manual.py は SEEFT_API_BASE_URL を既定の URL より先に使い、https ならどのホストでも通すので、手順のコマンドに送り先を明示した。gh pr view --json files は 100 件までしか返さない(変更ファイル 116 件の PR #33 で確かめた)ので、gh api --paginate に変えた。 --- docs/development/manual-html-operations.md | 8 ++++---- docs/operations/deploy.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/development/manual-html-operations.md b/docs/development/manual-html-operations.md index f66cf0c6..ba7b5f57 100644 --- a/docs/development/manual-html-operations.md +++ b/docs/development/manual-html-operations.md @@ -194,10 +194,10 @@ PUT https://seeft-api.nutfes.net/manuals/{id} `--doc-url` にはGoogleドキュメントの共有URLを渡す。⑤で対応表のB列に入れる値になる。 ```bash -python3 scripts/automation/upload_manual.py --id en-nichi --doc-url "https://docs.google.com/document/d/xxxx/edit" docs/manuals/45th_企画マニュアル_縁日 +python3 scripts/automation/upload_manual.py --base-url https://seeft-api.nutfes.net --id en-nichi --doc-url "https://docs.google.com/document/d/xxxx/edit" docs/manuals/45th_企画マニュアル_縁日 ``` -トークンは訊かれるので貼り付ける。入力は画面にもシェルの履歴にも残らない。環境変数 `MANUAL_UPLOAD_TOKEN` を設定してあればそちらが使われる。 +送り先は `--base-url` で明示する(理由は下の「AI のツールに頼むとき」)。トークンは訊かれるので貼り付ける。入力は画面にもシェルの履歴にも残らない。環境変数 `MANUAL_UPLOAD_TOKEN` を設定してあればそちらが使われる。 送信前にHTMLが `` で閉じているかとサイズ上限を検査するので、壊れたファイルや大きすぎるファイルを配信してしまうことはない。 @@ -233,10 +233,10 @@ Claude などの AI のツールに作業を頼むときも、トークンを会 mkdir -p ~/.config/seeft && chmod 700 ~/.config/seeft && printf 'アップロードトークンを貼り付けてEnter: ' && read -rs t && echo && (umask 077 && printf '%s' "$t" > ~/.config/seeft/manual-upload-token) && unset t ``` -ツールには、そのファイルを環境変数に読み込んでから実行するように頼む。トークンそのものは会話に出てこない。 +ツールには、そのファイルを環境変数に読み込んでから実行するように頼む。トークンそのものは会話に出てこない。送り先は `--base-url` で明示する。付けないと、環境変数 `SEEFT_API_BASE_URL` に入っている値が既定の URL より先に使われ、https ならどのホストにもトークンが送られるためである。 ```bash -MANUAL_UPLOAD_TOKEN="$(cat ~/.config/seeft/manual-upload-token)" python3 scripts/automation/upload_manual.py --id en-nichi --doc-url "https://docs.google.com/document/d/xxxx/edit" docs/manuals/45th_企画マニュアル_縁日 +MANUAL_UPLOAD_TOKEN="$(cat ~/.config/seeft/manual-upload-token)" python3 scripts/automation/upload_manual.py --base-url https://seeft-api.nutfes.net --id en-nichi --doc-url "https://docs.google.com/document/d/xxxx/edit" docs/manuals/45th_企画マニュアル_縁日 ``` ### レスポンス diff --git a/docs/operations/deploy.md b/docs/operations/deploy.md index b424bd5c..c2480e64 100644 --- a/docs/operations/deploy.md +++ b/docs/operations/deploy.md @@ -70,10 +70,10 @@ git diff --name-only HEAD..origin/develop | `postgresql/` | **この手順ではない。** DB の変更を伴うので、中身を確かめてから別に計画する | | `gas/` | コンテナとは関係ない。`clasp` で反映する([gas/README.md](../../gas/README.md)) | -**DB の変更があるか(`postgresql/` の行に当たるか)は、PR の最終版の差分で確かめる。** ほかの人や AI のツールの「DB の変更は無い」という説明を、そのまま信じない。途中のコミットで足したファイルを、最後のコミットで消している PR もある(45th の #546 は、途中でテーブルを足すファイルを入れ、最後に消していた)。PR ごとに、最終版で変わるファイルの一覧を見る。 +**DB の変更があるか(`postgresql/` の行に当たるか)は、PR の最終版の差分で確かめる。** ほかの人や AI のツールの「DB の変更は無い」という説明を、そのまま信じない。途中のコミットで足したファイルを、最後のコミットで消している PR もある(45th の #546 は、途中でテーブルを足すファイルを入れ、最後に消していた)。PR ごとに、最終版で変わるファイルの一覧を見る。`gh pr view <番号> --json files` は 100 件までしか返さないので、ページを全部取る次の形で見る。 ```bash -gh pr view --json files --jq '.files[].path' +gh api --paginate repos/NUTFes/SeeFT/pulls//files --jq '.[].filename' ``` ### 2. ディスクの空きを確かめる