docs: add Philosophy.md — living security-first design philosophy

ober

d01913202bc0a1084c06c66d9a0a2e0950b87330

diff --git a/docs/Philosophy.md b/docs/Philosophy.md
new file mode 100644
index 0000000..43f0152
--- /dev/null
+++ b/docs/Philosophy.md
@@ -0,0 +1,266 @@
+# Jerboa Philosophy
+
+Living document — last revised 2026-05-24. Honest, no hype, no stubs.
+
+This file states the long-term design philosophy for the Jerboa stack: the
+principles we hold while growing it toward a best-in-breed, defensible
+replacement for the npm/Node/JS and C-based stacks. **The organizing goal is
+security.** It is meant to be iterated on — by humans and by other LLMs.
+
+It sits *above* the concrete docs: see [`capability.md`](capability.md) for the
+object-capability implementation, [`ai-threat.md`](ai-threat.md) for the
+adversarial threat model, and [`security-reference.md`](security-reference.md)
+for the hardening reference. This document is the *why*; those are the *how*.
+
+---
+
+## How to iterate on this document
+
+- **Keep the tone: concrete, no hype, no stubs.** Claims about code must be
+  verifiable in the tree. Mark aspirational items as such.
+- **Separate principle from state.** A principle is durable; "current state"
+  notes change as the tree changes. Don't let a temporary gap weaken a principle.
+- **Never delete a principle to win an argument.** If you disagree, record the
+  counter-argument under *Open tensions* and leave the principle standing until
+  it's actually resolved. (This mirrors the stack's "never remove, always fix"
+  rule, applied to ideas.)
+- **Every proposed change carries its security rationale.** "Why is this safer?"
+  is the question each edit must answer.
+- **Date significant revisions** at the top.
+
+---
+
+## North Star
+
+Replace the npm/Node/JS and C stacks with one that is *both* more capable and
+fundamentally more defensible — a single memory-safe language (Jerboa on stock
+Chez) orchestrating a small, audited native core (Rust), where the common case
+needs no third-party code at all.
+
+The spine of everything below is one claim:
+
+> **Memory safety is table stakes. The real game is *authority*.**
+
+Both stacks we are replacing lost on authority, not just safety. C has no
+boundaries at all. npm pairs *ambient authority* (any package can do anything
+the process can) with an unsigned, code-executing supply chain. A memory-safe
+rewrite that still hands code ambient power has solved the smaller half of the
+problem. So every principle here serves: **least authority, proven provenance,
+smallest trusted base.**
+
+---
+
+## Principle 1 — Object-capability by default; ambient authority is the bug
+
+Nothing — a package, a script, a builtin, a piece of AI-generated code — touches
+the filesystem, network, processes, or secrets without a capability it was
+*handed*. Authority flows by explicit grant and can only be *attenuated*, never
+amplified. This is the single principle that makes a large ecosystem survivable:
+a malicious or merely buggy dependency can only do what it was granted.
+
+**Why it's the keystone.** It is the through-line of every concrete failure we
+care about:
+- An `ssh-agent` socket is a *signing oracle*; whoever can `connect()` signs as
+  you. "Find a socket and use it" (e.g. `ssh-find-agent`) is a credential
+  hijack wearing a convenience tool's clothes — possible only because the oracle
+  sits in an ambient, shared namespace.
+- Every unsigned `.el` in a stock Emacs runs with the *full authority of the
+  editor process* — it can read `~/.authinfo`, exec anything, open sockets. Same
+  disease at editor scale.
+- The fix in both cases is the same shape: the secret/oracle lives behind a
+  capability boundary (see jsh's encrypted `//embed/` store, unlocked into the
+  narrowest scope, never ambient), not in a place any same-uid code can reach.
+
+**Rules out:** ambient authority as the default execution model; "trusted because
+it's installed"; extensions/packages that inherit the host's full power.
+
+**Current state:** seeded and real — `(std capability)` provides unforgeable,
+attenuable, revocable tokens ([`capability.md`](capability.md)); jsh carries
+OS-level sandbox hooks (landlock/seccomp/pledge/unveil) and the `//embed/`
+secret store. **Aspirational:** making capability-scoping the *pervasive default*
+for packages and editor extensions, not an opt-in library.
+
+---
+
+## Principle 2 — Depth in the core beats breadth in the ecosystem
+
+npm won on reach: "there's a package for everything, one import away." We beat
+that not by copying it but by inverting it — a large, *first-party, audited*
+standard library so the common case needs zero third-party code. Every capability
+that would be a sketchy micro-dependency elsewhere becomes a reviewed builtin
+operating on **structured data, not text**.
+
+**Why it's safer.** The thing that makes shell/JS glue dangerous is composing
+tools by parsing each other's *text* (`ls`/`ps`/`find` output), `eval`-ing
+constructed strings, and `exec`-ing a dozen binaries — each step a footgun. A
+broad first-party stdlib of typed operations removes the reason to reach for that
+glue, and shrinks the dependency *surface*, not merely the dependency count.
+
+**Rules out:** deep, unaudited transitive dependency trees; "data as text" as the
+default interchange; reaching for a third-party micro-package for something the
+core should own.
+
+**Current state:** 229 `(std *)` modules; jsh's builtins operate on data, not
+text. **Aspirational:** the deliberate, ongoing project of promoting common glue
+into reviewed builtins faster than an ecosystem of micro-deps would form.
+
+---
+
+## Principle 3 — Provenance is mandatory; installing must never run code
+
+To have a package ecosystem without npm's disease, invert npm's defaults:
+artifacts are **signed** (rooted in hardware — see `jerboa-yubikey`),
+**content-addressed**, and **reproducible**; installing a package executes
+**no code** — no `postinstall`, no arbitrary build-time scripts. Build steps are
+declarative and sandboxed, not a shell escape hatch.
+
+**Why it's safer.** npm's worst supply-chain incidents are not memory bugs — they
+are unsigned, mutable artifacts plus install-time code execution (a compromised
+or typosquatted package runs arbitrary code on every `npm install`). Signing
+fixes provenance; *no-install-code* removes the most-abused execution surface.
+And note the layering: signing answers "who made this," capabilities (Principle 1)
+still answer "what it may do" — even a correctly-signed package runs at least
+authority.
+
+**Rules out:** unsigned/mutable packages; install/build-time arbitrary code
+execution; flat, typosquat-friendly namespaces with no provenance.
+
+**Current state:** `jerboa-yubikey` provides the hardware signing root.
+**Aspirational:** the package manager and registry that enforce
+signing + content-addressing + no-install-code as non-negotiable defaults.
+
+---
+
+## Principle 4 — Safe by construction, fast by delegation, minimal trusted base
+
+Memory-safe Scheme orchestrates. Drop to Rust only for genuine hot paths and for
+parsing hostile bytes fast — and when you do, prefer *pure-Rust* backends, isolate
+the most dangerous parsers in a wasm sandbox, and keep the FFI marshalling surface
+small and audited. Keep the compiler additive (new primitives, no behavioral
+patches) so the trusted base never forks semantically.
+
+**Why it's safer.** Memory-safety CVEs cluster in untrusted-input parsers, not in
+GC/scheduler runtimes — so the high-leverage move is getting *parsers* off C, and
+where possible into bounds-checked Scheme (e.g. `jerboa-wafter` dissects packets
+in ~1,700 pure-Scheme dissectors, zero `foreign-procedure` calls — safer than even
+Rust-with-`unsafe` for that surface, at a throughput cost). But "Rust" is not
+automatically "no C": watch for `bundled` C amalgamations (sqlite/duckdb), C++ JIT
+engines (mozjs/SpiderMonkey), and C-backed compression. The FFI/marshalling glue
+is where *our own* `unsafe` lives — [`ai-threat.md`](ai-threat.md) names it the #1
+attack surface — so it must stay minimal, audited, and ideally generated and
+bounds-checked.
+
+**Rules out:** trading a removed C-CVE for a silently re-added bundled-C-CVE;
+sprawling hand-written FFI; behavioral forks of the compiler; growing the trusted
+computing base without accounting for it.
+
+**Current state:** stock-Chez-additive discipline; `libjerboa_native` favors
+audited pure-Rust crates (`regex`, `rustls`, the `*-dalek` crypto, `wasmi`);
+pure-Scheme parsing where throughput allows. **Aspirational:** an honest, written
+TCB accounting and a continuously-audited, minimized FFI boundary.
+
+---
+
+## Principle 5 — Be the safest substrate for AI-written code
+
+This stack is itself built with AI, and its threat model
+([`ai-threat.md`](ai-threat.md)) is adversaries using AI to find bugs. Lean into
+that: design so that AI-generated code is *safe by default* and AI is turned
+loose to harden us before attackers do.
+
+**Why it's safer.** Capabilities (Principle 1) cap an autonomous agent's blast
+radius — code an agent writes can't exceed the authority it was handed.
+Structured-data builtins (Principle 2) remove the `eval`/exec/string-munging
+footguns that AI most readily reproduces from training data. And the same AI
+that hunts our bugs can generate dissectors, fuzz harnesses, and test suites at
+scale (`jerboa-wafter`'s generated dissector corpus; `jerboa-lora`/`jerboa-code`)
+— we should find our own CVEs first.
+
+**Rules out:** giving generated/automated code ambient authority; treating AI
+codegen as a convenience while ignoring it as an attack surface.
+
+**Current state:** `jerboa-lora` (a Jerboa-aware model) and `jerboa-code` (an
+agentic coding tool) exist; much of the ecosystem is AI-generated already.
+**Aspirational:** capability-bounded execution contexts for agent-written code by
+default, and a standing "AI red-team your own tree" practice.
+
+---
+
+## What we explicitly reject
+
+- **Ambient authority** as the default — the root cause, not a detail.
+- **The npm supply-chain model**: unsigned/mutable packages, deep unaudited
+  transitive trees, install-time code execution, typosquat-friendly namespaces.
+- **Secrets in ambient reach**: in process arguments (`ps`-visible), in
+  shared filesystem namespaces, or in ambient env any same-uid process can read.
+- **"Data as text" composition**: `eval`, output-parsing, and exec-sprawl as the
+  way tools talk to each other.
+- **Stubbing or removing features to make a build pass** — a broken safety
+  guarantee is no guarantee; fix the root cause.
+- **Silent C/C++ re-entry** via bundled amalgamations or JIT engines pulled in
+  without scrutiny.
+- **"Memory-safe rewrite" as the finish line.** Safety without authority control
+  is half a solution.
+
+---
+
+## Open tensions (unresolved — bring arguments)
+
+These are honest, unsettled trade-offs. Add to them; don't paper over them.
+
+1. **Capability ergonomics vs. friction.** Ambient authority is popular because
+   it's frictionless. If granting/threading capabilities is tedious, developers
+   route around it and the model rots. How do we make *least authority the easy
+   path* — sane defaults, inference, good tooling — without weakening it?
+2. **Ecosystem reach vs. mandatory signing/no-install-code.** npm's strength is
+   reach. How do we bootstrap breadth while refusing the defaults that gave npm
+   its reach? Chicken-and-egg adoption is real.
+3. **Isolation vs. integration when embedding** (e.g. jsh-in-emacs). In-process
+   gives one address space and one capability model with secrets never crossing a
+   boundary, but couples failures and makes tty/job-control hard; a PTY/process
+   boundary isolates faults but reintroduces the `SSH_AUTH_SOCK`-style bridge.
+4. **wasm isolation vs. throughput.** `wasmi` is an interpreter; sandboxing hot
+   parsers in wasm costs performance. When is the isolation worth the slowdown
+   versus trusting an in-process pure-Rust parser?
+5. **The FFI boundary is our `unsafe`.** Can the marshalling layer be largely
+   *generated* and bounds-checked so hand-written FFI (the #1 attack surface)
+   approaches zero?
+6. **Honest TCB accounting.** The Chez runtime, additive primitives, every Rust
+   dep's `unsafe`, and the host kernel are all trusted. What is the real, written
+   trusted base — and what defends the cases where even the kernel is hostile
+   (hardware-held keys, remote attestation, "no secrets on the box")?
+7. **Confused-deputy and capability leakage.** Ocap prevents forgery, not misuse:
+   handing a capability to the wrong code still leaks authority. What patterns
+   keep grants from drifting?
+
+---
+
+## Glossary
+
+- **Authority** — what a piece of code is *able to do* (read a file, open a
+  socket, sign with a key), as distinct from whether it's memory-safe.
+- **Ambient authority** — authority a program holds simply by running, without
+  being explicitly granted it (the default in C, shells, Node, and elisp).
+- **POLA (Principle of Least Authority)** — every component runs with the minimum
+  authority it needs, and no more.
+- **Object-capability (ocap)** — a model where an unforgeable token *is* the
+  authority; no token, no access. See [`capability.md`](capability.md).
+- **Attenuation** — deriving a *narrower* capability from one you hold (read-only
+  from read-write); the only permitted transformation. You can never amplify.
+- **Signing oracle** — a service that signs/authenticates on a key's behalf
+  without exposing the key (e.g. `ssh-agent`); access to the oracle *is* access
+  to the key's power.
+- **Provenance** — verifiable evidence of who produced an artifact and that it
+  hasn't changed (signatures, content-addressing).
+- **TCB (Trusted Computing Base)** — the set of components that must be correct
+  for security to hold; smaller is better.
+- **Confused deputy** — a privileged component tricked into misusing its
+  authority on behalf of a less-privileged caller.
+
+---
+
+## Related docs
+
+- [`capability.md`](capability.md) — the `(std capability)` object-capability implementation.
+- [`ai-threat.md`](ai-threat.md) — adversarial (AI-assisted) threat model; FFI as #1 surface.
+- [`security-reference.md`](security-reference.md) — hardening reference.