fleetos_1607: reconcile pre-apply gate — validate placement compatibility before reconcile applies - #206
Open
adamkrawczyk wants to merge 1 commit into
Open
fleetos_1607: reconcile pre-apply gate — validate placement compatibility before reconcile applies#206adamkrawczyk wants to merge 1 commit into
adamkrawczyk wants to merge 1 commit into
Conversation
…atibility before reconcile applies
Adds placement_svc.reconcile_precheck(): re-runs the capability/secret
preflight (loop requires{} vs member provides{}) against every LIVE
placement in a fleet, so drift introduced AFTER assign (manifest
re-declared with a new requirement, member re-pinged with fewer
capabilities) is caught before a reconcile applies further changes
instead of silently propagating bad state.
- app/services/placement.py: reconcile_precheck(db, fleet_id)
- app/mcp/tools/placement.py: loopskill_reconcile_precheck MCP tool,
wired into _PLACEMENT_TOOLS + dispatch_placement
- app/fleet_routes.py: POST /api/fleets/{id}/reconcile-precheck HTTP
route (thin adapter, mirrors the MCP contract per PM7); added
fleet_not_found -> 404 to the route's error-status map (previously
only sync/subscribe hit fleet_routes, which never surfaced that error)
- 8 new tests: clean fleet, post-assign drift detection (keystone),
removed-placement exclusion, manager-capability 403, MCP dispatch,
HTTP route (200/404/403)
41+32 targeted tests pass (test_fleetos_A_placements, test_fleetos_I_ingest,
test_portal_0610_j3_fleet_routes). ruff check + format clean.
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.
What
Adds a pre-apply gate that re-validates every LIVE fleet placement's compatibility (loop
requires{}vs memberprovides{}) BEFORE a reconcile applies further changes.Why (fleetos_1607 gap)
preflight_memberonly ran once, atassigntime. If a manifest is re-declared with a new requirement, or a member re-pings with fewer capabilities, the now-incompatible placement stays live and nothing catches the drift — it silently propagates until the loop fails at runtime on a host it can no longer satisfy.What ships
app/services/placement.py::reconcile_precheck(db, fleet_id)— walks every live (assigned/active/draining) placement, re-runs the existing preflight, returns{ok, checked, incompatible[]}with named missing requirements per placement.app/mcp/tools/placement.py::loopskill_reconcile_precheck— MCP tool, manager-capability gated (same asloopskill_assign/loopskill_placements), wired into_PLACEMENT_TOOLS+dispatch_placement.app/fleet_routes.py—POST /api/fleets/{id}/reconcile-precheckHTTP adapter (mirrors the MCP contract per PM7). Also addedfleet_not_found → 404to the route's shared error-status map (this is the first placement-tool route exposed over HTTP; the map previously only needed to handle sync/subscribe's error vocabulary).Tests
8 new tests across the service/tool/route layers:
requiresgains a package), precheck catches it with the named missing requirementpytest tests/test_fleetos_A_placements.py tests/test_fleetos_I_ingest.py tests/test_portal_0610_j3_fleet_routes.py -q→ 41 + 32 passed (ran in two batches, no regressions).ruff check+ruff format --checkclean on all touched files.Full suite wasn't run in this session (10-min budget cap on the fallback-executor cron that authored this) — targeted coverage on every file touched, all green.
🤖 Shipped via atomic-habits fallback executor (2026-08-07, rank-1, Adam absent).