Complete historical inventory and query services

This commit is contained in:
2026-10-26 16:09:32 +00:00
parent cacc558288
commit 76521f7cd8
13 changed files with 311 additions and 78 deletions

View File

@@ -58,6 +58,8 @@ type historyModel struct {
observations []historyObservation
attributions []historyAttribution
baseline *document.Node
final *document.Node
inventoryRoots []*document.Node
sourcePayloads []historySourcePayload
inheritancePayloads []historyInheritancePayload
cliPayloads []historySourcePayload
@@ -69,6 +71,7 @@ type historyModel struct {
shapeOrder []Path
observationsByPointer map[string][]int
reportedPathIndex pathPrefixIndex
documentLookup *documentLookup
frozen bool
}
@@ -134,21 +137,33 @@ func (builder *historyBuilder) addObservation(observation historyObservation) in
}
func (builder *historyBuilder) observeDocument(root *document.Node, phase historyPhase) {
builder.observeDocumentAt(root, Path{}, phase)
}
func (builder *historyBuilder) observeDocumentAt(root *document.Node, prefix Path, phase historyPhase) {
builder.requireOpen()
if root == nil {
return
}
builder.registerDocumentRoot(root)
payload := builder.nextPayload(phase)
walkDocument(root, Path{}, func(path Path, node *document.Node) {
builder.addObservation(historyObservation{
path: path,
phase: phase,
payload: payload,
reportedPath: path,
role: historyRoleInventory,
sensitive: node.Sensitive,
attributionRef: noHistoryAttribution,
})
walkDocument(root, prefix, func(path Path, node *document.Node) {
builder.addInventoryObservation(path, path, payload, phase, node.Sensitive)
})
}
func (builder *historyBuilder) registerDocumentRoot(root *document.Node) {
builder.requireOpen()
if root != nil {
builder.model.inventoryRoots = append(builder.model.inventoryRoots, root)
}
}
func (builder *historyBuilder) addInventoryObservation(path, reportedPath Path, payload historyPayloadRef, phase historyPhase, sensitive bool) int {
return builder.addObservation(historyObservation{
path: path, phase: phase, payload: payload,
reportedPath: reportedPath, role: historyRoleInventory,
sensitive: sensitive, attributionRef: noHistoryAttribution,
})
}
@@ -173,6 +188,7 @@ func (builder *historyBuilder) advanceScratch(root *document.Node) {
func (builder *historyBuilder) freeze() *historyModel {
builder.requireOpen()
builder.scratch = nil
builder.model.documentLookup = buildDocumentLookup(builder.model.documentRoots()...)
builder.model.frozen = true
model := builder.model
builder.model = nil
@@ -180,6 +196,48 @@ func (builder *historyBuilder) freeze() *historyModel {
return model
}
func (model *historyModel) documentRoots() []*document.Node {
if model == nil {
return nil
}
roots := append([]*document.Node(nil), model.inventoryRoots...)
roots = append(roots, model.baseline, model.final)
for _, payload := range model.sourcePayloads {
if payload.kind == historySourceApplicationPayload {
roots = append(roots, payload.application.value)
}
}
for _, payload := range model.inheritancePayloads {
for _, operation := range payload.operations {
roots = append(roots, operation.parent, operation.effective)
}
}
for _, payload := range model.cliPayloads {
if payload.kind == historySourceApplicationPayload {
roots = append(roots, payload.application.value)
}
}
if model.preCLICheckpoint != nil {
roots = append(roots, model.preCLICheckpoint.root)
}
if model.postCLICheckpoint != nil {
roots = append(roots, model.postCLICheckpoint.root)
}
if model.resolutionPayload != nil {
for _, snapshot := range model.resolutionPayload.snapshots {
roots = append(roots, snapshot.before, snapshot.after)
}
}
return roots
}
func (model *historyModel) documentAt(root *document.Node, path Path) (*document.Node, bool) {
if model == nil || model.documentLookup == nil {
return nil, false
}
return documentAtPathWithLookup(root, path, model.documentLookup)
}
func (builder *historyBuilder) addShape(path Path) {
pointer := path.String()
for _, existing := range builder.model.shapesByPointer[pointer] {