Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Dockerfile.local
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ ARG RUNTIME_IMAGE=debian:bookworm-20260112-slim@sha256:56ff6d36d4eb3db13a741b342
FROM ${RUST_IMAGE} AS builder
WORKDIR /build

# These named contexts are supplied by the sibling Locks Compose project. The
# Paykit contexts are crate directories, so the paykit-rs repository needs no
# Docker-owned files and its workspace target directory is never transferred.
# These named contexts are supplied by the calling build or Compose project.
# The Paykit contexts are crate directories, so the paykit-rs repository needs
# no Docker-owned files and its workspace target directory is never transferred.
RUN --mount=from=paykit-lib,target=/contexts/paykit-lib,ro \
--mount=from=paykit-sdk,target=/contexts/paykit-sdk,ro \
--mount=from=locks,target=/contexts/locks,ro \
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,10 @@ Startup fails before bind if configuration, secrets, PostgreSQL, migrations, aut

### Local Locks demo image

`Dockerfile.local` packages this repository for sibling Locks Compose stack. It consumes checked-out Paykit Rust and Locks trees through named BuildKit contexts, then produces unprivileged local image containing server and helper binaries.
`Dockerfile.local` packages this repository for the Locks Compose stack. It
accepts pinned public Git sources or deliberate local-worktree overrides through
named BuildKit contexts, then produces an unprivileged local image containing
the server and helper binaries.

Build command, image contract, source-rewrite behavior, and generated config contract live in [`docs/local-locks-demo.md`](docs/local-locks-demo.md).

Expand Down
33 changes: 27 additions & 6 deletions docs/local-locks-demo.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
# Local Locks demo image

`Dockerfile.local` packages Paykit Server for sibling Locks Compose stack. It is local/demo packaging, not production image.
`Dockerfile.local` packages Paykit Server for the Locks Compose stack. It is local/demo packaging, not a production image.

## Build
## Build from public pinned sources

Build from this repository with checked-out Paykit Rust and Locks source trees supplied as named BuildKit contexts:
From a fresh anonymous clone of this repository, build with the exact Paykit
Rust and Locks revisions pinned in `Cargo.toml`:

```bash
docker buildx build --load \
--build-context paykit-lib='https://github.com/pubky/paykit-rs.git#52a852995bfc457b78d32f5a45f6741766a89bba:paykit-lib' \
--build-context paykit-sdk='https://github.com/pubky/paykit-rs.git#52a852995bfc457b78d32f5a45f6741766a89bba:paykit-sdk' \
--build-context locks='https://github.com/pubky/locks.git#df5ea1b6d8dcdec3a9b5a915c3f57bca69d75c8a' \
-f Dockerfile.local \
-t paykit-server:local .
```

These contexts are anonymously reachable and reproducible. Update the URLs
together with the corresponding `Cargo.toml` pins; exact dependency-pin matches
make source drift fail closed.

## Build from local worktrees

For coordinated development, override the named contexts with local source
trees. This mode intentionally includes uncommitted source edits:

```bash
docker buildx build --load \
Expand All @@ -15,7 +34,9 @@ docker buildx build --load \
-t paykit-server:local .
```

Build uses exact local source-tree contents, including uncommitted source edits. Crate-level `paykit-lib` and `paykit-sdk` contexts avoid transferring Paykit Rust workspace target directory and require no Docker files in that repository. Locks context must exist and applies its existing source-tree exclusions.
Crate-level `paykit-lib` and `paykit-sdk` contexts avoid transferring the Paykit
Rust workspace target directory and require no Docker-owned files in that
repository. The Locks context applies its existing source-tree exclusions.

Builder runs [`scripts/prepare-local-docker-sources.sh`](../scripts/prepare-local-docker-sources.sh) against copied manifests to resolve `paykit-lib`, `paykit-sdk`, and `locks-core` from named contexts. Committed Git dependency declarations and lockfile remain unchanged. No SSH agent or Cargo credentials are mounted. Exact dependency-pin matches make source drift fail closed.

Expand All @@ -29,11 +50,11 @@ Final pinned Debian image:
- adds CA certificates and three application binaries to pinned runtime base;
- contains no source tree, Cargo cache, runnable config, DB credentials, or application secrets.

Supply `PAYKIT_CONFIG`, `PAYKIT_DATABASE_URL`, and `PAYKIT_MASTER_KEY` at runtime. Mount generated ignored local config. Sibling Compose definition owns mounts, env values, infrastructure image pins, and helper command overrides.
Supply `PAYKIT_CONFIG`, `PAYKIT_DATABASE_URL`, and `PAYKIT_MASTER_KEY` at runtime. Mount generated ignored local config. The calling Compose definition owns mounts, environment values, infrastructure image pins, and helper command overrides.

## Generated local config contract

Sibling Locks orchestration generates `.local/paykit-server/config.toml` only after local Lock Server identity exists. Directory is Git-ignored. It must replace deliberately invalid `<ACTUAL_CANONICAL_LOCK_SERVER_PUBKY>` token below with exact canonical `pubky...` value exposed by Lock Server as `credentials.lock_server_public_key`. This block is not runnable config.
Locks orchestration generates `.local/paykit-server/config.toml` only after the local Lock Server identity exists. The directory is Git-ignored. It must replace the deliberately invalid `<ACTUAL_CANONICAL_LOCK_SERVER_PUBKY>` token below with the exact canonical `pubky...` value exposed by Lock Server as `credentials.lock_server_public_key`. This block is not runnable config.

```toml
[http]
Expand Down
8 changes: 4 additions & 4 deletions docs/plans/0001-receiver-only-prototype-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ Only **EXPLICIT**, **AUTHORITATIVE SOURCE**, and **CONSTRAINT** entries may driv

The user designated these as authoritative for Locks Server ↔ Paykit Server HTTP behavior:

- `../../Pubky/locks/docs/ADRs/0020-locks-paykit-v1-integration-boundary.md`
- matching behavior in `../../Pubky/locks/locks-server/src/paykit_http_client.rs`
- [Locks ADR 0020](https://github.com/pubky/locks/blob/df5ea1b6d8dcdec3a9b5a915c3f57bca69d75c8a/docs/ADRs/0020-locks-paykit-v1-integration-boundary.md)
- matching [Locks Paykit HTTP client](https://github.com/pubky/locks/blob/df5ea1b6d8dcdec3a9b5a915c3f57bca69d75c8a/locks-server/src/paykit_http_client.rs)

### Product flow

Expand All @@ -40,8 +40,8 @@ Current `../paykit-rs` code/specifications define dependency behavior. They are
**EXPLICIT**:

- Canonical Locks creator, reader, bundle, addressed lock-resource identifiers,
and Paykit-payment policy validation use `locks-core` pinned at revision
`06bc63c4b5ff7df194f26f3f3fecb8dab4d28995`; Paykit Server does not duplicate
and Paykit-payment policy validation use `locks-core` pinned at public revision
`df5ea1b6d8dcdec3a9b5a915c3f57bca69d75c8a`; Paykit Server does not duplicate
their parsing, canonicalization, or policy grammar.

## Actors and key boundaries
Expand Down
4 changes: 2 additions & 2 deletions docs/plans/0002-receiver-only-prototype-implementation.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

**Authoritative requirements:**
- `docs/plans/0001-receiver-only-prototype-design.md`
- `../../Pubky/locks/docs/ADRs/0020-locks-paykit-v1-integration-boundary.md`
- Matching Locks behavior in `../../Pubky/locks/locks-server/src/paykit_http_client.rs`
- [Locks ADR 0020](https://github.com/pubky/locks/blob/df5ea1b6d8dcdec3a9b5a915c3f57bca69d75c8a/docs/ADRs/0020-locks-paykit-v1-integration-boundary.md)
Comment thread
dzdidi marked this conversation as resolved.
Outdated
- Matching [Locks Paykit HTTP client](https://github.com/pubky/locks/blob/df5ea1b6d8dcdec3a9b5a915c3f57bca69d75c8a/locks-server/src/paykit_http_client.rs)

**Hard boundary:** Do not implement unsupported Paykit wire/Encrypted-Link behavior locally. Delegate it to the pinned `paykit-sdk` dependency.

Expand Down
22 changes: 16 additions & 6 deletions docs/plans/0004-local-locks-compose-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

**Tech stack:** Rust 1.91.1, Axum, `paykit-sdk`, PostgreSQL/SQLx, Docker multi-stage builds, Pubky static testnet, Bitcoin Core regtest, BDK Electrum.

**Publication note:** The original peer implementation plan was intentionally
not included in the fresh public Locks history. The public cross-service
contract is [Locks ADR 0020](https://github.com/pubky/locks/blob/df5ea1b6d8dcdec3a9b5a915c3f57bca69d75c8a/docs/ADRs/0020-locks-paykit-v1-integration-boundary.md).
Public image builds use anonymous pinned Git contexts; sibling worktrees remain
an explicit local-development override.

---

## Requirement provenance
Expand All @@ -26,12 +32,12 @@

### AUTHORITATIVE SOURCE

- `../paykit-rs/specs/pubky-auth-companion-claims.md`.
- `../paykit-rs/paykit-sdk/src/pubky_session/companion_claim.rs`.
- [Paykit companion-claim specification](https://github.com/pubky/paykit-rs/blob/52a852995bfc457b78d32f5a45f6741766a89bba/specs/pubky-auth-companion-claims.md).
- [Paykit SDK companion-claim implementation](https://github.com/pubky/paykit-rs/blob/52a852995bfc457b78d32f5a45f6741766a89bba/paykit-sdk/src/pubky_session/companion_claim.rs).
- `paykit-server/src/bitkit_claim.rs` for exact `watch-only-account-v1` payload and receiver validation.
- `paykit-server/src/real_setup.rs` for setup commit ordering and xpub validation.
- `README.md` and `config/paykit-server.example.toml` for supported runtime/config behavior.
- Peer plan: `../../Pubky/locks/docs/plans/0042-local-paykit-integration-demo.md`.
- Public peer contract: [Locks ADR 0020](https://github.com/pubky/locks/blob/df5ea1b6d8dcdec3a9b5a915c3f57bca69d75c8a/docs/ADRs/0020-locks-paykit-v1-integration-boundary.md).

### CONSTRAINTS OBSERVED IN CURRENT CODE

Expand Down Expand Up @@ -126,7 +132,7 @@ No implementation task may invent an answer to these gates.

**Files:**
- Create/Modify: `docs/plans/0004-local-locks-compose-integration.md`
- Review: `../../Pubky/locks/docs/plans/0042-local-paykit-integration-demo.md`
- Review: public [Locks ADR 0020](https://github.com/pubky/locks/blob/df5ea1b6d8dcdec3a9b5a915c3f57bca69d75c8a/docs/ADRs/0020-locks-paykit-v1-integration-boundary.md)

**Steps:**
1. Resolve all gates one question at a time.
Expand Down Expand Up @@ -265,8 +271,12 @@ No implementation task may invent an answer to these gates.
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --check
docker buildx build --build-context paykit-lib=../paykit-rs/paykit-lib --build-context paykit-sdk=../paykit-rs/paykit-sdk --build-context locks=../../Pubky/locks -f Dockerfile.local -t paykit-server:local .
docker buildx build --load \
--build-context paykit-lib='https://github.com/pubky/paykit-rs.git#52a852995bfc457b78d32f5a45f6741766a89bba:paykit-lib' \
--build-context paykit-sdk='https://github.com/pubky/paykit-rs.git#52a852995bfc457b78d32f5a45f6741766a89bba:paykit-sdk' \
--build-context locks='https://github.com/pubky/locks.git#df5ea1b6d8dcdec3a9b5a915c3f57bca69d75c8a' \
-f Dockerfile.local -t paykit-server:local .
git diff --check
```

The sibling Locks plan must add executable wrapper commands that load ignored generated credentials and run explicit `TEST_DATABASE_URL` suites plus the Compose smoke without printing secrets.
The corresponding Locks integration must add executable wrapper commands that load ignored generated credentials and run explicit `TEST_DATABASE_URL` suites plus the Compose smoke without printing secrets.
Loading