From 14e5f799e87965ead80e78d5a837ce9663a64fad Mon Sep 17 00:00:00 2001 From: Ruben Hensen Date: Thu, 6 Aug 2026 16:29:02 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20CLAUDE.md=20=E2=80=94=20branch=20protec?= =?UTF-8?q?tion=20now=20requires=20the=20single=20Wire=20compat=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #262 merged as 0343369 (#295) and branch protection was repointed at the new wire-compat job; the two old per-language check names are no longer required. --- CLAUDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 8b14140..a75841f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ Migrated from the dobby memory repo (`encryption4all/dobby`). This file is the h ## Workspace & CI -- Workspace members: `pg-core` (lib), `pg-ffi` (C ABI), `pg-pkg` (PKG service), `pg-cli`, `cryptify` (file-transfer service, merged in 2026-07-31). `pg-wasm` is a sibling crate the root `Cargo.toml` lists under `exclude`, so it is not part of the workspace and is built separately with wasm-pack (see Release & configuration). Sub-crates share workspace files. Build the workspace from repo root with `cargo build`. A bare `cargo test --workspace` FAILS to compile: `pg-core`'s tests are gated behind its `test` feature (also `rust`/`stream`), so the item is configured out and imports like `crate::test::TestSetup` don't resolve. CI (`.github/workflows/build.yml`) runs tests per crate: `cargo test --manifest-path pg-core/Cargo.toml --features test,rust,stream` for core, `--all-targets` for `cryptify` (it declares no features of its own, so that is the equivalent invocation), `--all-features` for `pkg`/`cli`/`ffi`. None of these cover `pg-wasm`. The `test`/`format`/`clippy` matrices key on the crate **directory** rather than a `pg-` suffix, because `cryptify` doesn't carry that prefix — so the check contexts are `Test workspace (pg-core)`, not `Test workspace (core)`. Nothing required points at them today, but whatever adds to the required list later must use the current names. Where that list lives is not obvious and an agent cannot read it: required checks come from **classic branch protection** (`gh api repos/encryption4all/postguard/branches/main/protection`, currently exactly `Wire compat (published pg-core)` and `Wire compat (published pg-wasm/pg-js)`), *not* from the `main` ruleset, which carries only `deletion`/`non_fast_forward`/`pull_request` and no `required_status_checks` rule at all. `dobby-coder` gets 403 on the protection endpoint, so reading the ruleset alone concludes nothing is required, which is wrong — ask a maintainer rather than inferring. `pg-core` uses CGWKV + MKEM for multi-recipient encryption (production feature set `["cgwkv", "mkem"]`). [#262](https://github.com/encryption4all/postguard/issues/262) added a single `wire-compat` job in `build.yml` that consolidates the two `Wire compat` checks above (`needs: [wire-compat-rust, wire-compat-js]`); branch protection still lists the two per-language names until a maintainer repoints it at `wire-compat` — check which is current with the `gh api` command above rather than assuming the repoint happened. +- Workspace members: `pg-core` (lib), `pg-ffi` (C ABI), `pg-pkg` (PKG service), `pg-cli`, `cryptify` (file-transfer service, merged in 2026-07-31). `pg-wasm` is a sibling crate the root `Cargo.toml` lists under `exclude`, so it is not part of the workspace and is built separately with wasm-pack (see Release & configuration). Sub-crates share workspace files. Build the workspace from repo root with `cargo build`. A bare `cargo test --workspace` FAILS to compile: `pg-core`'s tests are gated behind its `test` feature (also `rust`/`stream`), so the item is configured out and imports like `crate::test::TestSetup` don't resolve. CI (`.github/workflows/build.yml`) runs tests per crate: `cargo test --manifest-path pg-core/Cargo.toml --features test,rust,stream` for core, `--all-targets` for `cryptify` (it declares no features of its own, so that is the equivalent invocation), `--all-features` for `pkg`/`cli`/`ffi`. None of these cover `pg-wasm`. The `test`/`format`/`clippy` matrices key on the crate **directory** rather than a `pg-` suffix, because `cryptify` doesn't carry that prefix — so the check contexts are `Test workspace (pg-core)`, not `Test workspace (core)`. Nothing required points at them today, but whatever adds to the required list later must use the current names. Where that list lives is not obvious and an agent cannot read it: required checks come from **classic branch protection** (`gh api repos/encryption4all/postguard/branches/main/protection`, currently exactly `Wire compat`), *not* from the `main` ruleset, which carries only `deletion`/`non_fast_forward`/`pull_request` and no `required_status_checks` rule at all. `dobby-coder` gets 403 on the protection endpoint, so reading the ruleset alone concludes nothing is required, which is wrong — ask a maintainer rather than inferring. `pg-core` uses CGWKV + MKEM for multi-recipient encryption (production feature set `["cgwkv", "mkem"]`). [#262](https://github.com/encryption4all/postguard/issues/262) (merged `0343369`, #295) replaced the two per-language `Wire compat (published pg-core)` / `Wire compat (published pg-wasm/pg-js)` required checks with this single `wire-compat` job (`needs: [wire-compat-rust, wire-compat-js]`, `permissions: contents: read`); the two old names are no longer required and the underlying per-language jobs still exist and still run, just aren't required individually anymore. - `cryptify` was a separate repo until `ba380a1` (#277) merged it as a workspace member, history-preserving, the deliberate yes decided in #255/#285. What that bought: one lockfile, which closes a real drift class — the two trees previously built `pg-core`'s container serializer against two different `bincode-next` versions with nothing comparing them. What it costs is a **standing dependency coupling, and it does not go away**: `pg-pkg` reaches `libsqlite3-sys` through `sqlx`, `cryptify` reaches it through `rusqlite`, and it is `libsqlite3-sys` itself that declares `links = "sqlite3"` (`rusqlite`, `sqlx` and `sqlx-sqlite` all declare none — check with `cargo metadata`, not by guessing which crate in the chain owns it). Only one package per resolve graph may claim a given `links` value, and optional dependencies sit in the graph whether their feature is enabled or not — so `sqlx-sqlite` is locked even though `pg-pkg` enables only `postgres`. The newest intersecting pair is **sqlx 0.9 + rusqlite 0.39** (`libsqlite3-sys 0.37` in the root lockfile), so every `rusqlite` bump waits on sqlx's `libsqlite3-sys` ceiling — and that block is live today, not merely future: `rusqlite` 0.40.0 wants `libsqlite3-sys ^0.38.0` and 0.40.1 wants `^0.38.1`, both published, neither yanked, and both outside `sqlx-sqlite` 0.9.0's `>=0.30.1, <0.38.0`, so a lone rusqlite bump does not resolve at all. Don't bump either half alone; check the intersection first. - `pg-compat` is a second excluded sibling crate (root `Cargo.toml` `exclude`), and the exclusion is load-bearing: it depends on `pg-core` from **crates.io** (`=0.6.1`), not on `../pg-core`, so it can open bytes sealed by this tree with published readers. It has its own `Cargo.lock` (run it with `--locked`). Its input comes from `cargo run -p pg-core --features stream --example seal-samples -- `, a deterministic sealer whose output layout is documented in `pg-compat/README.md`. CI wires the two together: `wire-compat-rust` in `build.yml` seals with HEAD and opens with published pg-core on any PR touching the wire surface (pg-core/pg-wasm/pg-compat/pg-compat-js trees, the ROOT `Cargo.lock`/`Cargo.toml` — pg-core resolves from the root lockfile — and build.yml itself); `pg-compat-lint` covers the crate's fmt/clippy, which the per-crate matrices don't. The `=0.6.1` pin is currently one release behind: `pg-core` 0.6.2 published 2026-07-30 and neither the pin nor `COMPATIBILITY.md`'s `crates.io` reader row moved, because nothing reads those rows — the npm rows cannot drift this way, since `manifest.test.mjs` machine-reads them. Tracked in #268; move the row and the pin together. - `pg-compat-js` is the Node half of the same gate: a private npm package (no build step, no lint/format tooling in the repo) that opens the sealer's output with the published npm readers, installed side by side through `npm:` aliases (`pg-wasm-0-6-1`, `pg-js-2-3-3`, `pg-js-1-11-0`) because several versions of one package have to coexist. Run it locally with `npm --prefix pg-compat-js ci` then `PG_COMPAT_ARTIFACTS= npm --prefix pg-compat-js test`; in CI the `wire-compat-js` job in `build.yml` downloads the artifact `wire-compat-rust` sealed and runs the same suite, gated on `needs.wire-compat-rust.outputs.sealed` rather than a second copy of the path filter. `node --test test/` does NOT work (Node reads the bare directory as a module path and dies with `Cannot find module .../test`) — the `test` script passes the glob `"test/*.test.mjs"` instead. Its reader list is not free to edit on its own: `test/manifest.test.mjs` parses the fenced `Reader list` block in root `COMPATIBILITY.md` (` ` rows) and compares the `npm` rows against `readers()`, so that block is machine-read and reformatting it into prose or a table breaks the test. It also compares each declared `package` and `version` against the installed alias's own `package.json`, read off disk because neither published package exports `package.json` (`import('/package.json')` is `ERR_PACKAGE_PATH_NOT_EXPORTED`).