v0.317.0: a second copy counts only on a proven different disk; the no-drive install speaks in words (felhom.eu architecture/16, build A)
gates / gates (push) Successful in 46s

Tier-2 and the one-copy notice ask the host agent (POST /disks/same-disk, agent 0.157.0): different +
proven -> made and counted; same disk -> not made (D1); unknown (VM, hidden USB serial) -> made, not
counted, the row says why (D2); a NAS never counts and no longer hides the notice (R-1075). An older
agent keeps the st_dev rule, logged once. D4: a data-folder or media app on a box with no drive is
refused in words with a link to the drives page (R-1068's raw-error half). MinAgent 0.157.0.

Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
This commit is contained in:
2026-10-15 21:21:54 +02:00
parent c6a567122e
commit 0626b9fc8a
34 changed files with 665 additions and 200 deletions
+7 -2
View File
@@ -437,7 +437,7 @@ func deployStatusFor(err error) int {
switch {
case errors.Is(err, stacks.ErrAlreadyDeployed), errors.Is(err, stacks.ErrKeptDataChoice):
return http.StatusConflict
case errors.Is(err, stacks.ErrRequiredField), errors.Is(err, stacks.ErrPathMissing),
case errors.Is(err, stacks.ErrRequiredField), errors.Is(err, stacks.ErrPathMissing), errors.Is(err, stacks.ErrNeedsDrive),
errors.Is(err, stacks.ErrNotEnoughMemory):
return http.StatusBadRequest
}
@@ -535,7 +535,12 @@ func (r *Router) deployStack(w http.ResponseWriter, req *http.Request, name stri
if err != nil {
r.logger.Printf("[ERROR] [api] Deploy failed for %s: %v", name, err)
// R-553 — the status code comes from the refusal's KIND (deployStatusFor), never from its words.
writeJSON(w, deployStatusFor(err), apiResponse{OK: false, Error: r.errText(req, err)})
resp := apiResponse{OK: false, Error: r.errText(req, err)}
if errors.Is(err, stacks.ErrNeedsDrive) {
// D4 (`16` §5): the wizard renders the sentence with a link to the drives page.
resp.Data = map[string]string{"code": "needs_drive", "link": "/storage"}
}
writeJSON(w, deployStatusFor(err), resp)
return
}