/** * Entry-point tier classifier (cognium-dev#128). * * Deterministic, AST-based classification of a method's position relative * to a program's *real* entry points (HTTP handlers, message-queue * listeners, scheduled jobs, CLI main, etc.). Designed to drive the * `interprocedural_param` source-suppression gate in `taint-matcher.ts` * and `interprocedural-pass.ts` — preventing the speculative * engine-emitted sources on Tier 3 (library API) methods from * propagating through verification. * * # Why * * `taint-matcher.ts:218-237` currently emits an `interprocedural_param` * source for every parameter of every method in a file, regardless of * whether that method is reachable from a program entry point. On the * top-25 Java OSS corpus this produces ~1,768 of 1,968 high-severity * findings against `redis/jedis`'s `UnifiedJedis.executeCommand` / * `Jedis.executeCommand` facade methods — pure signature amplification * on a library that is called *by* its users, never *by* a network * boundary. * * This classifier returns the tier of the enclosing method so callers * (taint-matcher, interprocedural-pass) can drop the speculative source * before it reaches the verifier. * * # Provenance * * Ported verbatim from * `cognium-ai/circle-ir-ai/src/analysis/entry-point-detection.ts` * (shipped in `circle-ir-ai@2.14.0`, 2026-06-21) — the same classifier * that currently runs as a downstream `runMerge` gate in the * cognium-ai stack. The downstream gate becomes a no-op once this * pass is wired into `taint-matcher.ts:findSinks()`, after which it * will be retired in a follow-up cognium-ai bump. * * No behavioral wiring in this commit — the file lands as a no-op * (not yet consumed by any pass). Wiring + heuristic gap-closures * (`*Util` / `*Utils` / `*Helper`, `*.template.*` / `*.engine.*`, * JDK facade interface-implements via `TypeHierarchyResolver`) come * in follow-up commits per the cognium-dev#128 Sprint 35 plan. * * # Tiers * * - **TIER_1_ENTRY_POINT** — Method itself is annotated as an entry * point (`@RequestMapping`, `@KafkaListener`, etc.), is a method of * an entry-point class (`@RestController`, JAX-RS `@Path` resource, * `extends HttpServlet`), or matches the `main(String[])` signature. * These methods *are* the trust boundary. * * - **TIER_2_REACHABLE** — Method called by a Tier 1 method (1-hop). * Not implemented in ship 1; requires `ProjectGraph` call-graph * traversal. Reserved by the `ctx.callGraph` parameter so the * classifier surface does not change when Tier 2 ships. Ship 1 * classifies every non-Tier-1 Java method as Tier 3. * * - **TIER_3_LIBRARY_API** — Public method, no entry-point annotation, * no entry-point class context, no `main` signature. Library API * surface — callers validate, not us. * * - **TIER_UNKNOWN** — Non-Java language, or insufficient AST info to * classify. Callers should treat UNKNOWN as pass-through (no * filtering), so ship 1's Java-only scope does not affect Python / * Node / Go / Rust / Bash analysis. * * # Deferred heuristic gaps (cognium-dev#136 audit) * * The 22-repo audit also surfaced three patterns that do NOT fit the * classifier surface (which sees only `MethodInfo` + `TypeInfo` * shape, no body AST, no call graph, no lambda-scope tracking) and * are routed to other components: * * - **Builder / fluent-setter chains** (`this.x = x; return this;` * identity-return hop) — body-shape concern. Noise reduction is * the job of cross-file finding-coalescing (cognium-dev#143), not * tier classification. The setter itself is correctly TIER_3. * * - **Lambda-captured params** (`Stream.map(s -> someSink(s))`) — in * the current IR, lambdas live inside the enclosing method's body * and are not separately represented as `MethodInfo` records, so * they already inherit the enclosing method's tier without any * classifier change. If the IR ever lifts lambdas into standalone * method records, a follow-up should propagate the parent tier. * * - **`Callable` / `Runnable` posted to `ExecutorService`** — pure * Tier 2 call-graph reachability concern (the TIER_1 method posts * the `Runnable`, which becomes reachable in a worker thread). * Reserved for the deferred Tier 2 ship; see `ctx.callGraph`. * * # Reference * * - cognium-dev#128 — entry-point-anchored taint sources. * - cognium-dev#136 — Tier 1 heuristic gaps audit (Spring stereotypes). * - cognium-dev#154 — Netty handler classes (CVE-2022-26884 * dolphinscheduler `NettyRequestProcessor.process`). * - `taint-matcher.ts:218-237` — speculative source emission site. * - `interprocedural-pass.ts:137-146` — engine's awareness comment. */ import type { TypeInfo, MethodInfo, CallInfo, RuntimeRegistration } from '../types/index.js'; export type EntryPointTier = 'TIER_1_ENTRY_POINT' | 'TIER_2_REACHABLE' | 'TIER_3_LIBRARY_API' | 'TIER_UNKNOWN'; export interface EntryPointContext { /** All TypeInfo records in this file. */ types?: ReadonlyArray | null; /** Language from CircleIR.language (e.g. 'java', 'python'). */ language?: string | null; /** * Project-wide call graph — Tier 2 reachability. Reserved for a * follow-up; ship 1 classifies every non-Tier-1 method as Tier 3. */ callGraph?: unknown; /** * File path (`CircleIR.meta.file`) — used by the polyglot library- * facade path heuristic for Python / JS-TS / Go / Bash where package * metadata is thin. Java classification does not require this. * * Added 3.166.0 for cognium-dev #237 polyglot expansion. */ filePath?: string | null; /** * All `CallInfo` records for the file (`CircleIR.calls`). Consumed by * the Go classifier for the `http.HandleFunc` / gin / chi framework- * registration walk (no runtime-registration extractor exists for Go * — the classifier walks `ir.calls` inline). * * Added 3.166.0 for cognium-dev #237. */ calls?: ReadonlyArray | null; /** * `RuntimeRegistration[]` records for the file * (`CircleIR.runtime_registrations`). Consumed by the JS/TS and * Python classifiers to resolve handler methods registered via * Express / Fastify / Flask / FastAPI / Django / Click / Celery * calls (already extracted per `core/extractors/runtime-registrations.ts`). * * Added 3.166.0 for cognium-dev #237. */ runtimeRegistrations?: ReadonlyArray | null; } /** * Classify a method's entry-point tier. * * Order: * 1. UNKNOWN short-circuit for non-Java languages (ship 1 scope). * 2. Library-facade short-circuit (#128 step 2) — `*Util` / `*Utils` * / `*Helper(s)` class name, `*.template|engine.*` package, or * direct JDK-facade `implements` → TIER_3, overriding any * spurious framework-shaped annotations on the type. * 3. Method-level annotation match → TIER_1. * 4. Class-level annotation match → TIER_1. * 5. Supertype lifecycle method match → TIER_1. * 6. `main(String[])` signature → TIER_1. * 7. Tier 2 reachability (not implemented in ship 1). * 8. Fallback → TIER_3_LIBRARY_API. */ export declare function classifyEntryPointTier(method: MethodInfo | undefined, enclosingType: TypeInfo | undefined, ctx: EntryPointContext): EntryPointTier; /** * Source-suppression predicate for callers that emit speculative taint * sources from method-parameter shape alone. * * Returns true iff the source should be DROPPED. Only fires on * `interprocedural_param` sources whose enclosing method classifies * as TIER_3_LIBRARY_API. LLM-discovered sources (which carry other * type tags) and statically-confirmed framework sources are never * gated by this predicate. * * Intentionally narrow: post-verify severity rubrics elsewhere in the * pipeline still apply to whatever passes this gate. The two filters * are layered, not overlapping. */ export declare function shouldGateInterproceduralParam(sourceType: string | null | undefined, enclosingMethod: MethodInfo | undefined, enclosingType: TypeInfo | undefined, ctx: EntryPointContext): boolean; //# sourceMappingURL=entry-point-detection.d.ts.map