|
| 1 | +// SPDX-License-Identifier: PMPL-1.0-or-later |
| 2 | +// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> |
| 3 | += Contributing — Developer Guide |
| 4 | +Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> |
| 5 | +:toc: left |
| 6 | +:toclevels: 3 |
| 7 | +:icons: font |
| 8 | +:source-highlighter: rouge |
| 9 | + |
| 10 | +This guide is for contributors making *code changes* to verisimiser. For |
| 11 | +repository-wide RSR conventions (commit signing, file layout, contractiles) |
| 12 | +see `.github/CONTRIBUTING.md`. |
| 13 | + |
| 14 | +Three common contribution shapes get a checklist each: |
| 15 | + |
| 16 | +* Adding a new database backend |
| 17 | +* Adding a new drift category |
| 18 | +* Adding a new Tier 2 overlay |
| 19 | + |
| 20 | +== Clone, build, test |
| 21 | + |
| 22 | +[source,bash] |
| 23 | +---- |
| 24 | +git clone git@github.com:hyperpolymath/verisimiser.git |
| 25 | +cd verisimiser |
| 26 | +cargo build |
| 27 | +cargo test --lib --bins |
| 28 | +cargo clippy --all-targets -- -D warnings |
| 29 | +---- |
| 30 | + |
| 31 | +The full `cargo test` runs integration tests under `tests/`. On Windows those |
| 32 | +hit a TOML path-escape issue and fail spuriously; CI is the source of truth. |
| 33 | + |
| 34 | +The `Justfile` lists shorthand recipes for the common loops (`just test`, |
| 35 | +`just quality`, etc.). New Justfile recipes are only added once their |
| 36 | +underlying command works — see `docs/decisions/0002-no-aspirational-justfile-recipes.adoc`. |
| 37 | + |
| 38 | +== Adding a database backend |
| 39 | + |
| 40 | +Adding a backend (say, MySQL) means making the entire codegen + interception |
| 41 | +pipeline aware of it. Checklist: |
| 42 | + |
| 43 | +[%interactive] |
| 44 | +* [ ] Add a variant to `enum DatabaseBackend` in `src/abi/mod.rs`. |
| 45 | +* [ ] Update `DatabaseBackend::from_str` to recognise the new name plus |
| 46 | + common aliases. |
| 47 | +* [ ] Update `DatabaseBackend::as_str` (and any `Display` impl) for the |
| 48 | + new variant. |
| 49 | +* [ ] Decide the *interception strategy* (binlog CDC, change streams, |
| 50 | + WAL monitoring, application middleware …) and document it on the |
| 51 | + enum variant doc comment. |
| 52 | +* [ ] Add the dialect to `src/codegen/query.rs::build_entity_id_expr` |
| 53 | + so the no-PK fallback row identifier is correct (e.g. SQLite uses |
| 54 | + `rowid`, Postgres uses `ctid`). |
| 55 | +* [ ] Add a dialect branch to any other backend-aware site in |
| 56 | + `src/codegen/` — search for `DatabaseBackend::` usages. |
| 57 | +* [ ] If the backend needs a separate sidecar dialect, extend |
| 58 | + `src/codegen/overlay.rs` to emit the right `CREATE TABLE` syntax. |
| 59 | +* [ ] Add a unit test in `src/codegen/query.rs::tests` covering the new |
| 60 | + variant for at least one interceptor type. |
| 61 | +* [ ] Update `Cargo.toml` only if the backend needs a new connector |
| 62 | + crate (e.g. `mysql_async`). Prefer interception via the database's |
| 63 | + replication interface; pull in connector crates only as a fallback. |
| 64 | +* [ ] If the backend belongs in the published interception list, add it |
| 65 | + to `README.adoc` under *Interception methods*. Otherwise leave it |
| 66 | + in `ROADMAP.adoc`. |
| 67 | + |
| 68 | +== Adding a drift category |
| 69 | + |
| 70 | +The drift system is V-L1-E (see #48 for the eight-category ADR). Each |
| 71 | +category is an isolated detector with input type, distance function, and |
| 72 | +threshold. |
| 73 | + |
| 74 | +[%interactive] |
| 75 | +* [ ] Open an ADR in `docs/decisions/` documenting the category's input |
| 76 | + type, distance function, and default threshold. |
| 77 | +* [ ] Add a variant to `DriftCategory` in `src/tier1/drift.rs`. |
| 78 | +* [ ] Implement a `measure(prior, current) -> f64` function returning a |
| 79 | + distance in `[0.0, 1.0]`. |
| 80 | +* [ ] Wire the measurement into the `DriftReport` aggregator. |
| 81 | +* [ ] Add unit tests for: identical inputs → 0.0; maximally different |
| 82 | + inputs → 1.0; threshold-edge cases. |
| 83 | +* [ ] Update `docs/architecture/THREAT-MODEL.adoc` if the category has |
| 84 | + adversarial implications. |
| 85 | + |
| 86 | +== Adding a Tier 2 overlay |
| 87 | + |
| 88 | +Tier 2 overlays require additional storage alongside the target database |
| 89 | +(graph, vector, tensor, semantic, …). New overlays are not the same as |
| 90 | +new backends. |
| 91 | + |
| 92 | +[%interactive] |
| 93 | +* [ ] Add a boolean field to `Tier2Config` in `src/manifest/mod.rs` (and |
| 94 | + its `Default` impl) for the manifest toggle. |
| 95 | +* [ ] Decide the sidecar storage technology (pure Rust, HNSW, ndarray, …) |
| 96 | + and document it on the `Tier2Config` field doc comment. |
| 97 | +* [ ] Add overlay DDL emission in `src/codegen/overlay.rs` behind the new |
| 98 | + flag. |
| 99 | +* [ ] Add an interceptor in `src/codegen/query.rs` that routes the right |
| 100 | + queries to the overlay. |
| 101 | +* [ ] Add a round-trip test in `src/codegen/overlay.rs::tests` covering |
| 102 | + the flag both on and off. |
| 103 | +* [ ] Update `README.adoc`'s *Octad: Eight Modalities* table to reflect |
| 104 | + the new overlay's tier and storage. |
| 105 | + |
| 106 | +== Style notes |
| 107 | + |
| 108 | +* Treat `cargo clippy --all-targets -- -D warnings` as part of `cargo |
| 109 | + build`. The crate has no blanket `#![allow(...)]` blocks |
| 110 | + (`docs/decisions/0001` and 0002 keep the surface clean). |
| 111 | +* Public items used as the library API should be `pub`; binary-only |
| 112 | + helpers stay private. |
| 113 | +* All commits are SSH-signed (see `.github/CONTRIBUTING.md`). |
| 114 | +* PRs target `main`. Auto-merge with `--squash` is the norm. |
0 commit comments