diff --git a/gitnexus-shared/src/graph/types.ts b/gitnexus-shared/src/graph/types.ts index 8b46113df..60466b3e3 100644 --- a/gitnexus-shared/src/graph/types.ts +++ b/gitnexus-shared/src/graph/types.ts @@ -306,4 +306,18 @@ export interface GraphRelationship { readonly weight: number; readonly note?: string; }[]; + /** + * When `true`, the edge originates inside a code branch known at + * index time to be unreachable in production — e.g. a Zig + * `if (CONST_FALSE)` block where the condition reduces to a + * comptime-known `false`. Consumers of impact / context queries + * can filter these edges out to suppress paper-tiger callers + * caused by feature-flag-gated dead code paths. + * + * Optional and additive: edges from languages that don't compute + * static gating leave this `undefined`, which existing readers + * treat identically to "live". Currently set only by the Zig + * call-extractor. + */ + staticGated?: boolean; } diff --git a/gitnexus/src/core/lbug/csv-generator.ts b/gitnexus/src/core/lbug/csv-generator.ts index 83b630207..76d1b56be 100644 --- a/gitnexus/src/core/lbug/csv-generator.ts +++ b/gitnexus/src/core/lbug/csv-generator.ts @@ -396,7 +396,7 @@ class BufferedCSVWriter { /** Canonical relationship CSV header — shared by the emit pass and the * `splitRelCsvByLabelPair` differential oracle. */ -export const REL_CSV_HEADER = 'from,to,type,confidence,reason,step'; +export const REL_CSV_HEADER = 'from,to,type,confidence,reason,step,staticGated'; /** Build the escaped CSV row (no trailing newline) for one relationship. * Single source of the relationship row bytes — used by the emit pass and by @@ -409,6 +409,10 @@ export const buildRelRow = (rel: GraphRelationship): string => escapeCSVNumber(rel.confidence, 1.0), escapeCSVField(rel.reason), escapeCSVNumber(rel.step, 0), + // `staticGated` persists as 0/1 (LadybugDB BOOLEAN COPY accepts both). + // Every edge that does not carry the flag writes 0, so readers treat + // absence and `false` identically. + rel.staticGated === true ? '1' : '0', ].join(','); /** Canonical BasicBlock node CSV header — taint/PDG substrate (issue #2080). diff --git a/gitnexus/src/core/lbug/lbug-adapter.ts b/gitnexus/src/core/lbug/lbug-adapter.ts index 40ccdb8e0..97dda7673 100644 --- a/gitnexus/src/core/lbug/lbug-adapter.ts +++ b/gitnexus/src/core/lbug/lbug-adapter.ts @@ -1466,22 +1466,28 @@ export const fallbackRelationshipInserts = async ( for (let i = 1; i < validRelLines.length; i++) { const line = validRelLines[i]; try { - const match = line.match(/"([^"]*)","([^"]*)","([^"]*)",([0-9.]+),"([^"]*)",([0-9-]+)/); + // CSV layout: from,to,type,confidence,reason,step[,staticGated] + // The trailing `staticGated` column (0/1) is optional so we remain + // tolerant of legacy CSVs written before the column existed. + const match = line.match( + /"([^"]*)","([^"]*)","([^"]*)",([0-9.]+),"([^"]*)",([0-9-]+)(?:,([01]))?/, + ); if (!match) continue; - const [, fromId, toId, relType, confidenceStr, reason, stepStr] = match; + const [, fromId, toId, relType, confidenceStr, reason, stepStr, gatedStr] = match; const fromLabel = getNodeLabel(fromId); const toLabel = getNodeLabel(toId); if (!validTables.has(fromLabel) || !validTables.has(toLabel)) continue; const confidence = parseFloat(confidenceStr) || 1.0; const step = parseInt(stepStr) || 0; + const staticGated = gatedStr === '1'; await queryAndDrain( conn, ` MATCH (a:${escapeLabel(fromLabel)} {id: ${formatCypherValue(fromId)} }), (b:${escapeLabel(toLabel)} {id: ${formatCypherValue(toId)} }) - CREATE (a)-[:${REL_TABLE_NAME} {type: ${formatCypherValue(relType)}, confidence: ${confidence}, reason: ${formatCypherValue(reason)}, step: ${step}}]->(b) + CREATE (a)-[:${REL_TABLE_NAME} {type: ${formatCypherValue(relType)}, confidence: ${confidence}, reason: ${formatCypherValue(reason)}, step: ${step}, staticGated: ${staticGated}}]->(b) `, ); } catch { diff --git a/gitnexus/src/core/lbug/schema.ts b/gitnexus/src/core/lbug/schema.ts index 946f729e6..d8c66d906 100644 --- a/gitnexus/src/core/lbug/schema.ts +++ b/gitnexus/src/core/lbug/schema.ts @@ -657,7 +657,8 @@ ${generatedPairDdl()}, type STRING, confidence DOUBLE, reason STRING, - step INT32 + step INT32, + staticGated BOOLEAN )`; // ============================================================================