docs: split context into layered, agent-oriented files
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.
This commit is contained in:
103
playbooks/add-encryption.md
Normal file
103
playbooks/add-encryption.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user