Replace the single file-structure.md with a stratified layout designed
for AI/agent skill consumption: tables and concrete identifiers over
prose, files loaded on demand, content separated by churn rate.
Layers:
- architecture/ stable structural reference (overview, source-map,
test-map, data-flow)
- patterns/ memory, commands, autocomplete, events, xmpp,
encryption, ui, plugins
- testing/ unit-tests, stubs, functional-tests, bench
- build/ local, docker, ci
- playbooks/ add-command, add-test, add-autocomplete,
add-event-handler, add-encryption
- gotchas.md append-only dated entries (seven seed entries)
- wip/ branch-specific notes; deleted on merge to master
Stable layers describe cproof on master only. In-flight feature
branches (currently feat/ai) get a single file under wip/.
INDEX.md is the entry map with churn labels; SKILL.md is the
always-loaded skill hint pointing to it.
104 lines
3.1 KiB
Markdown
104 lines
3.1 KiB
Markdown
# Playbook: touch encryption modules safely
|
|
|
|
Encryption stacks (OMEMO, OTR, PGP/OX) are independent and each is gated
|
|
behind a `configure` option. Edits must respect three things: the gating
|
|
macro, the bridge file split, and the matching unit-test stubs.
|
|
|
|
See `patterns/encryption.md` for the architectural split.
|
|
|
|
## 1. Identify the bridge
|
|
|
|
| Stack | Module dir | Bridge file (XMPP side) |
|
|
|---|---|---|
|
|
| OMEMO | `src/omemo/` | `src/xmpp/omemo.c` |
|
|
| OTR | `src/otr/` | (none — in-stream on `src/xmpp/message.c`) |
|
|
| PGP / OX | `src/pgp/` | `src/xmpp/ox.c` |
|
|
|
|
Outbound calls (cproof → encryption) usually live in the bridge file.
|
|
Inbound (decrypted message → cproof) usually surfaces in the bridge or
|
|
directly in `src/xmpp/message.c`.
|
|
|
|
## 2. Identify the gating macro
|
|
|
|
```sh
|
|
grep -n "HAVE_OMEMO\|HAVE_LIBOTR\|HAVE_LIBGPGME" src/xmpp/<bridge>.c
|
|
```
|
|
|
|
Every call into the encryption module is wrapped:
|
|
|
|
```c
|
|
#ifdef HAVE_OMEMO
|
|
omemo_encrypt_message(jid, plaintext, &ciphertext);
|
|
#else
|
|
// graceful fallback or skip
|
|
#endif
|
|
```
|
|
|
|
When you add a new call, copy the existing guard. Do **not** drop the
|
|
fallback — the build must succeed with the feature disabled.
|
|
|
|
## 3. Update the public surface (header)
|
|
|
|
If you add or change an exported function in `src/omemo/omemo.h` /
|
|
`src/otr/otr.h` / `src/pgp/gpg.h` / `src/pgp/ox.h`, update **two** places:
|
|
|
|
1. The header itself.
|
|
2. The corresponding stub: `tests/unittests/{omemo,otr,pgp}/stub_*.c`.
|
|
|
|
Keep the stub signature byte-for-byte identical to the header.
|
|
|
|
## 4. Stubs
|
|
|
|
Stubs exist regardless of whether a stack is enabled at runtime — they
|
|
satisfy the unit-test linker. Three flavours, see `testing/stubs.md`.
|
|
|
|
If a unit test needs to drive the new function, switch the stub to `mock()`
|
|
and queue with `will_return`. If a unit test needs to assert arguments,
|
|
switch to `check_expected` and queue with `expect_string` / `expect_value`.
|
|
|
|
## 5. `test_forced_encryption`
|
|
|
|
`tests/unittests/test_forced_encryption.{c,h}` exercises the policy that
|
|
refuses plaintext sends when a session is encryption-locked. **Run it after
|
|
any encryption-policy change.**
|
|
|
|
## 6. Encryption-aware command tests
|
|
|
|
| Test file | Covers |
|
|
|---|---|
|
|
| `test_cmd_otr.c` / `.h` | `/otr` command surface. |
|
|
| `test_cmd_pgp.c` / `.h` | `/pgp` command surface. |
|
|
|
|
(No `test_cmd_omemo.c` exists at the time of writing — confirm with `ls
|
|
tests/unittests/test_cmd_*.c` before assuming.)
|
|
|
|
## 7. Build matrix
|
|
|
|
After changes, build with each encryption flag in turn:
|
|
|
|
```sh
|
|
./configure --disable-omemo
|
|
make check
|
|
|
|
./configure --disable-otr
|
|
make check
|
|
|
|
./configure --disable-pgp
|
|
make check
|
|
```
|
|
|
|
(Inside Docker — see `build/docker.md`.)
|
|
|
|
CI does not necessarily run every disable combination; verify locally if
|
|
your change affects gating logic.
|
|
|
|
## Conventions
|
|
|
|
- Never strip the `#ifdef HAVE_*` guard "for clarity". The disabled-build
|
|
must still compile.
|
|
- Encryption keys / fingerprints persist via the module's own store (`src/
|
|
omemo/store.c`, libotr's keystore, gpgme's keyring). Do not invent
|
|
parallel storage.
|
|
- Outbound encryption sits between message build and stanza send — see
|
|
`patterns/xmpp.md` for the flow.
|