docs: consolidate design documentation and standardize crate English

This commit is contained in:
2026-10-12 14:58:00 +09:00
parent a633a53274
commit 4efb0ace1f
404 changed files with 4556 additions and 11654 deletions
+31
View File
@@ -0,0 +1,31 @@
# 正本・権限・実行の分離
## 正本と観測
永続的な判断の根拠は、その判断を所有する明示的な記録に置く。UIの表示、キャッシュ、通知、プロセスの生存情報は、正本を再確認するための観測として扱う。これらだけから操作の成功、作業の完了、権限の継続を推定しない。
永続化する情報と、現在の状態から再構成できる情報を分ける。別の所有者が管理する状態を複写して第二の状態機械を作ると、更新漏れと復旧時の不一致が生じる。親の処理は子の識別子を保持し、必要な時点で子の正本を読む。
## 権限と入力
操作権限は認証された主体、明示的な付与、対象資源の現在の制約から決定する。プロンプト、Profile名、表示名、cwd、ファイルの存在、ツールが見えることを権限の根拠にしない。別の操作経路を設けても、同じ所有者の検証を通す。
委譲では親が実際に委譲できる範囲を上限にする。読取り、書込み、コマンド実行、観測、レビュー、統合を混同しない。探索で対象を発見できても操作権限を得たことにはならない。
## 履歴とLLM入力
LLMの生成に影響する入力は、リクエストへ加える前に履歴へ確定し、永続化形式からリクエストを再構成できるようにする。揮発的な入力の差込みでは、後のターンから発言やツール呼出しの根拠を追えなくなる。
履歴は追記を基本とする。圧縮や保持範囲の変更は、明示的な境界と再構成規則を持つ処理に限定する。過去の記録を黙って書き換えず、キャッシュとトークン消費への影響をセッションの実測に基づいて判断する。
## 初期設定と実行処理
環境変数などの暗黙的なプロセス状態は、起動境界で明示的な入力へ変換する。通常の処理は解決済みの型付き設定を受け取り、実行中に環境を読み直して判断を変えない。秘密情報は明示的な参照で扱い、設定の説明や診断へ値を複製しない。
## 状態と操作の独立性
作業の結論、レビュー判断、コード統合、Worker停止、記録の保持、接続解除、資源削除は別の判断である。一つの成功を別の操作の許可として流用しない。自動的に連動させる場合は、その責任を持つ操作として条件と結果を定義する。
競合確認では、何を、どの観測と比較し、どの操作の前後で検査するかを名前と処理で示す。到着順や時刻で足りる処理に不透明な更新番号を加えない。内容の一致、同じ操作の再送、鍵の一致、接続の生存期間を確認する場合は、それぞれを識別する根拠を使う。
個別の永続操作と再試行の判断は[永続操作の原則](durable-operations.md)に従う。具体的な認証、保存、復旧の仕組みは所有moduleのドキュメントに置く。
+196
View File
@@ -0,0 +1,196 @@
# Workspace Web Design Language
この文書は、Workspace Webのrendered resultが満たす設計規則を定義する。
一つの規則は最も具体的な一箇所だけをauthorityとする。具体的な二案の一方を棄却できない文は規則として残さない。
## 1. Principles
複数の規則や要求が競合した場合だけ、この章の優先原理を使う。
### Task before explanation
次の有効なactionへ到達する前の操作、scroll、常設説明が少ない案を選ぶ。ただし、説明を省くと対象、結果、permission、不可逆性を誤認する場合は説明をactionより前に置く。
### Meaning before decoration
情報の関係、重要度、操作可能性、stateのいずれも変えない視覚差を追加しない。
### Authority before convenience
Backend authorityが確定していないdata、state、permission、actionを、UIの都合で補完または推測する案を棄却する。
## 2. Semantics / Grammar
### Information structure
- pageと、page内で一つのtaskまたは判断を完結させる領域をscopeとする。
- 各scopeで最も強い視覚要素はheading、現在判断が必要なattention、filled actionのいずれか一つだけにする。同じ強さのheading、attention、filled actionを複数置かない。
- hierarchyをcolorだけで表現しない。DOMと画面上の配置順を一致させた上で、size、weight、contrastを使う。
- scopeを識別するprimary titleは、一つのscopeにつき一度だけ表示する。
- actionは、そのactionが影響するscope内に置く。
- DTOにfieldが存在するという理由だけで表示せず、current taskの判断またはactionを変える値だけを常設する。
**Disclosure**
- Raw dataやデバッグ情報など、通常は必要としない詳細な情報は折りたたみ領域に隠す。
- 作成または編集のformを表示用screenへ常時同居させず、明示的なactionで開く折りたたみ領域または別pageに置く。
### Interaction and state
- actionにはbutton、navigationにはlink、選択には対応するform controlを使う。
- interactive elementはhover、focus、active、disabledを視覚的に区別する。
- staticなstatus、key、metadataをbuttonやpillの形にしない。
- clickable rowは遷移先を一つだけ持ち、row全体で同じ遷移を実行する。
- permissionがないactionをdisabled controlとして表示しない。
**State and operation**
- stateの違いによってユーザーの判断または利用できるactionが変わる場合、その違いを一つの表示へ統合しない。
- UI stateはそのstateを所有するauthorityから取得し、別domainやtransportのsignalから推測しない。
- 非同期mutationでは楽観的更新か悲観的更新を選ぶ。楽観的更新は暫定stateを明示し、failure時のrollbackまたは再取得を定義できる場合だけ使う。それ以外は確定済みstateを維持し、operationのpending stateを別に表示する。
- loading、failure、unavailableの表示は利用不能になった最小のscopeだけを置き換え、利用可能な親scopeとsibling scopeを残す。
- destructive actionは対象と結果を明記し、復元できない場合だけconfirmationを要求する。
### Language / Copy
- title、navigation label、control labelで明らかな内容を説明文で繰り返さない。
- 常設proseは、対象またはactionの選択を変えるwarning、permission、validation constraint、error recoveryに必要な内容だけにする。
- button labelには具体的なactionを表す動詞を使い、`Submit`と`OK`を使わない。
- identifier、API名、type名を別の語へ言い換えない。
### Responsive behavior
- page全体にhorizontal scrollを発生させない。
- wrappingまたはstack化によって情報の対応関係が失われる場合だけ、その領域内にbounded horizontal scrollを持たせる。それ以外のside-by-side layoutは一列にする。
- primary actionを初期viewportから追い出さない。
- contentをtruncateする場合、完全な値をcopyまたはdetailで取得できるようにする。
### Accessibility
- action、navigation、form controlを非semantic elementだけで実装しない。
- すべてのcontrolにaccessible nameを与える。
- keyboard focusを不可視にしない。
- tab orderを画面上の順序と一致させる。
- stateをcolorだけで区別しない。
- horizontal scroll regionをkeyboard focus可能にし、accessible nameを与える。
## 3. Primitives / Tokens
### Color / Theme
colorはCSS custom propertyをauthorityとし、通常のWorkspace colorはOKLCHで定義する。lightとdarkは同じsemantic token名を使う。
```css
--bg
--bg-raised
--bg-subtle
--line
--line-strong
--text
--text-strong
--text-muted
--text-faint
--code
--accent
--accent-muted
--success
--warning
--danger
--interactive-hover
--interactive-selected
--shadow-overlay
```
- `--bg`、`--bg-raised`、`--bg-subtle`へhueを持たせない。
- accentはfocus、current navigation、current selectionだけに使い、通常本文や通常actionの背景へ使わない。
- success、warning、dangerを、それぞれ対応するstate以外へ使わない。
- componentへraw colorを追加せず、上記semantic tokenを使う。
- ConsoleとterminalのANSI paletteを通常のstatusやformへ流用しない。
### Typography
font sizeは、その領域でユーザーが行う読み方によって選ぶ。
- defaultは`14px / 20px`とし、個々のtextを読むこと自体がtaskの中心になる領域に使う。
- 同じ構造の反復を一覧として走査する領域と、位置、順序、形、選択状態を中心に識別するUI chromeには`12px / 16px`を使う。textを読まなければactionの意味や結果を判断できない場合は`14px / 20px`を使う。
- `24px / 32px`はページまたはdocument内で唯一かつ最大のheadingだけに使う。
- 収めるため、または情報を弱く見せるためにfont sizeを下げない。`12px`未満と`13px`を使わない。
- 機械的な値にはmonospace familyを使う。
```css
--font-sans
--font-mono
--font-size-title /* 24px */
--line-height-title /* 32px */
--font-size-body /* 14px */
--line-height-body /* 20px */
--font-size-compact /* 12px */
--line-height-compact /* 16px */
```
### Spacing / Shape
```css
--space-1 /* 4px */
--space-2 /* 8px */
--space-3 /* 12px */
--space-4 /* 16px */
--space-5 /* 24px */
--space-6 /* 32px */
--radius-soft
```
- 一つの境界にspacing、line、surface backgroundを重ねず、primary cueを一つだけ使う。
- 汎用的な`Card` primitiveを設けない。
- nested surfaceでparentと同じ境界表現を繰り返さない。
- shadowは通常flowから浮くmenu、popover、Tooltipだけに使う。
- radiusはinteractive controlだけに使う。
### Motion
- motion完了をactionの受付、state change、content理解の条件にしない。
- 繰り返しまたは連続animationを、`prefers-reduced-motion: reduce`で停止する。
## 4. Components / Patterns
### Border / Structural edge
- `Bevel`は1pxの単色borderを描くvisual wrapperであり、照明、raised/inset、ridge/grooveを表現しない。
- `Bevel`自体へbackgroundやsurface toneを与えず、必要なbackgroundは内側のsemantic childが持つtext/content areaへ適用する。
- 隣接するsurfaceでは、実際に境界となる辺だけを有効にする。
- standaloneな閉じた領域は全辺を`Bevel`で囲う。Desktop shellではHeaderのbottom edgeとSidebarのright edgeだけを有効にし、viewport外周のtop/left edgeを描かない。
- `BevelLine`は開いた領域内の1px separatorだけに使う。同じlayerではheading、本文、Lineの端を揃え、Lineだけに端方向のpaddingやmarginを追加しない。
- nested layerでは親layoutがそのlayer全体へinline方向の余白を与え、content、row、Lineを一緒に移動する。Lineだけを短くしない。
- control自身のborder、focus ring、status marker、table gridを`Bevel`または`BevelLine`で置き換えない。
### Sidebar
- Desktop幅は`clamp(220px, 20vw, 280px)`とする。
- navigation contentだけをscrollさせる。
- Desktopのfold controlはSidebar下部、Mobileのfold controlはHeaderに置く。
- MobileでSidebarを表示するときはHeader下の残りviewport全体を使い、main contentと同時表示しない。
- navigationとscope control以外を置かない。
- navigation linkはSidebar幅全体を使うflat rowとする。
- active routeは一つの視覚cueと`aria-current="page"`で示す。
- iconだけでnavigation labelを置き換えない。
- fold controlは一つだけ置き、current stateに対応するaccessible nameを使う。
### Tooltip / Contextual help
- operationやtable全体を説明する常設proseを置く前に、button labelとcolumn headingだけで識別できるようにする。
- labelだけでは表現できない補助説明だけを、対象へbindしたTooltipに入れる。
- pointer hoverとkeyboard focusの両方で開く。
- triggerとTooltipを`aria-describedby`で関連付ける。
- hoverはdelay後、focusは直ちに表示する。
- `Escape`で閉じ、triggerからfocusを移動しない。
- 複数paragraph、form、link、buttonを入れない。
- error、permission、validation constraint、不可逆操作の結果、current stateをTooltipへ入れない。
- touch環境ではTooltipだけを説明への到達手段にしない。
### Generic component patterns
- **Form field**: label、control、constraintまたはhelp、field errorの順に配置する。
- **Key-value**: 一つのresourceの属性には`dl`を使う。
Design-labではcomponent名と実際のsampleだけを表示する。規則とrationaleをUIへ書かない。
+43
View File
@@ -0,0 +1,43 @@
# 永続操作と再試行
永続操作には、同じ依頼を識別する情報と、安全な再試行に必要な事実を保存する。Rustの関数呼出しや待機位置を、そのまま永続状態として記録しない。再読取りで分かる情報や安全に繰り返せる処理は、再構成または再実行する。
## 記録の分類
| 種類 | 保存する理由 |
| --- | --- |
| 原子的な冪等性記録 | 正本の更新と結果が一つのDBトランザクションで確定する。同一依頼の再送には保存済み結果を返し、異なる依頼による操作IDの再利用は拒否する。途中状態は不要。 |
| 予約 | 後続の結付けに先立ち、資源IDや排他的な権利を確保する。予約先、依頼、権限、確定した結付けを記録する。 |
| 外部副作用を伴う操作 | DB外で起きた効果を再試行で重複させないため、安定した依頼ID、必要なチェックポイント、結果を残す。 |
| 親ワークフロー | 複数の操作を調整する。親の依頼、権限、安定した子操作ID、最終結果を持ち、子の状態は子の正本から読む。 |
同じDB内で原子的に確定できる処理を、永続操作を設けるためだけに分割しない。補償にも独立した副作用や再試行がある場合は、暗黙的な後始末ではなく、識別可能な子操作として扱う。
## 操作の識別
操作IDは所有するWorkspaceなどの権限範囲で識別する。依頼のfingerprintには、変わると別の依頼になる入力を含める。Serverが採番した結果ID、時刻、試行回数、変動する観測値、秘密の値は含めない。
厳密な再送で固定する権限・設定と、実行時に再検証する制約を分ける。固定した入力があっても、現在の割当、所有、接続、削除制約の検証を省略しない。子の作成も安定したIDまたは原子的な結付けで冪等にし、再送で別の子を増やさない。
## チェックポイントの条件
チェックポイントは、再試行の方法が変わる事実を記録する。次の条件をすべて満たす場合だけ追加する。
1. 現在のトランザクション外で副作用が発生し得る。
2. その事実を十分確実に再観測できない、または安全に繰り返せない。
3. 記録の前後で再試行の処理が変わる。
4. 記録の前後それぞれの挙動をテストできる。
「検証中」「終了処理中」などコード位置を表す段階名ではなく、削除確認、子操作との結付け、確定結果の識別子などの事実を保存する。要求を送信した事実と、副作用の完了を確認した事実は区別する。
## 状態・失敗・処置
操作が未完か完了か、直近の失敗、現在の阻害条件、保持・削除などの処置結果は別の情報である。阻害条件は実行前に現在の正本から再判定する。過去の失敗から再試行可能性を推測せず、所有するdomainの規則に従う。
外部providerには、利用できる冪等性キー、期待する内容、安定した資源IDを渡し、権威ある応答または観測で結果を確認する。応答喪失を失敗と決めつけて、新しい操作IDで副作用を繰り返さない。確認できなければ最後に確定した事実を保持し、結果不明または要確認として扱う。
## 保証の限界
対象は重複要求、返却エラー、timeout、既知の部分成功、最後に確定した記録からの再起動復旧である。任意の命令位置でのpanic、強制終了、マシン喪失、電源断に対して、一度だけ実行されることを一般的には保証しない。すべての`await`の前後に状態を書いて、その保証を装わない。
破壊的・機密性の高い操作に強い耐障害性が必要なら、providerの契約、記録順、再送規則、照合根拠を個別に定義する。診断には調査と再試行に必要な識別子・分類だけを残し、秘密、生のプロンプト、セッション全文、内部パスを複製しない。
+61
View File
@@ -0,0 +1,61 @@
# Workspace WebのUX設計
Workspace Webの画面構成と、リソースごとの表示・操作を決める規則を定める。視覚表現と操作の共通規則は[Design Language](design-language.md)に従い、この文書では製品固有の判断を扱う。
## 作業面の目的
Workspace Webは、Workspaceの確定した状態を確認し、注意が必要な箇所を判断し、次の操作を行うための作業面とする。マーケティング用のdashboard、分析画面、Backend DTOをそのまま並べる画面にはしない。
操作の流れは、対象のWorkspaceとリソースを選び、現在の状態を確認し、操作を行い、その結果を確認する順とする。通常の表示とURLには各リソースのcanonical keyを使い、内部UUIDをlabelや代替リンクとして露出しない。
## ナビゲーションの区分
- Globalでは、Workspaceの選択・作成、Account、Device Loginなど、Workspaceを選ぶ前の操作を扱う。
- Workspaceでは、Tickets、Objectives、Merge Requests、Drive、Memory、Workersなど、選択中のWorkspaceで日常的に扱う対象へ移動する。
- Settingsでは、Runtime、Repositoryとそのアクセス設定、Configuration Sources、Profile Sources、Workspace Identityなど、Workspaceの管理と構成を扱う。これらを日常作業のナビゲーションへ混ぜない。
存在しないWorkspace、閲覧できないWorkspace、読込みに失敗したWorkspaceは区別し、別のWorkspaceへ暗黙に切り替えない。読取り専用の場合も、利用できる閲覧機能を残す。
## ページの目的
各routeの主要目的は、「Ticketを選ぶ」「Workerを確認する」「Repositoryのアクセスを設定する」のように、動詞と対象を一つずつ使って表現できるものにする。
- 一覧・boardは、対象を探し、注意が必要な項目を見つけるために使う。
- 詳細は、一つの対象を理解し、現在実行できる操作を行うために使う。
- form・editorは、範囲の明確な変更を行うために使う。
- Consoleは、一つのWorkerを操作しながら履歴を確認するために使う。
一つのrouteで複数の形式を組み合わせるのは、同じ目的を支える場合に限る。
## 一覧と詳細
同じ項目をリソース間で比較する一覧には、平坦なlistまたはtableを使う。人が読む名前とcanonical keyを最初の列に置く。providerの詳細、変更ID、digestは比較用の列へ常設せず、詳細表示や診断用の開閉領域へ置く。
詳細では、対象の識別情報、現在の状態、注意が必要な事項を最初に示し、本文や履歴を主領域に置く。関連、target、review、workflowの状態をそれぞれ別の主体が確定する場合は、独立したsectionに分ける。
## Ticket board
boardは横方向にlaneを比較する作業面とする。laneはworkflow stateを表し、隣接laneとの関係を維持する。狭い画面でもboard内の横スクロールで比較できるようにする。
各Ticketにはkey、title、優先判断を変える情報を表示する。blockerとattentionは文字でも示す。
## Settingsと編集
一つのSettings routeは一つの設定関心事を扱う。編集操作の前または同時に現在有効な値を示し、一つの判断に必要な入力項目をまとめる。form内で塗りつぶしによって強調する操作は保存だけとする。
## Memory
Memoryは、明示的に選択したsubjectを起点に閲覧する。subjectの詳細では現在接続しているWorkerを示し、過去のWorkerやSessionの帰属情報を現在の接続として表示しない。
- `Surface`は生成されたresident contextの現在の状態を示す。生成済み、生成済みだが空、未生成、古くなった状態、生成失敗を区別する。取得要求の失敗を生成状態として扱わない。
- `Committed Memory`は現在の確定Memoryを一覧と詳細で示す。変更履歴は現在の内容とは別に閲覧できるようにし、過去の変更内容を現在値の代わりに表示しない。
- `Sources`では、候補とその処理結果、根拠となったMemoryと変更、Hostが記録したSessionへの帰属をたどれるようにする。Sessionの内容を表示するのは閲覧権限がある場合に限る。
## Worker Console
Consoleは会話と実行の履歴を主領域とする。コマンド出力はterminalに近い簡潔な表示にし、通常のメッセージ本文と分ける。
- 直接のSubWorkerの履歴を表示している間も、Composerと実行制御の対象は親Workerのままとする。
- OverviewとNormalの切替では見せ方だけを変え、操作対象や権限を変えない。
- 現在のWorker状態はWorkerの確定したsnapshotから表示し、WebSocketの接続状態や一時的なeventで置き換えない。
- 非公開の推論と生のsystem promptは、debug表示でも公開しない。