Skip to content

feat(#5904): description side-table — enrichment writeback stops rewriting graph.fb (#5915 P1)#5918

Merged
cajasmota merged 3 commits into
mainfrom
worktree-agent-a6010554c28fca1e6
Jul 22, 2026
Merged

feat(#5904): description side-table — enrichment writeback stops rewriting graph.fb (#5915 P1)#5918
cajasmota merged 3 commits into
mainfrom
worktree-agent-a6010554c28fca1e6

Conversation

@cajasmota

Copy link
Copy Markdown
Owner

What

Moves entity description enrichment off the graph rewrite and onto a per-repo side-table (<stateDir>/descriptions.json), merged back at read time — the first #5904(e) slice and the #5915 P1 fix (enrichment must not rewrite graph.fb, which under the segmented format would force a whole-graph collapse).

Slices

  1. internal/graph/descriptions — per-repo side-table {version, computed_at, source_key, results: map[entityID]string}, atomic tmp+rename (split Unix/Windows), Read→(nil,false) on absent/corrupt/stale (source-key vs CurrentGraphDescriptor), Upsert.
  2. Read-time overlayapplyDescriptionOverlay merges the sidecar in both the MCP mmap path (LabelIndex.descOverlay in materializeFromReader) and the Doc path, additively (never clobbers a baked-in description), memoized by sidecar mtime under the existing readerMu/readRetired safety.
  3. Writeback repointhandleEnrichmentWriteback Target 1 now calls descriptions.Upsert + invalidate instead of WriteGraphGen+WriteAtomic (no graph rewrite). Markdown + audit targets unchanged.

Verification (independent adversarial review — APPROVE)

  • Never-clobber proven: unconditional-clobber mutation → TestDescOverlay_Absent_NoClobber + mmap variant both RED.
  • No graph rewrite proven: re-inserting WriteAtomicTestWriteback_success RED; segment-set collapse path is gone.
  • Flat parity (flag on/off), segment-set source-key (gen-dir+manifest mtime), -race ×10 clean, full mcp/dashboard/descriptions suites green.

Segment-set mmap serving deferred to #5912 (Doc-stamp is the operative merge there for now).

Refs #5904
Refs #5915

🤖 Generated with Claude Code

jcajasmc and others added 3 commits July 22, 2026 23:58
… slice 1)

Add internal/graph/descriptions: a per-repo <stateDir>/descriptions.json
side-table (version, computed_at, source_key, results map[id]string) with an
atomic tmp+rename write (Windows-safe split file), absence/corrupt/stale-
tolerant Read, and an Upsert read-modify-write. The source-freshness key is
derived from graph.CurrentGraphDescriptor (segment-set -> gen-dir/manifest
mtime; single-file -> .fb mtime; JSON-only -> graph.json mtime), never the
collapsed single-file path (5915 P2 discipline).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017quGgaqK7NRoxGT6BTqV2o
…slice 2)

Merge the per-repo <stateDir>/descriptions.json side-table onto entities at
READ time, mirroring the group-algo overlay:

- internal/mcp: applyDescriptionOverlay stamps PropSet("description") onto
  lr.Doc.Entities (flag-OFF Doc path) and builds a LabelIndex.descOverlay
  index-keyed table for the flag-ON mmap path (materializeFromReader /
  materializeEntityOverlay additively PropSet it). Per-repo memoized by the
  sidecar mtime + the repo reparse mtime; applied on reload and re-checked on
  the Group() serving path. Absence/corrupt/stale -> no-op; a miss never clears
  an entity's baked-in/extractor-native description (ADDITIVE guarantee).
- internal/dashboard: loadGroupForRef merges the sidecar onto DashRepo.Doc so
  the PropGet("description") consumers (openapi/DAG export) surface write-back
  descriptions now that write-back no longer bakes them into the graph.

Tests cover single-file (Doc + mmap paths), segment-set (Doc path; the MCP
serve path serves a segment-set from the collapsed Doc, Reader nil), the
additive no-clobber guarantee, and stale-after-reindex no-op.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017quGgaqK7NRoxGT6BTqV2o
…ide-table (#5904 PR-a slice 3)

handleEnrichmentWriteback Target 1 no longer rewrites the whole graph
(fbwriter.WriteGraphGen + graph.WriteAtomic on graph.json). It now upserts the
description into <stateDir>/descriptions.json (source key from the graph
descriptor) and invalidates the group cache so the next load re-merges the
sidecar. The in-memory PropSet is kept for immediate visibility of the resident
group; Target 2 (markdown doc) and Target 3 (audit) are unchanged.

This removes the #5915 P1 hazard: for a #5901 segment-set the resident Document
is a COLLAPSED union of every segment, so re-serialising it as one flat
graph.<gen>.fb re-materialised the whole graph in memory (OOM) and discarded the
segmented layout. The side-table leaves the graph file / generation untouched.

The success test now asserts the description lands in descriptions.json and that
graph.json is NOT rewritten with it (no collapse).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017quGgaqK7NRoxGT6BTqV2o
@cajasmota
cajasmota merged commit 3d133e0 into main Jul 22, 2026
1 of 2 checks passed
@cajasmota
cajasmota deleted the worktree-agent-a6010554c28fca1e6 branch July 22, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants