R2D2-MERIDIAN/crates/git-credential-nostr
Joshua Belke de4cfec61e feat: rebrand Codebase Chat to Meridian
Renames the product to Meridian across 1826 files: 24 crates
(codebase-chat-* -> meridian-*), the Flutter package, env vars
(CODEBASE_CHAT_* -> MERIDIAN_*), the deep-link scheme (meridian://),
Postgres GUCs, Helm charts, skills, and the agent surface.

White-labels every external identity onto self-hosted infrastructure:
hosts move from *.codebase.design to *.meridian.r2d2.office.ilab.zone,
images to registry.r2d2.office.ilab.zone/meridian-*, the repo slug to
r2d2/meridian, and bundle IDs to zone.ilab.office.r2d2.meridian.*.
The Block staging relay and the four Block-internal build repos are not
reachable from a self-hosted deployment and are no longer referenced.

The mark becomes a pixel M. It is 5x6 rather than a square 5x5 because
the avatar-pile mask asserts the hole clears the glyph's right edge:
at 5x5 that edge moves from 68.4% to 73% of the tile, which overruns the
56px team-card hole outright and leaves the other three piles under a
pixel. At 5x6 the aspect is 0.833 against the retired C's 0.800, so all
four masks clear it unchanged. All 59 materializations are regenerated
from the generators; `just check-brand` passes.

Four things are deliberately NOT renamed, because they match what was
*stored* rather than what now ships. Rewriting any of them makes a
migration no-op on exactly the installs it exists to repair:

- Frozen migrations 0001-0030. Their SHA-256 digests are pinned in
  n-minus-one-pins.json and embedded in the attested N-1 image. The new
  vocabulary lands as forward migration 0031, which dual-reads all three
  generations' GUCs, lock names, app profiles and mesh d_tags. The
  push-gateway's own 0001 is likewise restored byte-identical, with
  0002 widening its app_profile CHECK.
- Legacy namespace chains. xyz.block.codebasechat.app is *prepended* to
  LEGACY_RELEASE_IDENTIFIERS and its dev/localStorage twins, per the rule
  in legacy_dirs.rs that a previous rename already broke once.
- Bead IDs (codebaseChat-*), which are cited from commits and docs.
- CHANGELOG history and upstream issue links.

The Codebase-era persona ids are added to RETIRED_PERSONAS with their
prompts verbatim, but deliberately NOT to RETIRED_PERSONA_REPLACEMENTS:
that map drives migration::retire_agents, which deletes deployed
instances, and its safety argument is that the successor is already
deployed alongside. That held for Buzz->Codebase; nothing provisions a
Meridian agent on an install that already onboarded, so mapping these
would delete a working agent and leave nothing in its place.

The brand-guard self-test changes axis: the M is symmetric about its
vertical axis, so a mirrored M *is* the canonical M and asserting a
rejection there would assert a bug. It now flips top-to-bottom (the mark
reads as a W) and pins the horizontal symmetry so the coupling is visible
if the mark ever becomes asymmetric again.

Verified: cargo check --workspace --all-targets clean, just fix-all
clean, flutter analyze clean, just check-skills pass, check-brand 59/59,
brand-core 9/9, avatarPileMask 4/4, starter-avatar contrast 2/2.

Signed-off-by: Joshua Belke <joshua@innovationhub-act.org>
2026-08-04 14:06:04 -04:00
..
src feat: rebrand Codebase Chat to Meridian 2026-08-04 14:06:04 -04:00
tests feat: rebrand Codebase Chat to Meridian 2026-08-04 14:06:04 -04:00
Cargo.toml feat: rebrand Codebase Chat to Meridian 2026-08-04 14:06:04 -04:00
README.md feat: rebrand Codebase Chat to Meridian 2026-08-04 14:06:04 -04:00

git-credential-nostr

NIP-98 credential helper for git — signs HTTP auth events with your Nostr key so git can push/pull from Meridian's git server without passwords.

Requirements

  • git 2.46+ (requires authtype capability in the credential protocol)
  • Rust toolchain (for building from source)

Installation

cargo install --path crates/git-credential-nostr

Setup

# 1. Register the helper for your relay origin. The empty helper resets any
# inherited helper list (including macOS osxkeychain) before adding nostr.
git config --global --replace-all credential.https://relay.example.helper ""
git config --global --add credential.https://relay.example.helper nostr
git config --global credential.https://relay.example.useHttpPath true

# 2. Store your nsec in a key file (must be 0600).
mkdir -p ~/.nostr
echo "nsec1..." > ~/.nostr/key && chmod 600 ~/.nostr/key
git config --global nostr.keyfile ~/.nostr/key

That's it. Use git normally — git clone, git push, git fetch.

Replace https://relay.example with the exact origin in your clone URL. Git credential helpers are additive across system and global configuration. A plain git config --global credential.helper nostr therefore does not replace the system osxkeychain helper on macOS; the empty host-scoped entry above does. You can verify the effective list without exposing credentials:

git config --get-all --show-origin credential.https://relay.example.helper
# expected for the host-scoped entries: one empty value, then nostr

CI / CD

Set $NOSTR_PRIVATE_KEY instead of a key file. The env var takes precedence over nostr.keyfile and avoids touching the filesystem:

export NOSTR_PRIVATE_KEY=nsec1...
git clone https://relay.example.com/git/owner/repo.git

When a trusted reverse-proxy/test transport connects to a private address but sends a different public Host authority, set MERIDIAN_GIT_CANONICAL_AUTHORITY=relay.example.com. The helper then binds the NIP-98 u tag to that public authority. Do not set it for ordinary direct connections.

How It Works

When a Meridian git server returns HTTP 401 with a WWW-Authenticate: Nostr realm="...", method="GET" header, git calls this helper with the request details on stdin. The helper loads your Nostr private key, builds a NIP-98 kind-27235 event signed over the request URL and method, base64-encodes it, and writes it back to stdout. Git then retries the request with Authorization: Nostr <token>, which the server verifies by checking the event signature.

git ──stdin──▶ git-credential-nostr ──stdout──▶ git
                     │
                     ▼
              sign kind:27235 event
              (NIP-98 HTTP Auth)

Troubleshooting

Error Cause Fix
no nostr key configured Neither $NOSTR_PRIVATE_KEY nor nostr.keyfile is set Follow the Setup steps above
insecure permissions Key file is readable by group/others chmod 600 ~/.nostr/key
method hint Server's WWW-Authenticate header is missing method="..." Upgrade the Meridian server
useHttpPath credential.useHttpPath is not set git config --global credential.useHttpPath true
Empty output / no auth git version is older than 2.46 Upgrade git
clock skew / auth rejected System clock is off by more than 60 s Sync your system clock (ntpdate, timedatectl)