Product Lock スコアリング
バージョン 0.1.0 — 2026年2月
product.lock.json から導出される複雑度スコアリングシステム。
同じロック、同じスコア。スコアはコードの複雑度ではなく、プロダクトの複雑度を測定する。
完全な仕様については、Product Lock Specification を参照のこと。
目次
1. 何を測定するか
Product Lock Score(PLS)は、ソフトウェアプロダクトのプロダクト境界の複雑度を測定する。「プロダクトの観点から見て、このプロダクトはどのくらい複雑か?」という問いに答える。
PLS が測定するもの:
- プロダクトが管理するデータの量
- どれだけの機能を持つか
- 各パーツがどのように相互接続されているか
- アクセス制御がどのくらい複雑か
PLS が測定しないもの:
- コード品質やコードサイズ
- 実装の技術的難易度
- パフォーマンス要件
- インフラの複雑度
スコアは完全に product.lock.json から導出される。 同じロック、同じスコア。言語、フレームワーク、アーキテクチャはスコアに影響しない。
2. 4つの次元
プロダクトの複雑度は4つの独立した次元に分解される:
D — データ複雑度
プロダクトが保存するデータ量。より多くのエンティティとフィールド = より高いデータ複雑度。
D = entity_count × avg_fields_per_entity × 0.3
平均14フィールドの45エンティティを持つプロダクト(Sentry)は、平均6フィールドの7エンティティを持つプロダクト(Hacker News)より根本的にデータ複雑度が高い。
F — 機能複雑度
プロダクトが実行できること。各機能は独立して識別可能な能力である。
F = feature_count × 1.0
機能がプロダクトの「できること」の最も直接的な指標であるため、重み1.0。180の機能を持つプロダクト(GitLab)は、12の機能を持つプロダクト(Hacker News)よりも多くのことを行う。
I — インタラクション複雑度
パーツがどう結びつくか。ストーリーはエンティティをまたぐフローを記述し、ストーリーが多いほどプロダクトはより相互接続されている。
I = story_count × 0.5
ストーリーはナラティブ(1つのストーリーが複数のインタラクションをカバーする場合がある)であり、エンティティや機能ほど数が正確ではないため、重み0.5。
A — アクセス複雑度
誰が何をできるか。より多くのアクターとより異なるパーミッションセット = より複雑なアクセス制御。
A = permission_matrix_size × 0.1
パーミッションマトリクスサイズ = 意味のあるアクター-機能の組み合わせの数。アクセス制御は組織的な複雑度を追加するが、プロダクトの「できること」を変えないため、重み0.1。
3. 計算式
PLS = D + F + I + A
ここで:
D = entity_count × avg_fields_per_entity × 0.3
F = feature_count × 1.0
I = story_count × 0.5
A = permission_matrix_size × 0.1
product.lock.json から各フィールドを読む方法
| 変数 | ソース | 数え方 |
|---|---|---|
entity_count |
entities |
エンティティキーの数(ルースまたはストリクトモード) |
avg_fields_per_entity |
entities |
フィールド配列の平均長(ストリクトモードのみ) |
feature_count |
features |
features 配列の長さ |
story_count |
stories |
stories 配列の長さ |
permission_matrix_size |
permissions |
すべてのアクターにわたるパーミッション配列の合計 |
欠落フィールドの扱い
| 状況 | ルール |
|---|---|
entities がルースモード(string[])の場合 |
デフォルト:エンティティあたり8フィールド |
entities がストリクトモードで [] の場合 |
そのエンティティのフィールドは0として数える |
features が省略されている場合 |
F = 0 |
stories が省略されている場合 |
I = 0 |
permissions が省略されている場合 |
A = 0 |
permissions が文字列("rbac")の場合 |
デフォルト:actors × features × 0.6 |
actors が省略されている場合 |
1を使用(単一ユーザータイプ) |
denied |
スコアに含めない(複雑度ではなく境界の成熟度) |
denied が除外される理由
denied はプロダクトの複雑度ではなく、境界の成熟度を測定する。50の denied 項目を持つプロダクトは、0のプロダクトより複雑ではない — より制約されている。制約は複雑度の対極にある。
4. スコアレベル
| PLS 範囲 | レベル | 説明 | 例 |
|---|---|---|---|
| < 50 | シンプル | 単一目的のツール、最小限のデータモデル、少数の機能 | Hacker News (32)、Excalidraw (44) |
| 50-150 | 中程度 | 明確なドメインに焦点を絞ったプロダクト、中程度のデータモデル | Plausible (58)、Ghost (145) |
| 150-300 | 複雑 | 多機能プラットフォーム、豊富なデータモデル、エンティティ間のインタラクション | Cal.com (162)、Discourse (170)、Supabase (250) |
| 300-500 | 非常に複雑 | エンタープライズプラットフォーム、広範なデータモデル、深いパーミッションシステム | Elasticsearch (287)、Sentry (325) |
| 500+ | 巨大 | マルチプロダクトプラットフォーム、数百のエンティティと機能 | GitLab (1037) |
各レベルの実践的な意味
| レベル | 人間のレビュー時間 | AI生成のスコープ | 典型的なロックサイズ |
|---|---|---|---|
| シンプル | 数秒 | 単一プロンプト | 30行未満 |
| 中程度 | 1-3分 | 単一セッション | 30-80行 |
| 複雑 | 3-10分 | 複数セッション | 80-200行 |
| 非常に複雑 | 10-30分 | 段階的生成 | 200-500行 |
| 巨大 | 30分以上 | AIエージェントのチーム | 500行以上 |
5. 計算ルール
ルール1:プロダクトエンティティのみを数える
entities フィールドに記載されたエンティティのみを数える。実装テーブル(キャッシュ、キュー、マイグレーション)はロックに含まれるべきではなく、スコアに影響しない。
ルール2:ストリクトモードの方がスコアが高くなる
ストリクトモードはより多くのフィールドをロックし、より高い(そしてより正確な)Dスコアを生成する。これは意図的である — 正確なフィールドを指定するプロダクトは、より定義された(したがって測定可能な)データモデルを持つ。
// ルース: entity_count=3, avg_fields=8 (デフォルト)
// D = 3 × 8 × 0.3 = 7.2
"entities": ["User", "Post", "Comment"]
// ストリクト: entity_count=3, avg_fields=10
// D = 3 × 10 × 0.3 = 9.0
"entities": {
"User": ["avatar", "email", "id", "name", "role"],
"Post": ["authorId", "content", "createdAt", "id", "slug", "status", "tags", "title"],
"Comment": ["authorId", "content", "createdAt", "id", "postId", "replyToId", "status"]
}
ルール3:パーミッションマトリクスは実際のエントリを数える
permissions がオブジェクトの場合、パーミッションエントリの合計数を数える:
"permissions": {
"Admin": ["createPost", "deletePost", "manageUsers", "publishPost"],
"Editor": ["createPost", "publishPost"],
"Viewer": ["viewPost"]
}
// permission_matrix_size = 4 + 2 + 1 = 7
permissions が "rbac" のような文字列の場合、推定する:actors × features × 0.6。
ルール4:スコアは決定的
同じロックは常に同じスコアを生成する。ランダム性なし、外部データなし、主観的判断なし。計算式はロックファイルに存在するデータのみを使用する。
ルール5:整数に丸める
最終的な PLS は最も近い整数に丸める。
6. ベンチマーク
10の著名なオープンソースプロダクトに対して検証済み。すべてのスコアが一般的に認知されている複雑度のランキングと一致する。
| # | プロダクト | Entities | AvgFields | Features | Stories | PermMatrix | D | F | I | A | PLS | レベル |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Hacker News | 7 | 6 | 12 | 10 | 26 | 12.6 | 12 | 5 | 2.6 | 32 | シンプル |
| 2 | Excalidraw | 8 | 10 | 14 | 10 | 10 | 24 | 14 | 5 | 1 | 44 | シンプル |
| 3 | Plausible | 12 | 8 | 18 | 15 | 36 | 28.8 | 18 | 7.5 | 3.6 | 58 | 中程度 |
| 4 | Ghost | 22 | 12 | 34 | 45 | 90 | 79.2 | 34 | 22.5 | 9 | 145 | 中程度 |
| 5 | Cal.com | 26 | 11 | 38 | 55 | 105 | 85.8 | 38 | 27.5 | 10.5 | 162 | 複雑 |
| 6 | Discourse | 28 | 10 | 42 | 60 | 135 | 84 | 42 | 30 | 13.5 | 170 | 複雑 |
| 7 | Supabase | 40 | 11 | 78 | 35 | 220 | 132 | 78 | 17.5 | 22 | 250 | 複雑 |
| 8 | Elasticsearch | 35 | 12 | 90 | 45 | 480 | 126 | 90 | 22.5 | 48 | 287 | 複雑 |
| 9 | Sentry | 45 | 14 | 75 | 60 | 310 | 189 | 75 | 30 | 31 | 325 | 非常に複雑 |
| 10 | GitLab | 120 | 18 | 180 | 250 | 840 | 648 | 180 | 125 | 84 | 1037 | 巨大 |
検証
スコアリングは、広く受け入れられている複雑度の認識と一致するランキングを生成する:
Hacker News (32) < Excalidraw (44) < Plausible (58) < Ghost (145) < Cal.com (162)
< Discourse (170) < Supabase (250) < Elasticsearch (287) < Sentry (325) < GitLab (1037)
ベンチマークからの重要な観察:
- シンプルなプロダクト(< 50):単一目的、エンティティ10未満、機能15未満
- 中程度のプロダクト(50-150):焦点を絞ったドメイン、エンティティ10-25、機能15-35
- 複雑なプロダクト(150-300):多機能プラットフォーム、エンティティ25-40、機能35-80
- 非常に複雑なプロダクト(300-500):エンタープライズプラットフォーム、エンティティ35-50、機能75-90、深いパーミッションモデル
- 巨大なプロダクト(500+):マルチプロダクトプラットフォーム、エンティティ100以上、機能150以上、ストーリー200以上
7. ユースケース
プロダクトの比較
「我々のプロダクトは Ghost より複雑か?」両方のプロダクトをロックする。スコアを比較する。
複雑度の増加を追跡
バージョン 1.0:PLS 85(中程度) バージョン 2.0:PLS 160(複雑) バージョン 3.0:PLS 340(非常に複雑)
スコアが予期せず跳ね上がった場合、スコープクリープを示している可能性がある。ロックバージョン間の差分を確認して何が追加されたかを見つける。
工数の見積もり
スコアは実装工数と相関する。複雑なプロダクト(150-300)はシンプルなプロダクト(< 50)よりも大幅に多くの作業を要する。ベンチマークのプロダクトを参照点として使用する:
- 「我々のプロダクトは170で、Discourse に近い。同程度のスコープを想定する。」
- 「我々のプロダクトは45で、Excalidraw に近い。これは焦点を絞ったツールである。」
スコープ制御
プロダクトバージョンのターゲット PLS を設定する:
「MVP は PLS 100 以下に留めなければならない。超える機能追加は v2 に移す。」
機能追加がターゲットを超えてスコアを増加させる場合、スコープを再考するシグナルである。
ロックバージョンの比較
v1.0.0 → v1.1.0: PLS 120 → 128 (+8) // 小規模な機能追加
v1.1.0 → v2.0.0: PLS 128 → 195 (+67) // 大規模なスコープ拡大
v2.0.0 → v2.1.0: PLS 195 → 210 (+15) // 中程度の追加
v2.1.0 → v3.0.0: PLS 210 → 340 (+130) // 警告:スコープクリープの可能性
このスコアリングシステムは Product Lock Specification の一部です。