# Changelog

What changed in each release of the penname gateway, newest first. Every
version is published as `pennameio/gateway:<version>` on Docker Hub, and
`latest` always points at the newest one.

To update an install: `docker compose pull && docker compose up -d`.
`penname-gateway --version` (or the image's `org.opencontainers.image.version`
label) says which one you are running.

---

## 0.3.0 — 2026-09-18

**The gateway now says what it did *not* protect.** Before this, an install
could look like it was working long before it protected anything.

- **Calls with no scope header are flagged.** Without `X-Penname-Scope` the
  gateway cannot tell whose rows to read, so names go out unprotected: only
  emails, phones and ID numbers, which a detector finds by their shape. The
  first such call now logs `NO X-Penname-Scope HEADER`, every one is marked
  `NO-SCOPE(names unprotected)` on its log line, and the count reaches your
  dashboard. `PENNAME_REQUIRE_SCOPE=true` still refuses them outright.
- **Images are flagged.** penname substitutes text, never pixels, so a
  scanned contract or a photo of an ID card reaches the model as sent. The
  first call carrying an image logs a warning, every one is marked
  `IMG(n unread)`, and the count reaches your dashboard. Nothing is blocked.
- **`init` can run without a person at the keyboard**, so a coding agent or a
  CI job can set penname up: `--api-key`, `--db-url` and `--yes`, with
  `PENNAME_API_KEY` / `PENNAME_DB_URL` as fallbacks. When nothing is typing
  into it, it behaves as if `--yes` was given instead of waiting at a prompt.
- **Better field-map suggestions.** `organizations.name` and `companies.name`
  are proposed as `ORG`, not `PERSON`. Columns *about* a credential
  (`password_reset_channel`, `…_method`, `…_status`, `…_provider`) are no
  longer proposed as `SECRET`, which had put the word `sms` on the block list.
- **`DETAIL_LOGGING` is readable.** It printed the whole request and reply as
  indented JSON. The reply was dumped *after* the real values were put back,
  so it wrote customer data into the log. It now prints the conversation
  exactly as the model read it, as plain text, word for word, under the list
  of swapped values. No JSON, no settings, no reply.
- **`--version`**, and a version label on the image, so `latest` and a
  version tag can be told apart.
- **Docs:** a ready-made system-prompt line that stops models treating
  `PERSON_7K3Q2M9XAB` as a placeholder, and an exact description of what
  `SECRET` does. By default it *cuts the value out* and the call carries on.

## 0.2.0 — 2026-09-17

**A penname API key is required.** No key, no gateway.

- The gateway refuses to start without `PENNAME_API_KEY`, and a key the
  control plane rejects stops it at startup. There is no setting that turns
  this off. Leaving `PENNAME_CONTROL_PLANE_URL` unset now means
  `https://penname.io`, not "ask nobody".
- A key over quota or suspended keeps the gateway up but serving nothing:
  `402` on calls, `503` on `/healthz`. It recovers by itself within a minute
  of the key being good again.
- If the control plane is unreachable, an already-authorized gateway keeps
  serving for `PENNAME_OFFLINE_GRACE_SECONDS` (a day by default), then fails
  closed.
- The 0.1.x images, which ran without a key, were removed from Docker Hub.

## 0.1.4 — 2026-09-16

- Everything moved to **https://penname.io**: the wizard's control-plane
  default, the signup link and the MCP command. Installs pointing at the old
  address keep working.

## 0.1.3 — 2026-09-16

- `docker run pennameio/gateway` with no setup now tells you what to do: get
  a free key at penname.io/signup, then run `init`. It used to suggest
  generating a master key by hand, which skipped the API key and the database.

## 0.1.2 — 2026-09-16

- `init` ends by printing the command that adds penname's MCP server to Claude
  Code or Cursor, with your key already in it, so your coding agent can read
  your schema and set the field map for you.

## 0.1.1 — 2026-09-16

- **Secrets live in their own file.** `init` writes `.env` (settings, safe to
  send to support) and `secrets.env` (master key, API key, database URL;
  readable by you only, gitignored), plus a `.gitignore`.
- **One master key across several gateways.** `penname-gateway key show`
  prints an install's master key, and `init --master-key <key>` reuses it, so
  staging and production issue the same pen names.
- Every secret also takes a `_FILE` form (`PENNAME_MASTER_KEY_FILE`, …) for
  Docker secrets, Kubernetes and cloud secret managers.

## 0.1.0 — 2026-09-16

The first public release: a compiled Docker image and a setup wizard, so
there is nothing to clone and nothing to build.

- `docker run -it -v ${PWD}:/setup pennameio/gateway init` checks your key
  before writing anything, generates your master key, and writes the config
  and a compose file.
- An OpenAI-compatible proxy: `/v1/chat/completions` and the Responses API
  (`/v1/responses`), plus Anthropic's `/v1/messages`. Streaming included.
- Reads PostgreSQL, MySQL/MariaDB, SQLite and MongoDB, and works out from
  your foreign keys whose row is whose.
- The field map is set in the dashboard at penname.io, or by your coding
  agent through the MCP server.
- Keywords for names that live only in prose, a neutral alias style
  (`REF_…`), a schema-only mode that never reads a row, and `SECRET` values
  that are cut out of the prompt.
