The roster is consulted ahead of every tab map, so a live registered member is no longer read back as a lead. Both refusals still matter, for the narrower case where the pane is alive and the roster holds no entry for it. Behaviour unchanged. Verified in a throwaway worktree, not piped: Tests run: 2008, FleetConfigTest 170, BUILD SUCCESS.
This commit is contained in:
@@ -2776,9 +2776,10 @@ public record FleetConfig(
|
|||||||
});
|
});
|
||||||
if (!bad.isEmpty()) {
|
if (!bad.isEmpty()) {
|
||||||
throw new IllegalStateException("refusing to start: " + String.join("; ", bad)
|
throw new IllegalStateException("refusing to start: " + String.join("; ", bad)
|
||||||
+ ". Every member labelled that way would be read back as a lead or "
|
+ ". A member labelled that way, while its pane carries no entry in the "
|
||||||
+ "collaborator and granted that identity's authority. Change one of the two "
|
+ "spawned-member roster, is read back as a lead or collaborator and granted "
|
||||||
+ "so member tabs cannot be confused with a lead's or collaborator's tab.");
|
+ "that identity's authority. Change one of the two so member tabs cannot be "
|
||||||
|
+ "confused with a lead's or collaborator's tab.");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> collisions = new ArrayList<>();
|
List<String> collisions = new ArrayList<>();
|
||||||
@@ -2877,7 +2878,8 @@ public record FleetConfig(
|
|||||||
* the focused tab rather than its own, so it can land inside a lead's or collaborator's own
|
* the focused tab rather than its own, so it can land inside a lead's or collaborator's own
|
||||||
* labelled tab. {@link dev.ltms.fleet.herdr.LeadTabScanner} identifies a lead or collaborator
|
* labelled tab. {@link dev.ltms.fleet.herdr.LeadTabScanner} identifies a lead or collaborator
|
||||||
* purely by that tab's label — it does not exclude the member space — so a member that ends up
|
* purely by that tab's label — it does not exclude the member space — so a member that ends up
|
||||||
* there would be read back as that lead or collaborator and granted that identity's authority.
|
* there, while its pane carries no entry in the spawned-member roster, is read back as that
|
||||||
|
* lead or collaborator and granted that identity's authority.
|
||||||
*
|
*
|
||||||
* <p>Only an entry with a non-blank {@code tab} is in scope: one with no {@code tab} feeds
|
* <p>Only an entry with a non-blank {@code tab} is in scope: one with no {@code tab} feeds
|
||||||
* nothing into {@link dev.ltms.fleet.herdr.LeadTabScanner}, so it creates no hazard here.
|
* nothing into {@link dev.ltms.fleet.herdr.LeadTabScanner}, so it creates no hazard here.
|
||||||
@@ -2908,8 +2910,9 @@ public record FleetConfig(
|
|||||||
}
|
}
|
||||||
throw new IllegalStateException("refusing to start: profile(s) " + bad
|
throw new IllegalStateException("refusing to start: profile(s) " + bad
|
||||||
+ " use placement: pane while fleet.leaders or fleet.collaborators names a tab. A "
|
+ " use placement: pane while fleet.leaders or fleet.collaborators names a tab. A "
|
||||||
+ "pane-placed member can land inside that labelled tab and be read back as the "
|
+ "pane-placed member can land inside that labelled tab, and while its pane "
|
||||||
+ "lead or collaborator, granted that identity's authority. Set placement: tab for "
|
+ "carries no entry in the spawned-member roster, it is read back as the lead or "
|
||||||
|
+ "collaborator and granted that identity's authority. Set placement: tab for "
|
||||||
+ "each named profile, or remove the tab from every fleet.leaders and "
|
+ "each named profile, or remove the tab from every fleet.leaders and "
|
||||||
+ "fleet.collaborators entry.");
|
+ "fleet.collaborators entry.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -850,7 +850,8 @@ class FleetConfigTest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The hazard this guard closes: a pane-placed member lands inside the focused tab rather than
|
* The hazard this guard closes: a pane-placed member lands inside the focused tab rather than
|
||||||
* its own, so it can land inside a lead's labelled tab and be read back as that lead.
|
* its own, so it can land inside a lead's labelled tab and, while its pane carries no entry in
|
||||||
|
* the spawned-member roster, be read back as that lead.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void aPanePlacedProfileWithALeadTabRefusesToStart(@TempDir Path dir) throws Exception {
|
void aPanePlacedProfileWithALeadTabRefusesToStart(@TempDir Path dir) throws Exception {
|
||||||
@@ -1087,8 +1088,9 @@ class FleetConfigTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fleetd #669: a member tabLabel that can render as a configured collaborator tab is the same
|
* A member tabLabel that can render as a configured collaborator tab is the same hazard as the
|
||||||
* hazard as the lead case above — a member labelled that way is read back as the collaborator.
|
* lead case above — while its pane carries no entry in the spawned-member roster, a member
|
||||||
|
* labelled that way is read back as the collaborator.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void aProfileTabLabelOverrideMatchingACollaboratorTabRefusesToStart(@TempDir Path dir)
|
void aProfileTabLabelOverrideMatchingACollaboratorTabRefusesToStart(@TempDir Path dir)
|
||||||
|
|||||||
Reference in New Issue
Block a user