Extract inheritance input preparation

This commit is contained in:
2026-10-25 13:32:01 +00:00
parent 729c6fb5d5
commit f404168900
3 changed files with 133 additions and 71 deletions

View File

@@ -1,6 +1,6 @@
# 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.
## 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.
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
existing scope/policy helpers.
@@ -589,6 +589,12 @@ existing scope/policy helpers.
**Finish:** the executor no longer embeds child/control and parent/policy
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
**Owners:** new engine `inheritance_combine.go`, `inheritance_collection.go`,

View 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,
}
}

View File

@@ -188,27 +188,19 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
for _, index := range order {
node := templates[index]
templatePolicies := cloneCollectionPolicyScopeForInheritance(node.collectionPolicies)
payload := withoutInheritanceDirective(node.entry.Value)
operationStart, replacementStart := len(result.operations), len(result.replacements)
childOrigins := directInheritanceOrigins(payload, node.path, inputOrigins)
if node.hasDirective {
control := inheritanceControl{
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)
child := prepareInheritanceChild(node, inputOrigins)
if child.control != nil {
result.controls = append(result.controls, *child.control)
result.operations = append(result.operations, inheritanceOperation{
control: &control, controlOrigin: controlOrigins[control.path.String()],
control: child.control, controlOrigin: child.controlOrigin,
})
}
if limits.nodes >= 0 {
remaining := limits.nodes - retained - adapter.slotOverhead()
within := inheritanceLowerBoundWithin(payload, remaining)
within := inheritanceLowerBoundWithin(child.payload, remaining)
if node.hasParent {
within = inheritanceOverlayLowerBoundWithin(resolved[node.parent], payload, remaining)
within = inheritanceOverlayLowerBoundWithin(resolved[node.parent], child.payload, remaining)
}
if !within {
return nil, []Diagnostic{inheritanceBudgetDiagnostic(node.path, node.entry.Value.Location)}
@@ -217,65 +209,41 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
if node.hasParent {
parent := resolved[node.parent]
parentPolicies := cloneInheritancePolicyTemplates(resolvedPolicyTemplates[node.parent])
effectivePolicies := append(cloneInheritancePolicyTemplates(parentPolicies), cloneCollectionPolicyScopeForInheritance(templatePolicies))
parentPolicyScope := projectInheritanceCollectionPolicies(resolvedPolicies[node.parent], node.path)
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)
}
preparedParent := prepareInheritanceParent(
node, templates[node.parent].path, parent, resolvedPolicyTemplates[node.parent],
resolvedPolicies[node.parent], child, adapter.applicationPolicy(),
)
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 {
return nil, policyDiagnostics
}
transfer := inheritanceTransfer{
from: templates[node.parent].path, to: node.path,
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()])
mergedOrigins := transferredInheritanceOrigins(resolvedOrigins[node.parent], preparedParent.transfer.from, node.path, preparedParent.transfer)
mergeInheritanceOrigin(mergedOrigins, node.path, child.origins[node.path.String()])
var sequenceContributions []sequenceHistoryContribution
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) {
copyInheritanceSubtree(mergedOrigins, childOrigins, incoming, childPath)
copyInheritanceSubtree(mergedOrigins, child.origins, incoming, childPath)
},
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) {
previous := displacedOrigins(existing, mergedOrigins, childPath)
result.replacements = append(result.replacements, inheritanceReplacement{
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)
copyInheritanceSubtree(mergedOrigins, childOrigins, incoming, childPath)
copyInheritanceSubtree(mergedOrigins, child.origins, incoming, childPath)
},
merge: func(childPath Path, existing, incoming *document.Node) (*document.Node, bool) {
resolution, _, _, active, issues := inheritanceCollectionResolution(
childPath, parentPolicyScope, childPolicyScope, adapter.applicationPolicy(), incoming,
childPath, preparedParent.parentPolicyScope, preparedParent.childPolicyScope, adapter.applicationPolicy(), incoming,
)
if len(issues) != 0 {
combinationDiagnostics = append(combinationDiagnostics, issues...)
@@ -291,11 +259,11 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
return existing, false
}
policy := applyInheritanceSequencePolicy(
childPath, combined, resolution, parentPolicyScope, childPolicyScope,
childPath, combined, resolution, preparedParent.parentPolicyScope, preparedParent.childPolicyScope,
)
mergedPolicyScope.set(childPath, policy)
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}
if resolution.operation == sequenceModeReplace {
@@ -311,32 +279,32 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
return combined.value, true
},
})
preserveInheritanceIdentityFields(merged, payload, node.identityFields)
preserveInheritanceIdentityFields(preparedParent.payload, child.payload, node.identityFields)
if len(combinationDiagnostics) != 0 {
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
}
merged.Location = node.entry.Value.Location
resolved[index], resolvedOrigins[index] = merged, mergedOrigins
preparedParent.payload.Location = node.entry.Value.Location
resolved[index], resolvedOrigins[index] = preparedParent.payload, mergedOrigins
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{
transfer: &transfer, parent: historyParent, effective: merged,
transfer: &preparedParent.transfer, parent: preparedParent.historyParent, effective: preparedParent.payload,
parentOrigins: resolvedOrigins[node.parent], effectiveOrigins: mergedOrigins,
parentPolicies: cloneInheritancePolicyTemplates(parentPolicies),
templatePolicies: cloneCollectionPolicyScopeForInheritance(templatePolicies),
effectivePolicies: cloneInheritancePolicyTemplates(effectivePolicies),
parentPolicies: cloneInheritancePolicyTemplates(preparedParent.policyTemplates),
templatePolicies: cloneCollectionPolicyScopeForInheritance(child.policyTemplates),
effectivePolicies: cloneInheritancePolicyTemplates(preparedParent.effectivePolicyTemplates),
sequences: cloneSequenceHistoryContributions(sequenceContributions),
identityFields: cloneStrings(node.identityFields),
})
resolvedPolicyTemplates[index] = effectivePolicies
resolvedPolicyTemplates[index] = preparedParent.effectivePolicyTemplates
} else {
resolved[index] = document.Clone(payload)
resolvedOrigins[index] = childOrigins
resolvedPolicyTemplates[index] = []collectionPolicyScope{templatePolicies}
resolvedPolicies[index] = cloneCollectionPolicyScopeForInheritance(templatePolicies)
resolved[index] = document.Clone(child.payload)
resolvedOrigins[index] = child.origins
resolvedPolicyTemplates[index] = []collectionPolicyScope{child.policyTemplates}
resolvedPolicies[index] = cloneCollectionPolicyScopeForInheritance(child.policyTemplates)
}
count, _ := inheritanceLowerBoundCount(resolved[index], limits.nodes)