Hand a moved module by its manifest, its build and the machine, never by the vault's reading of its plan, so a node with no plan yet makes the plan that hands it (issue 1966)
The vault judged a module handed only when its assignment already carried a handing plan, and the node-engine followed that word: a module with no plan was composed the old way, refused for a key only the provider's helper answers (forge-account's ssh_alias), and so never got its plan. resolution.Handing is now the manifest, its build and the machine alone; the vault's word is read only to say where the two disagree. A refusal of a file or an own secret the provisioner's client should fill now says "handed module not handed" and why, never only the keys a binding lacks or a secret to make. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
@@ -96,22 +96,74 @@ func renderingHanding(with mcat.Rendering, m mcat.Manifest) bool {
|
||||
}
|
||||
|
||||
// Handing is whether a machine composed with this rendering hands the module to the provisioner, its files and
|
||||
// its own secrets (design 57 P6, V4): a moved module there, assigned or only pulled in by another (issue 765), on a
|
||||
// machine that can take it. The controller makes and seals none of such a module's secrets for that machine: its
|
||||
// client asks the vault.
|
||||
// its own secrets (design 57 P6, V4): a moved module there whose build kept what the client fills from
|
||||
// (catalogue.Handed, written by Resolve), assigned or only pulled in by another (issue 765), on a machine that can take
|
||||
// it (its node-engine writes a filled file on the client's word, and the client's account is named). The controller
|
||||
// makes and seals none of such a module's secrets for that machine: its client asks the vault.
|
||||
//
|
||||
// **Where the vault judged the module, its word is the rule** (Rendering.Assigned, issue 774): the vault leaves a
|
||||
// module's own secrets out of `own` exactly when the plan in its assignment hands it (AssignmentHands), so a node
|
||||
// composing itself hands exactly those, whatever its own reading of the manifest and the machine says. On 2026-10-31
|
||||
// postgres on novox was held: its plan handed its secrets, the vault answered none of them, and the node, judging by
|
||||
// the manifest and the machine, composed them itself and refused for want of `reader`. Two readers, one rule.
|
||||
// **The manifest, its build and the machine are the rule, never the plan** (issue 1966). The plan in a module's
|
||||
// assignment is what a node's last composition made of it; when the vault's reading of it (Rendering.Assigned) was the
|
||||
// rule, a module with no plan yet was judged not handed, composed the old way, refused there (its files ask the
|
||||
// provider's helper for what only the helper answers), and so never got the plan that would hand it: on 2026-11-04
|
||||
// ace's three build modules and ssh-client, and shanks's mesh-build-image and ssh-client. The vault's word follows the
|
||||
// plans this rule makes, one composition later, and is read only to say where the two disagree (VaultDisagrees).
|
||||
func Handing(with mcat.Rendering, m mcat.Manifest) bool {
|
||||
if hands, judged := with.Assigned[m.Module]; judged {
|
||||
return hands
|
||||
}
|
||||
return m.Moved && m.Handed != nil && with.Hands && with.Provisioner != ""
|
||||
}
|
||||
|
||||
// machineWhy is why a machine does not take a moved module's handed files, "" where it does.
|
||||
func machineWhy(with mcat.Rendering) string {
|
||||
switch {
|
||||
case !with.Hands:
|
||||
return "this machine's node-engine has not stated that it writes a filled file on the provisioner client's word"
|
||||
case with.Provisioner == "":
|
||||
return "this machine's declaration names no account the provisioner's client runs as"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// VaultDisagrees says why this composition does not hand a module the vault judged handed (Rendering.Assigned: the plan
|
||||
// in its assignment hands it, so the vault left its own secrets out of what it answered this node), "" where they agree
|
||||
// or the vault said nothing of it. Said where one of those secrets is then missing, as a handed module not handed, never
|
||||
// as a secret to make (issue 1966).
|
||||
func VaultDisagrees(with mcat.Rendering, m mcat.Manifest) string {
|
||||
if !with.Assigned[m.Module] || Handing(with, m) {
|
||||
return ""
|
||||
}
|
||||
switch {
|
||||
case !m.Moved:
|
||||
return "the vault judged it handed by its plan, and it is not moved"
|
||||
case m.Handed == nil:
|
||||
return "the vault judged it handed by its plan, and its build kept no templates"
|
||||
}
|
||||
return "the vault judged it handed by its plan, and " + machineWhy(with)
|
||||
}
|
||||
|
||||
// notHandedWhy says why a file of this module is composed here, filled by the node-engine, rather than by the
|
||||
// provisioner's client: the module is not moved, its build kept nothing to hand, the machine cannot take it, its build
|
||||
// kept no template for this file, or the file merges the layers' settings (begin). Said where a placeholder only a
|
||||
// handed file can name is refused (boundInto); handedFile is whether the module's manifest and build hand this file, so
|
||||
// that a refusal of it is a handed module not handed.
|
||||
func notHandedWhy(with mcat.Rendering, m mcat.Manifest, r map[string]any) (why string, handedFile bool) {
|
||||
id := fmt.Sprint(r["id"])
|
||||
switch {
|
||||
case !m.Moved:
|
||||
return m.Module + " is not moved, so its node-engine fills its files", false
|
||||
case m.Handed == nil:
|
||||
return m.Module + " is moved and its build kept no templates, so its node-engine fills its files", false
|
||||
}
|
||||
if _, kept := m.Handed.Templates[id]; !kept {
|
||||
return fmt.Sprintf("its build kept no template for %s, so its node-engine fills that file", id), false
|
||||
}
|
||||
if mergesFile(r) {
|
||||
return fmt.Sprintf("%s merges the layers' settings, which its node-engine does (issue 831)", id), false
|
||||
}
|
||||
if why := machineWhy(with); why != "" {
|
||||
return why, true
|
||||
}
|
||||
return fmt.Sprintf("its build kept a template for %s and this composition filled it itself", id), true
|
||||
}
|
||||
|
||||
// requiredByWords begins why a module only pulled in by another is on a machine (Resolution.Because): `required by
|
||||
// <module>`.
|
||||
const requiredByWords = "required by "
|
||||
|
||||
Reference in New Issue
Block a user