Skip to content

精度と制約

このページでは、各ツールが何を返せて何を返せないのか、そしてその理由を説明します。内容は v0.6.53 時点の開発ガイド(CLAUDE.md)に基づいています。

テキスト経路で落ちるもの

RFC 8650 より前の RFC には、公式の RFCXML がありません。これらの RFC と、RFC 8650 以降であっても XML の取得が 404 以外の理由(5xx やタイムアウト)で失敗した RFC は、テキスト形式(.txt)を解析します。どちらの経路で解析したかは応答の _source に、注意が必要な場合はその理由が _sourceNote に入ります。

XML の構造に依存している機能は、テキスト経路では精度が下がります。

ツールXMLテキストAPI による補完備考
get_rfc_structure✅ 完全⚠️ 階層の精度が下がる✅ メタデータを補完abstract と著者は Datatracker API から補完する。category / stream は API から取得できたときだけ付き、届かなかった場合は _sourceNote にその旨を書く。公開日は RFC 本文から取る
get_requirements✅ 完全⚠️ 抽出の精度が下がる❌ なし段落の形から推測する
get_definitions✅ 完全⚠️ 抽出の精度が下がる❌ なし<dl> が無いため、用語: 説明 の形と、用語の下に説明を字下げして書く形から推測する
get_rfc_dependencies✅ 完全✅ 良好✅ Datatracker relateddocument参考文献の欄があればそこから取り、無ければ API から取る
get_related_sections✅ 完全⚠️ 本文中の Section N の記述から❌ なし節どうしの相互参照は本文にしか書かれておらず、API では取得できない
generate_checklist✅ 完全⚠️ 抽出の精度が下がる❌ なしget_requirements を使うため、同じ制約を受ける
validate_statement✅ 完全⚠️ 抽出の精度が下がる❌ なし同上

凡例

✅ 完全 / ⚠️ 制限あり(精度が下がる) / ❌ 取得できない

get_rfc_dependencies の応答にだけ付く _referencesSource は、参照関係をどこから取ったかを示します。

取得元補足
'xml'RFCXML の <references>anchor と題名が完全に付く
'text'テキスト本文の参考文献の欄題名は参考文献の欄から取るので、仮の値ではない。参考文献の欄が 1 つしかない RFC(RFC 2616 など)では normative / informative を区別できず、すべて informative に入る。そのときだけ _sourceNote が付く
'api'Datatracker の relateddocument API題名と anchor は仮の値(title: "RFC N"anchor: "RFCN")。本文に参考文献の欄が無いときに使う

空の結果は「要件が無い」という意味ではありません

結果が空だったとき、それは「指定した範囲の本文に一致するものが無かった」という意味であって、「そのような要件は存在しない」という意味ではありません。要件の抽出は BCP 14 のキーワード(RFC 2119 / RFC 8174)を手がかりにしているため、キーワードを使わずに書かれた要件は報告されません。

validate_statement は判定器ではありません

validate_statement は、渡された主張に関係する要件を RFC の中から探し、主張と要件の間に明らかな矛盾があれば報告します。適合しているかどうかを判定するものではありません。応答の isValid は次の 3 つの値を取ります。

isValid意味
null判断できるだけの一致が見つからなかった
false主張と要件の間に矛盾を検出した
true一致した要件の中に矛盾は見つからなかった。準拠していることの証明ではない

true を準拠の証明として扱わないでください

true は「一致した要件の中に矛盾が見つからなかった」ことしか意味しません。照合は英語のキーワードに基づく近似で、後述の受動態の禁止や限定語の言い換えのように、矛盾を検出できない形が残っています。

値は次の規則で決まります。

  • 最も強く一致した要件が、スコアの下限と「主語以外に 2 語以上が一致する」という条件の両方を満たさない場合は null になります。主語だけが一致した場合はスコアの下限に届くことがありますが、主張が何について述べているのかが分からないため、判定しません。
  • false の根拠は、最も強く一致した要件でなくても構いません。conflicts に挙がった要件が同じ条件を満たしていれば false になります。矛盾は見つかったものの、その要件が条件を満たさない場合は null のままで、注記に「矛盾はあるが判定の条件に届かない」と書きます。
  • 主張の中のキーワードは、RFC 8174 のとおり大文字で書かれたものだけをレベルとして読みます。小文字の optionalrequired は普通の形容詞として扱い、detectedLevelnull になります。
  • 矛盾の検出は、要件文のうちキーワードより後ろの部分(要求されている行為)だけを対象にします。要件の条件節に含まれる否定を、要求されている行為の否定と取り違えないためです。
  • 主張が禁止された行為を行っていると言うためには、主張の主動詞がその行為でなければなりません。「The server removes masking …」の主動詞は removes であって mask ではないので、「mask してはならない」という要件とは矛盾しません。
  • 動詞の言い換えは表で吸収していますが、表は網羅的ではありません。表に無い動詞では矛盾を検出しません。検出しなかった場合は true(矛盾は見つからなかった)になりますが、これは準拠を意味しません。

次の 2 つの場合は、誤った true を返さないために、判定を保留して null を返します。

受動態で書かれた禁止(MUST NOT be <過去分詞>

「A reference identity of type CN-ID MUST NOT be used by clients.」のような要件では、禁止されている行為が「be used by clients」であり、行為の実行者が文の中にありません。矛盾の検出は「主張の主語がその動詞を実行しているか」を見るので、この要件に違反する主張を渡しても conflicts は空になります。空のまま true にすると、違反している主張に「矛盾なし」と答えることになります。そのため、MUST NOT be <過去分詞> の形の要件に一致した場合は isValidnull にし、suggestions に該当する要件の ID を出します。主張自身が否定形(not / never / no / cannot)で書かれている場合は準拠を述べているので、この保留は行いません。機械的に生成した受動態の違反文 40 件で測ったところ、誤って true になるものは 13 件から 4 件に減りました。要件どおりに書いた 179 件のうち、保留になったのは 4 件です。

限定語の言い換え(withouthas no / lacks

RFC 9110 §6.6.1 には「An origin server with a clock MUST generate …」と「An origin server without a clock MUST NOT generate …」が並んでいます。2 つの要件を区別しているのは with / without なので、同じ行為かどうかの判定では主張にも同じ語があることを求めます。しかし「… even though it has no clock.」のように言い換えられると without が無いため矛盾が検出されず、以前は true を返していました。現在は、限定語を無視すれば矛盾が検出され、かつ主張が同じ否定(no clock / does not have a clock / lacks a clock)を述べている場合に限って null にします。「with a clock」の側は準拠している主張なので保留しません。without 以外の限定語については言い換えの形が定まらないため、この処理は行いません。禁止の要件 1,668 件のうち without を含むものは 51 件です。

公開日は RFC 本文から取ります

INFO

Datatracker API の document.time は、レコードが最後に更新された時刻であって公開日ではありません。RFC 9293 では 2026-05-20 が返りますが、公開は 2022 年 8 月です。

このサーバーは、公開日を RFCXML の front/date から、テキスト経路では先頭のヘッダー行から取ります。Datatracker の値はツールの応答には出しません。

表の行は 1 行ずつ要件にします

図や表の行に BCP 14 のキーワードがある場合、その 1 行だけを要件文にします。段落全体を要件にすると、RFC 2131 §4.3.1 の Table 3(2 ページにわたる表)のような箇所で、generate_checklist に 2,000 文字の「要件」がレベルごとに 4 回並んでしまうためです。

XML 経路の <table> の扱い

XML 経路の <table> も同じ規則で、本文の行から 1 行ずつ(セルを " | " でつないで)要件にします。見出し行は対象にしません(RFC 9293 §3.11 は見出し行に MUST / SHOULD / MAY を並べています)。キーワードの直後が -数字MUST-14 のような要求 ID のラベル)だけの行も要件にしません。RFC 9293 Appendix B の一覧表がこれに当たり、要件そのものは §3.1 などの本文から取れています。表から取った要件には fullContext に見出し行とその行を入れ、主語・条件・行為の切り出しは行いません。なお、監査に使っている XML 形式の RFC 32 本には本文の行にキーワードを持つ <table> が無いため、この経路は単体テストでだけ検証しています。

ASN.1 の型定義(keyIdentifier [0] KeyIdentifier OPTIONAL, のような行)は散文ではないので、OPTIONAL があっても要件にしません。

公開前に通している検査

v0.6.0 から v0.6.13 までの間に見つかった 13 件の不具合は、すべて公開後の試用で見つかったものでした。公開前に手元で同じ操作をしていれば、どれも見つかっていたはずです。そのため、公開の前に次の検査を順に通しています。件数は v0.6.53 時点のもので、検査を増やすたびに変わります。

手順見つけるもの
npm test単体テストで書いた条件の取りこぼし(622 件)
npm run test:e2eMCP クライアントから見た振る舞い(76 件)
npm run audit想定していない書式で解析が崩れる箇所(実物の RFC 171 本 × 不変条件 51 種)
npm run crosscheckツールどうしの出力の食い違い(RFC 171 本 × 14 種)
npm run snapshot条件として書けない見た目の崩れ(出力見本 38 本)
ローカル登録したサーバーで試用実際の使い方で気づくもの

CI では、push と pull request ごとに lintformat:checknpm testbuildnpm run test:e2e を回します。npm への公開時(publish.yml)は npm testnpm run buildnpm run test:e2e を通してから公開します。audit / crosscheck / snapshot は実物の RFC を多数取得するため、毎週月曜 00:00 UTC(日本時間 09:00)と手動実行で回しています。

npm run snapshot で固定している出力は 出力例 に載せています。