Architecture

How Pretense works

A local proxy that scans, mutates, transmits, and reverses — in under one millisecond. Your code never leaves your machine in its original form.

1

Token Scanning

Pretense parses source code to extract every identifier — functions, classes, and variables — without touching comments or string literals.

The scanner uses a regex-based AST walker that understands TypeScript, JavaScript, Python, Go, Java, C#, Ruby, and Rust syntax. Comments are preserved verbatim because they carry developer intent that LLMs need. String literals are preserved because multiline strings cannot be safely mutated without breaking semantics.

Input source
// Fetch the user's payment token from the vault
async function getUserPaymentToken(userId: string): Promise<string> {
  const vaultClient = new PaymentVaultClient(process.env.VAULT_URL);
  return vaultClient.getToken(userId);
}
Token classification
getUserPaymentTokenfunctionmutate
userIdvariablemutate
vaultClientvariablemutate
PaymentVaultClientclassmutate
// Fetch the user's payment token...commentpreserve
2

Mutation Algorithm

Each identifier is hashed with SHA-256 and the first 4 hex characters become the mutation suffix. The result is deterministic, reversible, and meaningless to external observers.

Determinism is critical: the same identifier always produces the same synthetic, so the LLM sees a stable codebase across sessions. The 4-char suffix gives 65,536 possible values — enough uniqueness for any real codebase.

Mutation transform
mutate("getUserPaymentToken", type="function"):
  hash  = SHA256("getUserPaymentToken")   // full 64-char hex
  short = hash.slice(0, 4)               // "4a2b"
  return "_fn" + short                   // "_fn4a2b"

mutate("userId", type="variable"):
  hash  = SHA256("userId")
  short = hash.slice(0, 4)               // "9x2c"
  return "_v" + short                    // "_v9x2c"
Token classification
getUserPaymentTokenfunction_fn4a2b
userIdvariable_v9x2c
PaymentVaultClientclass_cls8d3f
3

Proxy Transmission

The mutated source is sent to the LLM API. Secrets detected in transit are blocked entirely — the request never leaves your machine if a credential is found.

Pretense runs a parallel secrets scan on every outbound request using 30+ regex patterns covering API keys, JWT tokens, AWS credentials, database connection strings, and PII.

What the LLM receives
// Fetch the user's payment token from the vault
async function _fn4a2b(_v9x2c: string): Promise<string> {
  const _v7e1a = new _cls8d3f(process.env.VAULT_URL);
  return _v7e1a.getToken(_v9x2c);
}
4

Reversal

When the LLM responds, Pretense applies the mutation map in reverse. Every synthetic identifier is swapped back to the original. The developer never sees mutated code.

The reversal pass is a simple string substitution driven by the in-memory MutationMap built during the scan phase. The reversal is byte-exact — indentation, whitespace, and comments are untouched.

LLM response after reversal
// Fetch the user's payment token from the vault
async function getUserPaymentToken(userId: string): Promise<string> {
  const vaultClient = new PaymentVaultClient(process.env.VAULT_URL);
  return vaultClient.getToken(userId);
}

// Pretense restored 4 identifiers from MutationMap

Why LLM output quality is preserved

Variable names are noise to LLMs. Models infer meaning from structure, types, comments, and relationships — none of which Pretense touches.

Structural semantics preserved

Function signatures, class hierarchies, and call graphs remain intact.

Comments never touched

Developer intent, TODOs, and business-logic annotations are passed through verbatim.

Types and interfaces intact

TypeScript type annotations, generics, and return types are preserved.

String literals unchanged

Error messages, SQL queries, and template strings pass through unmodified.

What you write
function getUserPaymentToken(
  userId: string
): Promise<string> {
  // real function name
  // real variable names
}
What the LLM sees
function _fn4a2b(
  _v9x2c: string
): Promise<string> {
  // real function name
  // real variable names
}

Rust hot-path

The scanner and SHA-256 hashing are implemented in Rust via a native Node.js addon. The Rust layer uses rayon for parallel work-stealing across all CPU cores, making it 27x faster than a pure JavaScript implementation.

27x
Speedup vs pure JS
on 1M token scan
rayon
Parallelism
work-stealing thread pool
480 MB/s
Scanner throughput
on M-series Mac
<1 ms
Latency added
p99 on 10K-line file

Security model

Pretense is local-first. Nothing about your source code is ever sent to Pretense servers. The mutation map lives in memory and on disk in your project directory.

DataWhere it livesSent externally
Source identifiers (real names).pretense/ (local)Never
Mutated identifiersOutbound LLM requestYes — to LLM API only
Comments and stringsOutbound LLM requestYes — verbatim
Detected secretsBlocked before transmissionNever
Audit log.pretense/audit.db (SQLite)Never
Mutation map.pretense/mutations.jsonNever
Was this page helpful?