# Local-First Routing with Human Gates

**Public-candidate case study — review required**  
**Observed and implemented:** August 23–24, 2026  
**Domain:** Local AI, model routing, privacy boundaries, deterministic validation, human approval

## The short version

I wanted routine, bounded work to run locally without turning privacy, cost, or capability into a silent routing decision.

The result is not a universal automatic model switcher. It is a narrower system with explicit lanes:

- exact transformations use deterministic local software;
- one frozen structured-extraction schema may use a small local model;
- sensitive, malformed, ambiguous, or unsupported work stops and asks;
- hard or high-risk work may recommend a larger cloud model, but the router cannot launch it; and
- ordinary prompts remain on the user-selected default path.

The most important design decision was to separate three things that are often collapsed:

> A model can be capable of doing work without being permitted to receive the data or authorized to act.

## The problem

Using the largest available model for every task can be expensive and unnecessary. Sending every prompt to a cloud model can also be inappropriate when content is sensitive, local execution is sufficient, or the user has not approved the transfer.

But automatic local routing creates its own risks:

- prompt text can try to grant itself permission;
- a smaller model can produce plausible but invalid structured output;
- a local failure can silently fall through to cloud execution;
- hooks can duplicate work if they cannot replace the already selected model;
- audit logs can become a second store of sensitive content;
- configuration drift can change authority without review; and
- a cost-saving mechanism can become a hidden decision-maker.

The router therefore began as a non-executing deterministic planner, not as an automatic model launcher.

## The initial routing contract

The first policy supported four outcomes:

| Route | Meaning | Execution authority |
|---|---|---|
| `local` | Eligible for a named local deterministic or model-backed lane | Only through an explicit, frozen schema |
| `test-client` | Disposable synthetic evaluation | No assigned model; non-executable |
| `sol` | Hard or high-risk work may need the larger cloud model | Recommendation only; explicit approval required |
| `ask` | Ambiguous, sensitive, external, malformed, or failed gates | No execution |

Safety precedence was fixed:

```text
ask → sol recommendation → explicit test client → local
```

Higher-safety conditions override cheaper routes. Prompt text never grants permission; only validated structured metadata can establish eligibility.

The inactive router foundation passed:

- 8/8 unit tests;
- 20/20 synthetic routing cases twice;
- byte-identical canonical results; and
- zero sensitive-fixture leakage matches.

Unknown fields, routes, policy versions, permissions, tools, and limits failed closed.

## Why I did not attach execution to the global hook

The application exposed an observational prompt hook, but the inspected interface did not provide a verified output for replacing the model selected for the session.

Launching a local model inside that observer could therefore create this failure:

```text
Prompt submitted
   ├── local hook launches a model
   └── selected cloud model still receives and processes the prompt
```

That would duplicate work and could duplicate sensitive data handling.

The global observer was kept asynchronous, silent, redacted, non-executing, and incapable of model selection. Its activated verification passed 24/24 twice with byte-identical results, owner-only audit permissions, no raw prompt fields, and no local-model process invocation.

The supported execution pattern became an explicit command that chooses a lane before starting work.

## The explicit router

The user-local `alex-route` entrypoint accepts only versioned JSON envelopes. It cannot interpret ordinary prose as permission.

Initial explicit-router verification produced:

- 19/19 tests twice with byte-identical results;
- one exact eligible local smoke;
- `ask` with no execution for unknown work;
- `ask` with no execution for sensitive material;
- no cloud fallback;
- no hook attachment; and
- a rehearsed disable and restoration.

Installation was also reversible. The command symlink and targeted shell-path block were removed, the original shell configuration was restored byte-for-byte, and the same installation was then reconstructed to the verified state. The ordinary application command remained unchanged.

## Two local lanes, two different engines

### Lane 1 — exact tag normalization

Tag normalization is completely specified: trim, lowercase, whole-value deduplicate, and sort.

After a local model failed a preregistered copying matrix, inference was removed from this lane. The replacement is deterministic local software:

- 22/22 lane tests twice;
- 19/19 router tests twice;
- 12/12 frozen representative replay;
- every accepted length from 1–64 exact;
- 32/32 concurrent audit records;
- zero model tokens, retries, tools, or external network; and
- exact rollback to the prior model-era hashes in a disposable rehearsal.

### Lane 2 — bounded structured extraction

Structured extraction can require semantic interpretation, so this lane retained a small local model. It uses deterministic grounding to validate the extracted answer.

The frozen trial asked the model to extract bounded fields from synthetic, non-sensitive documents and to escalate ambiguity.

The first run scored 6/6, but the runner had not retained the exact raw synthetic evidence promised by preregistration. That outcome was preserved rather than silently upgraded. After an approved evidence-retention correction, an unchanged confirmation run again scored 6/6 with the complete raw synthetic record.

Before activation, the lane remained checked-in disabled. Its explicit activation later verified:

- extraction suite: 25/25 twice;
- router suite: 28/28 twice;
- one installed synthetic invoice smoke with exact grounded title, date, and category;
- 145 prompt tokens and 49 completion tokens for that smoke;
- 1.19 seconds reported inference time;
- zero retries, tools, or external access;
- sensitive and malformed requests denied before execution;
- no audit record for denied payloads;
- one bounded, redacted, owner-only audit record for the successful smoke;
- two-switch disable with no execution and unchanged audit; and
- restored active state followed by another complete passing suite.

The extraction lane remains available only through the explicit router for its exact synthetic/non-sensitive schema. It is not attached to ordinary prompts.

## The decision trace

The resulting route behavior is deliberately legible:

| Input state | Route | Engine | Human gate |
|---|---|---|---|
| Explicit eligible tag envelope | `local` | Deterministic software | User invoked the exact route |
| Explicit eligible extraction envelope | `local` | Small local model + deterministic grounding | User invoked the exact route |
| Ambiguous local extraction | `ask` | Local inference may run, but no answer is released | Alex decides what to clarify or do next |
| Sensitive or malformed local request | `ask` | No local execution | Alex chooses a legitimate path |
| Unknown work | `ask` | None | Alex chooses the route |
| Hard/high-risk cloud candidate | `sol` recommendation | None | Separate privacy/cloud approval required |
| Ordinary prompt | Existing default behavior | User-selected default model | Existing interface choice remains controlling |

Audit records retain route metadata, reason codes, timing, token counts where applicable, validation state, and failure codes. They exclude raw prompts, document text, answers, commands, secrets, and filenames.

## Testing the automatic bridge—and refusing to activate it

I also tested an inactive bridge that could recognize an explicit local grammar before the cloud-default path.

The preregistered behavior was:

- a validated local result blocks the cloud prompt and returns a bounded local result;
- ambiguity, sensitivity, malformed input, timeout, or routing failure blocks and asks Alex;
- ordinary clearly non-sensitive work continues without a local call; and
- local failure never silently falls through to cloud execution.

Direct contract evidence passed:

- 25/25 unit tests twice;
- 7/7 direct command-hook cases;
- exact deterministic tag result;
- exact grounded extraction result;
- ambiguity blocked without releasing an answer;
- sensitive and malformed inputs blocked without local calls;
- hard non-sensitive work continued without a local call;
- 32 concurrent prompts produced exactly 32 calls and 32 parseable audit records; and
- disposable removal passed.

But direct contract success was not enough to justify activation.

## The failures that stopped global activation

### Timeout boundary

The first unit run scored 24/25 because a mocked timeout escaped the internal handler. The top-level boundary still blocked cloud fallthrough, but the internal contract was weaker than specified. The correction converted the failure into the frozen bounded `ask` response without changing fixtures, scoring, retries, or routing rules.

### The rejected model tripwire

The first command-line smoke used an intentionally nonexistent local model so any request after hook failure would remain cloud-impossible. The application checked model availability before the hook and attempted a model download.

The download failed and installed nothing, but the method violated the no-download boundary. That tripwire was rejected rather than normalized as harmless test behavior.

### Hook discovery remained unproven

A corrected cloud-impossible smoke used an already installed local model and ignored user configuration. The nested project hook produced no audit change, and the local-only command hung until terminated.

Because the hook was not observed:

- hook discovery was unproven;
- zero local inference could not be claimed; and
- global activation was blocked.

The automatic bridge remains inactive. Ordinary prompts are not silently intercepted or rerouted.

## What this demonstrates

This case supports a bounded professional claim:

> I designed and implemented an explicit local routing system that separates eligibility, capability, validation, and permission; uses deterministic software for exact work; uses a small local model only for a frozen semantic schema; fails closed on sensitive, malformed, ambiguous, and unsupported work; preserves redacted evidence; rehearses disable and rollback; and blocks automatic activation when interface discovery remains unproven.

It demonstrates:

- architecture based on supported interfaces rather than desired behavior;
- local/cloud decisions tied to task semantics and data boundaries;
- independent validation of model output;
- explicit human approval for cloud or unresolved work;
- sensitivity checks before inference;
- bounded, redacted audit design;
- reversible activation and installation;
- preserved failures and evaluator corrections; and
- refusal to promote a technically promising bridge without end-to-end evidence.

## What this does not demonstrate

This case does **not** establish that:

- ordinary desktop prompts are dynamically routed between models;
- the inactive pre-cloud bridge works end to end in the application;
- the router is production-ready;
- sensitive or proprietary material is safe for arbitrary local models;
- local execution is universally preferable to cloud execution;
- the small model is suitable for schemas beyond the frozen extraction lane;
- every audit or filesystem race has been eliminated; or
- a recommendation confers permission to act.

## The broader principle

Routing is not merely a model-selection problem.

It is a decision about:

- what the task actually requires;
- what data the candidate engine may receive;
- how output will be validated;
- what happens when the result is ambiguous;
- whether failure can silently cross a privacy boundary;
- which action remains reversible; and
- who has authority to approve the next path.

The router’s most important output is sometimes not `local` or `cloud`.

It is `ask`.

---

**Evidence state:** Explicit lanes implemented and verified in the named local configuration; automatic bridge remains inactive and unproven end to end.  
**Publication state:** Public candidate; privacy, claim, and website review still required.  
**Production state:** No production-readiness claim.

