/**
* 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