[1.0 Review] daemon リソース上限の compiled-in 固定と daemon status 報告の凍結 #10

Closed
opened 2026-09-03 16:04:37 +09:00 by natsukium · 1 comment
Owner

背景

daemon は複数のリソースに対して上限(ceiling)を持ち、超過時は typed refusal で拒否する。reference/spec.md REQ-915 / REQ-1008 等と reference/cli.md「Daemon status」節に上限と観測値の報告が仕様化されているが、上限自体は compiled-in(daemon は config file を読まない)。

現状の問題 / 凍結前に決めるべき点

1. compiled-in caps

resource limit scope 観測
sessions 256 daemon daemon status rows
image_store_bytes 256 MiB per session rows
in_flight_decodes 256 (session cap と同数) daemon rows
in_flight_decode_bytes 64 MiB per session rows
subscriber_queue_bytes 512 MiB per subscriber deepest
grid geometry 2048x2048 (REQ-605a) per session info.dims
frame body 64 MiB (DEFAULT_MAX_BODY) per connection

全て reference/workspace.md「Cargo configuration」や felis-daemon の定数で決まる。control-surfaces.md「Diagnostic verbs」で「daemon は config を読まないので caps は報告するだけで tunable にしないのは v1 では十分」と明記。

問い: 1.0 でこの「caps は compiled-in、報告のみ」を凍結するか? 運用で 256 sessions では足りないユースケース(CI で大量 spawn)が現れた時に、再ビルド無しで上げられない。1.0 で daemon に config / env での tunable を持たせるなら今しか破壊的に決められない。

代替:

  • FELIS_DAEMON_SESSIONS=512 felis-daemon serve のような env override。
  • ~/.config/felis/daemon.toml のような daemon config(ただし control-surfaces.md の「daemon は config を読まない」原則を崩す)。
  • felis daemon set-limit のような IPC verb(ただし daemon が持つ limit を動的に変えるのは複雑)。

現行の「報告はするが tunable にしない」は、1つの定数なら正当だが 3つ目の tunable が欲しくなった時点で config file を導入する Revisit trigger として記録されている。1.0 でこの trigger を維持するか、今のうちに env override だけでも足すか。

2. daemon status の sampling vs counter

daemon status は pool と session actor から sampling した瞬間値を報告。hot path に counter を置かない代わりに status 呼び出し時に actor message を集約する。control-surfaces.md で「counters は drift したら authoritative に見えて危険」と却下。

1.0 でこの sampling 方式を凍結するか、将来の subscriber_queue_bytes のように頻繁に動く値で sampling の race が問題になるか。

3. image_store_bytesin_flight_decode_bytes の二重 cap

t=d の chunked upload は in_flight_decode_bytes(64MiB per session)で、store 自体が image_store_bytes(256MiB per session)で、それぞれ eviction / refusal の挙動が違う。1.0 でこの二重 cap の値を変える余地は無いか。特に in_flight の 64MiB は t=s(shm)経由なら不要に見えるが、攻撃者が m=1 で無限に chunk を送る DoS 耐性のために必要。

4. slow-subscriber eviction

現行は出力量(OutEvent::approx_wire_len の推定)で SUBSCRIBER_BUFFER_CAP を超えたら cut。backlog.md に「byte-bounded + write deadline の policy に置き換える案は deferred(観測された必要が無い)」と記載。1.0 で volume-only を凍結するか、deadline 付きに今直すか。

提案

  • 1.0 で「caps は compiled-in」を凍結するなら、reference/spec.md REQ-915 と reference/cli.md「Daemon status」に「1.0 凍結、tunable にしない理由」を明記し、将来の tunable 追加は explanation/architecture/control-surfaces.md の Revisit trigger(「2つ目の tunable が欲しくなったら daemon config を検討」)に委ねる。
  • env override を今足すなら、FELIS_DAEMON_* の naming を FELIS_TERM / FELIS_SOCKET と整合する形で決め、reference/terminal-identity.md ではなく reference/cli.md「Daemon status」の表に「limit の由来(compiled-in vs env)」を追記。
  • daemon statuslimit が omitted になるケース(ceiling 無し resource)を 1.0 で許すか、将来の row 追加は必ず limit を持つことを契約にするか決める。

判定基準

  • 1.0 の felis daemon status の出力を見て、運用者が「なぜ spawn が at_capacity で拒否されたか」を limitused の差で即断できること。
  • 将来 sessions cap を 256→512 に上げる時に、wire の AttachFailure::SessionLimitReacheddetail(count/limit)がそのまま新しい値を運べること。

cc @natsukium

## 背景 daemon は複数のリソースに対して上限(ceiling)を持ち、超過時は typed refusal で拒否する。`reference/spec.md` REQ-915 / REQ-1008 等と `reference/cli.md`「Daemon status」節に上限と観測値の報告が仕様化されているが、上限自体は compiled-in(daemon は config file を読まない)。 ## 現状の問題 / 凍結前に決めるべき点 ### 1. compiled-in caps | resource | limit | scope | 観測 | |---|---|---|---| | sessions | 256 | daemon | `daemon status` rows | | image_store_bytes | 256 MiB | per session | rows | | in_flight_decodes | 256 (session cap と同数) | daemon | rows | | in_flight_decode_bytes | 64 MiB | per session | rows | | subscriber_queue_bytes | 512 MiB | per subscriber | deepest | | grid geometry | 2048x2048 (REQ-605a) | per session | `info.dims` | | frame body | 64 MiB (`DEFAULT_MAX_BODY`) | per connection | | 全て `reference/workspace.md`「Cargo configuration」や `felis-daemon` の定数で決まる。`control-surfaces.md`「Diagnostic verbs」で「daemon は config を読まないので caps は報告するだけで tunable にしないのは v1 では十分」と明記。 **問い:** 1.0 でこの「caps は compiled-in、報告のみ」を凍結するか? 運用で 256 sessions では足りないユースケース(CI で大量 spawn)が現れた時に、再ビルド無しで上げられない。1.0 で daemon に config / env での tunable を持たせるなら今しか破壊的に決められない。 代替: - `FELIS_DAEMON_SESSIONS=512 felis-daemon serve` のような env override。 - `~/.config/felis/daemon.toml` のような daemon config(ただし `control-surfaces.md` の「daemon は config を読まない」原則を崩す)。 - `felis daemon set-limit` のような IPC verb(ただし daemon が持つ limit を動的に変えるのは複雑)。 現行の「報告はするが tunable にしない」は、1つの定数なら正当だが 3つ目の tunable が欲しくなった時点で config file を導入する Revisit trigger として記録されている。1.0 でこの trigger を維持するか、今のうちに env override だけでも足すか。 ### 2. `daemon status` の sampling vs counter `daemon status` は pool と session actor から sampling した瞬間値を報告。hot path に counter を置かない代わりに `status` 呼び出し時に actor message を集約する。`control-surfaces.md` で「counters は drift したら authoritative に見えて危険」と却下。 1.0 でこの sampling 方式を凍結するか、将来の `subscriber_queue_bytes` のように頻繁に動く値で sampling の race が問題になるか。 ### 3. `image_store_bytes` と `in_flight_decode_bytes` の二重 cap `t=d` の chunked upload は `in_flight_decode_bytes`(64MiB per session)で、store 自体が `image_store_bytes`(256MiB per session)で、それぞれ eviction / refusal の挙動が違う。1.0 でこの二重 cap の値を変える余地は無いか。特に `in_flight` の 64MiB は `t=s`(shm)経由なら不要に見えるが、攻撃者が `m=1` で無限に chunk を送る DoS 耐性のために必要。 ### 4. slow-subscriber eviction 現行は出力量(`OutEvent::approx_wire_len` の推定)で `SUBSCRIBER_BUFFER_CAP` を超えたら cut。`backlog.md` に「byte-bounded + write deadline の policy に置き換える案は deferred(観測された必要が無い)」と記載。1.0 で volume-only を凍結するか、deadline 付きに今直すか。 ## 提案 - 1.0 で「caps は compiled-in」を凍結するなら、`reference/spec.md` REQ-915 と `reference/cli.md`「Daemon status」に「1.0 凍結、tunable にしない理由」を明記し、将来の tunable 追加は `explanation/architecture/control-surfaces.md` の Revisit trigger(「2つ目の tunable が欲しくなったら daemon config を検討」)に委ねる。 - env override を今足すなら、`FELIS_DAEMON_*` の naming を `FELIS_TERM` / `FELIS_SOCKET` と整合する形で決め、`reference/terminal-identity.md` ではなく `reference/cli.md`「Daemon status」の表に「limit の由来(compiled-in vs env)」を追記。 - `daemon status` の `limit` が omitted になるケース(ceiling 無し resource)を 1.0 で許すか、将来の row 追加は必ず `limit` を持つことを契約にするか決める。 ## 判定基準 - 1.0 の `felis daemon status` の出力を見て、運用者が「なぜ spawn が `at_capacity` で拒否されたか」を `limit` と `used` の差で即断できること。 - 将来 `sessions` cap を 256→512 に上げる時に、wire の `AttachFailure::SessionLimitReached` の `detail`(count/limit)がそのまま新しい値を運べること。 cc @natsukium
Author
Owner

Superseded by #14–#16 and #25–#26. These split aggregate admission, bounded queues, payload limits, portable stop/drain, and dimensionally correct status reporting under #12.

Superseded by #14–#16 and #25–#26. These split aggregate admission, bounded queues, payload limits, portable stop/drain, and dimensionally correct status reporting under #12.
Sign in to join this conversation.
No description provided.