mesh-module-assigner client: CheckProposalID, the id a proposal and the ask about it carry (ADR 0634 §4; issue 1966)

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-05 14:49:56 +01:00
parent fb5451f694
commit 074032e9d4
2 changed files with 24 additions and 0 deletions
@@ -12,6 +12,13 @@ import (
)
func TestPlacementClient(t *testing.T) {
t.Run("proposal id", func(t *testing.T) {
for id, ok := range map[string]bool{"p-20261028t183000-1a2b3c": true, "abc": true, "ab": false, "A-bc": false, "-abc": false, "a.bc": false, "": false} {
if (CheckProposalID(id) == nil) != ok {
t.Errorf("CheckProposalID(%q) = %v", id, CheckProposalID(id))
}
}
})
t.Run("key and file", func(t *testing.T) {
// Research 072 row 37: one node key and one key per module, a legacy key read beside them, any other refused.
for key, want := range map[string]struct {
@@ -0,0 +1,17 @@
package meshmoduleassignerclient
import (
"fmt"
"regexp"
)
var proposalIDOK = regexp.MustCompile(`^[a-z0-9][a-z0-9-]{2,62}$`)
// CheckProposalID refuses an id that is no proposal's: lower-case letters, digits and dashes, 3 to 63 of them, so it is one
// key token. The holder writes proposals under it, and the keys of the asks about a proposal (`placement.<id>`) carry it.
func CheckProposalID(id string) error {
if !proposalIDOK.MatchString(id) {
return fmt.Errorf("mesh-module-assigner: %q is no proposal id (lower-case letters, digits and dashes, one key token)", id)
}
return nil
}