[v0.1/P1] Reset the first public wire baseline to protocol 2.0 #30
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#30
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?
Parent: #12 (P1.9). Supersedes the pre-release versioning question in #5 and #9.
Why
Protocol major 1 was reused across incompatible untagged development snapshots. Freezing its minor-1-through-5 downgrade branches would preserve compatibility code without identifying a real supported peer.
Scope
felis.v2, protocol major 2 minor 0.Acceptance criteria
Triage plan (2026-09-03)
Source-grounded triage against
mainat69076d42, reviewed through seven rounds of an independent reviewer (pisol/luna) until it passed with no findings. The dependency order that supersedes the tracker's is posted on #12. Where a "Review amendments" section below conflicts with an earlier section, the amendment is the decision.Claim check
Accurate against HEAD. The three post-snapshot commits (#28, #53/#54) touched config and CLI only; the wire is unchanged.
PROTOCOL_MAJOR = 1,PROTOCOL_MINOR = 5(crates/felis-protocol/src/preface.rs:52,:57; mirrored atfelis.proto:40-41and asserted bythe_protocol_version_matches_the_schema,preface.rs:758-777). Packagefelis.v1(felis.proto:3), generated atcrates/felis-protocol/src/generated/felis/v1/, exposed aswire::v1(src/wire.rs).MINOR_GEOMETRY_OUT_OF_RANGE,MINOR_LIVE_ONLY_ATTACH,MINOR_ENV_BASE,MINOR_DAEMON_STATUS(preface.rs:59-80);SWITCH_SCOPE_MINOR+check_scope_minor(crates/felis-client-core/src/connector.rs:138-156, re-exportedlib.rs:60, used bycli_bridge.rs:2067-2085);daemon_statusgate (connector.rs:996-1005);geometry_refusal/session_limit_refusal/exited_refusal(crates/felis-daemon/src/serve.rs:1012-1039) and their call sites (:475,:496,:594); the pre-minor-2 scope decode testan_absent_switch_scope_decodes_as_the_all_mirror_form(convert.rs:377-400) and itsscope: None → Allbranch inconvert/ops.rs; proto "Minor N" annotations (felis.proto:209, 215, 222, 523, 578, 1097, 1155, 1204); the ledger rows 1-5 (docs/reference/ipc.md:1748-1752); the effective-minor tests atconnector.rs:2077-2164that assume minors 0..5 exist.preface.rs:488-490(00 01 00 05),:512-514; row-codec vectors:crates/felis-grid/src/wire.rs(golden).felis daemon statusprints the wire major/minor (CHANGELOG Unreleased entry;skills/felis/SKILL.md:220), so its JSON changes from 1.5 to 2.0.RefusalReason 1, 2(felis.proto:169-170),SearchMsg 3 "done"(:1630-1631),OpsStatusReply 6, 7(:1416). The issue's "fold every shipped field into the baseline" implies these can be compacted; it does not say so explicitly.buf breakingusesWIRE_JSON(buf.yaml) and thepr.yml:45-60proto job; a package rename is a breaking change by every rule, so this lands only through #19's explicit pre-release acknowledgement path.docs/reference/ipc.md:1680-1687anddocs/explanation/architecture/ipc.md:914-922say a post-freeze major owes a deprecation window; 2.0 is the first freeze, so no window is owed. Consistent.Verdict
accept-with-changes: do it as scoped, plus two explicit decisions the issue leaves implicit: (a) compact the dev-only
reservednumbers in the same change (there is no v1 peer to protect; areservedline in a first public schema is history, which the docs rule says belongs togit log), and (b) state in the explanation that 2.0 opens with no deprecation window and that the first post-2.0 major is the first that owes one. Land strictly last, as the trackers say.Approach
Mechanical, one commit series on top of every other wire edit:
package felis.v2, header commentPROTOCOL_MAJOR = 2/PROTOCOL_MINOR = 0, delete the eight "Minor N" annotations and thereservedlines above (renumberRefusalReason,SearchMsg,OpsStatusReplyto dense source order, per the "1-based source order" rule atfelis.proto:18-22).buf.gen.yamloutput path stays;just protoregenerates intogenerated/felis/v2/;src/wire.rsexportspub mod v2(grepwire::v1acrosscrates/and update;convert/*.rs,codec.rs:96-100,:150-199,lib.rs:174,messagestests). Delete thefelis/v1generated directory.preface.rs:PROTOCOL_MAJOR = 2,PROTOCOL_MINOR = 0, deleteMINOR_*(:59-80); update the golden bytes at:488-490,:512-514;this_build_serves_exactly_its_own_major(:780-784) stays.AttachFailuresends its real reason unconditionally;daemon_statussends unconditionally;SwitchScopedecode: absent scope is a malformed frame orDefault(pickDefaultonly if #24/#26 did not already settle it; otherwise malformed, since 2.0 has no peer that omits it). RemoveConnectError::MinorTooOldonly if #50 does not reuse it (it does; keep).connector.rs:2077-2164,cli_bridge.rs:2067-2085) as the #50 synthetic-fixture tests;serve/tests.rs:401(unsupported major) now sends major 1 and expectsRefuse { 2, 2 }, which is the "development-major peer is refused" criterion;preface.rsduplex tests infelis-transport/src/preface.rs:115-134follow the constants.docs/reference/ipc.md:320-336(packagefelis.v2),:1680-1687(drop "until the compatibility freeze ... under major 1"),:1745-1752ledger collapses to the single minor-0 row naming 2.0 as the base schema,:199-206;docs/explanation/architecture/ipc.md:60-68proto header mirror,:901-906,:914-922(replace the pre-freeze paragraph with: 2.0 is the first tagged schema; dev major 1 was never tagged and gets no decoder; the first post-2.0 major owes the window);docs/reference/spec.md:54-57if any REQ names major 1 (grepmajor 1,felis.v1,minor 5acrossdocs/before declaring done);docs/reference/testing.mdif it names the vectors;docs/reference/cli.mdfordaemon statusoutput examples showing1.5.CHANGELOG.md: under Unreleased / Changed, one entry: "Wire: the first public protocol is 2.0 (packagefelis.v2). The untagged development major 1 is refused at the preface; there is no v1 decoder. Every addition made during development (minor 1-5) is part of the 2.0 baseline." Fold the existing "Wire: protocol minor 5" bullet into it (an unreleased minor-5 line is meaningless once 2.0 is the first release).skills/felis/SKILL.md:220and any example output showing1.5;docs/reference/control-surfaces.mdbridge JSON if it echoes the wire version.pr.ymlproto job). After the tag,buf breaking --against <tag>is the baseline (#19 acceptance "the tagged schema is the CI compatibility baseline").felis-tui,felis-web-component,felis.el, perdocs/explanation/architecture/overview.md"Reuse paths for non-Rust clients") regenerate fromfelis.v2; note it in the commit body, not the docs.Dependencies
After every other wire edit: #45, #47, #48, #49, #51, #20, #24, #26, and #46; #50's mechanism is built on this tree afterwards (see the #50 report for the #12/#52 ordering conflict and the recommended resolution: #30 → #50 → #29). #19 must be in place so the breaking check is real and the acknowledgement path exists. Then #52 closes and #31 runs the gates.
Risk/effort
M (1-2 days, wide but mechanical). Main risk: a missed
felis.v1/1.5/minor 5mention in docs or in an external client's generated code; the grep sweep in step 5 and thethe_protocol_version_matches_the_schema/every_message_kind_matches_the_schema_enumtests are the guards. Second: the compaction in step 1 must happen in the same commit as the package rename so no intermediate state has recycled numbers underfelis.v1.Labels
Keep
priority/P1,release/v0.1.0. It is the last wire commit before the tag and gates #52/#31.Review amendments (round 2)
reserved 6, 7atfelis.proto:1419belongs toResourceKind, notOpsStatusReply. Full list of non-field-100 reservations at HEAD:RefusalReason 1, 2(:169),ConnHello 1(:637),ConnRefused 2(:667),RetargetTarget 1-5(:1305),ResourceKind 6, 7(:1419),RegionRowsDone 1(:1511),SearchMsg 3(:1630). Decision: all seven are development-only history and are compacted to dense source order in the 2.0 reset. The wire-wide field-100Correlationreservations (:621, :721, :797, :979and the family wrappers) are design, not history, and stay.#30 は #138 の決定により 見送り とします。
felis.v1維持、protocol は1.0(現行1.9を含む)を初回公開 baseline としてリセットBREAKING.mdをfirst-releaseのみにリセット済み(f56f5529)felis.v2/ major 2 への bump は、将来 side-by-side decoder が必要になった時点で検討この issue は close します。次の release gate(#115, #31)は 1.0 baseline として現行 proto を採用します。