/** * Parse-health disclosure (change: add-parse-health-boundary-disclosure). * * The language-support registry can't over-claim a *language* — but it says nothing about failed * extraction *inside* a supported language. A file the pinned grammar rejects, a tree tree-sitter * recovered with a large `ERROR` region, or a source that decoded lossily today yields a silently * smaller graph indistinguishable from "there is genuinely nothing there." This module records * per-file parse health so downstream conclusions can disclose *unknown* instead of implying * *absent* — the exact failure mode the `NoFalseCompleteness` requirement exists to prevent. * * Two honesty rules, mirroring the style-fingerprint and IaC extractors: * 1. Clean files pay zero: `tallyParseHealth` returns `undefined` unless the parsed tree actually * carries an error, so a healthy repo produces no records and no boundary is ever emitted. * 2. The signal is a LOWER BOUND: an ERROR region can swallow well-formed neighbors, so a * disclosed count is "at least this degraded," never "exactly this and no more." * * Tallied in the SAME per-file AST walk that extracts nodes/edges (no second parse), exactly like * the style fingerprint. Deterministic: integer tallies over a deterministic walk, sorted keys, no * clock — byte-identical across re-analyses of a fixed repository state. */ /** Bump when the persisted artifact shape changes incompatibly. */ export declare const PARSE_HEALTH_SCHEMA_VERSION = 1; /** * Cap on the number of error-region start lines retained per file. A bound on the persisted record * (a pathological file could otherwise carry thousands of ERROR nodes); the counts stay exact, only * the line LIST is truncated, and truncation is disclosed (`truncated: true`). */ export declare const PARSE_HEALTH_LINE_CAP = 25; /** * Per-file parse health. Present ONLY for a file with at least one signal (error region, parse * failure, or encoding fallback) — a clean file has no record. Absent fields mean "not observed." */ export interface FileParseHealth { filePath: string; language: string; /** tree-sitter `ERROR` nodes (unparseable spans the recovery inserted). */ errorCount: number; /** tree-sitter `MISSING` nodes (tokens the grammar expected but the source omitted). */ missingCount: number; /** 1-based start lines of the error/missing regions, sorted + deduped, bounded by the cap. */ errorLines: number[]; /** `errorLines` hit the cap — more regions exist than are listed. */ truncated?: boolean; /** The extractor threw or produced no usable tree — the whole file contributed nothing. */ parseFailed?: boolean; /** The source decoded lossily (contained U+FFFD) — parse output may be garbage. */ encodingFallback?: boolean; } /** * Minimal structural view of a tree-sitter node. Kept dependency-light (no `tree-sitter` import) so * this module stays a leaf, and defensive across binding versions: `ERROR` is detected by `type` * (stable across bindings) and `MISSING` by `isMissing` as either a boolean property (node-tree- * sitter) or a method (web-tree-sitter). A plain test object supplying only `type`/`children` * still works. */ export interface ParseHealthNode { type: string; startPosition: { row: number; }; isMissing?: boolean | (() => boolean); hasError?: boolean | (() => boolean); children: ParseHealthNode[]; childCount?: number; child?(i: number): ParseHealthNode | null; } /** * Record parse health for one file from its already-parsed tree. Returns `undefined` for a clean * tree (the fast path — no walk, zero cost, so a healthy repo produces no records). When the tree * carries an error it walks ALL children (not just named — an unnamed ERROR token still counts), * tallying `ERROR` and `MISSING` nodes and collecting their start lines up to the cap. * * The walk fires only on the rare error tree, so its `children` allocation is not on the hot path. */ export declare function tallyParseHealth(language: string, rootNode: ParseHealthNode, filePath: string): FileParseHealth | undefined; /** * True if decoding these bytes as UTF-8 is LOSSY — the source contains byte sequences that are not * valid UTF-8 and would be replaced by U+FFFD. Detected at the BYTE level (a strict decode that * throws), NOT by scanning the decoded string for U+FFFD: a file may legitimately CONTAIN U+FFFD * (as valid UTF-8 bytes `EF BF BD`), and flagging that would be a false positive. Only genuinely * undecodable bytes count. */ export declare function isLossyUtf8(bytes: Uint8Array): boolean; /** A file is "degraded" if it carries any parse-health signal at all. */ export declare function isDegraded(h: FileParseHealth): boolean; /** One language's rolled-up degradation, for the compact summary. */ export interface ParseHealthLanguageSummary { language: string; degradedFiles: number; errorRegions: number; parseFailures: number; encodingFallbacks: number; } /** The persisted, rolled-up parse-health report (its own `parse-health.json` artifact). */ export interface ParseHealthReport { version: number; /** Files carrying at least one signal. */ totalDegradedFiles: number; /** Sum of ERROR + MISSING regions across all degraded files. */ totalErrorRegions: number; /** Per-language rollup, sorted by degraded-file count desc then name. */ byLanguage: ParseHealthLanguageSummary[]; /** The worst offenders, sorted by region count desc then path, bounded. */ topFiles: FileParseHealth[]; /** Every per-file record (the source of truth the watcher splices and consumers scan). */ files: FileParseHealth[]; } /** * Roll the raw per-file records up into the persisted report. Returns `undefined` when there are no * records at all — a clean repo persists no artifact and every consumer treats "no artifact" as * "nothing degraded," so clean repos pay zero (no boundary, no payload growth). */ export declare function buildParseHealthReport(records: FileParseHealth[], topN?: number): ParseHealthReport | undefined; /** A compact, one-line-per-language string list for the `orient` summary (bounded upstream). */ export declare function compactParseHealthSummary(report: ParseHealthReport): string[]; //# sourceMappingURL=parse-health.d.ts.map