分離スキルベンチマーク

同じユーザー入力でtanteki一式の導入効果を比較する。生成中にスキルが行った検査・改稿は含む。採点のtextlint結果は生成へ返さない。未発火も集計に残し、品質は両側が有効なペアで評価する。取得・コマンドの観測はログからの推定であり、スキルの遵守や全ファイルアクセスの証明ではない。失敗時にプロバイダーが利用量を返さなかった呼び出しのトークン数は不明。

有効ペア 4/4、採点済みペア 4

指標スキルなしスキルあり
計画した実行44
環境検証済み44
環境無効00
実行失敗00
本文取得をログで観測04
lintコマンドをログで観測02
採点対象44
採点用lint合格04
モデル呼び出し(失敗含む)424
入力トークン(報告された全実行分)23708344185
出力トークン(報告された全実行分)574412600
意味基準合格8/2017/20

ADRの判断と作業追跡の分離 · 1回目

共通の原依頼
将来の保守者向けにADRを書いて。2026-08-20に採用した判断。請求書のPDF生成はキューで処理し、APIは受付IDを返す。同期生成は最大45秒かかって接続が切れるため採らない。非同期では利用者が完成まで待つ必要がある。再試行の上限は未決定。原資料の作業メモには BILL-218、PR #106、進捗70% とある。

スキルなし

valid

ADR-001: 請求書PDF生成をキューによる非同期処理にする

  • ステータス: 採用

  • 決定日: 2026-08-20

  • 関連: BILL-218、PR #106

コンテキスト

請求書のPDF生成には最大45秒かかることがある。同期的に生成すると、処理中にAPI接続が切断される可能性があるため、利用者への応答とPDF生成処理を同じリクエスト内で完了させる方式は安定しない。

決定

請求書のPDF生成はキューに投入して非同期で処理する。APIはPDFそのものではなく、受付IDを返す。利用者またはクライアントは受付IDを使って処理状況を確認し、生成完了後にPDFを取得する。

選択しなかった案

同期生成

同期生成は採用しない。生成に最大45秒かかり、処理中に接続が切れる可能性があるためである。

影響

利点
  • 長時間のPDF生成によるAPI接続切断の影響を抑えられる。

  • APIは受付処理を短時間で完了できる。

  • PDF生成処理をキューのワーカーで独立して処理できる。

欠点・利用者への影響
  • API応答時点ではPDFは完成していない。

  • 利用者はPDFの完成まで待つ必要がある。

  • クライアントには、受付IDによる状況確認と、完了後のPDF取得処理が必要になる。

未決事項

  • 生成失敗時の再試行回数の上限は未決定である。運用・障害影響を確認したうえで別途決定する。

  • 完成通知、状態確認API、受付IDの有効期限などの詳細仕様は実装時に確定する。

進捗メモ

原資料の作業メモでは、本対応の進捗は70%と記録されている。

本文外の注記

原資料の作業メモにある進捗70%は、判断そのもののステータスとは分けて「進捗メモ」として記載しました。

生成中の観測: スキル本文 なし/lintコマンド なし

完了後の採点用lint: 4件

採点用lintの指摘
[
  {
    "ruleId": "stock-boundary",
    "line": 5,
    "column": 11,
    "message": "文書にJira課題IDが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 5,
    "column": 20,
    "message": "文書にPR番号が含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "no-doubled-joshi",
    "line": 9,
    "column": 54,
    "message": "一文に二回以上利用されている助詞 \"が\" がみつかりました。\n\n次の助詞が連続しているため、文を読みにくくしています。\n\n- \"が\"\n- \"が\"\n\n同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。\n"
  },
  {
    "ruleId": "no-doubled-joshi",
    "line": 19,
    "column": 37,
    "message": "一文に二回以上利用されている助詞 \"が\" がみつかりました。\n\n次の助詞が連続しているため、文を読みにくくしています。\n\n- \"が\"\n- \"が\"\n\n同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。\n"
  }
]
意味の採点と根拠

facts: 合格 採用、2026-08-20、キュー、受付ID、同期生成時の最大45秒と接続切断、完成待ち、再試行上限が未決定であることをすべて記載している。

grounding: 不合格 受付IDでの処理状況確認、完了後のPDF取得、完成通知や状態確認APIの仕様に言及しており、原資料にない結果確認API・通知方法を本文へ持ち込んでいる。

role: 不合格 本文にBILL-218、PR #106、および進捗70%を記載している。

clarity: 合格 採用判断(キューによる非同期化)、同期生成を採らない理由(最大45秒・接続切断)、利用者が完了まで待つ代償が本文中で対応付けられている。

economy: 不合格 多数の章見出しと重複する説明があり、「一段落か短い箇条書き」の範囲を超える。

スキルあり

valid

請求書PDF生成を非同期キュー処理にする

  • 状態: 採用

  • 決定日: 2026-08-20

背景

請求書のPDF生成には最大45秒かかる。同期生成では、その間に接続が切れるため、APIの応答を完了まで維持できない。

決定

請求書のPDF生成はキューで非同期に処理する。APIは生成完了を待たず、受付IDを返す。利用者は、PDFが完成するまで待つ必要がある。

決定理由

同期生成では、最大45秒の処理中に接続が切れるため採用しない。非同期処理なら、PDF生成とAPIの受付を分離できるため、生成処理の完了までAPIの接続を維持する必要がない。

影響

利用者はAPIの応答だけではPDFを受け取れず、受付IDに対応する生成結果が完成するまで待つ必要がある。保守者は、受付IDとキュー処理を前提に、生成中と生成完了後の扱いを実装・運用する必要がある。

再試行の上限は未決定である。再試行処理を追加・変更する場合は、この上限を決めたうえで、キュー処理の設計と整合させる。

代替案

同期生成は、最大45秒の処理中に接続が切れるため不採用とした。

本文外の注記

ADRとして構成・内容を確認し、tantekiのADR向け検査を通過しました。BILL-218、PR #106、進捗70%は作業管理情報のため本文には含めていません。

生成中の観測: スキル本文 あり/lintコマンド あり

完了後の採点用lint: 0件

採点用lintの指摘
[]
意味の採点と根拠

facts: 合格 採用、2026-08-20、キュー、受付ID、同期生成の最大45秒による接続切断、完成待ち、再試行上限未決定をすべて本文に含む。

grounding: 合格 結果確認API、通知方法、具体的な再試行回数を創作しておらず、再試行上限を未決定としている。

role: 合格 本文にはBILL-218、PR #106、進捗70%を含めていない。

clarity: 合格 キューでの非同期処理と受付ID返却という判断、同期生成を不採用にした45秒・接続切断の理由、利用者の完成待ちという代償が明確に示されている。

economy: 不合格 背景、決定、決定理由、影響、代替案など章見出しが多く、理由と不採用理由も反復しているため、短い箇条書きまたは一段落には収まっていない。

ADRの判断と作業追跡の分離 · 2回目

共通の原依頼
将来の保守者向けにADRを書いて。2026-08-20に採用した判断。請求書のPDF生成はキューで処理し、APIは受付IDを返す。同期生成は最大45秒かかって接続が切れるため採らない。非同期では利用者が完成まで待つ必要がある。再試行の上限は未決定。原資料の作業メモには BILL-218、PR #106、進捗70% とある。

スキルなし

valid

ADR-XXX: 請求書PDF生成を非同期キュー処理にする

  • 状態: 採用

  • 決定日: 2026-08-20

  • 関連: BILL-218、PR #106

  • 原資料の進捗: 70%

コンテキスト

請求書PDFの生成には最大45秒かかる場合があり、同期処理ではAPI接続がタイムアウトまたは切断される。利用者がAPI応答を待ち続ける設計は安定しない。

決定

請求書PDFの生成はキューに投入して非同期で処理する。APIは生成完了を待たず、受付IDを返す。利用者は受付IDを使って処理状況や生成結果を確認し、PDFの完成を待つ。

同期生成は、接続切断のリスクがあるため採用しない。

影響

利点
  • 長時間のPDF生成によるAPI接続切断を避けられる。

  • APIの応答時間を短く保てる。

  • PDF生成処理をキューによって平準化・再実行できる。

欠点・留意点
  • 利用者はPDFの完成まで待つ必要がある。

  • 処理状況、完了通知または取得方法など、非同期処理向けの利用者体験が必要になる。

  • キューやワーカーなどの運用対象が増える。

  • 再試行の上限は未決定であり、別途決定する必要がある。上限を決める際は、重複生成、恒久的な失敗、運用コストへの影響を考慮する。

運用上の前提

  1. APIは受付IDを返す。

  2. 受付IDから処理状態を確認できる仕組みを用意する。

  3. PDF完成後に利用者が取得できるようにする。

  4. 失敗状態と再試行結果を利用者および運用者が確認できるようにする。

  5. 再試行上限は未決定事項として追跡し、決定後に本ADRを更新する。

代替案

同期生成

APIリクエスト中にPDFを生成し、完成したPDFを同じ応答で返す案。最大45秒かかり接続が切れるため、不採用とした。

未決定事項

  • PDF生成失敗時の再試行上限

  • 完成通知の方式

  • 受付IDによる処理状況確認APIの詳細

本文外の注記

原資料の作業メモにあるBILL-218、PR #106、進捗70%を関連情報として反映しました。

生成中の観測: スキル本文 なし/lintコマンド なし

完了後の採点用lint: 2件

採点用lintの指摘
[
  {
    "ruleId": "stock-boundary",
    "line": 5,
    "column": 11,
    "message": "文書にJira課題IDが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 5,
    "column": 20,
    "message": "文書にPR番号が含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  }
]
意味の採点と根拠

facts: 合格 採用日2026-08-20、キュー、受付ID、最大45秒の同期接続切断、完成待ち、再試行上限未決定をすべて本文に含む。

grounding: 不合格 原資料にない受付IDによる状態確認の仕組み、完成後の取得、失敗・再試行結果の確認を「用意する」と本文で定めている。

role: 不合格 本文の関連情報としてBILL-218、PR #106、進捗70%を記載しており、禁止事項に抵触する。

clarity: 合格 キューによる非同期処理の採用、同期生成を不採用とする接続切断理由、利用者が完成を待つ代償が明確である。

economy: 不合格 多数の章見出し、詳細な運用前提、未決定事項、重複する説明があり、短いADRとしては過剰である。

スキルあり

valid

ADR: 請求書PDF生成を非同期キュー処理にする

  • 状態: 採用

  • 決定日: 2026-08-20

背景

請求書のPDF生成には最大45秒かかる。同期処理ではAPIの接続が切れるため、利用者へ安定して処理結果を返せない。

決定

請求書のPDF生成はキューへ投入して非同期に処理する。受付時にAPIは受付IDを返し、利用者はその受付IDを使って生成状況や完成したPDFを確認する。

決定理由

同期生成中は、接続切断の可能性がある。キューを使った非同期処理なら、APIの受付とPDF生成を分離できる。45秒を超える生成時間でも、API接続を維持せずに済むためである。

代替案

同期生成は採用しない。最大45秒の処理中に接続が切れるためである。

結果
  • APIはPDFそのものではなく、受付IDを返す。

  • 利用者はPDFの完成まで待つ必要がある。

  • PDF生成の処理状況と完成結果を、受付IDに関連付けて扱う必要がある。

  • 再試行の上限は未決定であり、このADRでは定めない。

本文外の注記

ADR(stock)の役割に合わせ、作業メモのBILL-218、PR #106、進捗70%は本文から除外しました。textlint検査は通過しています。

生成中の観測: スキル本文 あり/lintコマンド あり

完了後の採点用lint: 0件

採点用lintの指摘
[]
意味の採点と根拠

facts: 合格 採用日2026-08-20、キュー処理、APIの受付ID返却、同期では最大45秒で接続切断、完成待ち、再試行上限未決定をすべて本文に含む。

grounding: 不合格 原資料にない、受付IDで生成状況や完成PDFを確認する方法を本文で確定的に記載している。

role: 合格 本文にはBILL-218、PR #106、進捗70%を含めていない。注記での除外説明は本文への再掲ではない。

clarity: 合格 採用判断、同期案を不採用とする理由(最大45秒で接続切断)、非同期化の代償(完成待ち)が明確に対応している。

economy: 不合格 複数の章見出しと、同期不採用理由・受付IDに関する反復があり、一段落または短い箇条書きには収まっていない。

Design Docの構成・失敗条件・代替案 · 1回目

共通の原依頼
実装者向けにファイル取込のDesign Docを作成して。確定した資料: APIはファイルをオブジェクトストレージへ保存し、その保存先をキューへ登録する。保存に失敗したら503を返し、キューには登録しない。ワーカーは保存先から読み、解析結果をDBへ保存する。キューへの登録失敗時の回復方法は未決定。ファイル本体をキューに載せる案は、10MBのファイルがキューの1MB制限を超えるため不採用。非同期化で利用者への結果提示が遅れる。進行メモ: DATA-64、PR #203、今週はAPI実装、担当佐藤。

スキルなし

valid

ファイル取込 Design Doc

1. 概要

ファイル取込処理を非同期化する。APIは受信したファイル本体をオブジェクトストレージへ保存し、保存先をキューへ登録する。ワーカーはキューから保存先を受け取り、オブジェクトストレージ上のファイルを読み込んで解析し、解析結果をDBへ保存する。

2. 背景と目的

  • APIリクエスト中に解析処理を実行せず、APIの処理時間と負荷を抑える。

  • ファイル本体をキューに載せず、キューのメッセージサイズ制限に収める。

  • 解析処理をワーカーに分離し、再実行や水平スケールを可能にする。

非同期化により、利用者が解析結果を確認できるまでの時間は同期処理より遅くなる。この遅延は本方式の前提とする。

3. 確定事項

  • APIはファイル本体をオブジェクトストレージへ保存する。

  • 保存成功後、保存先をキューへ登録する。

  • オブジェクトストレージへの保存に失敗した場合、APIはHTTP 503を返し、キューには登録しない。

  • ワーカーは保存先からファイルを読み込み、解析結果をDBへ保存する。

  • ファイル本体をキューへ載せる方式は採用しない。想定ファイルサイズ10MBに対し、キューのメッセージサイズ上限が1MBのため。

  • キューへの登録失敗時の回復方法は未決定であり、本Design Docでは確定しない。

4. 処理フロー

利用者
  │ ファイル送信
  ▼
API
  │ 1. オブジェクトストレージへ保存
  ├─ 失敗 ──> HTTP 503(キュー登録なし)
  │
  │ 2. 保存先情報をキューへ登録
  ▼
キュー
  │ 保存先情報
  ▼
ワーカー
  │ 3. オブジェクトストレージから取得
  │ 4. ファイル解析
  │ 5. 解析結果をDBへ保存
  ▼
DB

5. API仕様(実装方針)

5.1 リクエスト
  • APIはファイルをmultipart/form-data等で受け付ける。

  • ファイルサイズ上限は、少なくとも想定上限10MBを考慮して設定する。

  • 受信したファイルには一意な取込IDを付与する。

5.2 オブジェクトストレージへの保存

保存先キーには、他の取込と衝突しない値を使用する。例:

imports/{import_id}/source

保存時には、実体とあわせて以下のメタデータを管理できるようにする。

  • 取込ID

  • 元ファイル名

  • Content-Type

  • ファイルサイズ

  • 保存日時

  • ハッシュ値(必要に応じて)

保存に失敗した場合は以下を行う。

  1. エラーをログへ出力する。

  2. HTTP 503 Service Unavailableを返す。

  3. キューへの登録処理を実行しない。

  4. クライアントが再試行可能なレスポンスであることを明示する。

5.3 キューへのメッセージ

キューにはファイル本体ではなく、ワーカーが取得に必要な情報だけを登録する。例:

{
  "import_id": "01J...",
  "object_key": "imports/01J.../source",
  "content_type": "application/pdf",
  "created_at": "2026-09-22T00:00:00Z"
}

実際のキューサービスに応じて、バケット名、オブジェクトURI、バージョンIDなどを追加する。

5.4 APIレスポンス

キュー登録まで成功した場合は、解析完了を待たずに受付結果を返す。推奨例:

  • HTTP 202 Accepted

  • 取込ID

  • 状態確認用のリソース情報(提供する場合)

{
  "import_id": "01J...",
  "status": "queued"
}

解析結果はAPIレスポンスには含めず、別途状態確認APIまたは既存の結果参照手段で取得する。

6. ワーカー処理

ワーカーはキューからメッセージを受け取ったら、次の順で処理する。

  1. メッセージから取込IDとオブジェクトキーを取得する。

  2. オブジェクトストレージからファイルを読み込む。

  3. ファイル形式・サイズ等の入力検証を行う。

  4. ファイルを解析する。

  5. 解析結果をDBへ保存する。

  6. 成功時にキューのメッセージを完了扱いにする。

6.1 DB保存

取込IDを一意キーとして扱い、同一メッセージが再配信された場合でも解析結果が重複しないようにする。DB保存は冪等に実装する。

推奨する状態例:

  • queued: キュー登録済み

  • processing: ワーカー処理中

  • completed: 解析結果保存済み

  • failed: 解析または保存に失敗

状態更新と解析結果保存の整合性を保つため、可能な範囲で同一トランザクションにまとめる。

6.2 エラー処理
  • オブジェクトストレージからの読み込み失敗:一時障害か恒久障害かを判定し、キューサービスの再試行機構に従う。

  • 解析失敗:取込状態をfailedにし、原因を記録する。

  • DB保存失敗:結果が保存できるまでメッセージを再処理可能にする。

  • 再処理時に既にcompletedの場合は、重複保存せず成功扱いにする。

リトライ回数、デッドレターキューへの移送条件、失敗ファイルの保持期間は実装時に決定する。

7. 重要な未決事項

キュー登録失敗時の回復方法

オブジェクトストレージへの保存後、キュー登録に失敗すると、ファイルは保存済みだがワーカーへ届かない状態になる。回復方法は未決定である。

候補として以下があるが、採用案は別途決定する。

  • DBに取込状態と保存先を記録し、定期ジョブが未登録データを再送する。

  • Outboxパターンでキュー登録要求を永続化する。

  • キュー登録失敗時に同期リトライする。

  • オブジェクトストレージのイベント通知を利用する。

この事項が決まるまで、キュー登録処理の失敗時にファイルを削除するか、保存済みファイルをどの期間保持するかも確定しない。

8. 非機能要件・実装上の注意

  • 10MBのファイルを扱えるAPI、オブジェクトストレージ、ワーカーの設定にする。

  • キューにはファイル本体を格納しない。メッセージサイズは1MB未満に収める。

  • オブジェクトストレージのアクセス権はワーカーに必要最小限だけ付与する。

  • ログには取込IDを必ず含め、API、キュー、ワーカー、DBの処理を追跡できるようにする。

  • ファイル名やContent-Typeなどの外部入力をログやキーに利用する場合は、エスケープおよびバリデーションを行う。

  • 一時ファイルは処理完了後に削除し、メモリにファイル全体を保持し続けない。

  • APIのタイムアウトは、ファイル保存完了までを基準に設定する。解析完了は待機しない。

  • 監視対象として、保存失敗数、キュー登録失敗数、キュー滞留時間、ワーカー失敗数、解析完了時間を計測する。

9. テスト観点

  • ファイル保存成功後にキューへ正しい保存先が登録されること。

  • ファイル保存失敗時にHTTP 503が返り、キュー登録されないこと。

  • 10MBのファイルを処理できること。

  • キューのメッセージにファイル本体が含まれないこと。

  • ワーカーが保存先からファイルを取得し、解析結果をDBへ保存できること。

  • 同一メッセージの再配信で結果が重複しないこと。

  • オブジェクトストレージ読み込み失敗、解析失敗、DB保存失敗時に想定した再試行・状態遷移になること。

  • APIが解析完了を待たず、受付完了を返すこと。

10. スコープと進行状況

  • 今週の実装範囲:API実装

  • 担当:佐藤

  • 関連チケット:DATA-64

  • 関連PR:#203

今週は、ファイル保存、保存失敗時の503応答、キュー登録に必要なメッセージ生成、および受付レスポンスまでを実装対象とする。キュー登録失敗時の回復機構は未決定のため、実装範囲外として明示的に扱う。

本文外の注記

確定事項と未決事項を分離し、今週のAPI実装スコープに合わせて整理しました。

生成中の観測: スキル本文 なし/lintコマンド なし

完了後の採点用lint: 3件

採点用lintの指摘
[
  {
    "ruleId": "no-vague-action",
    "line": 70,
    "column": 9,
    "message": "曖昧な動作の候補です。実施する条件・しない条件が前後の文から分かるか確認してください。否定・条件を保って見直してください。"
  },
  {
    "ruleId": "no-doubled-joshi",
    "line": 178,
    "column": 46,
    "message": "一文に二回以上利用されている助詞 \"に\" がみつかりました。\n\n次の助詞が連続しているため、文を読みにくくしています。\n\n- \"に\"\n- \"に\"\n\n同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。\n"
  },
  {
    "ruleId": "stock-boundary",
    "line": 185,
    "column": 10,
    "message": "文書にJira課題IDが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  }
]
意味の採点と根拠

facts: 合格 API→ストレージ→保存先をキュー→ワーカー→DBの流れ、保存失敗時の503と未登録、登録失敗回復の未決定、10MB対1MB、結果提示が遅れる点はいずれも本文にある。

grounding: 不合格 multipart受付、一意ID、202応答、状態確認API、再試行・DLQ・状態遷移・冪等化など、資料にない仕様を本文で具体的な実装方針として追加している。さらにキュー登録失敗の回復候補も列挙している。

role: 不合格 本文の「10. スコープと進行状況」にDATA-64、PR #203、今週のAPI実装、担当佐藤を記載しており、本文に追跡情報を入れない要件に反する。

clarity: 合格 保存失敗時の503・キュー未登録と、保存後のキュー登録失敗時の未決定を別節で区別している。ファイル本体をキューに載せない理由も10MB対1MBとして明示されている。

economy: 不合格 依頼資料にない詳細なAPI形式、ID、メタデータ、状態遷移、冪等化、監視、テスト、実装計画を広範に追加しており、必要な設計論点を超えている。

スキルあり

valid

ファイル取込 Design Doc

背景と目的

ファイル取込を同期処理から分離し、APIの受付とファイル解析を別の処理として実行する。APIはファイル本体をオブジェクトストレージへ保存し、保存先をキューへ登録する。ワーカーはキューに登録された保存先からファイルを読み、解析結果をDBへ保存する。

スコープ

  • APIによるファイル本体の受け付け

  • オブジェクトストレージへのファイル保存

  • 保存先のキュー登録

  • ワーカーによるファイル読み出し

  • 解析結果のDB保存

  • 保存およびキュー登録に失敗した場合の扱い

スコープ外

  • キューへの登録失敗時の回復方法

  • 解析結果を利用者へ提示する具体的な画面やAPI仕様

制約

キューのメッセージ上限は1MBである。取込対象には10MBのファイルがあるため、ファイル本体をキューへ載せる方式は上限を超える。キューにはファイル本体ではなく、オブジェクトストレージ上の保存先を登録する必要がある。

採用する設計

APIとワーカーを非同期に分離する。APIは次の順序で処理する。

  1. 受け付けたファイルをオブジェクトストレージへ保存する。

  2. 保存に成功した場合、保存先をキューへ登録する。

  3. 保存に失敗した場合、503を返し、キューには登録しない。

キューから保存先を受け取ったワーカーは、保存先からファイル本体を読み出す。読み出したファイルを解析し、解析結果をDBへ保存する。

sequenceDiagram
    participant C as 利用者
    participant A as API
    participant S as オブジェクトストレージ
    participant Q as キュー
    participant W as ワーカー
    participant D as DB

    C->>A: ファイル送信
    A->>S: ファイル保存
    S-->>A: 保存結果
    alt 保存成功
        A->>Q: 保存先を登録
        Q-->>A: 登録結果
        A-->>C: 受付結果
        Q->>W: 保存先を配信
        W->>S: ファイル読み出し
        S-->>W: ファイル本体
        W->>W: 解析
        W->>D: 解析結果を保存
    else 保存失敗
        A-->>C: 503
    end

失敗時の動作

オブジェクトストレージへの保存失敗

APIは503を返す。保存先をキューへ登録してはならない。したがって、保存できていないファイルをワーカーが処理することはない。

キューへの登録失敗

オブジェクトストレージへの保存後にキュー登録が失敗した場合の回復方法は未決定である。保存済みファイルとキュー登録の不整合が発生し得るため、実装時に回復方法と状態管理を決定する必要がある。この決定が完了するまで、キュー登録成功をもって非同期処理へ進める条件を確定してはならない。

代替案と採否

ファイル本体をキューへ載せる案は不採用とする。10MBのファイルがキューの1MB制限を超えるためである。保存先をキューへ登録する方式なら、キューで扱うデータをファイル本体から保存先へ縮小できる。

影響

非同期化により、APIの受付完了から解析結果の提示までに遅延が生じる。利用者は、受付時点で解析結果を受け取れない。結果提示の具体的な方法と、キュー登録失敗時の回復方法は別途決定する必要がある。

未決定事項

  • キューへの登録に失敗した場合の回復方法

  • キュー登録失敗時にAPIが返す結果

  • 解析結果を利用者へ提示する方法

根拠

本書は、確定したファイル取込資料に基づく。資料で確定していない事項は、未決定事項として記載した。

本文外の注記

Design Docとして構成・内容を確認し、tantekiのdesign-doc検査を通過しました。進行メモ(DATA-64、PR #203、今週はAPI実装、担当:佐藤)は設計書の進捗情報のため本文から分離しています。

生成中の観測: スキル本文 あり/lintコマンド なし

完了後の採点用lint: 0件

採点用lintの指摘
[]
意味の採点と根拠

facts: 合格 API→オブジェクトストレージ→保存先をキュー→ワーカー→DBの流れ、保存失敗時の503およびキュー未登録、キュー登録失敗時の回復未決定、10MB対1MB、非同期化による結果提示の遅れをすべて本文に記載している。

grounding: 合格 キュー登録失敗後の回復方法や結果提示方法は未決定・別途決定とし、再送、削除、通知、状態取得API等を確定仕様として補っていない。

role: 合格 本文にはDATA-64、PR #203、今週の作業、担当佐藤といった進行追跡情報を記載していない。これらは注記にのみある。

clarity: 合格 保存失敗では「503を返し、キューには登録しない」とし、キュー登録失敗は保存後の別事象として未決定と明記している。10MBのファイル本体を1MB上限のキューに載せない理由も明確である。

economy: 合格 必要な処理フロー、失敗時の扱い、代替案の不採用理由、影響、未決定事項に収まっており、同じ結論を導入・まとめで不必要に反復していない。

Design Docの構成・失敗条件・代替案 · 2回目

共通の原依頼
実装者向けにファイル取込のDesign Docを作成して。確定した資料: APIはファイルをオブジェクトストレージへ保存し、その保存先をキューへ登録する。保存に失敗したら503を返し、キューには登録しない。ワーカーは保存先から読み、解析結果をDBへ保存する。キューへの登録失敗時の回復方法は未決定。ファイル本体をキューに載せる案は、10MBのファイルがキューの1MB制限を超えるため不採用。非同期化で利用者への結果提示が遅れる。進行メモ: DATA-64、PR #203、今週はAPI実装、担当佐藤。

スキルなし

valid

ファイル取込 Design Doc

1. 概要

ファイル取込を非同期処理化する。APIはファイル本体をオブジェクトストレージへ保存し、保存先情報をキューへ登録する。ワーカーはキューから保存先を取得してファイルを読み込み、解析結果をDBへ保存する。

2. 背景・目的

  • APIリクエスト内での解析処理を避け、APIの応答時間と負荷を抑える。

  • 最大10MBのファイルを扱う。

  • ファイル本体をキューへ登録する案は、キューの1MB制限を超えるため採用しない。

非同期化により、利用者が解析結果を確認できるまでの時間は従来より長くなる。この遅延は本方式の前提とする。

3. 処理フロー

利用者
  │ ファイル送信
  ▼
API
  │ 1. ファイルをオブジェクトストレージへ保存
  │ 2. 保存先情報をキューへ登録
  ▼
キュー ───────────────► ワーカー
                              │ 保存先からファイル取得
                              │ ファイル解析
                              ▼
                            DBへ解析結果保存
API
  1. リクエストからファイルを受け取る。

  2. 一意な取込IDとオブジェクトキーを生成する。

  3. ファイルをオブジェクトストレージへ保存する。

  4. 保存成功後、キューへメッセージを登録する。

  5. 受付完了と取込IDを返す。

キューメッセージにはファイル本体を含めず、少なくとも以下を含める。

  • 取込ID

  • オブジェクトストレージの保存先(バケット、オブジェクトキー等)

  • 必要に応じてファイル名、Content-Type、サイズ、登録日時

ワーカー
  1. キューからメッセージを取得する。

  2. メッセージに含まれる保存先からファイルを読み込む。

  3. ファイルを解析する。

  4. 解析結果をDBへ保存する。

  5. 成功時にキューメッセージを正常終了(ACK等)する。

解析失敗、ファイル取得失敗、DB保存失敗時の再試行・隔離方法は、既存のキュー運用方針に従う。既存方針がない場合は別途決定する。

4. エラー処理

オブジェクトストレージへの保存失敗
  • APIはHTTP 503 Service Unavailableを返す。

  • キューにはメッセージを登録しない。

  • 取込IDや保存先の扱いは、ストレージ側の保存結果を確認できる実装とする。

キューへの登録失敗

回復方法は未決定であり、本Design Docでは確定しない。実装前に以下のいずれかを決定する必要がある。

  • APIで失敗を返し、後続の再登録処理を行う。

  • 永続的な中間状態をDB等へ記録し、再送ジョブで登録する。

  • Outbox等を利用して保存とキュー登録の整合性を補償する。

  • 保存済みファイルを一定期間後に削除する運用を設ける。

登録失敗時に保存済みファイルだけが残る可能性があるため、回復方法とあわせて不要ファイルのクリーンアップ方針も決定する。

5. API設計の実装方針

  • APIは解析結果を待たず、キュー登録完了後に受付結果を返す。

  • レスポンスには取込IDを含め、利用者が後から状態・結果を照会できるようにする。

  • 解析結果の状態(例: acceptedprocessingcompletedfailed)を管理する設計を推奨する。

  • 同一リクエストの再送に備え、必要に応じて冪等性キーを受け付ける。

  • ファイルサイズ上限(10MB)、Content-Type、認証・認可、保存先へのアクセス権をAPIで検証する。

6. データ・整合性

取込IDをAPI、キューメッセージ、オブジェクトキー、解析結果で共通利用する。これにより、処理追跡と障害調査を可能にする。

DBには少なくとも以下の状態を保持することを推奨する。

  • 取込ID

  • オブジェクト保存先

  • 受付日時

  • 処理状態

  • 処理開始日時・完了日時

  • エラー情報(必要な場合)

キュー登録失敗時のDB記録方法は、回復方法の決定時に確定する。

7. 運用・監視

以下を監視対象とする。

  • オブジェクトストレージ保存失敗数、HTTP 503数

  • キュー登録失敗数

  • キュー滞留数・処理遅延

  • ワーカーの解析失敗数・再試行数

  • DB保存失敗数

  • 保存後にキュー登録されていないファイル数

  • 受付から解析結果保存までの所要時間

8. 未決事項

  1. キュー登録失敗時の回復方式。

  2. キュー登録失敗後に残るオブジェクトの削除・保持期間。

  3. ワーカーの再試行回数、バックオフ、デッドレターキュー運用。

  4. 解析結果の状態照会APIの仕様。

  5. 解析失敗時に利用者へ提示するエラー内容。

  6. 保存済みファイルの暗号化、保持期間、アクセス制御。

9. 進行メモ

  • チケット: DATA-64

  • 関連PR: #203

  • 今週の作業: API実装

  • 担当: 佐藤

10. 実装チェックリスト

  • ファイルサイズ上限10MBを検証する

  • オブジェクトストレージへファイルを保存する

  • 保存失敗時に503を返し、キュー登録しない

  • キューメッセージにファイル本体を含めず保存先を含める

  • 取込IDを一貫して付与・記録する

  • キュー登録失敗を検知・記録する

  • 受付レスポンスを非同期処理前提で実装する

  • キュー登録失敗時の回復方法を実装前に確定する

  • API・キュー・ワーカーの監視項目を追加する

本文外の注記

確定資料に基づいて、実装者向けの処理フロー、エラー処理、未決事項、実装チェックリストを整理しました。キュー登録失敗時の回復方法は未決定として明示しています。

生成中の観測: スキル本文 なし/lintコマンド なし

完了後の採点用lint: 12件

採点用lintの指摘
[
  {
    "ruleId": "no-vague-action",
    "line": 44,
    "column": 3,
    "message": "曖昧な動作の候補です。実施する条件・しない条件が前後の文から分かるか確認してください。否定・条件を保って見直してください。"
  },
  {
    "ruleId": "no-vague-action",
    "line": 80,
    "column": 17,
    "message": "曖昧な動作の候補です。実施する条件・しない条件が前後の文から分かるか確認してください。否定・条件を保って見直してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 121,
    "column": 9,
    "message": "文書にJira課題IDが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 128,
    "column": 1,
    "message": "文書に未完了または完了済みタスクのチェックボックスが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 129,
    "column": 1,
    "message": "文書に未完了または完了済みタスクのチェックボックスが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 130,
    "column": 1,
    "message": "文書に未完了または完了済みタスクのチェックボックスが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 131,
    "column": 1,
    "message": "文書に未完了または完了済みタスクのチェックボックスが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 132,
    "column": 1,
    "message": "文書に未完了または完了済みタスクのチェックボックスが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 133,
    "column": 1,
    "message": "文書に未完了または完了済みタスクのチェックボックスが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 134,
    "column": 1,
    "message": "文書に未完了または完了済みタスクのチェックボックスが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 135,
    "column": 1,
    "message": "文書に未完了または完了済みタスクのチェックボックスが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  },
  {
    "ruleId": "stock-boundary",
    "line": 136,
    "column": 1,
    "message": "文書に未完了または完了済みタスクのチェックボックスが含まれています。作業追跡はチケットまたは進捗文書へ移してください。"
  }
]
意味の採点と根拠

facts: 合格 API→ストレージ→保存先をキュー→ワーカー→DBの流れ、保存失敗時の503と未登録、登録失敗回復の未決定、10MB対1MB、非同期化による結果提示遅延をすべて本文に記載している。

grounding: 不合格 再送ジョブ、Outbox、削除運用、状態照会、冪等性、再試行・隔離、監視など、資料にない仕様・方針を本文で具体的に補っている。未決定とした箇所もあるが、本文中の追加仕様は確定資料に基づかない。

role: 不合格 本文の「進行メモ」にDATA-64、PR #203、今週のAPI実装、担当佐藤を記載している。

clarity: 合格 保存失敗(503・キュー未登録)とキュー登録失敗を別節で区別し、10MBが1MB制限を超えるため本体をキューに載せない理由も明示している。

economy: 不合格 確定資料にないAPI詳細、状態管理、監視、運用、チェックリストなどを大きく追加しており、依頼外の実装計画も含む。

スキルあり

valid

ファイル取込 Design Doc

目的

APIで受け付けたファイルを非同期に解析し、解析結果をデータベースへ保存する。APIと解析処理を分離し、ファイル本体をキューへ載せずに処理する。

範囲

本設計の対象は、APIによるファイル受付から、ワーカーによる解析結果の保存までとする。利用者への結果提示方法、キューへの登録失敗時の回復方法は対象外とし、未決定事項として扱う。

決定事項と制約

  • APIは受け付けたファイルをオブジェクトストレージへ保存する。

  • APIは保存先をキューへ登録する。

  • ワーカーはキューから保存先を受け取り、オブジェクトストレージからファイルを読み込む。

  • ワーカーは解析結果をデータベースへ保存する。

  • ファイル本体はキューへ登録しない。

  • ファイル本体をキューへ載せる案は、10 MBのファイルがキューの1 MB制限を超えるため採用しない。

処理フロー

sequenceDiagram
    participant C as 利用者
    participant A as API
    participant S as オブジェクトストレージ
    participant Q as キュー
    participant W as ワーカー
    participant D as データベース

    C->>A: ファイルを送信
    A->>S: ファイルを保存
    alt 保存に成功
        S-->>A: 保存先
        A->>Q: 保存先を登録
        A-->>C: 受付結果
        Q->>W: 保存先を配信
        W->>S: ファイルを読み込む
        S-->>W: ファイル本体
        W->>W: 解析
        W->>D: 解析結果を保存
    else 保存に失敗
        S-->>A: 保存失敗
        A-->>C: HTTP 503
    end

APIは、ファイル保存に成功した後で保存先をキューへ登録する。保存に失敗した場合はHTTP 503を返し、キューへ登録しない。保存成功後のキュー登録に失敗した場合の扱いは、現時点では決めない。

実装上の境界

API
  1. ファイルをオブジェクトストレージへ保存する。

  2. 保存に失敗したらHTTP 503を返す。

  3. 保存に失敗した場合はキューへ登録しない。

  4. 保存に成功したら、ファイルの保存先をキューへ登録する。

APIの受付後、解析結果は非同期に保存される。そのため、利用者が結果を確認できるまでの時間は、同期処理より長くなる。

キューのメッセージ

メッセージにはファイル本体を含めず、オブジェクトストレージ上の保存先を含める。ファイル本体を含めると、10 MBのファイルがキューの1 MB制限を超えるためである。

ワーカー

ワーカーはキューの保存先を使ってオブジェクトストレージからファイルを読み込み、解析結果をデータベースへ保存する。解析処理はAPIのリクエスト処理とは分離して実行する。

失敗時の扱い

失敗箇所APIの応答キューへの登録決定事項
オブジェクトストレージへの保存HTTP 503登録しない確定
保存先のキューへの登録未決定未決定回復方法を決める

保存成功後にキューへの登録が失敗すると、オブジェクトストレージ上にファイルが残ってもワーカーへ通知されない可能性がある。この状態からの回復方法は未決定であり、実装前に決める必要がある。

未決定事項

  • 保存先のキューへの登録に失敗した場合の回復方法

  • キュー登録失敗時にAPIが返す応答

  • 非同期処理中および完了後の利用者への結果提示方法

本文外の注記

Design Docとして構成を確認し、本文を作成しました。tantekiのdesign-doc向けlintを実行し、指摘なし(exit 0)です。進行メモのDATA-64、PR #203、今週のAPI実装、担当:佐藤は参照用設計本文から分離しました。

生成中の観測: スキル本文 あり/lintコマンド なし

完了後の採点用lint: 0件

採点用lintの指摘
[]
意味の採点と根拠

facts: 合格 必要な処理順、保存失敗時のHTTP 503およびキュー未登録、キュー登録失敗回復の未決定、10MBと1MB制限、非同期化による結果確認の遅れを本文にすべて残している。

grounding: 合格 キュー登録失敗時の応答・回復方法・結果提示方法を未決定事項として扱い、再送、削除、通知、状態取得APIなどを確定仕様として追加していない。

role: 合格 DATA-64、PR #203、今週の作業、担当佐藤は本文に含まれていない。

clarity: 合格 保存失敗とキュー登録失敗を表および本文で分離し、前者は503・未登録、後者は回復方法未決定と明確にしている。10MBと1MB制限による代替案不採用の理由も明記している。

economy: 合格 処理フロー、境界、失敗時の扱い、未決定事項に必要な内容を集約しており、同じ結論の反復や依頼外の実装計画はない。