The node-engine's live path holds a module whose claim or credential fails (issue 1966, review round 1)
mesh/delivery merged: source.main moved to novox/mesh-host@6e461bd24aa5
mesh/check being carried to ef41fa2e2796 on 6e461bd24aa5 | from 7c483da93a03
mesh/delivery merged: source.main moved to novox/mesh-host@6e461bd24aa5
mesh/check being carried to ef41fa2e2796 on 6e461bd24aa5 | from 7c483da93a03
compose.CompositionsHolding returns the modules the declaration leaves out for a claim that cannot be held or a refused credential; frombus composeEach holds each with those words, so the node-engine keeps what it handed of the module (no stop of a running module), the candidate answer and the check's sandbox name it refused, and the rest composes. CredentialsNeeded asks nothing for a held module. Resolve and checkClaims move to a test helper (production uses ResolveHolding and holdClaims); a pass refused anyway names a held module's reason among the others. Quick fix: Declared.Held read in the composer only. Thorough, chosen: the same held words reach every reader of the composition (selfcompose, ComposeSent, the candidate answer) through composeEach's one hold path. Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
This commit is contained in:
@@ -26,26 +26,17 @@ func (r *Refusal) Error() string {
|
||||
return "these assignments cannot be applied:\n - " + strings.Join(r.Problems, "\n - ")
|
||||
}
|
||||
|
||||
// Resolve works out everything a node runs, from what was assigned to it.
|
||||
//
|
||||
// The catalogue is every module the mesh knows about; assigned is what a person put on this node.
|
||||
// What comes back is the closure — assigned modules plus everything they require — or a refusal
|
||||
// naming every reason it could not be closed.
|
||||
func Resolve(catalogue map[string]mcat.Manifest, assigned []string, node mcat.Node, world mcat.World) (mcat.Resolution, error) {
|
||||
resolution, _, err := resolve(catalogue, assigned, node, world, true)
|
||||
return resolution, err
|
||||
}
|
||||
|
||||
// ResolveHolding is Resolve where a claim problem costs the module that has it, not the machine (issue 1966, ADR 0636 §3: a
|
||||
// refused claim blocks that claimant only). The modules that cannot hold what they claim come back with why, each still in
|
||||
// ResolveHolding works out everything a node runs, from what was assigned to it. The catalogue is every module the mesh knows
|
||||
// about; assigned is what a person put on this node. What comes back is the closure -- assigned modules plus everything they
|
||||
// require -- or a refusal naming every reason it could not be closed. A claim problem costs the module that has it, not the
|
||||
// machine (issue 1966, ADR 0636 §3: a refused claim blocks that claimant only). The modules that cannot hold what they claim come back with why, each still in
|
||||
// the resolution's modules and none of them in its claims; the caller leaves them out of what it declares (LeftOut), so the
|
||||
// machine composes everything else. Every other refusal is Resolve's.
|
||||
func ResolveHolding(catalogue map[string]mcat.Manifest, assigned []string, node mcat.Node, world mcat.World) (mcat.Resolution, map[string]string, error) {
|
||||
return resolve(catalogue, assigned, node, world, false)
|
||||
return resolve(catalogue, assigned, node, world)
|
||||
}
|
||||
|
||||
// resolve is Resolve; with strict, a claim problem is a refusal beside every other, and without it a module held.
|
||||
func resolve(catalogue map[string]mcat.Manifest, assigned []string, node mcat.Node, world mcat.World, strict bool) (mcat.Resolution, map[string]string, error) {
|
||||
func resolve(catalogue map[string]mcat.Manifest, assigned []string, node mcat.Node, world mcat.World) (mcat.Resolution, map[string]string, error) {
|
||||
elsewhere := world.Held
|
||||
var problems []string
|
||||
|
||||
@@ -608,12 +599,6 @@ func resolve(catalogue map[string]mcat.Manifest, assigned []string, node mcat.No
|
||||
|
||||
problems = append(problems, checkCapabilities(resolution.Modules, node)...)
|
||||
claims, held := holdClaims(resolution.Modules, node, elsewhere, world.Holdings)
|
||||
if strict {
|
||||
for _, why := range held {
|
||||
problems = append(problems, why)
|
||||
}
|
||||
held = nil
|
||||
}
|
||||
problems = append(problems, checkResources(resolution.Modules)...)
|
||||
resolution.Claims = claims
|
||||
|
||||
@@ -634,6 +619,10 @@ func resolve(catalogue map[string]mcat.Manifest, assigned []string, node mcat.No
|
||||
}
|
||||
|
||||
if len(problems) > 0 {
|
||||
// A pass refused anyway says every reason at once, a held module's among them.
|
||||
for _, why := range held {
|
||||
problems = append(problems, why)
|
||||
}
|
||||
sort.Strings(problems)
|
||||
return mcat.Resolution{}, nil, &Refusal{Problems: problems}
|
||||
}
|
||||
@@ -691,21 +680,8 @@ func checkCapabilities(modules []mcat.Manifest, node mcat.Node) []string {
|
||||
return problems
|
||||
}
|
||||
|
||||
// checkClaims refuses two modules holding one singular thing.
|
||||
//
|
||||
// Within this node's own set, and against what is already held elsewhere for the wider scopes. A
|
||||
// claim at mesh scope is the same idea as the mesh's one hub, said once instead of hard-coded.
|
||||
func checkClaims(modules []mcat.Manifest, node mcat.Node, elsewhere []mcat.Held, holdings []mcat.Held) ([]mcat.Held, []string) {
|
||||
held, problems := claimsOf(modules, node, elsewhere, holdings)
|
||||
var out []string
|
||||
for _, p := range problems {
|
||||
out = append(out, p.why)
|
||||
}
|
||||
return held, out
|
||||
}
|
||||
|
||||
// holdClaims is checkClaims with each problem put on the module that has it: the claims that hold, and for each module that
|
||||
// cannot hold what it claims, why (every reason, joined).
|
||||
// holdClaims refuses two modules holding one singular thing, within this node's own set and against what is held elsewhere for
|
||||
// the wider scopes: the claims that hold, and for each module that cannot hold what it claims, why (every reason, joined).
|
||||
func holdClaims(modules []mcat.Manifest, node mcat.Node, elsewhere []mcat.Held, holdings []mcat.Held) ([]mcat.Held, map[string]string) {
|
||||
held, problems := claimsOf(modules, node, elsewhere, holdings)
|
||||
var out map[string]string
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package resolution
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
)
|
||||
|
||||
// Resolve is ResolveHolding for a test that wants a claim problem as a refusal of the whole set, as before issue 1966.
|
||||
func Resolve(catalogue map[string]mcat.Manifest, assigned []string, node mcat.Node, world mcat.World) (mcat.Resolution, error) {
|
||||
got, held, err := ResolveHolding(catalogue, assigned, node, world)
|
||||
if err != nil {
|
||||
return mcat.Resolution{}, err
|
||||
}
|
||||
if len(held) > 0 {
|
||||
var problems []string
|
||||
for _, why := range held {
|
||||
problems = append(problems, why)
|
||||
}
|
||||
sort.Strings(problems)
|
||||
return mcat.Resolution{}, &Refusal{Problems: problems}
|
||||
}
|
||||
return got, nil
|
||||
}
|
||||
|
||||
// checkClaims is holdClaims with the problems as a list.
|
||||
func checkClaims(modules []mcat.Manifest, node mcat.Node, elsewhere []mcat.Held, holdings []mcat.Held) ([]mcat.Held, []string) {
|
||||
held, why := holdClaims(modules, node, elsewhere, holdings)
|
||||
var problems []string
|
||||
for _, w := range why {
|
||||
problems = append(problems, w)
|
||||
}
|
||||
sort.Strings(problems)
|
||||
return held, problems
|
||||
}
|
||||
Reference in New Issue
Block a user