surface

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package surface is the core framework for surface mapping (PRD section 10): the language-agnostic home for surface categories and, in Fase 1, the SurfaceQuery format (codefit's own declarative format for enumerating auditable structural surface, distinct from the Semgrep-format rules used for deterministic findings — PRD section 17).

Status: SKELETON. Today it declares the surface categories. The aggregation framework and the SurfaceQuery type and runner are implemented in Fase 1. The per-language enumeration currently lives in each provider's AnalyzeSurface (ADR 0001, provisional); core/surface will host the shared machinery once a second language exists to factor it against.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Run

func Run(queries []Query, root syntax.Node, file string) []findings.SurfaceItem

Run executes each query over the file and returns the union of their items with stable ids stamped. The framework is agnostic: it only orchestrates.

func StableID

func StableID(file string, line int, category string) string

StableID derives a short, stable id for a surface item from (file, line, category). It is a PURE function of those three components: the enumeration stamps it on each item, and the confirmation step recomputes it to validate that a verdict refers to a real item — this is what keeps codefit stateless (it stores nothing between enumeration and confirmation, it recomputes).

func StampIDs

func StampIDs(items []findings.SurfaceItem)

StampIDs fills the stable id of any item that does not yet have one. It is idempotent, so emitting boundaries (the sensor, the MCP handler) can call it without caring whether a provider already stamped.

func Summary

func Summary(category string, enumerated int, in Integration) string

Summary renders the complete-audit metric for a category: how many surface items were enumerated and how the agent's verdicts split. It reports complete coverage (every enumerated item reasoned), not a sample.

Types

type Category

type Category string

Category is a class of auditable surface the agent reasons about. These match the Category field of findings.SurfaceItem.

const (
	CategoryIDOR      Category = "idor"      // endpoints that access a resource by ID
	CategoryAuthz     Category = "authz"     // protectable handlers
	CategoryOverfetch Category = "overfetch" // serializations of domain objects
	CategoryNPlus1    Category = "nplus1"    // a query call sits inside a loop (dimension db)

	// DB-structure surface categories (schema-only rules, dimension "db"). One
	// category per rule so a baseline fingerprint is distinct per rule, the same
	// reason a finding's fingerprint carries its rule ID. These do not participate
	// in the scan-all endpoint bucketing (idor/authz/overfetch) — the DB sensor is
	// standalone.
	CategoryDBFKNoIndex   Category = "db-fk-no-index"        // DB-001: FK with no covering index
	CategoryDBDupIndex    Category = "db-duplicate-index"    // DB-011: exact duplicate index
	CategoryDBMultivalued Category = "db-multivalued-column" // DB-002: multivalued (array) column

	// CategoryDBViewSensitiveColumn (DB-020, Phase 2.2): a VIEW's top-level
	// SELECT column list exposes a column/alias whose name matches a
	// sensitive token (the same name-heuristic vocabulary CategoryDBSensitive
	// Unencrypted/DB-053 already uses). Body-derived (View.Body), unlike the
	// structural DB-001/011/002 categories above — grouped with the name-
	// heuristic block below it would also be reasonable; it lives here
	// because it is schema-STRUCTURE-adjacent (a view definition), not a
	// column-type heuristic.
	CategoryDBViewSensitiveColumn Category = "db-view-sensitive-column"

	// CategoryDBPrefixRedundantIndex (DB-011's prefix-redundant half, Unit E,
	// Phase 2.2): an index [a] whose columns are a strict leading prefix of
	// another index-like column list [a,b] on the same table (a real
	// composite index, or the primary key treated as an implicit index, same
	// as DB-001/rules.go's indexLike). Distinct from CategoryDBDupIndex
	// (DB-011's EXACT-duplicate case, same length): the two are mutually
	// exclusive by construction (a strict prefix is, by definition, strictly
	// SHORTER than what subsumes it). Closes the gap declared at
	// coverage.go:34 ("Prefix-redundant indexes ... are NOT yet detected").
	CategoryDBPrefixRedundantIndex Category = "db-prefix-redundant-index"

	// Name-heuristic DB categories (slice 2b) — pure surface (ADR 0017).
	CategoryDBFKTextType           Category = "db-fk-text-type"          // DB-051: FK typed as text vs a numeric/uuid key
	CategoryDBNoTimestamps         Category = "db-no-timestamps"         // DB-052: missing audit timestamps
	CategoryDBSensitiveUnencrypted Category = "db-sensitive-unencrypted" // DB-053: sensitive-looking column stored in the clear
	CategoryDBRepeatingGroups      Category = "db-repeating-groups"      // DB-003: repeating groups (1NF smell)
)

type Confirmation

type Confirmation struct {
	SurfaceID  string            `json:"surface_id"`
	Category   string            `json:"category"`
	File       string            `json:"file"`
	Line       int               `json:"line"`
	Verdict    Verdict           `json:"verdict"`
	Reasoning  string            `json:"reasoning"`
	Confidence float64           `json:"confidence"`
	Severity   findings.Severity `json:"severity,omitempty"`
}

Confirmation is what the agent returns after reasoning over a surface item. It carries everything codefit needs to integrate the verdict statelessly: the surface id (revalidated by recomputation) plus the anchor (file/line/category) and the agent's judgment. Severity is optional — the agent, which understands what resource is exposed, judges it; codefit falls back to a class default.

type Integration

type Integration struct {
	Findings  []findings.Finding
	Dismissed []Confirmation
	Uncertain []Confirmation
	Invalid   []Confirmation
}

Integration is the result of folding the agent's verdicts into the report. Each verdict lands in exactly one bucket: Findings (vulnerable, probabilistic), Dismissed (not_vulnerable, kept for traceability, no score impact), Uncertain (flagged for human review — developer autonomy), Invalid (the surface id did not recompute, so the verdict refers to nothing codefit can anchor).

func Integrate

func Integrate(confs []Confirmation) Integration

Integrate folds agent verdicts into the report. It is a pure function of the confirmations passed in — codefit keeps no session. A vulnerable verdict becomes a probabilistic finding (confidence < 1.0 always) anchored to the surface item; the id is revalidated by recomputing StableID.

type Query

type Query interface {
	// Enumerate returns the surface items found in the file rooted at root. file
	// is the project-relative path (a query may restrict itself by path, e.g.
	// Next App Router handlers live in app/**/route.ts).
	Enumerate(root syntax.Node, file string) []findings.SurfaceItem
}

Query enumerates the auditable structural surface of one category over a parsed file. Each category+provider implements it; the framework orchestrates queries without knowing any category (it never knows about IDOR or Next).

type Verdict

type Verdict string

Verdict is the agent's judgment on one surface item after reasoning over it.

const (
	VerdictVulnerable    Verdict = "vulnerable"
	VerdictNotVulnerable Verdict = "not_vulnerable"
	VerdictUncertain     Verdict = "uncertain"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL