Extract inheritance input preparation
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Consolidation Implementation Plan
|
# Consolidation Implementation Plan
|
||||||
|
|
||||||
Status: in progress. Stages 1 through 13 are complete; follow Stage 14 through Stage 20 in order.
|
Status: in progress. Stages 1 through 14 are complete; follow Stage 15 through Stage 20 in order.
|
||||||
The target executor is a Luna coding agent working through one end-to-end sprint.
|
The target executor is a Luna coding agent working through one end-to-end sprint.
|
||||||
|
|
||||||
## Authority, Baseline, And Execution
|
## Authority, Baseline, And Execution
|
||||||
@@ -566,7 +566,7 @@ retains containment, identity/cycle checks, graph updates, and recursive
|
|||||||
placement coordination; item placement receives the admitted record directly.
|
placement coordination; item placement receives the admitted record directly.
|
||||||
Validation group A and `./scripts/check.sh` passed.
|
Validation group A and `./scripts/check.sh` passed.
|
||||||
|
|
||||||
## Stage 14 — Extract Inheritance Child And Parent Preparation
|
## Stage 14 — Extract Inheritance Child And Parent Preparation (Complete)
|
||||||
|
|
||||||
**Owners:** engine `inheritance_schedule.go`, new `inheritance_prepare.go`, and
|
**Owners:** engine `inheritance_schedule.go`, new `inheritance_prepare.go`, and
|
||||||
existing scope/policy helpers.
|
existing scope/policy helpers.
|
||||||
@@ -589,6 +589,12 @@ existing scope/policy helpers.
|
|||||||
**Finish:** the executor no longer embeds child/control and parent/policy
|
**Finish:** the executor no longer embeds child/control and parent/policy
|
||||||
preparation. Actual recursive combination/evidence moves in Stage 15.
|
preparation. Actual recursive combination/evidence moves in Stage 15.
|
||||||
|
|
||||||
|
Progress notes (2026-10-25): extracted child/control and parent/policy preparation
|
||||||
|
into focused records in `inheritance_prepare.go`. The executor retains its
|
||||||
|
preliminary budget checks, scheduler, and combination path, while history and
|
||||||
|
transfer inputs stay available to combination. Engine inheritance coverage and
|
||||||
|
facade inheritance tests passed.
|
||||||
|
|
||||||
## Stage 15 — Return One Inheritance Combination Result
|
## Stage 15 — Return One Inheritance Combination Result
|
||||||
|
|
||||||
**Owners:** new engine `inheritance_combine.go`, `inheritance_collection.go`,
|
**Owners:** new engine `inheritance_combine.go`, `inheritance_collection.go`,
|
||||||
|
|||||||
88
internal/engine/inheritance_prepare.go
Normal file
88
internal/engine/inheritance_prepare.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package engine
|
||||||
|
|
||||||
|
import "gitea.maximumdirect.net/eric/ConfigKit/internal/document"
|
||||||
|
|
||||||
|
type preparedInheritanceChild struct {
|
||||||
|
payload *document.Node
|
||||||
|
origins map[string]Origin
|
||||||
|
policyTemplates collectionPolicyScope
|
||||||
|
control *inheritanceControl
|
||||||
|
controlOrigin Origin
|
||||||
|
}
|
||||||
|
|
||||||
|
type preparedInheritanceParent struct {
|
||||||
|
payload *document.Node
|
||||||
|
historyParent *document.Node
|
||||||
|
policyTemplates []collectionPolicyScope
|
||||||
|
effectivePolicyTemplates []collectionPolicyScope
|
||||||
|
parentPolicyScope collectionPolicyScope
|
||||||
|
childPolicyScope collectionPolicyScope
|
||||||
|
replaced collectionReplacementPaths
|
||||||
|
transfer inheritanceTransfer
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareInheritanceChild(template inheritanceExecutionTemplate, inputOrigins map[string]Origin) preparedInheritanceChild {
|
||||||
|
policyTemplates := cloneCollectionPolicyScopeForInheritance(template.collectionPolicies)
|
||||||
|
payload := withoutInheritanceDirective(template.entry.Value)
|
||||||
|
prepared := preparedInheritanceChild{
|
||||||
|
payload: payload, origins: directInheritanceOrigins(payload, template.path, inputOrigins),
|
||||||
|
policyTemplates: policyTemplates,
|
||||||
|
}
|
||||||
|
if template.hasDirective {
|
||||||
|
control := inheritanceControl{
|
||||||
|
path: template.directivePath, locations: []Location{publicLocation(template.directive.Value.Location)},
|
||||||
|
cancelled: template.cancelled,
|
||||||
|
}
|
||||||
|
controlOrigins := directInheritanceOrigins(template.directive.Value, control.path, inputOrigins)
|
||||||
|
prepared.control = &control
|
||||||
|
prepared.controlOrigin = controlOrigins[control.path.String()]
|
||||||
|
}
|
||||||
|
return prepared
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareInheritanceParent(
|
||||||
|
template inheritanceExecutionTemplate,
|
||||||
|
parentPath Path,
|
||||||
|
parent *document.Node,
|
||||||
|
resolvedParentPolicyTemplates []collectionPolicyScope,
|
||||||
|
resolvedParentPolicies collectionPolicyScope,
|
||||||
|
child preparedInheritanceChild,
|
||||||
|
applicationPolicy sequencePolicy,
|
||||||
|
) preparedInheritanceParent {
|
||||||
|
parentPolicies := cloneInheritancePolicyTemplates(resolvedParentPolicyTemplates)
|
||||||
|
effectivePolicies := append(
|
||||||
|
cloneInheritancePolicyTemplates(parentPolicies),
|
||||||
|
cloneCollectionPolicyScopeForInheritance(child.policyTemplates),
|
||||||
|
)
|
||||||
|
parentPolicyScope := projectInheritanceCollectionPolicies(resolvedParentPolicies, template.path)
|
||||||
|
childPolicyScope := projectCurrentInheritanceCollectionPolicies(child.policyTemplates, template.path)
|
||||||
|
var replaced collectionReplacementPaths
|
||||||
|
if len(parentPolicyScope.collections) != 0 || len(childPolicyScope.collections) != 0 {
|
||||||
|
claims := compositionClaims{byPath: make(map[string][]compositionClaim)}
|
||||||
|
claims.append(child.payload, template.path, 0)
|
||||||
|
declarations := make(map[string][]sequenceDeclarationSpec, len(childPolicyScope.collections))
|
||||||
|
for key, entry := range childPolicyScope.collections {
|
||||||
|
declarations[key] = inheritanceDeclarationsAt(entry.destination, entry.policy)
|
||||||
|
}
|
||||||
|
parentPolicyScope, replaced = lowerCollectionPoliciesForClaims(parentPolicyScope, claims.ordered, declarations, applicationPolicy)
|
||||||
|
}
|
||||||
|
parentPayload := inheritanceParentPayload(parent, template.identityFields)
|
||||||
|
historyParent := parent
|
||||||
|
if len(template.identityFields) != 0 {
|
||||||
|
// The retained parent snapshot is the inherited payload, before child
|
||||||
|
// fields are applied, with parent identity excluded.
|
||||||
|
historyParent = document.Clone(parentPayload)
|
||||||
|
}
|
||||||
|
transfer := inheritanceTransfer{
|
||||||
|
from: parentPath, to: template.path, reference: template.directivePath,
|
||||||
|
locations: []Location{publicLocation(template.directive.Value.Location)},
|
||||||
|
policyTemplates: parentPolicies, templatePolicies: cloneCollectionPolicyScopeForInheritance(child.policyTemplates),
|
||||||
|
projectedPolicies: projectInheritancePolicyTemplates([]collectionPolicyScope{resolvedParentPolicies}, template.path),
|
||||||
|
}
|
||||||
|
return preparedInheritanceParent{
|
||||||
|
payload: parentPayload, historyParent: historyParent,
|
||||||
|
policyTemplates: parentPolicies, effectivePolicyTemplates: effectivePolicies,
|
||||||
|
parentPolicyScope: parentPolicyScope, childPolicyScope: childPolicyScope,
|
||||||
|
replaced: replaced, transfer: transfer,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -188,27 +188,19 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
|
|||||||
|
|
||||||
for _, index := range order {
|
for _, index := range order {
|
||||||
node := templates[index]
|
node := templates[index]
|
||||||
templatePolicies := cloneCollectionPolicyScopeForInheritance(node.collectionPolicies)
|
|
||||||
payload := withoutInheritanceDirective(node.entry.Value)
|
|
||||||
operationStart, replacementStart := len(result.operations), len(result.replacements)
|
operationStart, replacementStart := len(result.operations), len(result.replacements)
|
||||||
childOrigins := directInheritanceOrigins(payload, node.path, inputOrigins)
|
child := prepareInheritanceChild(node, inputOrigins)
|
||||||
if node.hasDirective {
|
if child.control != nil {
|
||||||
control := inheritanceControl{
|
result.controls = append(result.controls, *child.control)
|
||||||
path: node.directivePath,
|
|
||||||
locations: []Location{publicLocation(node.directive.Value.Location)},
|
|
||||||
cancelled: node.cancelled,
|
|
||||||
}
|
|
||||||
result.controls = append(result.controls, control)
|
|
||||||
controlOrigins := directInheritanceOrigins(node.directive.Value, control.path, inputOrigins)
|
|
||||||
result.operations = append(result.operations, inheritanceOperation{
|
result.operations = append(result.operations, inheritanceOperation{
|
||||||
control: &control, controlOrigin: controlOrigins[control.path.String()],
|
control: child.control, controlOrigin: child.controlOrigin,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if limits.nodes >= 0 {
|
if limits.nodes >= 0 {
|
||||||
remaining := limits.nodes - retained - adapter.slotOverhead()
|
remaining := limits.nodes - retained - adapter.slotOverhead()
|
||||||
within := inheritanceLowerBoundWithin(payload, remaining)
|
within := inheritanceLowerBoundWithin(child.payload, remaining)
|
||||||
if node.hasParent {
|
if node.hasParent {
|
||||||
within = inheritanceOverlayLowerBoundWithin(resolved[node.parent], payload, remaining)
|
within = inheritanceOverlayLowerBoundWithin(resolved[node.parent], child.payload, remaining)
|
||||||
}
|
}
|
||||||
if !within {
|
if !within {
|
||||||
return nil, []Diagnostic{inheritanceBudgetDiagnostic(node.path, node.entry.Value.Location)}
|
return nil, []Diagnostic{inheritanceBudgetDiagnostic(node.path, node.entry.Value.Location)}
|
||||||
@@ -217,65 +209,41 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
|
|||||||
|
|
||||||
if node.hasParent {
|
if node.hasParent {
|
||||||
parent := resolved[node.parent]
|
parent := resolved[node.parent]
|
||||||
parentPolicies := cloneInheritancePolicyTemplates(resolvedPolicyTemplates[node.parent])
|
preparedParent := prepareInheritanceParent(
|
||||||
effectivePolicies := append(cloneInheritancePolicyTemplates(parentPolicies), cloneCollectionPolicyScopeForInheritance(templatePolicies))
|
node, templates[node.parent].path, parent, resolvedPolicyTemplates[node.parent],
|
||||||
parentPolicyScope := projectInheritanceCollectionPolicies(resolvedPolicies[node.parent], node.path)
|
resolvedPolicies[node.parent], child, adapter.applicationPolicy(),
|
||||||
childPolicyScope := projectCurrentInheritanceCollectionPolicies(templatePolicies, node.path)
|
)
|
||||||
var replaced collectionReplacementPaths
|
|
||||||
if len(parentPolicyScope.collections) != 0 || len(childPolicyScope.collections) != 0 {
|
|
||||||
claims := compositionClaims{byPath: make(map[string][]compositionClaim)}
|
|
||||||
claims.append(payload, node.path, 0)
|
|
||||||
declarations := make(map[string][]sequenceDeclarationSpec, len(childPolicyScope.collections))
|
|
||||||
for key, entry := range childPolicyScope.collections {
|
|
||||||
declarations[key] = inheritanceDeclarationsAt(entry.destination, entry.policy)
|
|
||||||
}
|
|
||||||
parentPolicyScope, replaced = lowerCollectionPoliciesForClaims(parentPolicyScope, claims.ordered, declarations, adapter.applicationPolicy())
|
|
||||||
}
|
|
||||||
merged := inheritanceParentPayload(parent, node.identityFields)
|
|
||||||
historyParent := parent
|
|
||||||
if len(node.identityFields) != 0 {
|
|
||||||
// The retained parent snapshot is the inherited payload, before
|
|
||||||
// child fields are applied, with parent identity excluded.
|
|
||||||
historyParent = document.Clone(merged)
|
|
||||||
}
|
|
||||||
mergedPolicyScope, policyDiagnostics := mergeInheritanceCollectionPolicies(
|
mergedPolicyScope, policyDiagnostics := mergeInheritanceCollectionPolicies(
|
||||||
parentPolicyScope, childPolicyScope, node.path, parent, payload, adapter.applicationPolicy(), replaced,
|
preparedParent.parentPolicyScope, preparedParent.childPolicyScope,
|
||||||
|
node.path, preparedParent.payload, child.payload,
|
||||||
|
adapter.applicationPolicy(), preparedParent.replaced,
|
||||||
)
|
)
|
||||||
if len(policyDiagnostics) != 0 {
|
if len(policyDiagnostics) != 0 {
|
||||||
return nil, policyDiagnostics
|
return nil, policyDiagnostics
|
||||||
}
|
}
|
||||||
transfer := inheritanceTransfer{
|
mergedOrigins := transferredInheritanceOrigins(resolvedOrigins[node.parent], preparedParent.transfer.from, node.path, preparedParent.transfer)
|
||||||
from: templates[node.parent].path, to: node.path,
|
mergeInheritanceOrigin(mergedOrigins, node.path, child.origins[node.path.String()])
|
||||||
reference: node.directivePath,
|
|
||||||
locations: []Location{publicLocation(node.directive.Value.Location)},
|
|
||||||
policyTemplates: parentPolicies, templatePolicies: cloneCollectionPolicyScopeForInheritance(templatePolicies),
|
|
||||||
projectedPolicies: projectInheritancePolicyTemplates(
|
|
||||||
[]collectionPolicyScope{resolvedPolicies[node.parent]}, node.path,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
mergedOrigins := transferredInheritanceOrigins(resolvedOrigins[node.parent], transfer.from, node.path, transfer)
|
|
||||||
mergeInheritanceOrigin(mergedOrigins, node.path, childOrigins[node.path.String()])
|
|
||||||
var sequenceContributions []sequenceHistoryContribution
|
var sequenceContributions []sequenceHistoryContribution
|
||||||
var combinationDiagnostics []Diagnostic
|
var combinationDiagnostics []Diagnostic
|
||||||
mergeRecursiveMappings(merged, payload, node.path, new(mappingIndex), recursiveMergeHooks{
|
mergeRecursiveMappings(preparedParent.payload, child.payload, node.path, new(mappingIndex), recursiveMergeHooks{
|
||||||
added: func(childPath Path, incoming *document.Node) {
|
added: func(childPath Path, incoming *document.Node) {
|
||||||
copyInheritanceSubtree(mergedOrigins, childOrigins, incoming, childPath)
|
copyInheritanceSubtree(mergedOrigins, child.origins, incoming, childPath)
|
||||||
},
|
},
|
||||||
combined: func(childPath Path, _ *document.Node) {
|
combined: func(childPath Path, _ *document.Node) {
|
||||||
mergeInheritanceOrigin(mergedOrigins, childPath, childOrigins[childPath.String()])
|
mergeInheritanceOrigin(mergedOrigins, childPath, child.origins[childPath.String()])
|
||||||
},
|
},
|
||||||
replaced: func(childPath Path, existing, incoming *document.Node) {
|
replaced: func(childPath Path, existing, incoming *document.Node) {
|
||||||
previous := displacedOrigins(existing, mergedOrigins, childPath)
|
previous := displacedOrigins(existing, mergedOrigins, childPath)
|
||||||
result.replacements = append(result.replacements, inheritanceReplacement{
|
result.replacements = append(result.replacements, inheritanceReplacement{
|
||||||
path: childPath.clone(), before: existing, after: incoming,
|
path: childPath.clone(), before: existing, after: incoming,
|
||||||
previous: previous, effective: cloneOrigin(childOrigins[childPath.String()]),
|
previous: previous, effective: cloneOrigin(child.origins[childPath.String()]),
|
||||||
})
|
})
|
||||||
deleteOriginSubtree(mergedOrigins, childPath, existing)
|
deleteOriginSubtree(mergedOrigins, childPath, existing)
|
||||||
copyInheritanceSubtree(mergedOrigins, childOrigins, incoming, childPath)
|
copyInheritanceSubtree(mergedOrigins, child.origins, incoming, childPath)
|
||||||
},
|
},
|
||||||
merge: func(childPath Path, existing, incoming *document.Node) (*document.Node, bool) {
|
merge: func(childPath Path, existing, incoming *document.Node) (*document.Node, bool) {
|
||||||
resolution, _, _, active, issues := inheritanceCollectionResolution(
|
resolution, _, _, active, issues := inheritanceCollectionResolution(
|
||||||
childPath, parentPolicyScope, childPolicyScope, adapter.applicationPolicy(), incoming,
|
childPath, preparedParent.parentPolicyScope, preparedParent.childPolicyScope, adapter.applicationPolicy(), incoming,
|
||||||
)
|
)
|
||||||
if len(issues) != 0 {
|
if len(issues) != 0 {
|
||||||
combinationDiagnostics = append(combinationDiagnostics, issues...)
|
combinationDiagnostics = append(combinationDiagnostics, issues...)
|
||||||
@@ -291,11 +259,11 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
|
|||||||
return existing, false
|
return existing, false
|
||||||
}
|
}
|
||||||
policy := applyInheritanceSequencePolicy(
|
policy := applyInheritanceSequencePolicy(
|
||||||
childPath, combined, resolution, parentPolicyScope, childPolicyScope,
|
childPath, combined, resolution, preparedParent.parentPolicyScope, preparedParent.childPolicyScope,
|
||||||
)
|
)
|
||||||
mergedPolicyScope.set(childPath, policy)
|
mergedPolicyScope.set(childPath, policy)
|
||||||
applyInheritanceSequenceOrigins(
|
applyInheritanceSequenceOrigins(
|
||||||
result, mergedOrigins, childOrigins, childPath, lowerValue, incoming, combined, resolution.operation,
|
result, mergedOrigins, child.origins, childPath, lowerValue, incoming, combined, resolution.operation,
|
||||||
)
|
)
|
||||||
history := sequenceHistoryContribution{path: childPath.clone(), mode: sequenceHistoryMapped}
|
history := sequenceHistoryContribution{path: childPath.clone(), mode: sequenceHistoryMapped}
|
||||||
if resolution.operation == sequenceModeReplace {
|
if resolution.operation == sequenceModeReplace {
|
||||||
@@ -311,32 +279,32 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
|
|||||||
return combined.value, true
|
return combined.value, true
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
preserveInheritanceIdentityFields(merged, payload, node.identityFields)
|
preserveInheritanceIdentityFields(preparedParent.payload, child.payload, node.identityFields)
|
||||||
if len(combinationDiagnostics) != 0 {
|
if len(combinationDiagnostics) != 0 {
|
||||||
return nil, canonicalDiagnostics(combinationDiagnostics)
|
return nil, canonicalDiagnostics(combinationDiagnostics)
|
||||||
}
|
}
|
||||||
if problems := validateRegisteredInheritanceSequences(merged, node.path, adapter.applicationPolicy()); len(problems) != 0 {
|
if problems := validateRegisteredInheritanceSequences(preparedParent.payload, node.path, adapter.applicationPolicy()); len(problems) != 0 {
|
||||||
return nil, problems
|
return nil, problems
|
||||||
}
|
}
|
||||||
merged.Location = node.entry.Value.Location
|
preparedParent.payload.Location = node.entry.Value.Location
|
||||||
resolved[index], resolvedOrigins[index] = merged, mergedOrigins
|
resolved[index], resolvedOrigins[index] = preparedParent.payload, mergedOrigins
|
||||||
resolvedPolicies[index] = inheritancePolicyScopeAtPath(mergedPolicyScope, node.path)
|
resolvedPolicies[index] = inheritancePolicyScopeAtPath(mergedPolicyScope, node.path)
|
||||||
result.transfers = append(result.transfers, transfer)
|
result.transfers = append(result.transfers, preparedParent.transfer)
|
||||||
result.operations = append(result.operations, inheritanceOperation{
|
result.operations = append(result.operations, inheritanceOperation{
|
||||||
transfer: &transfer, parent: historyParent, effective: merged,
|
transfer: &preparedParent.transfer, parent: preparedParent.historyParent, effective: preparedParent.payload,
|
||||||
parentOrigins: resolvedOrigins[node.parent], effectiveOrigins: mergedOrigins,
|
parentOrigins: resolvedOrigins[node.parent], effectiveOrigins: mergedOrigins,
|
||||||
parentPolicies: cloneInheritancePolicyTemplates(parentPolicies),
|
parentPolicies: cloneInheritancePolicyTemplates(preparedParent.policyTemplates),
|
||||||
templatePolicies: cloneCollectionPolicyScopeForInheritance(templatePolicies),
|
templatePolicies: cloneCollectionPolicyScopeForInheritance(child.policyTemplates),
|
||||||
effectivePolicies: cloneInheritancePolicyTemplates(effectivePolicies),
|
effectivePolicies: cloneInheritancePolicyTemplates(preparedParent.effectivePolicyTemplates),
|
||||||
sequences: cloneSequenceHistoryContributions(sequenceContributions),
|
sequences: cloneSequenceHistoryContributions(sequenceContributions),
|
||||||
identityFields: cloneStrings(node.identityFields),
|
identityFields: cloneStrings(node.identityFields),
|
||||||
})
|
})
|
||||||
resolvedPolicyTemplates[index] = effectivePolicies
|
resolvedPolicyTemplates[index] = preparedParent.effectivePolicyTemplates
|
||||||
} else {
|
} else {
|
||||||
resolved[index] = document.Clone(payload)
|
resolved[index] = document.Clone(child.payload)
|
||||||
resolvedOrigins[index] = childOrigins
|
resolvedOrigins[index] = child.origins
|
||||||
resolvedPolicyTemplates[index] = []collectionPolicyScope{templatePolicies}
|
resolvedPolicyTemplates[index] = []collectionPolicyScope{child.policyTemplates}
|
||||||
resolvedPolicies[index] = cloneCollectionPolicyScopeForInheritance(templatePolicies)
|
resolvedPolicies[index] = cloneCollectionPolicyScopeForInheritance(child.policyTemplates)
|
||||||
}
|
}
|
||||||
|
|
||||||
count, _ := inheritanceLowerBoundCount(resolved[index], limits.nodes)
|
count, _ := inheritanceLowerBoundCount(resolved[index], limits.nodes)
|
||||||
|
|||||||
Reference in New Issue
Block a user