[v0.1/Tracker] Close release blockers before v0.1.0 #12

Open
opened 2026-09-03 16:10:52 +09:00 by natsukium · 6 comments
Owner

v0.1.0 release-readiness tracker

Review snapshot: 2645b986 plus the review working tree
Focused protobuf/IPC review: 5077d74b, tracked by #52
Compatibility assumption: pre-v0.1.0; public surfaces may still break without migration

This issue tracks the first public contract. Close it only after every P0 and P1 child below is closed, accepted decisions are recorded in their owning reference/explanation twins, and the exact tagged revision passes the release gates.

Decisions that are not being reopened

  • The daemon owns PTY/parser/grid/scrollback/image state; the client owns pixels and input.
  • One window shows one PTY. Mirroring is additive attach, not tabs, splits, or panes.
  • Typed CLI, bridge, protobuf, config, and keybinding values are the extension surfaces. There is no evaluator, content sniffing, or URL detection.
  • Keep the frozen preface, protobuf socket encoding, typed correlation, explicit row codec, effective-minor send authorization, and connection-local corruption handling.
  • Advertise only x86_64-linux as supported for v0.1.0. Other targets remain buildable but ungated.

P0 — release blockers

  • #13 — harden OSC 8 activation, preview, and logging
  • #14 — add aggregate daemon admission and handshake limits
  • #15 — bound PTY and GUI outbound queues
  • #16 — enforce outbound frame and operation-specific limits
  • #17 — define build identity and offline version output
  • #18 — add the tag-driven immutable artifact gate
  • #19 — make protobuf compatibility checks use the real CI base
  • #45 — reject preface acceptance for an unoffered major
  • #49 — bound receiver allocations from protobuf scalar claims

P1 — freeze before the first public contract

  • #20 — move detached spawn to correlated Ops and make create+attach atomic
  • #21 — bound bridge input/work/output and stop on stdout failure
  • #22 — close on shell exit and reconnect the same session after transport loss
  • #23 — simplify the CLI machine contract
  • #24 — track retarget completion with operation ids
  • #25 — add portable daemon stop/drain operations
  • #26 — make daemon status resource scopes unambiguous
  • #27 — add one explicit --config PATH surface
  • #28 — rename font.size to font.size_px
  • #29 — publish CLI/bridge JSON schemas and golden conversations
  • #30 — reset the first public wire baseline to protocol 2.0
  • #46 — extend the shared driver through application phases
  • #47 — reconcile frame-family taxonomy with routing
  • #48 — make correlation an exact per-arm identity
  • #50 — centralize effective-minor send authorization
  • #51 — make image transfers canonical and stateful
  • #52 — close the focused protobuf/IPC review after #45–#51

Release completion

  • #31 — run the exact-revision gates, cut v0.1.0, and publish immutable artifacts

Each implementation issue owns its reference/explanation/manual/schema/help/completions/man/skills/felis/CHANGELOG.md cascade where applicable. #31 performs the final cross-repository consistency sweep rather than postponing those cascades until release day.

  1. #13.
  2. #14, followed by or coordinated with #15, #16, and #49.
  3. #19 and #45.
  4. #17, then #18.
  5. Decide #47 and #48, then land #20 and #46 against those shapes.
  6. #21, #22, and #24.
  7. #23, #27, and #28.
  8. #25 and #26.
  9. #51 against #49's receiver limits.
  10. #50, then #29 after the bridge, CLI, and minor-evolution contracts settle.
  11. #30 after every other wire edit.
  12. Close #52, then run #31 after all P0/P1 work is closed.

Explicitly deferred past v0.1.0

These are not closure dependencies for this tracker:

  • #32 — preserve sessions across daemon replacement
  • #33 — split coordination hotspots after contracts freeze
  • #34 — retire temporary redesign transfer logs after decisions land
  • #35 — require a Point/Stream/Exempt class for future verbs
  • #36 — choose the scrollback-capacity control surface

Until #32 lands, the product claim remains: sessions survive client/window loss, not daemon loss.

Contract freeze boundary

The first tag freezes:

  • preface, protobuf schema, row codec, and evolution rules;
  • CLI command/option meanings, exit-status classes, and machine JSON epoch 1;
  • bridge JSON epoch 1 and stream lifecycle;
  • documented config keys, units, merge behavior, and defaults;
  • documented environment variables;
  • observable session/window/mirror/update behavior.

It does not freeze human output layout, log wording, unpublished Rust APIs, private module structure, or every crate's current pub visibility. felis-protocol remains free to evolve as a Rust API until it is separately published.

Earlier review issues

#3–#11 were question-oriented review notes for an assumed “1.0” freeze. This review checked those proposals against implementation, selected concrete v0.1.0 changes, and split them into the implementation-sized issues above. The older issues are closed as superseded; their discussion remains available as review history.

# v0.1.0 release-readiness tracker **Review snapshot:** `2645b986` plus the review working tree **Focused protobuf/IPC review:** `5077d74b`, tracked by #52 **Compatibility assumption:** pre-`v0.1.0`; public surfaces may still break without migration This issue tracks the first public contract. Close it only after every P0 and P1 child below is closed, accepted decisions are recorded in their owning reference/explanation twins, and the exact tagged revision passes the release gates. ## Decisions that are not being reopened - The daemon owns PTY/parser/grid/scrollback/image state; the client owns pixels and input. - One window shows one PTY. Mirroring is additive attach, not tabs, splits, or panes. - Typed CLI, bridge, protobuf, config, and keybinding values are the extension surfaces. There is no evaluator, content sniffing, or URL detection. - Keep the frozen preface, protobuf socket encoding, typed correlation, explicit row codec, effective-minor send authorization, and connection-local corruption handling. - Advertise only `x86_64-linux` as supported for v0.1.0. Other targets remain buildable but ungated. ## P0 — release blockers - [ ] #13 — harden OSC 8 activation, preview, and logging - [ ] #14 — add aggregate daemon admission and handshake limits - [ ] #15 — bound PTY and GUI outbound queues - [ ] #16 — enforce outbound frame and operation-specific limits - [ ] #17 — define build identity and offline version output - [ ] #18 — add the tag-driven immutable artifact gate - [ ] #19 — make protobuf compatibility checks use the real CI base - [ ] #45 — reject preface acceptance for an unoffered major - [ ] #49 — bound receiver allocations from protobuf scalar claims ## P1 — freeze before the first public contract - [ ] #20 — move detached spawn to correlated `Ops` and make create+attach atomic - [ ] #21 — bound bridge input/work/output and stop on stdout failure - [ ] #22 — close on shell exit and reconnect the same session after transport loss - [ ] #23 — simplify the CLI machine contract - [ ] #24 — track retarget completion with operation ids - [ ] #25 — add portable daemon stop/drain operations - [ ] #26 — make daemon status resource scopes unambiguous - [ ] #27 — add one explicit `--config PATH` surface - [ ] #28 — rename `font.size` to `font.size_px` - [ ] #29 — publish CLI/bridge JSON schemas and golden conversations - [ ] #30 — reset the first public wire baseline to protocol 2.0 - [ ] #46 — extend the shared driver through application phases - [ ] #47 — reconcile frame-family taxonomy with routing - [ ] #48 — make correlation an exact per-arm identity - [ ] #50 — centralize effective-minor send authorization - [ ] #51 — make image transfers canonical and stateful - [ ] #52 — close the focused protobuf/IPC review after #45–#51 ## Release completion - [ ] #31 — run the exact-revision gates, cut `v0.1.0`, and publish immutable artifacts Each implementation issue owns its reference/explanation/manual/schema/help/completions/man/`skills/felis`/`CHANGELOG.md` cascade where applicable. #31 performs the final cross-repository consistency sweep rather than postponing those cascades until release day. ## Recommended dependency order 1. #13. 2. #14, followed by or coordinated with #15, #16, and #49. 3. #19 and #45. 4. #17, then #18. 5. Decide #47 and #48, then land #20 and #46 against those shapes. 6. #21, #22, and #24. 7. #23, #27, and #28. 8. #25 and #26. 9. #51 against #49's receiver limits. 10. #50, then #29 after the bridge, CLI, and minor-evolution contracts settle. 11. #30 after every other wire edit. 12. Close #52, then run #31 after all P0/P1 work is closed. ## Explicitly deferred past v0.1.0 These are not closure dependencies for this tracker: - #32 — preserve sessions across daemon replacement - #33 — split coordination hotspots after contracts freeze - #34 — retire temporary redesign transfer logs after decisions land - #35 — require a Point/Stream/Exempt class for future verbs - #36 — choose the scrollback-capacity control surface Until #32 lands, the product claim remains: sessions survive client/window loss, not daemon loss. ## Contract freeze boundary The first tag freezes: - preface, protobuf schema, row codec, and evolution rules; - CLI command/option meanings, exit-status classes, and machine JSON epoch 1; - bridge JSON epoch 1 and stream lifecycle; - documented config keys, units, merge behavior, and defaults; - documented environment variables; - observable session/window/mirror/update behavior. It does not freeze human output layout, log wording, unpublished Rust APIs, private module structure, or every crate's current `pub` visibility. `felis-protocol` remains free to evolve as a Rust API until it is separately published. ## Earlier review issues #3–#11 were question-oriented review notes for an assumed “1.0” freeze. This review checked those proposals against implementation, selected concrete v0.1.0 changes, and split them into the implementation-sized issues above. The older issues are closed as superseded; their discussion remains available as review history.
natsukium changed title from Pre-release: close release blockers before v0.1.0 to [v0.1/Tracker] Close release blockers before v0.1.0 2026-09-03 16:19:28 +09:00
Author
Owner

CLI argument grammar の focused review を #55 に整理した。新規 P1 は #53 (sessions spawn の command separator 統一) と #54 (ignored root --trace-perf の除去/scope 制限)。既存 #17/#23/#27/#37–#39/#42 に統合すべき acceptance gap も #55 と各 comment に記録した。

CLI command/option meanings がこの tracker の freeze boundary に含まれるため、#53/#54 を P1 closure dependency として扱いたい。

CLI argument grammar の focused review を #55 に整理した。新規 P1 は #53 (`sessions spawn` の command separator 統一) と #54 (ignored root `--trace-perf` の除去/scope 制限)。既存 #17/#23/#27/#37–#39/#42 に統合すべき acceptance gap も #55 と各 comment に記録した。 CLI command/option meanings がこの tracker の freeze boundary に含まれるため、#53/#54 を P1 closure dependency として扱いたい。
Author
Owner

Issue triage adds #42 as a P1 closure dependency: shell completion must not start an unbounded or interactive SSH connection on <TAB>, and the implementation must match the explanation document’s local-only contract. The broader SSH review (#44) is closed after folding carrier grammar into #23, deferring the macOS endpoint bug (#41) to P2, retaining the already-recorded --ssh-arg/ControlMaster and stable-agent decisions, and closing the incorrect cross-host env-leak report. Together with the earlier #53/#54 comment, the release tracker now has three post-snapshot CLI blockers: #42, #53, and #54.

Issue triage adds #42 as a P1 closure dependency: shell completion must not start an unbounded or interactive SSH connection on `<TAB>`, and the implementation must match the explanation document’s local-only contract. The broader SSH review (#44) is closed after folding carrier grammar into #23, deferring the macOS endpoint bug (#41) to P2, retaining the already-recorded `--ssh-arg`/ControlMaster and stable-agent decisions, and closing the incorrect cross-host env-leak report. Together with the earlier #53/#54 comment, the release tracker now has three post-snapshot CLI blockers: #42, #53, and #54.
Author
Owner

Triage plan update (2026-09-03)

Every open child (#13–#51, 31 issues) now carries a source-grounded plan comment and the status/planned label. The plan passed an independent reviewer (pi sol) after seven rounds; 19 blockers were resolved along the way and are recorded in each issue's "Review amendments" sections. No priority or release label changed: every P0/P1 stays a v0.1.0 blocker, every P2 stays deferred.

Dependency order (supersedes the orders in #12 and #52 where they conflict)

  1. #42, #19, #45 — independent, small, and they gate later work (#42 before #23; #19 before every proto edit; #45 before #30's vectors).
  2. #13.
  3. #16#49; #14#15 (with #16's MAX_PASTE_BYTES pinned); #26 after #14.
  4. Decide #47 and #48 (one design commit each, docs first).
  5. #20 (against the decided shapes; it may add its own arms with hand-written metadata that step 6 replaces).
  6. Implement #47 and #48 (ArmMeta, oneof id, CorrelationClass) → #46 (driver phases on that metadata) → #21 (after #16 and #20).
  7. #51 (on #49's shared caps).
  8. #24's v0.1.0 half: protocol and result shape (operation_id, queued) first, as its own commit.
  9. #23 in two named commits: (a) rename/cleanup that consumes #24's final shape (acceptedqueued, short_id removal, exit-code table); (b) the clap/usage/log/ValueEnum/--to-host work. #27 after #23. #22 (client-only) any time after #24(8).
  10. #25 after #20, #23, #26.
  11. #17, then #18.
  12. #30 after every wire edit above (#45–#51, #14, #20, #24, #26).
  13. #50 on the 2.0 tree, then #29 last among schemas.
  14. Close #52 and #55, then #31.

The conflict between #12 (step 10: #50 then #29) and #52 (#50 before #30) resolves as
#30#50#29: #50 needs the final arm set and 2.0's clean ledger, and #29's golden
conversations must be recorded against the frozen wire. The #23/#24 cycle is broken by
splitting #23: its rename/cleanup half follows #24's shape, and #24 never waits on #23.

Freeze-boundary additions

The Linux default daemon endpoint rule ($XDG_RUNTIME_DIR/felis, else ${TMPDIR:-/tmp}/felis.<uid>) is observable behavior and is frozen at v0.1.0; #41 must not alter it.

## Triage plan update (2026-09-03) Every open child (#13–#51, 31 issues) now carries a source-grounded plan comment and the `status/planned` label. The plan passed an independent reviewer (`pi` sol) after seven rounds; 19 blockers were resolved along the way and are recorded in each issue's "Review amendments" sections. No priority or release label changed: every P0/P1 stays a v0.1.0 blocker, every P2 stays deferred. ## Dependency order (supersedes the orders in #12 and #52 where they conflict) 1. #42, #19, #45 — independent, small, and they gate later work (#42 before #23; #19 before every proto edit; #45 before #30's vectors). 2. #13. 3. #16 → #49; #14 → #15 (with #16's `MAX_PASTE_BYTES` pinned); #26 after #14. 4. Decide #47 and #48 (one design commit each, docs first). 5. #20 (against the decided shapes; it may add its own arms with hand-written metadata that step 6 replaces). 6. Implement #47 and #48 (`ArmMeta`, `oneof id`, `CorrelationClass`) → #46 (driver phases on that metadata) → #21 (after #16 and #20). 7. #51 (on #49's shared caps). 8. #24's v0.1.0 half: protocol and result shape (`operation_id`, `queued`) first, as its own commit. 9. #23 in two named commits: (a) rename/cleanup that consumes #24's final shape (`accepted` → `queued`, `short_id` removal, exit-code table); (b) the clap/usage/log/`ValueEnum`/`--to-host` work. #27 after #23. #22 (client-only) any time after #24(8). 10. #25 after #20, #23, #26. 11. #17, then #18. 12. #30 after every wire edit above (#45–#51, #14, #20, #24, #26). 13. #50 on the 2.0 tree, then #29 last among schemas. 14. Close #52 and #55, then #31. The conflict between #12 (step 10: #50 then #29) and #52 (#50 before #30) resolves as #30 → #50 → #29: #50 needs the final arm set and 2.0's clean ledger, and #29's golden conversations must be recorded against the frozen wire. The #23/#24 cycle is broken by splitting #23: its rename/cleanup half follows #24's shape, and #24 never waits on #23. ## Freeze-boundary additions The Linux default daemon endpoint rule (`$XDG_RUNTIME_DIR/felis`, else `${TMPDIR:-/tmp}/felis.<uid>`) is observable behavior and is frozen at v0.1.0; #41 must not alter it.
Author
Owner

Triage update (2026-09-05)

Corrections to the body

  • #30 did not reset the wire to 2.0. f56f5529 (the #138 decision) keeps protocol 1.9 as the first public baseline and folds the pre-release base: lines into first-release. #147, which asked the same question, is closed onto that commit. Order steps 11-13 read as: #50 and then #29 on the 1.9 tree.
  • #13-#28, #42, #45-#49, #51, #53, #54 are merged; only #21, #22, #25, #50, #29, #31 remain from the original set.

New P1 children from the 2026-09-05 review (labeled priority/P1 + release/v0.1.0; each carries a verdict comment)

  • CLI (parent #55): #136 (--config on frontend: reject), #141 (remote auto-spawn contract: fix the reference, add the policy matrix test), #145 (Point-diagnostic row, one wire→ErrorKind map).
  • Config: #137 (Windows path flatten, macOS single location), #140 (schema client type matches runtime), #143 (accept TOML int for size_px, freeze indexed keys as strings).
  • Proto/IPC (parent #52): #139 (FRLY cap: freeze, document, typed diagnostic; no cap change), #144 (recommend freeze as-is, decision pending), #146 (docs-only freeze).

Where they slot in the order: all before #29, since #29 records the schemas and goldens they change; none touches the wire, so #50 is unaffected. #139's diagnostic and #137's path change are the only behavior changes.

Post-release follow-up: #115 (baseline commit after v0.1.0 publishes) is P2 but due immediately after #31.

Deferred (P2): #110-#114, #116-#123 (migrated from the deleted docs/backlog.md; #119/#121/#122/#123 are blocked on upstream winit/wgpu/rustc), #78 (CI flake under runner load).

## Triage update (2026-09-05) **Corrections to the body** - #30 did not reset the wire to 2.0. `f56f5529` (the #138 decision) keeps protocol 1.9 as the first public baseline and folds the pre-release `base:` lines into `first-release`. #147, which asked the same question, is closed onto that commit. Order steps 11-13 read as: #50 and then #29 on the 1.9 tree. - #13-#28, #42, #45-#49, #51, #53, #54 are merged; only #21, #22, #25, #50, #29, #31 remain from the original set. **New P1 children from the 2026-09-05 review** (labeled `priority/P1` + `release/v0.1.0`; each carries a verdict comment) - CLI (parent #55): #136 (`--config` on `frontend`: reject), #141 (remote auto-spawn contract: fix the reference, add the policy matrix test), #145 (Point-diagnostic row, one wire→`ErrorKind` map). - Config: #137 (Windows path flatten, macOS single location), #140 (schema `client` type matches runtime), #143 (accept TOML int for `size_px`, freeze `indexed` keys as strings). - Proto/IPC (parent #52): #139 (FRLY cap: freeze, document, typed diagnostic; no cap change), #144 (recommend freeze as-is, decision pending), #146 (docs-only freeze). **Where they slot in the order**: all before #29, since #29 records the schemas and goldens they change; none touches the wire, so #50 is unaffected. #139's diagnostic and #137's path change are the only behavior changes. **Post-release follow-up**: #115 (baseline commit after v0.1.0 publishes) is P2 but due immediately after #31. **Deferred (P2)**: #110-#114, #116-#123 (migrated from the deleted `docs/backlog.md`; #119/#121/#122/#123 are blocked on upstream winit/wgpu/rustc), #78 (CI flake under runner load).
Author
Owner

Triage update (2026-09-05, evening)

The nine P1 children from the second review pass now carry a "Triage plan (2026-09-05)" comment and status/planned. Three premises did not survive source grounding: #136 (--config on frontend is already refused since f2083767), #139 (the relay degrades on an over-cap carrier block; nothing reports daemon_unreachable), #143 item 1 (toml 1.1.5 accepts size_px = 14). Each plan says what remains.

Order correction. #144 (sequenceoptional NonZeroU64, attached_atgoogle.protobuf.Timestamp, idle_seconds absent = attached) and #146 (SpawnArgs.dimsoptional GridDims, create sentinel dropped) do break the wire, each with a base: line in BREAKING.md, so they land before #50 as well as before #29. Remaining order: #22, #25#136 #137 #139 #140 #141 #143 #145 (any order, small PRs) → #144, #146#50#29 → close #52/#55 → #31.

Skew posture for both wire changes: pre-release semantic break on the 1.9 tree; daemon and client are rebuilt together; no skew code (no released peer exists, per the #138 decision).

## Triage update (2026-09-05, evening) The nine P1 children from the second review pass now carry a "Triage plan (2026-09-05)" comment and `status/planned`. Three premises did not survive source grounding: #136 (`--config` on `frontend` is already refused since `f2083767`), #139 (the relay degrades on an over-cap carrier block; nothing reports `daemon_unreachable`), #143 item 1 (`toml 1.1.5` accepts `size_px = 14`). Each plan says what remains. **Order correction.** #144 (`sequence` → `optional NonZeroU64`, `attached_at` → `google.protobuf.Timestamp`, `idle_seconds` absent = attached) and #146 (`SpawnArgs.dims` → `optional GridDims`, create sentinel dropped) *do* break the wire, each with a `base:` line in `BREAKING.md`, so they land before #50 as well as before #29. Remaining order: #22, #25 → #136 #137 #139 #140 #141 #143 #145 (any order, small PRs) → #144, #146 → #50 → #29 → close #52/#55 → #31. Skew posture for both wire changes: pre-release semantic break on the 1.9 tree; daemon and client are rebuilt together; no skew code (no released peer exists, per the #138 decision).
Author
Owner

Freeze-list addition from #275 (plan v3, comment #275 (comment)): the default daemon endpoint derivation joins the first tag's frozen contract, stated once before the tag rather than inferred later. The rule as of that change: Linux $XDG_RUNTIME_DIR/felis when set → /run/user/<uid>/felis when that directory exists, is owned by the uid, and is mode 0700${TMPDIR:-/tmp}/felis.<uid>; macOS $TMPDIR/felis.<uid> when set → confstr(_CS_DARWIN_USER_TEMP_DIR)/felis.<uid>/tmp/felis.<uid>; Windows unchanged. Empty variables read as unset; a relative XDG_RUNTIME_DIR reads as unset (today's behavior). The earlier "frozen at v0.1.0" wording in #41's triage referred to the pre-#275 rule and was a triage decision, not a shipped promise; no tag exists yet.

Freeze-list addition from #275 (plan v3, comment https://git.natsukium.com/natsukium/felis/issues/275#issuecomment-2818): the **default daemon endpoint derivation** joins the first tag's frozen contract, stated once before the tag rather than inferred later. The rule as of that change: Linux `$XDG_RUNTIME_DIR/felis` when set → `/run/user/<uid>/felis` when that directory exists, is owned by the uid, and is mode `0700` → `${TMPDIR:-/tmp}/felis.<uid>`; macOS `$TMPDIR/felis.<uid>` when set → `confstr(_CS_DARWIN_USER_TEMP_DIR)/felis.<uid>` → `/tmp/felis.<uid>`; Windows unchanged. Empty variables read as unset; a relative `XDG_RUNTIME_DIR` reads as unset (today's behavior). The earlier "frozen at v0.1.0" wording in #41's triage referred to the pre-#275 rule and was a triage decision, not a shipped promise; no tag exists yet.
Sign in to join this conversation.
No description provided.