Repository navigation
Conversation
Contributor
🦩 Flamingo Code ReviewNot reviewed yet. Reviews start when you ask, so the reviewer reads this pull request when it is ready, not when it is opened. When it is ready:
Or comment Updated 2026-10-12 18:05 UTC · workflow run |
danylo-babenko-flamingo
approved these changes
Oct 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds client-side feature flags pushed by the backend through the delivery engine. Flags are applied only at startup. When a new set changes what the running client would enable, the client drains its work and restarts itself through a detached
restart-serviceprocess.To get there, the PR adds a generic Core-NATS command listener (
listener/command/) with delivery-engine results (ACKED/DONE/FAILED), a restart gate that waits for in-flight work, and a NATS integration test harness that uses a realnats-server.No production code reads the flags yet. The three flags are placeholders for moving tool installation, client uninstall and client update onto the delivery engine.
Wire contract
Inbound: Core NATS
machine.<machineId>.feature-flags{ "delivery": { "type": "CLIENT_FEATURE_FLAGS", "targetId": "...", "dispatchId": "...", "sequence": 11 }, "flags": { "delivery-tool-installation": { "enabled": true, "minVersion": "1.6.0" }, "delivery-client-uninstall": { "enabled": false, "minVersion": "1.6.0" }, "delivery-client-update": { "enabled": false, "minVersion": "1.6.0" } } }Outbound:
machine.<machineId>.delivery.result{ "delivery": { "...": "same ref" }, "result": "ACKED | DONE | FAILED", "error": "..." }ACKEDis published directly (publish + flush).DONEandFAILEDgo through the durable redb outbox and are published with a JetStream ack.DONEis sent by the new process after the restart.Behaviour
Effective value per flag:
0.0.0-dev), takeenabled.enabledif the client version is ≥minVersion(semver, pre-release aware).false.Validation:
enabledand a semverminVersionis dropped with a warning.Ordering: a per-machine
sequencegate. A stale or duplicate set is answeredDONEwithout being applied. A new registration (different machine id) accepts any sequence.Persistence:
secured/feature_flags.json, written atomically, holdsmachine_id,sequence,flags, and an optionalawaiting_restartdelivery ref. A missing or unreadable file means all features are off.Restart only when needed: the client restarts only if the resolved set differs from the running one. Changes that don't apply to this version, a moved
minVersionthat still applies, or unknown flags answerDONEimmediately.Drain (
RestartGate):Handoff:
openframe-client restart-servicedetached (macOSsetsid, WindowsDETACHED_PROCESS). It stops and starts the service.75and the service manager restarts it.exit(75).Startup order: a pending self-update is handled before the flags listener starts, so a flags restart can't cut post-update verification short.
Notable changes outside the new module
platform/detached_process.rs:spawn_detached()is extracted from self-uninstall and shared withrestart-service. Uninstall behaviour is unchanged.RestartGatereads narrow read-only views instead of whole services:ToolOps::busy_tools(),ExecutionService::running_scripts()(new running-script counter) andToolRunManager::client_update_pending().ClientUpdatePendingFlagnow uses a stdMutex, so its methods are sync. Call sites inopenframe_client_update_service.rsandclient_update_gate.rsonly drop.await.is_ack_subjectis renamed torequires_stream_ackand now also coversdelivery.result.NatsConnectionManager::use_client_for_tests(#[cfg(test)]) for the integration harness.