Repository navigation
refactor: remove host and wire-protocol legacy support - #4613
ScriptedAlchemy wants to merge 9 commits into
Conversation
|
There was a problem hiding this comment.
Devin Review found 1 potential issue.
1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)
| expected_version: &str, | ||
| ) -> Vec<StoreResetRequiredV1> { | ||
| if !daemon_control::daemon_reachable(profile) { | ||
| if !daemon_control::daemon_reachable(profile, crate::product_runtime::PRODUCT_BUILD_VERSION) { |
There was a problem hiding this comment.
🔴 Post-update store resets go unreported
After an upgrade installs a different build, restored_daemon_pending_resets probes with the old CLI version. The restored daemon refuses that handshake, so update reports completion without listing stores requiring reset.
Learn more
The update flow runs in the old CLI process while replacing the daemon binary. Its expected_version argument is the version of the newly installed binary, passed by run_update_flow. The new daemon refuses a readiness handshake advertising the old CLI build, and daemon_reachable only returns true for an initialize answer or a typed refusal. A typed refusal ordinarily counts as reachable, but the subsequent reset census uses the installed version; using that same version for both probes gives a consistent check and avoids mismatches when the old and new builds advertise the same release with different commit metadata.
Example: An old CLI at 1.0.0+aaaa installs a daemon at 1.0.0+bbbb with one store in reset-required state. The reachability probe advertises +aaaa; the new daemon refuses it, and the reset census is skipped instead of reporting the pending reset.
Recommended fix: Pass expected_version to daemon_reachable, matching the version already passed to daemon_reset_required_stores. Verify the post-update journey with same-release builds carrying different commit metadata.
| if !daemon_control::daemon_reachable(profile, crate::product_runtime::PRODUCT_BUILD_VERSION) { | |
| if !daemon_control::daemon_reachable(profile, expected_version) { |
Was this helpful? React with 👍 or 👎 to provide feedback.
Items removed: L013/L068 (fixed-action fact_* tool aliases and the fact_type->category translation in the plugin), L052 (hermes_cli.config get_hermes_home fallback), L053 (register_context_engine capability gate), L062 (state.db column probing and no-active frontier variant), L064 (wrapper compatibility API forwarders, /capabilities, _proxy). Callers migrated: skill.md and the stock/unit check scripts use fact_store(action=...) with category; the Hermes ctx test stubs implement register_context_engine; the sessions fixtures build state.db from one current-schema DDL (TEST_STATE_DB_SCHEMA_SQL); docs/dashboard.md no longer describes the /legacy frontend proxy. Tests deleted: fact_add/fact_type alias assertions (unit check, stock check), the LegacyCtx registration case, the minimal legacy state.db fixture and its pagination/seek-plan halves, and sweep_reads_legacy_stores_without_active_or_reasoning_columns. Upgrade impact: Hermes must provide hermes_constants, register_context_engine and the current state.db sessions/messages columns. Older builds fail plugin load, and their state.db is refused with a typed missing-columns error instead of being ingested. Agents must call fact_store(action=...); fact_add/fact_search/... and the wrapper's /holographic, /lcm, /graph, /savings, /analytics, /automation and /capabilities routes no longer exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Items removed: L057 (Codex event_msg user_message records), L058 (id-less Codex response goal context; Claude API-error placeholders recognised by the synthetic model without isApiErrorMessage), L063 (Kiro <workspace-hash>/<execution-id>.chat layout and its two .chat discovery scans), L067 (render-codex-hook-inputs user_message branch and the retired static tracedecay hint classification). The Cursor epoch-ms createdAt handling stays: Cursor's store keeps old composers, so it is current data. Callers migrated: every Codex rollout fixture in the sessions, host-admission, transcript-ingest, mcp, runtime and transport suites, the two benches and tool_sweep now write item_completed/UserMessage via one helper per crate; Kiro fixtures use extensionless execution files. Tests deleted: kiro_legacy_chat_populates_searchable_messages and write_legacy_chat, the content-addressed session_rewrite case, the older synthetic-model placeholder case, test_legacy_user_message_remains_supported. Upgrade impact: Codex rollouts with event_msg user_message prompts, Codex response goal-context items without an id, and Kiro .chat transcripts are no longer ingested; rows already ingested are kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Item removed: L056. AutomationTaskLock now holds only the <key>.lease file. Deleted the <key>.lock.lock publication-coordination lease, retire_pre_lease_owner, PreLeaseOwner, read_pre_lease_owner, parse_unique_lock_field, recorded_owner_was_reused, unverifiable_pre_lease_owner and MAX_PRE_LEASE_TASK_LOCK_BYTES. process_state, foreign_process_is_dead and append_lock_path stay: other callers use them. Callers migrated: the scheduler prefilter and memory-curator runner tests that held a lock by writing a pid file now hold a real lease through AutomationTaskLock::try_acquire(_keyed). Tests deleted: the old/new process participant harness and old_and_new_processes_exclude_publication_and_execution_until_release, the five pre_lease_* unit tests plus reaped_pid, the pid-file reclaim cases in automation_runner_test (and the liveness child helpers), and memory_curator_runner_recovers_stale_scheduler_lock_file. The cancellation, symlink and lifecycle tests lose their lock.lock halves. Upgrade impact: an older daemon that is still running no longer excludes the new daemon, so both can run the same automation task at once during a mixed-version upgrade. Stop the old daemon before starting the new one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Items removed: L060, L071, L079, L081. The daemon no longer serves a version-skewed client with a warning. Every handshake is checked once, before anything is routed: a client from another build, a client that reports no version, or one with a non-conforming instance id gets one typed unsupported_revision refusal frame, and the connection closes. Removed: the six #[serde(default)] handshake fields (a handshake missing any of them is refused as unsupported_revision), the empty-version no-skew rule, the per-client admission bypass for invalid instance ids, the skew log (client_version_skew_to_log, log_client_version_skew, logged_client_version_skews), the proxy-side skew warning (daemon_version_skew_warning_for_request), refuse_enrollment_from_another_build (subsumed by the handshake check), and the mixed-version docs. The saturation path now requires the auth preface and applies the same refusal. Callers migrated: daemon_reachable and daemon_socket_connectable take the caller's build version instead of daemon-control's own crate version, and the readiness probe reads a typed refusal frame as a running daemon of another version. Integration suites build handshakes through one helper that names only the release; the fixture runtime reports its release without a commit so a test process matches the daemon binary it spawns. Fixture client ids are conforming. Tests deleted: the legacy handshake decode cases, the version-skew log test, the empty-version skew case, per-client admission for legacy clients, the enrollment-from-another-build test, the legacy listChanged half of the proxy metadata test, the proxy skew-warning assertion in mcp_cli_serve_test. Added: skewed-client refusal at the handshake and over the live daemon, every-field-required, probe refusal case. Upgrade impact: an older CLI or long-lived `tracedecay serve` talking to a newer daemon, or the reverse, is refused with unsupported_revision (daemon_protocol_revision_skew) instead of being served with a warning. Restart MCP hosts and any running `tracedecay serve` after upgrading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Items removed: L016 (since/until aliases on tracedecay_lcm_grep, in the
MCP catalog schema, LcmGrepRequestV1, the retrieval merge, and the Hermes
lcm_grep schema), L061/L076 (bare `initialized` MCP method), L070
(AffectedResultV1.affected_tests and AffectedRankingMetadataV1.
compatibility_field; count and touched files now derive from
ranked_tests), L080 (authority_audit_error mirroring the typed reason; the
key now carries only the observed detail, null otherwise). message_search
and sessions_for keep their own since/until, and LSP `initialized` is
untouched.
Callers migrated: the lcm_grep MCP test and the preserved-profile
journey send start_time; the affected tests and the golden JSON assert
ranked_tests; the SDK client fixture drops the removed fields.
Regenerated in this commit: sdks/typescript/src/operations.ts and
plugin/chatgpt-extension/embedded/server.mjs (contracts:check and
check:embedded pass). The regeneration also picks up the StatusHookReplayV1
`waiting` variant that master's generated SDK was missing.
Tests deleted: the "compatibility list must remain exhaustive and
path-sorted" assertion. Added: classify_mcp_method("initialized") is
Unknown.
Upgrade impact: lcm_grep requests that send since/until are rejected;
use start_time/end_time. A host that sends a bare `initialized` gets
method-not-found; hosts must send notifications/initialized.
tracedecay_affected no longer returns affected_tests or
ranking_metadata.compatibility_field; read ranked_tests/recommended_tests.
Regenerate SDK clients. Doctor readers use authority_audit_reason.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Items removed: L069 (CodeIndexWorktreeFreshnessV1.rebuild_in_flight default), L073 (source_role default on CompactCandidate, FusedCandidate, ExactLaneEvidence and LexicalLaneEvidence, plus the LexicalRouteReceiptV1.decision default), L075 (the StorageReport and StorageReportCoverage serde defaults for size_coverage, root_state, unavailable_entry_count, graph_container, graph_replay_pool, code_generation_retention_availability, user_sessions_db_bytes, unregistered_size, unregistered_count_is_lower_bound, and the digest_verified default plus digest_verified_default), L077 (ReaderPoolSnapshot.snapshot_admissions default). Defaults paired with skip_serializing_if (full_profile_size, footprint, reason) stay. Regenerated: dashboard/codegen/schemas/dashboard-contracts.schema.json, sdks/typescript/src/operations.ts and plugin/chatgpt-extension/embedded/ server.mjs (contracts:check and check:embedded pass). Tests deleted: the older-response half of graph_serving_readiness_is_additive_for_older_daemon_responses (the test keeps the terminal-verdict cases under a new name) and exact_lane_evidence_treats_missing_source_role_as_production_other. Upgrade impact: a new CLI reading a storage report or freshness payload from an older daemon fails to decode it. Restart the daemon after upgrading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Item removed: L072. The git index preview input, preview and receipt wire structs no longer accept commit_intent, commit_intent_digest or created_commit (deny_unknown_fields now rejects them), the digest material no longer carries the always-null commit_intent_digest and created_commit keys, and final_snapshot_captured is required instead of defaulting to true. default_true stays: other crates use it. Tests deleted: records_stored_before_commit_index_removal_still_decode and tests/fixtures/git_index_legacy/ (three JSON fixtures). Added: removed_commit_fields_and_missing_receipt_flags_are_refused, which builds current records and proves the removed fields and the missing flag are refused. Upgrade impact: dropping the null keys changes the digest of every preview, preview input and receipt, so stored pending git-index previews and stored receipts written by an earlier build fail digest verification and are refused with the existing typed digest-mismatch error. Re-create pending git-index previews after upgrading. No migration code was added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
U17 (fb73388) made FusedCandidate.source_role required, but two tracedecay-mcp unit fixtures still decoded candidates from JSON without it, so route_evidence_is_attached_only_when_additional_routes_ran and markdown_search_trims_the_weak_tail_but_json_returns_every_row panicked with `missing field source_role` on Linux fleet CI. The fixtures now carry the current shape. No other fixture in the repo decodes a FusedCandidate from JSON (rg for "utility_micros" outside generated schemas). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
U16 (c912814) removed the bare `initialized` MCP alias, so classify_mcp_method("initialized") is Unknown and the request is no longer reserved control traffic. mcp_discovery_requests_are_reserved_control_traffic still asserted the alias was reserved and failed in //crates/tracedecay:unit_test on Linux fleet CI. The test now covers only notifications/initialized. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
96399c2 to
8b1a4c4
Compare
|
Combined into #4623 with lanes A, B and C, merged with --no-ff so this branch's commits land unchanged; that PR's merge commit marks this one merged. |
|
Landed on master through #4623 (merge commit f193d1d). |
Why
tracedecay keeps no legacy or backward-compatibility code. This PR removes inventory units U12–U18, which cover host compatibility and the wire protocol. One commit per unit; each commit body lists the items removed, the callers migrated, the tests deleted, and its upgrade impact. 125 files changed, +986 / −2,687.
Units
user_messagerecords, Kiro.chattranscripts and other older transcript shapes (L057, L058, L063, L067). Fixtures move toitem_completed/UserMessageserde(default)handshake fields, and preface-less broker clients (L060, L071, L079, L081). A client of another build gets the typeddaemon_protocol_revision_skewrefusalinitializedmethod, thelcm_grepsince/untilaliases, and tool-surface aliases (L016, L061, L070, L076, L080). The SDK, the dashboard schema and the ChatGPT-extension embed are regeneratedserde(default)on daemon status and storage responses (L069, L073, L075, L077)commit_index(L072)Upgrade impact
tracedecay servefrom a different build is refused by a new daemon. Restart it after upgrading.user_messagerecords and Kiro.chattranscripts are no longer ingested. Rows already ingested are kept.notifications/initializedinstead of the bareinitialized.lcm_grepcallers must use the current time-range fields.commit_indexno longer verify.Notes for review
versions_name_same_build. That function treats a version without build metadata as the same identity as any commit of that release, whichtracedecay updaterelies on when it compares a release tag with the binary it installed. When both sides name a commit, the commits must match.daemon_reachableanddaemon_socket_connectablenow send the caller's build version. The readiness probe treats a typed refusal as a running daemon of another build.Verification
bazel build --config=clippyandbazel teston the touched crates. U16–U18 also rancontracts:checkandcheck:embedded.gen_builds --checkis current, and the regenerated ChatGPT embed passescheck:embedded.remote_cli_testHTTPS cases also fail onmaster.hermes_plugin_unit_check.pyandhermes_stock_check.pywere only syntax-checked;uvand PyYAML aren't available locally.hermes_suitepasses.🤖 Generated with Claude Code