commits
Pure formatting: dune fmt fits the Ok branch on one line.
Run mdx on lib/block.mli so the {[ ... ]} odoc block now type-checks.
The example called `Block.of_file ~sw env#fs "disk.img" ~sector_size:512`,
but the real signature takes a single `_ Eio.Path.t` (not separate fs +
filename) and ends with `unit -> t` (the example was missing the
trailing `()`). Also dropped the trailing `(* ... *)` placeholder by
matching on `Block.read`'s `result` and printing the sector length on
success / a stderr error on failure.
Wrapped the whole thing in `let run () =` so the file open does not
materialise on disk at mdx test time.
The README example uses Eio_main.run, which yields Eio_unix.Stdenv.base
— that needs eio.unix to be in scope so the cmi resolves. Without it
MDX errors with 'Eio_unix.Stdenv.base is abstract because no
corresponding cmi file was found in path.'
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.
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.
The Usage example had tokens glued together (`blk Printf.printf`,
`data Block.write`, `Result.get_ok assert`). Rewrite as one clean
file-backed read/write flow.
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.
Rename make_superblock → superblock, make_inode_buf → inode_buf,
make_image → image, make_key → key in squashfs and streaming-aead.
Standardize fuzz and test conventions across 30+ packages:
- E715/E718: Add fuzz.ml runners referencing Fuzz_*.suite instead of
calling Fuzz_*.run() directly; update dune files accordingly
- E725: Fix fuzz_paseto suite name from "crowbar" to "paseto"
- E600: Create .mli interfaces for test modules (test_firmware,
test_remoteproc, test_pbkdf2, test_paseto) with single-group suites
- E605: Add missing test files (test_skills, test_monitor, test_openamp,
test_xrpc_server) with proper module extraction from inline test.ml
- E415: Add pp pretty-printer to xrpc_server type t
- E405: Add doc comment for pp_sync_action in skills.mli
- E205: Replace Printf with Fmt in fuzz_paseto and gen_corpus
- E331: Rename make_key to key in fuzz_paseto
- 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
Add (enabled_if (= %{profile} afl)), (source_tree corpus), and
gen_corpus.exe deps to all 25 fuzz directories
E722: Convert ocaml-crc (test ...) to (executable ...) with rules
E718: Add gen_corpus.ml to ocaml-crc/fuzz
E724: Rename (alias fuzz-afl) to (alias fuzz) in 12 fuzz directories
Add seed corpus generators with representative test data for:
ocaml-aos, ocaml-block, ocaml-bloom, ocaml-bpsec, ocaml-bundle,
ocaml-cfdp, ocaml-cgr, ocaml-clcw, ocaml-cookeio, ocaml-cpio
E722: Convert (test ...) to (executable ...) in ocaml-aos, ocaml-clcw
E724: Add (rule (alias runtest) ...) and (rule (alias fuzz-afl) ...)
to all fuzz directories: ocaml-ax25, ocaml-block, ocaml-bloom,
ocaml-bpsec, ocaml-bundle, ocaml-cbort, ocaml-cfdp, ocaml-cgr,
ocaml-cookeio, ocaml-cpio
Rename CamelCase internal modules to Snake_case per OCaml convention:
- ocaml-hap: TlvType→Tlv_type, HapError→Hap_error, CharType→Char_type
- ocaml-cookeio: SameSite→Same_site, DateParser→Date_parser
- ocaml-claudeio: PreToolUse→Pre_tool_use, PostToolUse→Post_tool_use,
UserPromptSubmit→User_prompt_submit, SubagentStop→Subagent_stop,
PreCompact→Pre_compact (wire format strings preserved)
- irmin: StringMap→String_map, PathSet→Path_set
- ocaml-block: ReadOnly→Read_only, WithCrc→With_crc
Change all test_*.mli to export val suite : string * unit Alcotest.test_case
list (singular tuple). Flatten multi-group test suites into single groups.
Fix incorrect v_* function renames in CLI call sites.
Refactor all test directories to follow the convention: test_*.ml exports
suite/suites values, test_*.mli exposes only the suite type, and a single
test.ml runner aggregates and calls Alcotest.run. Consolidate dune files
to single test stanzas per directory.
Fix 64 documentation style issues: add trailing periods, fix [name] format
mismatches, and correct arg count mismatches in doc comments. Add pp
pretty-printers to 7 modules (block_map, standard_site_api, tangled_api,
xrpc_auth_client, xrpc_client, xrpc_cred, block).
Replace Alcotest.fail (Fmt.str ...) with Alcotest.failf (E616) in
ocaml-block tests, hoist nested functions (E320), reduce nesting depth
(E010), and accept spaces in cookie values to match browser behavior.
Add chardev/channel/socket-serial support to ocaml-qemu so QEMU VMs
can expose virtio-serial IPC ports and redirect consoles to Unix
sockets. Update pid1 init to read IPC frames from P0 and store them
as events in the block device. Add Block.of_file ?sectors override
for Linux block devices that report st_size=0. Wire up space build
and run commands for the two-partition (P0 flight + P1 SpaceOS) demo
with Docker cross-compilation of both binaries.
Rename the d3t library to wire for clarity. Update all references
in bench, test, and library code across affected packages.
- License -> Licence
- color -> colour (in prose, not API/code)
- behavior -> behaviour
- analyze -> analyse
- organized -> organised
- Remove marketing buzzwords (leveraging)
- Remove emojis from prose
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.
- prune: Replace ppxlib with compiler-libs.common, converting
Ast_traverse.iter visitors to Ast_iterator.default_iterator
- prune: Adapt to OCaml 5.3 Longident changes (located strings)
- Remove ppxlib from root dune-project, prune dune-project and opam
- Clean up stale ppxlib references in merlint comments and docs
- Remove ppxlib dependency from merlint, use merlin-lib's AST analysis
via ocaml-merlin's Dump module instead
- Move dump.ml parser from merlint to ocaml-merlin library, adding
dump_ast with typedtree/parsetree fallback
- Add Location, Dump, Outline, Occurrence modules to ocaml-merlin with
proper re-exports from the main Merlin module
- Delete merlin_dump.ml thin wrapper; merlint rules use Merlin.Dump
directly throughout
- Unify Location types between merlint and ocaml-merlin (merlint
re-exports Merlin.Location with custom pp)
- Fix ocaml-block build (Eio/bytesrw API updates)
- Add ocaml-merlin cram tests for outline, occurrences, enclosing
Run mdx on lib/block.mli so the {[ ... ]} odoc block now type-checks.
The example called `Block.of_file ~sw env#fs "disk.img" ~sector_size:512`,
but the real signature takes a single `_ Eio.Path.t` (not separate fs +
filename) and ends with `unit -> t` (the example was missing the
trailing `()`). Also dropped the trailing `(* ... *)` placeholder by
matching on `Block.read`'s `result` and printing the sector length on
success / a stderr error on failure.
Wrapped the whole thing in `let run () =` so the file open does not
materialise on disk at mdx test time.
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.
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.
Standardize fuzz and test conventions across 30+ packages:
- E715/E718: Add fuzz.ml runners referencing Fuzz_*.suite instead of
calling Fuzz_*.run() directly; update dune files accordingly
- E725: Fix fuzz_paseto suite name from "crowbar" to "paseto"
- E600: Create .mli interfaces for test modules (test_firmware,
test_remoteproc, test_pbkdf2, test_paseto) with single-group suites
- E605: Add missing test files (test_skills, test_monitor, test_openamp,
test_xrpc_server) with proper module extraction from inline test.ml
- E415: Add pp pretty-printer to xrpc_server type t
- E405: Add doc comment for pp_sync_action in skills.mli
- E205: Replace Printf with Fmt in fuzz_paseto and gen_corpus
- E331: Rename make_key to key in fuzz_paseto
- 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
Rename CamelCase internal modules to Snake_case per OCaml convention:
- ocaml-hap: TlvType→Tlv_type, HapError→Hap_error, CharType→Char_type
- ocaml-cookeio: SameSite→Same_site, DateParser→Date_parser
- ocaml-claudeio: PreToolUse→Pre_tool_use, PostToolUse→Post_tool_use,
UserPromptSubmit→User_prompt_submit, SubagentStop→Subagent_stop,
PreCompact→Pre_compact (wire format strings preserved)
- irmin: StringMap→String_map, PathSet→Path_set
- ocaml-block: ReadOnly→Read_only, WithCrc→With_crc
Add chardev/channel/socket-serial support to ocaml-qemu so QEMU VMs
can expose virtio-serial IPC ports and redirect consoles to Unix
sockets. Update pid1 init to read IPC frames from P0 and store them
as events in the block device. Add Block.of_file ?sectors override
for Linux block devices that report st_size=0. Wire up space build
and run commands for the two-partition (P0 flight + P1 SpaceOS) demo
with Docker cross-compilation of both binaries.
- prune: Replace ppxlib with compiler-libs.common, converting
Ast_traverse.iter visitors to Ast_iterator.default_iterator
- prune: Adapt to OCaml 5.3 Longident changes (located strings)
- Remove ppxlib from root dune-project, prune dune-project and opam
- Clean up stale ppxlib references in merlint comments and docs
- Remove ppxlib dependency from merlint, use merlin-lib's AST analysis
via ocaml-merlin's Dump module instead
- Move dump.ml parser from merlint to ocaml-merlin library, adding
dump_ast with typedtree/parsetree fallback
- Add Location, Dump, Outline, Occurrence modules to ocaml-merlin with
proper re-exports from the main Merlin module
- Delete merlin_dump.ml thin wrapper; merlint rules use Merlin.Dump
directly throughout
- Unify Location types between merlint and ocaml-merlin (merlint
re-exports Merlin.Location with custom pp)
- Fix ocaml-block build (Eio/bytesrw API updates)
- Add ocaml-merlin cram tests for outline, occurrences, enclosing