[1.0 Review] IPC wire 凍結層(preface / frame / correlation / versioning)の最終確認 #5
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis#5
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
IPC は felis の唯一の拡張 surface かつ daemon/client 間の唯一の永続境界。
reference/ipc.mdとexplanation/architecture/ipc.mdに carrier / framing / versioning が仕様化され、felis.proto(felis.v1)が唯一の機械可読 authority。1.0 で wire を凍結する前に、凍結層と進化則を再確認する。現状の問題 / 凍結前に決めるべき点
1. frozen preface と frame header の endian 非対称
FLIS8B +FLIS10B + optionalFRLYcarrier block)は big-endian(network order)で凍結。len:u32 | kind:u16)は little-endian。意図的な乖離として文書化されているが、1.0 で「なぜ2つの endian が混在するか」を新 contributor が誤解する余地がある。統一(全て little-endian)への破壊的変更は今しかできない。現行の「preface は自己完結した frozen artifact なので network order、frame は毎秒百万回 decode される hot path なので host order」は妥当だが、1.0 で凍結理由をもう一度明記するか、統一するかを決める。
2.
FRLYcarrier block の凍結 limitsMAX_CARRIER_ENTRIES = 4096/MAX_CARRIER_PAYLOAD_BYTES = 1MiBが protocol major 単位で凍結。relay が送信前、daemon が受信時に両方で検査し、payload 長を先に読んでから payload を確保する。limit 自体は妥当だが、値を 1.0 で確定させる決定としてreference/ipc.mdの表に「なぜ 4096 / 1MiB か」の根拠(env の現実的な上限と DoS 耐性)を追記すべき。3. protobuf vs row codec の二層
RowEntry.packed_cells)だけが hand-written codec(reference/row-codec.md)で golden vector を持つ二層。felis-protocolがtokio/ OS 依存を持たない purity は、satellite client(felis-tui,felis.elviabridge)のために必須。問い: row codec を protobuf 内の
bytesではなくrepeated Cellにする代替は、1.0 で完全に閉じるか? 現行の「RLE + version tag + limits-before-alloc」設計は性能と前方互換のために必要だが、1.0 でrow-codec.mdを「この interior は protobuf ではない」として凍結宣言する必要がある。4. correlation envelope(field 100)
全 family wrapper の field 100 に
Correlation {request_id, stream_id}を予約。Connは deliberately 持たず、Grid/Image/Push/Inputも持たない。client が2つの独立 sequence(各 1 始まり、再利用なし、枯渇で切断)を持つ。破壊的見直し余地:
RequestIdとStreamIdを1つのIdに統一すると、実装は簡単になるが「inactive id が terminated なのか never-opened なのか」を区別できなくなり ABA が再発する(現行の2 sequence 分離の根拠)。1.0 でこの分離を凍結として明記するか。stream_idを daemon-assigned にすると client からの cancel-before-first-item が不可能になる。現行の client-allocated を維持する決定を再確認。5. versioning 則(major / minor / feature flag)
min(client, daemon)の send-side contract。pull_pacedのみ)。1.0 前は dev wire で major 1 のまま break を重ねている。今後
PROTOCOL_MAJOR = 2への bump は「pool する価値がある semantic break が溜まったら」とされているが、1.0 で1.xの minor ledger(reference/ipc.mdの ledger 表)をどこまで埋めてから freeze するか。6. frame kind の凍結
FrameKind(Conn=0, Input=1, Grid=2, Image=3, Session=4, Ops=5, Region=6, Notify=7, Push=8, Search=9)と各 family の oneof field number(Rust variant の1-based source order)が major 単位で凍結。reservedで retired number を再利用しない。新しい one-shot / push は新kindを生やす規則。1.0 でこの「新 kind を生やす」規則を破る既存 family への variant 追加が無いか最終監査する。提案
reference/ipc.mdの「Version preface」「Frame layer」「Correlation」「Versioning」各節に「1.0 で凍結(frozen)」ラベルを付与し、変更時は major bump が必要であることを明示。felis.protoの packagefelis.v1が crate version(0.1.0)と独立していることをreference/workspace.mdの Versioning 節に再掲し、1.0 での crate publish 時に semver と protocol version を混同しないガードを追加。just protoの生成物が stale なら CI で落とす現行のprotojob を、1.0 ではbuf breaking(前 commit からの wire-compat)も必須 gate に昇格。FRLYの limits と endian 選択の rationale をexplanation/architecture/ipc.mdの「Handshake bootstrap」節に追記し、将来の変更が「凍結層なので不可」であることを明確化。判定基準
explanation/architecture/ipc.mdの「Rejected」節を読んだ新 contributor が、なぜ代替案が却下されたかを再発明せずに理解できること。felis.protoとrow-codec.mdの golden vector が、1.1 の minor 追加と衝突しないこと(field 100 の予約、kind 番号の空き)。cc @natsukium
Superseded by #16, #19, #20, and #30. Those issues separate outbound limits, the compatibility gate, correlated spawn, and the clean protocol-2.0 baseline; #12 is the parent tracker.