Producer

Write in Emacs

Native pmbah-mode for content-blind writing records from GNU Emacs.

pmbah-mode is a buffer-local minor mode for GNU Emacs 29.1+ that records the shape of your editing as a content-blind process record. When you choose to sign, it uploads only the public, content-blind manifest and event log to the configured ingest service and copies the returned record URL to your kill ring. Nothing about what you typed leaves your machine; only the shape of the editing does.

What it captures

What it does not capture

Requirements

The Emacs package is not on MELPA / ELPA for v0. Install from a checkout or release archive.

Install from a checkout

From the repository root:

git clone https://github.com/juanre/possiblymadebyahuman.git
cd possiblymadebyahuman
npm ci
# or: make install

Add one checkout root variable to your Emacs configuration and derive the producer paths from it:

(defvar pmbah-checkout-root
  (expand-file-name "~/src/possiblymadebyahuman/"))

(add-to-list 'load-path
             (expand-file-name "producers/emacs" pmbah-checkout-root))
(require 'pmbah-mode)

(setq pmbah-helper-script
      (expand-file-name "producers/emacs/scripts/build-record.mjs"
                        pmbah-checkout-root))
;; Public service; this is also the package default.
(setq pmbah-api-base-url "https://possiblymadebyahuman.com")

Change only pmbah-checkout-root for your checkout location.

use-package users can use the same root variable:

(defvar pmbah-checkout-root
  (expand-file-name "~/src/possiblymadebyahuman/"))

(add-to-list 'load-path
             (expand-file-name "producers/emacs" pmbah-checkout-root))

(use-package pmbah-mode
  :commands (pmbah-mode pmbah-sign-buffer pmbah-show-session-status)
  :custom
  (pmbah-api-base-url "https://possiblymadebyahuman.com")
  (pmbah-helper-script
   (expand-file-name "producers/emacs/scripts/build-record.mjs"
                     pmbah-checkout-root)))

Emacs 29’s package-vc-install can fetch the Lisp code but does not install npm dependencies for the Node helper. For v0, use a manual checkout / release directory and run npm ci there.

Configuration

API base URL

pmbah-api-base-url defaults to the public service:

(setq pmbah-api-base-url "https://possiblymadebyahuman.com")

You normally do not need to set it. If you previously copied local-development configuration such as (setq pmbah-api-base-url "http://localhost:8000"), remove that line or replace it with the HTTPS production URL above.

For local development, override the URL to match your local container:

PMBAH_PORT=18800 make local-container
export PMBAH_API_BASE_URL=http://localhost:18800

For the default local port:

(setq pmbah-api-base-url "http://localhost:8000")

Node path for GUI Emacs

If GUI Emacs cannot find Node, set either:

export PMBAH_NODE=/opt/homebrew/bin/node

or:

(setq pmbah-node-command "/opt/homebrew/bin/node")

Use the path printed by command -v node in a shell where Node is available.

Usage

  1. Open a writing buffer. It may already contain text; PMBAH records only later mutation metadata.
  2. Enable capture: M-x pmbah-mode. The mode line shows PMBAH:N, where N is the local event count.
  3. Write normally.
  4. Check status when desired: M-x pmbah-show-session-status.
  5. Freeze, review the capture context, upload, and copy the record URL: M-x pmbah-sign-buffer.
  6. If you want to throw away the local session without uploading: M-x pmbah-discard-session.

After a successful upload, the local event log is cleared and a fresh session starts for the current buffer. If upload fails, the local event log is retained so you can retry.

Verify the installation

A quick public-service check:

  1. In Emacs, open a buffer and run M-x pmbah-mode.
  2. Type a short draft.
  3. Run M-x pmbah-show-session-status; confirm the API URL is https://possiblymadebyahuman.com.
  4. Run M-x pmbah-sign-buffer; review the capture context preview, upload, and confirm a short URL is copied to the kill ring.

For a local development check instead, start with make local-container (or PMBAH_PORT=18800 make local-container) and set PMBAH_API_BASE_URL / pmbah-api-base-url to the matching local origin.

Capture context review

pmbah-sign-buffer opens a *PMBAH capture context* preview before upload. It shows:

It then asks separately whether to include emacs.buffer_name and emacs.major_mode. If both are declined, the context is only:

{ "surface": "emacs" }

Event semantics

Troubleshooting

Sibling producers

The browser writing page is the no-install producer: an empty drafting canvas in your browser that records edits made inside it, signs, and returns a short URL. A capture-all browser extension producer of the same record format is also in the repository (apps/browser-extension/); its public install path will be linked here once the Chrome Web Store listing is approved.

All three producers (Emacs, the browser writing page, and the extension) sign content-blind manifests that packages/format verifies the same way. See the verification page for the chain of trust and the records page for the public record format.