Repository navigation
Conversation
The ownership probe's remote arm read GET /api/stacks as an array of objects carrying a name, but the endpoint answers with the stack names themselves. The match therefore matched nothing, so every remote name read as clear: Check again released a name_conflict row while the conflicting stack was still there, the preview never flagged a remote create as blocked, and the deploy pre-flight never ran. Only the leaf's own apply-local check held, which is why nothing was ever written over. Read the names the leaf sends, and fail closed when the answer is not readable: a name found among the readable entries is still answered from the marker, while a name absent from a list holding entries this version cannot read is an unverified probe rather than a clear name. A non-array body counts as unreadable rather than as an empty node. The local arm is unchanged.
This branch has not been deployed
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
On a remote node, a Blueprint name conflict was never detected. The ownership probe read the leaf's
GET /api/stacksresponse as an array of objects carrying aname, but that endpoint answers with the stack names themselves. The match therefore matched nothing, and the probe reported every remote name as clear.Three places were wrong as a result:
name_conflictrow answeredcleared: trueand moved the row topendingwhile the conflicting stack was still there, so the next reconcile tick parked it in conflict again.blocked_name_conflict.deployToNodeanddeployAuthorizedMaterializationnever ran on a remote node.Nothing was ever written over: the leaf re-checks ownership under its per-stack lock and refuses with a 409. The defect cost a wrong answer in three places plus a doomed round trip, not data.
The probe now reads the names the leaf sends. Where the answer is not readable it fails closed at the point that is still undecided. A name found among the readable entries is answered from the marker as before. A name absent from a list that also held entries this version cannot read is an unverified probe rather than a clear name. A non-array body counts as unreadable rather than as an empty node, which is what let the object-shape read pass. An empty list stays a real answer, a node with no stacks. The local arm is unchanged.
One consequence worth expecting: a plan that creates a Blueprint on a remote node holding an unmanaged same-named stack now shows a blocker, and
POST /:id/applyanswersPLAN_BLOCKED. That is what the same collision already does on a local node.Type of change
Related issue
Related to #2118, which added Check again and is where this was noticed. The probe defect predates it, and this is not a tracked issue, so there is nothing to close.
Testing performed
Backend:
npx tsc --noEmitclean;npm testreports 11,306 tests passing. The one failing suite isgit-transport-ssh.integration.test.ts, which refuses to run because loopback port 22 already has a listener on this machine. That is unrelated to this change, and the suite touches none of these files.Regression proof: with the service change reverted, seven of the new and updated tests fail, and the negative controls (no such stack, empty list, name free) keep passing in both directions. So the new tests fail for the reason the fix addresses rather than passing by construction.
Behaviour pinned by the new tests, through the public entry points rather than internals:
name_conflictfailed, notname_conflict, so a transport problem is not reported as an unowned stack sitting on the nodeTwo fixtures that had been answering
/api/stacksin a shape the leaf never sends were corrected. They are why the probe's own tests agreed with the defect: one of them was also asserting the message of the wrong failure path for the same reason.No user-visible label, path, or default changed, and the operator docs already describe the behavior this restores. No UI change, so no browser pass was needed.
Checklist