v0.318.0: a part is offered for formatting only while nothing on its disk is mounted (agent 0.158.1 formattable)
gates / gates (push) Successful in 45s

The agent's root mkfs wrapper (security review of agent 0.158.0) refuses any mounted node and trusts no sibling claim; the
wizard now matches it. A free filesystem part of an in-use disk stays offered for use. Red-proved.

Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
This commit is contained in:
2026-10-16 04:05:09 +02:00
parent a43d0423d5
commit 36da4089ca
7 changed files with 45 additions and 29 deletions
+11 -8
View File
@@ -186,13 +186,13 @@ func dropRegisteredDrives(resp agentapi.CandidatesResult, mountsText string, reg
if len(inUse) == 0 {
return resp
}
keep := func(in []agentapi.DiskCandidate) []agentapi.DiskCandidate {
keep := func(in []agentapi.DiskCandidate, usable func(agentapi.CandidatePartition) bool) []agentapi.DiskCandidate {
out := make([]agentapi.DiskCandidate, 0, len(in))
for _, c := range in {
if candidateBacksInUse(c, inUse) {
// `16` §6 (v0.318.0): a disk whose ONE part is a registered drive keeps its FREE parts on offer —
// `16` §6 (v0.318.0): a disk whose ONE part is a registered drive keeps its usable FREE parts on offer —
// the whole disk itself, never (WholeDiskInUse; handleStorageInit refuses it server-side too).
if free := freePartitions(c.Partitions, inUse); len(free) > 0 {
if free := freePartitions(c.Partitions, inUse, usable); len(free) > 0 {
c.Partitions, c.WholeDiskInUse = free, true
out = append(out, c)
}
@@ -202,8 +202,10 @@ func dropRegisteredDrives(resp agentapi.CandidatesResult, mountsText string, reg
}
return out
}
resp.Initialize = keep(resp.Initialize)
resp.Attach = keep(resp.Attach)
// Formatting a part needs a disk with nothing mounted (the agent's Formattable — its root wrapper refuses otherwise);
// USING a part with a filesystem erases nothing and stays offered.
resp.Initialize = keep(resp.Initialize, func(p agentapi.CandidatePartition) bool { return p.Formattable })
resp.Attach = keep(resp.Attach, func(p agentapi.CandidatePartition) bool { return p.State == agentapi.PartFilesystem && p.Mountable })
return resp
}
@@ -223,11 +225,12 @@ func deviceBacksRegistered(device, mountsText string, registered map[string]bool
return candidateBacksInUse(agentapi.DiskCandidate{Device: device}, inUse)
}
// freePartitions keeps the parts that are not a registered drive and not already Felhom's (state in_use).
func freePartitions(parts []agentapi.CandidatePartition, inUse map[string]bool) []agentapi.CandidatePartition {
// freePartitions keeps the parts that are not a registered drive, not already Felhom's (state in_use), and usable for
// the list in question.
func freePartitions(parts []agentapi.CandidatePartition, inUse map[string]bool, usable func(agentapi.CandidatePartition) bool) []agentapi.CandidatePartition {
var out []agentapi.CandidatePartition
for _, p := range parts {
if p.State == agentapi.PartInUse || inUse[p.Device] {
if p.State == agentapi.PartInUse || inUse[p.Device] || !usable(p) {
continue
}
out = append(out, p)