/** * Generated-artifact exclusion for the review synthesis input (mmnto-ai/totem#2398). * * `totem review` used to send generated-artifact bytes (lockfiles, * `compiled-rules.json`, `dist/**`, `*.wasm`, regenerated dashboards) to the LLM * as part of the review diff. The only exclusion mechanism was `ignorePatterns` * — opt-in, empty by default, and a **silent drop**: an excluded file simply * vanished from the payload, losing the signal that it changed at all. * * This module classifies generated artifacts by default and replaces their * bytes with a per-file SUMMARY (path, change shape, size delta, semantic hash) * injected into the synthesis input. The reviewer keeps the "this regenerated" * signal without paying review-context tokens for bytes no reviewer should read. * * Cautionary sibling #2329: the injected summary is CLEARLY LABELLED as a * Totem-generated summarization artifact (a distinct XML tag + a preamble that * says "not diff content") so the model cannot mistake it for real diff content * the way secret-redaction's env-var rewriting was mistaken for a real read. * * Aligns with the Prop 297 taxonomy (GENERATED spans take regeneration-diff * treatment, never prose review — mmnto-ai/totem-strategy#639 operating spec). */ /** * The default generated-artifact classification for the review payload. Seeded * globs covering the classes the issue names (lockfiles, `compiled-rules.json`, * `dist/**`, `*.wasm`) plus the conventional build-output + compiled-web set. * * These globs use `matchesGlob` semantics (see `@mmnto/totem` `matchesGlob`): * `**​/name` matches `name` at any depth, `**​/dir/**` matches a directory tree * at any depth, `*.ext` matches an extension anywhere. * * A false positive here strips a real-code file from LLM review — but it is * NEVER a silent drop: every excluded file is loudly named in the injected * summary (path + hash), and a repo un-marks a false positive Git-natively via * `.gitattributes` `linguist-generated=false` (honored below). Repos extend the * set the same way (`path/to/thing linguist-generated`). */ export declare const DEFAULT_GENERATED_ARTIFACT_GLOBS: readonly string[]; /** * Patterns parsed from a repo's `.gitattributes` `linguist-generated` markers: * - `generated` — patterns marked `linguist-generated` or `linguist-generated=true` * (ADD to the classification). * - `notGenerated` — patterns marked `linguist-generated=false` (an explicit * un-mark that OVERRIDES a default-glob match — the Git-native escape hatch). */ export interface GitattributesGeneratedPatterns { generated: string[]; notGenerated: string[]; } /** * Translate a `.gitattributes` path pattern into a `matchesGlob`-compatible glob. * * Full gitattributes/gitignore pattern fidelity is out of scope; this covers the * common forms the classification cares about: * - a leading `/` (root-anchored) is stripped — `matchesGlob` treats a * slash-bearing literal as repo-root-relative already; * - a trailing `/` (directory) becomes `/**` so the tree is matched; * - bare patterns (`*.lock`, `foo.map`) pass through — `matchesGlob` already * matches those at any depth. */ export declare function gitattributesPatternToGlob(pattern: string): string; /** * Parse `.gitattributes` at the repo root for `linguist-generated` markers. * Returns empty pattern lists when the file is absent or unreadable (best-effort * enrichment — a missing `.gitattributes` is never an error). Comment lines * (`#…`) and macro lines (`[attr]…`) are ignored. */ export declare function readGitattributesGeneratedPatterns(cwd: string): GitattributesGeneratedPatterns; export type GeneratedChangeShape = 'added' | 'deleted' | 'regenerated'; /** * A per-file summary of an excluded generated artifact. `addedLines` / * `removedLines` are the unified-diff insertion/deletion counts (the available * size-delta proxy, since the bytes themselves are excluded by design); * `binary` marks a file git reported as a binary change (no line counts). * `hash` is a semantic hash: sha256 (first 12 hex) over the file's own diff * segment — a stable fingerprint of exactly what was excluded. */ export interface GeneratedArtifactSummary { file: string; shape: GeneratedChangeShape; addedLines: number; removedLines: number; binary: boolean; hash: string; } export interface GeneratedArtifactClassification { /** Repo-relative paths classified as generated artifacts (bytes excluded). */ artifactFiles: string[]; /** Per-file summaries, in diff order. */ summaries: GeneratedArtifactSummary[]; /** The diff with every generated-artifact section removed (byte-identical to the input when none matched). */ keptDiff: string; /** `changedFiles` minus the generated artifacts. */ keptFiles: string[]; } export interface ClassifyGeneratedArtifactsParams { diff: string; changedFiles: string[]; /** Positive globs (defaults + `.gitattributes` generated). Defaults to {@link DEFAULT_GENERATED_ARTIFACT_GLOBS}. */ generatedGlobs?: readonly string[]; /** Un-mark globs (`.gitattributes` `linguist-generated=false`) — a match here is NEVER a generated artifact. */ excludeGlobs?: readonly string[]; } /** * A single file's section of a unified diff, with its destination path. * `file` is `null` for a leading preamble section (the text before the first * `diff --git`, normally empty) or a section whose header does not parse. */ interface DiffFileSection { file: string | null; section: string; } /** * Split a unified diff into per-file sections at `diff --git` boundaries and * extract each section's destination (`b/`) path. Mirrors the split + path * extraction that `filterDiffByPatterns` / `extractChangedFiles` use so the two * agree on file identity. Joining `section` values back reconstructs the input * exactly (the zero-width split consumes no characters). */ export declare function splitDiffIntoFileSections(diff: string): DiffFileSection[]; /** Semantic hash of an excluded artifact's diff segment: sha256, first 12 hex chars. */ export declare function hashDiffSection(section: string): string; /** * Classify the changed files into generated artifacts vs. kept files, remove the * artifact sections from the diff, and build a per-file summary of each excluded * artifact. A file is a generated artifact iff it matches ANY positive glob AND * matches NO un-mark (exclude) glob. * * When no artifact matches, `keptDiff === diff` and `keptFiles === changedFiles` * (order preserved) — the legacy review payload is byte-identical, so callers * can gate the new path on `summaries.length > 0`. */ export declare function classifyGeneratedArtifacts(params: ClassifyGeneratedArtifactsParams): GeneratedArtifactClassification; /** One operator-visible / prompt line for an excluded artifact. Paths are sanitized. */ export declare function formatGeneratedArtifactLine(summary: GeneratedArtifactSummary): string; /** * Build the synthesis-input section for the excluded generated artifacts. * Returns `''` when there are no artifacts (so the caller injects nothing on the * legacy path). The body is wrapped in a distinct XML tag and the preamble * states plainly that these lines are a Totem-generated summary, NOT diff * content — the #2329 mislabel guard. */ export declare function buildGeneratedArtifactSection(summaries: GeneratedArtifactSummary[]): string; export {}; //# sourceMappingURL=shield-generated.d.ts.map