commits
[Srp.Client.v] / [Srp.Server.v] / [Srp.Client.public] don't exist;
the API names are [Client.create], [Client.public_key],
[Client.compute_session_key] (returning [(_, [`Msg of string]) result]).
[Server.create] also takes [~username]; salt isn't passed by the
client to [compute_session_key], it's [~big_b] / [~big_a]. Initialise
[Crypto_rng_unix] so [Client.create] doesn't raise.
Pattern-match the [result], [assert] [String.equal] on the derived
keys, and add [nox-crypto-rng.unix] to the mdx libs.
Pure formatting: dune fmt drops the leading 2-space indent and
collapses the long key_s let-binding onto one line.
Run mdx on lib/srp.mli so the {[ ... ]} odoc block now type-checks
the registration + authentication flow against the real API.
The example used `username`/`password` as free names, shadowed `salt`
across stages of the protocol, and trailed off with `(* key_c =
key_s *)` in prose. Restructured as toplevel bindings: real username
and password literals, distinct names for `reg_salt` and
`server_salt` so the protocol stages stay readable, and an
`assert (String.equal key_c key_s)` that documents (and verifies)
the SRP claim that both sides derive the same session key.
Both compute_session_key calls return `(string, [`Msg of string])
result`; the example uses `Result.get_ok` so the expected-success
path stays one line, while a Msg payload still surfaces as a
documented exception in the example output.
The READMEs all share the standard install/overlay snippet, but the
sh blocks lacked the "<!-- $MDX skip -->" directive. `dune test`
would shell out to `opam install` against the live switch, which
either prompts interactively or fails with a package conflict —
either way diffing as a test failure.
Bulk-add skip directives in front of every install/overlay block.
Also collapse the doubled "non-deterministic + skip" stack on three
READMEs (memtrace, ocaml-dpop, ocaml-pid1, ocaml-yaml, merlint) where
`skip` already implies the runtime is bypassed.
Renames 35 packages to make blacksun forks distinguishable from their
opam-repository upstreams. Module names (Git.x, Tls.x, ...) stay bare;
opam package names and dune (public_name) findlib references move to
nox-X. After this commit, zero local package names overlap with
opam-repository.
Renamed:
- nox-git, nox-irmin
- nox-crypto, nox-crypto-pk, nox-crypto-rng, nox-crypto-ec
- nox-tls, nox-tls-eio, nox-tar, nox-tar-eio, nox-tty, nox-tty-eio
- nox-arp, nox-ca-certs, nox-cbor, nox-cookie, nox-crc, nox-csv
- nox-gpt, nox-hkdf, nox-http, nox-jwt, nox-kdf, nox-loc
- nox-memtrace, nox-pds, nox-sexp, nox-slack, nox-toml
- nox-websocket, nox-x509, nox-xdge, nox-yaml
Also drops orphan tar-mirage and tar-unix opam templates that had no
matching package stanza.
38 subtrees lacked a (source ...) stanza in their dune-project, so
their generated .opam files had no dev-repo: field. That broke
downstream tooling that uses dev-repo to identify the subtree
(notably the root.opam external-dep filter, which couldn't tell
internal packages from external ones).
Add (source (tangled gazagnaire.org/<subtree>)) to each, matching
the URL configured in sources.toml. dune regenerates dev-repo:,
homepage: and bug-reports: in every affected .opam.
Pure formatting changes from `dune fmt`: doc comment placement moves
from above the binding to below it for `type`s, multi-line `match`
expressions collapse onto one line where they fit, and infix operator
applications pick up spaces (`Soup.($?)` -> `Soup.( $? )`). No
semantic changes.
Object combinators: [Object.mem] -> [Object.member], [Object.opt_mem]
-> [Object.opt_member], [Object.case_mem] -> [Object.case_member]. The
sibling submodules [Object.Mem] / [Object.Mems] become
[Object.Member] / [Object.Members]. RFC 8259 §4 calls these
"name/value pairs, referred to as the members", so mirror the spec
name rather than the shortened [mem].
[Object.finish] -> [Object.seal]. "Seal" reads as "close the map, no
more members added", which is what the operation does.
Value constructors/queries: [Value.mem] (function) -> [Value.member];
[Value.mem_find] -> [Value.member_key]; [Value.mem_names] ->
[Value.member_names]; [Value.mem_keys] -> [Value.member_keys].
[type mem = ...] -> [type member = ...]; [type object'] still points
at [member list].
Downstream (~80 files across slack, sbom, stripe, sigstore, requests,
claude, irmin, freebox) updated via perl-pie. dune build clean,
dune test ocaml-json clean.
Follow up to the module rename: update the remaining callers that
still referenced [Err] (library [claude.ml{,i}], [client.ml], the test
driver [test.ml]), and fix one stray [^ e] string concatenation in
hermest's CLI that needed [Json.Error.to_string e] now that
[Json.of_string] yields a structured error.
Warning 69 (unused-field, mutable-never-assigned). Four independent
record fields were flagged as mutable but the code only mutates their
referents in place, never rebinds the record slot itself:
- ocaml-wal/lib/wal.ml: [t.file] (the Eio file resource; methods call
Eio.File.pwrite_all etc., the slot is set once at open time).
- ocaml-block/lib/block.ml: [Memory.state.data] (the backing bytes,
written via Bytes.blit_string; [Bytes.t] is already mutable).
- ocaml-sse/lib/sse.ml: [Parser.t.data_buf] (a Buffer.t, written via
Buffer.add_*; the slot never changes).
- ocaml-zephyr/lib/zephyr.ml: drop [mode : Read | Write] entirely —
set at open-time, read nowhere. The open_read / open_write
constructors already distinguish the two call shapes, so mode
tracking was redundant.
Generate .opam.template files with x-quality-* fields based on
detected package features:
- x-quality-build: has lib/ with .ml files
- x-quality-test: has test/ with .ml files
- x-quality-fuzz: has fuzz/ with .ml files
- x-quality-interop: has test/interop/ directory
- x-quality-cram: has test/*.t/ directories
These fields are picked up by dune's opam generation and will be
checked by merlint E910 for consistency.
Also: add fmt dep to ocaml-sse/lib/dune (Fmt.pf used without dep).
monopam quality — scans packages for quality features, caches by
git commit hash. 166 packages: build=163, test=162, fuzz=94,
interop=39, doc=42.
Standard vocabulary based on crates.io categories, erratique/opam
conventions, and monorepo domain coverage:
Org: org:blacksun
Domain: aerospace, codec, crypto, network, storage, git, merkle
Purpose: cli, test, bench, format, log, system
Protocol: ccsds, uslp, cop1, sdls, sle, atproto, tls, http, json, binary
Cross-cutting: eio, simulation, math, compression
Tags placed in dune-project (package ...) stanzas via (tags ...).
Propagated to .opam files by dune's opam generation.
- Update .ocamlformat to 0.29.0 across all 591 files
- csvt: reuse single Buffer.t for field reads (no alloc per field)
- sexpt: Obj members decoded from stream into Dict, typed Variant GADT
- Reformat all source files for 0.29.0
import used List.find_opt on raw map pairs, so a duplicate
"version" or "entries" key would shadow later occurrences.
Now checks for byte-equal duplicate keys before field extraction,
consistent with the receipt parser's cbor_check_unique_keys.
Ensure all 67 fuzz/dune files include gen_corpus.exe in the (alias fuzz)
rule deps for AFL corpus generation. Adds both missing runtest and fuzz
rules to ocaml-cose which had neither.
Fix invalid odoc markup in 54 files: convert {\!Module} to {!Module}
in fuzz .mli files, replace inline {v ... v} with [...] code spans,
fix "paragraph should begin on its own line" warnings, escape bare
brackets, and resolve ambiguous docstring placement (warning 50).
- Remove vendored crowbar/ directory
- Replace all Crowbar references with Alcobar across 176 .ml files
- Update all fuzz dune files: crowbar → alcobar in libraries
- Remove 77 gen_corpus.ml files (alcobar handles corpus internally)
- Update dune-project files: crowbar → alcobar in dependencies
- Update merlint rules (e705, e726): Crowbar → Alcobar in checks,
docs, and examples
- Update merlint generated docs (index.html)
428 files changed, ~1200 lines removed net.
- Replace Printf.sprintf/printf with Fmt.str/pr in fuzz_squashfs, gen_corpus
- Replace failwith (Fmt.str ...) with Fmt.failwith in squashfs.ml (E215)
- Replace invalid_arg (Fmt.str ...) with Fmt.invalid_arg in squashfs_writer, tc (E216)
- Add fmt to gen_corpus dune deps for squashfs, srp, streaming-aead, tar, tc
Add module doc comments to tar_gz.mli and test_vectors.mli, and value
doc comments across tar, tc, streaming-aead, squashfs, and srp.
- Change `run` signature to `string -> (string * test_case list) list -> unit`
matching Alcotest's grouping convention
- Fix `_name` bug: pass the name through to Alcotest.run_with_args
- Each fuzz module now exports `let suite = ("name", [test_case ...])`
- Entry points (fuzz.ml) collect suites: `Crowbar.run "pkg" [Fuzz_X.suite]`
- Remove stale `add_test`/`suite` API, keep only `test_case`/`run`
- Remove `let run () = ()` from fuzz_common.ml files
- Update merlint E725 rule to match new `let suite = ("name", ...)` pattern
- Update E725 test fixtures and expected output
- Restore cursor on exit via at_exit in Tty.Progress (fixes TTY corruption)
- Install SIGINT handler in monopam test for clean Ctrl-C
- Add 2s per-iteration timeout and 2s total budget to crowbar
- Group crowbar alcotest output by module prefix ("mdns: foo" → group "mdns")
- Skip fuzz runtest in afl context (enabled_if <> profile afl)
- Add merlint E725: enforce "module: description" fuzz test name convention
Convert all packages from:
(source (uri https://tangled.org/handle/repo))
to:
(source (tangled handle/repo))
This uses dune 3.21's native tangled support for cleaner source
declarations. Also removes redundant homepage/bug_reports fields
that are auto-generated from tangled sources.
Comprehensive seed corpus for efficient AFL fuzzing:
Text/Protocol formats:
- cookeio: HTTP cookies (simple, full attributes, multi-value)
- jsonwt: JWT tokens (header, valid token)
- json-logs: JSON strings with escapes
- tomlt: TOML config files
- hostname: Domain names with ports
- xff: X-Forwarded-For headers, CIDR notation
- punycode: ASCII and Unicode domains
- mdns: DNS headers and queries
Binary formats:
- sdnv: RFC 6256 variable-length integers
- hap: HomeKit TLV encoding
- space-packet: CCSDS packet headers
- tc-1/tm-1: Telecommand/Telemetry frames
- sle: Space Link Extension TML headers
- tls: TLS records and handshake messages
- requests: HTTP/1.1 and HTTP/2 frames
Crypto:
- crypto: 32-byte keys
- csrf: CSRF tokens and secrets
- paseto: v3.local prefix and keys
- pbkdf2: passwords and salts
- spake2/srp: authentication parameters
- streaming-aead: keys, nonces, plaintext
Misc:
- sgp4: TLE satellite orbit data
- tty: ASCII, Unicode, ANSI escape sequences
- github-oauth: OAuth parameters
- rate-limit: IPv4/IPv6 addresses
Update comment headers to use standardized format:
- Quick check: dune build @fuzz
- With AFL: crow start --cpus=4
Remove verbose afl-fuzz commands and fuzz-afl aliases since
crow now handles building and running AFL instrumented fuzzers.
[Srp.Client.v] / [Srp.Server.v] / [Srp.Client.public] don't exist;
the API names are [Client.create], [Client.public_key],
[Client.compute_session_key] (returning [(_, [`Msg of string]) result]).
[Server.create] also takes [~username]; salt isn't passed by the
client to [compute_session_key], it's [~big_b] / [~big_a]. Initialise
[Crypto_rng_unix] so [Client.create] doesn't raise.
Pattern-match the [result], [assert] [String.equal] on the derived
keys, and add [nox-crypto-rng.unix] to the mdx libs.
Run mdx on lib/srp.mli so the {[ ... ]} odoc block now type-checks
the registration + authentication flow against the real API.
The example used `username`/`password` as free names, shadowed `salt`
across stages of the protocol, and trailed off with `(* key_c =
key_s *)` in prose. Restructured as toplevel bindings: real username
and password literals, distinct names for `reg_salt` and
`server_salt` so the protocol stages stay readable, and an
`assert (String.equal key_c key_s)` that documents (and verifies)
the SRP claim that both sides derive the same session key.
Both compute_session_key calls return `(string, [`Msg of string])
result`; the example uses `Result.get_ok` so the expected-success
path stays one line, while a Msg payload still surfaces as a
documented exception in the example output.
The READMEs all share the standard install/overlay snippet, but the
sh blocks lacked the "<!-- $MDX skip -->" directive. `dune test`
would shell out to `opam install` against the live switch, which
either prompts interactively or fails with a package conflict —
either way diffing as a test failure.
Bulk-add skip directives in front of every install/overlay block.
Also collapse the doubled "non-deterministic + skip" stack on three
READMEs (memtrace, ocaml-dpop, ocaml-pid1, ocaml-yaml, merlint) where
`skip` already implies the runtime is bypassed.
Renames 35 packages to make blacksun forks distinguishable from their
opam-repository upstreams. Module names (Git.x, Tls.x, ...) stay bare;
opam package names and dune (public_name) findlib references move to
nox-X. After this commit, zero local package names overlap with
opam-repository.
Renamed:
- nox-git, nox-irmin
- nox-crypto, nox-crypto-pk, nox-crypto-rng, nox-crypto-ec
- nox-tls, nox-tls-eio, nox-tar, nox-tar-eio, nox-tty, nox-tty-eio
- nox-arp, nox-ca-certs, nox-cbor, nox-cookie, nox-crc, nox-csv
- nox-gpt, nox-hkdf, nox-http, nox-jwt, nox-kdf, nox-loc
- nox-memtrace, nox-pds, nox-sexp, nox-slack, nox-toml
- nox-websocket, nox-x509, nox-xdge, nox-yaml
Also drops orphan tar-mirage and tar-unix opam templates that had no
matching package stanza.
38 subtrees lacked a (source ...) stanza in their dune-project, so
their generated .opam files had no dev-repo: field. That broke
downstream tooling that uses dev-repo to identify the subtree
(notably the root.opam external-dep filter, which couldn't tell
internal packages from external ones).
Add (source (tangled gazagnaire.org/<subtree>)) to each, matching
the URL configured in sources.toml. dune regenerates dev-repo:,
homepage: and bug-reports: in every affected .opam.
Object combinators: [Object.mem] -> [Object.member], [Object.opt_mem]
-> [Object.opt_member], [Object.case_mem] -> [Object.case_member]. The
sibling submodules [Object.Mem] / [Object.Mems] become
[Object.Member] / [Object.Members]. RFC 8259 §4 calls these
"name/value pairs, referred to as the members", so mirror the spec
name rather than the shortened [mem].
[Object.finish] -> [Object.seal]. "Seal" reads as "close the map, no
more members added", which is what the operation does.
Value constructors/queries: [Value.mem] (function) -> [Value.member];
[Value.mem_find] -> [Value.member_key]; [Value.mem_names] ->
[Value.member_names]; [Value.mem_keys] -> [Value.member_keys].
[type mem = ...] -> [type member = ...]; [type object'] still points
at [member list].
Downstream (~80 files across slack, sbom, stripe, sigstore, requests,
claude, irmin, freebox) updated via perl-pie. dune build clean,
dune test ocaml-json clean.
Follow up to the module rename: update the remaining callers that
still referenced [Err] (library [claude.ml{,i}], [client.ml], the test
driver [test.ml]), and fix one stray [^ e] string concatenation in
hermest's CLI that needed [Json.Error.to_string e] now that
[Json.of_string] yields a structured error.
Warning 69 (unused-field, mutable-never-assigned). Four independent
record fields were flagged as mutable but the code only mutates their
referents in place, never rebinds the record slot itself:
- ocaml-wal/lib/wal.ml: [t.file] (the Eio file resource; methods call
Eio.File.pwrite_all etc., the slot is set once at open time).
- ocaml-block/lib/block.ml: [Memory.state.data] (the backing bytes,
written via Bytes.blit_string; [Bytes.t] is already mutable).
- ocaml-sse/lib/sse.ml: [Parser.t.data_buf] (a Buffer.t, written via
Buffer.add_*; the slot never changes).
- ocaml-zephyr/lib/zephyr.ml: drop [mode : Read | Write] entirely —
set at open-time, read nowhere. The open_read / open_write
constructors already distinguish the two call shapes, so mode
tracking was redundant.
Generate .opam.template files with x-quality-* fields based on
detected package features:
- x-quality-build: has lib/ with .ml files
- x-quality-test: has test/ with .ml files
- x-quality-fuzz: has fuzz/ with .ml files
- x-quality-interop: has test/interop/ directory
- x-quality-cram: has test/*.t/ directories
These fields are picked up by dune's opam generation and will be
checked by merlint E910 for consistency.
Also: add fmt dep to ocaml-sse/lib/dune (Fmt.pf used without dep).
Standard vocabulary based on crates.io categories, erratique/opam
conventions, and monorepo domain coverage:
Org: org:blacksun
Domain: aerospace, codec, crypto, network, storage, git, merkle
Purpose: cli, test, bench, format, log, system
Protocol: ccsds, uslp, cop1, sdls, sle, atproto, tls, http, json, binary
Cross-cutting: eio, simulation, math, compression
Tags placed in dune-project (package ...) stanzas via (tags ...).
Propagated to .opam files by dune's opam generation.
- Remove vendored crowbar/ directory
- Replace all Crowbar references with Alcobar across 176 .ml files
- Update all fuzz dune files: crowbar → alcobar in libraries
- Remove 77 gen_corpus.ml files (alcobar handles corpus internally)
- Update dune-project files: crowbar → alcobar in dependencies
- Update merlint rules (e705, e726): Crowbar → Alcobar in checks,
docs, and examples
- Update merlint generated docs (index.html)
428 files changed, ~1200 lines removed net.
- Replace Printf.sprintf/printf with Fmt.str/pr in fuzz_squashfs, gen_corpus
- Replace failwith (Fmt.str ...) with Fmt.failwith in squashfs.ml (E215)
- Replace invalid_arg (Fmt.str ...) with Fmt.invalid_arg in squashfs_writer, tc (E216)
- Add fmt to gen_corpus dune deps for squashfs, srp, streaming-aead, tar, tc
- Change `run` signature to `string -> (string * test_case list) list -> unit`
matching Alcotest's grouping convention
- Fix `_name` bug: pass the name through to Alcotest.run_with_args
- Each fuzz module now exports `let suite = ("name", [test_case ...])`
- Entry points (fuzz.ml) collect suites: `Crowbar.run "pkg" [Fuzz_X.suite]`
- Remove stale `add_test`/`suite` API, keep only `test_case`/`run`
- Remove `let run () = ()` from fuzz_common.ml files
- Update merlint E725 rule to match new `let suite = ("name", ...)` pattern
- Update E725 test fixtures and expected output
- Restore cursor on exit via at_exit in Tty.Progress (fixes TTY corruption)
- Install SIGINT handler in monopam test for clean Ctrl-C
- Add 2s per-iteration timeout and 2s total budget to crowbar
- Group crowbar alcotest output by module prefix ("mdns: foo" → group "mdns")
- Skip fuzz runtest in afl context (enabled_if <> profile afl)
- Add merlint E725: enforce "module: description" fuzz test name convention
Comprehensive seed corpus for efficient AFL fuzzing:
Text/Protocol formats:
- cookeio: HTTP cookies (simple, full attributes, multi-value)
- jsonwt: JWT tokens (header, valid token)
- json-logs: JSON strings with escapes
- tomlt: TOML config files
- hostname: Domain names with ports
- xff: X-Forwarded-For headers, CIDR notation
- punycode: ASCII and Unicode domains
- mdns: DNS headers and queries
Binary formats:
- sdnv: RFC 6256 variable-length integers
- hap: HomeKit TLV encoding
- space-packet: CCSDS packet headers
- tc-1/tm-1: Telecommand/Telemetry frames
- sle: Space Link Extension TML headers
- tls: TLS records and handshake messages
- requests: HTTP/1.1 and HTTP/2 frames
Crypto:
- crypto: 32-byte keys
- csrf: CSRF tokens and secrets
- paseto: v3.local prefix and keys
- pbkdf2: passwords and salts
- spake2/srp: authentication parameters
- streaming-aead: keys, nonces, plaintext
Misc:
- sgp4: TLE satellite orbit data
- tty: ASCII, Unicode, ANSI escape sequences
- github-oauth: OAuth parameters
- rate-limit: IPv4/IPv6 addresses