{"record":{"id":"5cd68862b18437bb","repo":"Egonex-AI/Understand-Anything","slug":"unresolved-incremental-symbol-loss-baseline-not-a","errorCode":null,"errorMessage":"Unresolved incremental symbol loss; baseline not advanced","messagePattern":"Unresolved incremental symbol loss; baseline not advanced","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"understand-anything-plugin/skills/understand/finalize-incremental.mjs","lineNumber":477,"sourceCode":"    const graph = {\n      ...previousGraph,\n      version: previousGraph.version ?? '1.0.0',\n      project: {\n        ...projectMetadata(previousGraph.project, plan, scan),\n        analyzedAt: now,\n      },\n      nodes: assembled.nodes,\n      edges: assembled.edges,\n      layers: assignLayers(rawLayers, assembled.nodes, assembled.edges),\n      tour: normalizeTour(rawTour, nodeIds, pathIndex),\n    };\n\n    // Ordering is intentional: a failed graph save must never advance the\n    // structural baseline and hide the failed update from the next run.\n    // Recheck the actual graph being saved, never trust a prior merge report.\n    const symbolReport = await validateIncrementalSymbols(projectRoot, { graph, intermediateDir });\n    process.stderr.write(`${formatSymbolReport(symbolReport)}\\n`);\n    if (!symbolReport.ok) throw new Error('Unresolved incremental symbol loss; baseline not advanced');\n    atomicWriteJson(graphPath, graph);\n  }\n\n  patchFingerprints(uaDir, plan, patch);\n  advanceMeta(uaDir, plan, scan.totalFiles);\n  process.stdout.write(\n    `Incremental update finalized: ${plan.action}; analyzedFiles=${scan.totalFiles}\\n`,\n  );\n}\n\nfunction isCliEntry() {\n  if (!process.argv[1]) return false;\n  try {\n    return realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1]);\n  } catch {\n    return false;\n  }\n}","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/Egonex-AI/Understand-Anything/blob/07edf82a04371b6f69779b067bdc8a1a8753a9db/understand-anything-plugin/skills/understand/finalize-incremental.mjs#L459-L495","documentation":"Before saving the merged incremental graph, finalize-incremental.mjs runs validateIncrementalSymbols to re-verify that the graph being saved contains no lost symbols relative to the previous graph and the patch. If the symbol report is not ok, the save is aborted and the baseline is not advanced — a deliberate safety ordering so a lossy merge never silently replaces knowledge-graph.json.","triggerScenarios":"Running finalize-incremental.mjs where the assembled graph (merged with previous nodes/edges) drops symbols: re-analyzed files lose whole-file or symbol nodes that the previous graph and fingerprint patch still reference, e.g. an agent returned partial output for a changed file, or normalization dropped nodes with missing/invalid ids.","commonSituations":"An LLM analysis pass returned truncated/incomplete node lists for re-analyzed files; a bug or schema change in the assembling agent's output caused nodes to be dropped during normalizeAssembled; concurrency — the baseline advanced while another process modified .ua/ files, so the patch and graph disagree.","solutions":["Inspect .ua/intermediate/incremental-symbol-report.json (and stderr report) to see which symbols/paths were lost, then re-run the analysis for the affected files so the assembled graph includes them.","Delete the stale .ua/intermediate/ artifacts and re-run the incremental pipeline from prepare-incremental.mjs so the merge is redone against a consistent baseline.","If the baseline itself is suspect, run the full /understand pipeline instead of the incremental path to rebuild knowledge-graph.json from scratch.","Check the fingerprint patch matches the current plan commits (finalize also validates this) and that no concurrent finalize is running against the same .ua/ directory."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// after assembling, before finalizing, check the report yourself\nimport { existsSync, readFileSync } from 'node:fs';\nconst reportPath = join(uaDir, 'intermediate', 'incremental-symbol-report.json');\nif (existsSync(reportPath)) {\n  const report = JSON.parse(readFileSync(reportPath, 'utf-8'));\n  if (report && report.ok === false) {\n    console.error('Symbol loss detected:', report.missing ?? report);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await finalizeIncremental(projectRoot);\n} catch (err) {\n  if (String(err.message).includes('Unresolved incremental symbol loss')) {\n    const report = JSON.parse(readFileSync(join(uaDir, 'intermediate', 'incremental-symbol-report.json'), 'utf-8'));\n    console.error('Re-analyze affected files:', report);\n  } else throw err;\n}","preventionTips":["Ensure re-analyzed files emit complete node lists (all symbols in the file), not just changed symbols — the validator compares against the previous graph.","Avoid concurrent finalize runs against the same .ua/ directory; the baseline and patch must stay in sync.","When the validator repeatedly flags loss, fall back to a full /understand run to rebuild the graph deterministically."],"tags":["pipeline","data-integrity","symbol-validation","incremental-analysis"],"backgroundTag":"schema-validation-failed","analyzedSha":"07edf82a04371b6f69779b067bdc8a1a8753a9db","analyzedAt":"2026-09-07T23:20:10.829Z","contentChangedAt":"2026-09-07T23:20:10.829Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}