commits
Sweep through 23 more packages flagged by [monopam lint] for
test-stanza references not declared in opam. Each verified by
[dune build] + [dune runtest] before moving on.
- irmin add (astring :with-test)
- ocaml-atproto-oauth add (eio_main :with-test) (nox-crypto-rng :with-test)
- ocaml-auth add (alcotest :with-test) (eio :with-test) (eio_main :with-test)
- ocaml-cam add (odm :with-test)
- ocaml-cbor add (alcotest :with-test) (ohex :with-test)
- ocaml-cfdp add (nox-csv :with-test)
- ocaml-claude add (vlog :with-test)
- ocaml-collision add (alcotest :with-test) (odm :with-test) (ptime :with-test)
- ocaml-cookie add (re :with-test)
- ocaml-cop1 add (nox-csv :with-test)
- ocaml-crc add (nox-csv :with-test) (nox-memtrace :with-test)
- ocaml-dns-eio add (mdx :with-test); also fix a misplaced
paren in the depends list.
- ocaml-gauth add (nox-crypto-rng :with-test)
- ocaml-http add (alcotest :with-test) (eio_main :with-test) (nox-csv :with-test)
- ocaml-ltp add (nox-csv :with-test)
- ocaml-matter add (ohex :with-test) (ptime :with-test)
- ocaml-oauth add (eio_main :with-test) (nox-crypto-ec :with-test)
- ocaml-ocm add (alcotest :with-test) (nox-csv :with-test)
- ocaml-oem add (alcotest :with-test) (nox-csv :with-test)
- ocaml-opm add (alcotest :with-test) (nox-csv :with-test)
- ocaml-pbkdf2 add (ohex :with-test)
- ocaml-requests add (astring :with-test) (nox-csv :with-test)
- ocaml-retry add (re :with-test)
Several packages had alcobar/alcotest/mdx/bytesrw/etc. used in
test/ or fuzz/ but undeclared in dune-project, leaving the opam
metadata silently incomplete. Sync the dune-project depends and
regenerate the opam files.
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.
Each README's 'opam install <pkg>' instructions now match the post-rename
opam package names. Auto-generated by 'monopam lint --fix' after the
nox-* prefix landed on the underlying packages.
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.
These libraries are all general-purpose (cyber-threat intel,
inter-partition messaging, Linux remoteproc, CRC-32C) but their
synopses/docstrings named SpaceOS as a specific consumer. Reword to
describe what each library does on its own terms.
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.
Previously the eight git-x subcommands sat flat at top level (split,
check, fix, verify, filter-paths, split-commit, drop-commit, reword),
with 'split' ambiguous between the subtree split and the per-directory
commit split.
Regrouped into two namespaces that mirror the object they act on:
git-x tree
split (was: git-x split)
add (new — inject a standalone history under a prefix)
drop (was: git-x filter-paths)
check (was: git-x check)
fix (was: git-x fix)
verify (was: git-x verify)
git-x commit
split (was: git-x split-commit)
drop (was: git-x drop-commit)
reword (was: git-x reword)
Each subcommand lives in cmd_<group>_<verb>.{ml,mli}; cmd_tree.ml and
cmd_commit.ml are the Cmd.group wrappers. git_x.ml registers just the
two groups.
'tree add' is a thin wrapper over Git.Subtree.add, which already
existed in the library but had no CLI exposure. It accepts a ref (e.g.
FETCH_HEAD after 'git fetch URL REF') and a --prefix, then builds a
subtree-merge commit with the current user's git config identity.
Log source names are updated to match (git-x.tree.split,
git-x.tree.fix). The cram test under test/cram/tree_split.t is
updated to use the new 'git-x tree split' invocation throughout.
Drops the redundant "t" suffix. Library name, opam package, module
(Csvt -> Csv), and directory all rename in lockstep. Every downstream
reference in interop tests, libraries, and docs updated.
Same refactor pattern as xmlt (d786b041, 067b745c):
- Dropped the custom error ADT (Missing_header, Missing_column,
Bad_value, Truncated_row, Encode_error, Invalid_utf8), error_to_string,
pp_error.
- module Error = Textloc.Error (re-exports shared infrastructure).
- module Sort = Row | Field | Header with to_string, pp, kinded,
or_kind.
- Internal helpers raise Textloc.Error.msgf/msg; try/with at boundaries.
- decode/decode_string/decode_channel/decode_file/fold_channel/fold_file
now return (_, string) result.
- Added primed variants returning (_, Error.t) result.
- Path threading: push_array for row index, push_object for column
name -- errors carry structural context.
- Added ?max_rows / ?max_cols limits on decode.
- Kept Invalid_utf8_encode of int exception.
Tests tightened to STRUCTURAL assertions (exact frames list, exact
message) instead of substring checks.
Same tightening retrofitted to xmlt's context tests -- 12 tests
now assert exact Textloc.Error.t shape (full frame list including
outer-first ordering, exact message) rather than 'contains'.
Downstream fixes: ocaml-cdm collapses its typed error ADT to
[Parse_error of string]; 38 interop test files updated from
[Alcotest.failf "%a" Csvt.pp_error e] to ["%s" e].
csvt: 60 tests pass. xmlt: 177 tests pass.
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.
ocaml-{erasure,viterbi,turbo,short-ldpc,rice,lfsr,ldpc,idc,hcomp}/lib/dune
and ocaml-crc/bench/dune, ocaml-xmlt/fuzz/dune all use Fmt.str without
depending on fmt.
ocaml-merkle-sync: reusable sync primitives for any content-addressed DAG.
- Layer 1: anti-entropy gossip (branch head exchange, O(log n))
- Layer 2: merkle descent (DAG diff by hash, dependency-order transfer)
- Bloom filter (FNV-1a, ~1% FP rate)
15 tests passing. Fuzz harness for bloom properties.
irmin/lib/sync.ml: Sync.S module type — discover/locate/fetch/push.
Each backend provides its own implementation.
Also: dune fmt across affected packages.
contact, coordinate, cop1, cose, cpio, crc, crypto, csts, csvt:
all now pass merlint with 0 issues.
Pass Eio switch from top-level Eio_main.run down to all
Git.Repository.open_repo calls instead of creating tiny
per-call Switch.run scopes that close prematurely.
- 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
- sexpt: use vcase_tag helper instead of c.tag on GADT value
- tcf: add type annotation to fix cuc_vector/cds_vector field
resolution ambiguity
- Add CRC-32C single byte "A" test (0xE16DCDEE, RevEng catalogue)
- Add CRC-32 and CRC-32C residue tests: verify that CRC(data || LE(CRC))
yields the expected constant (residue XOR xorout per RevEng)
- Add slicing-by-8 boundary tests at 1,7,8,9,15,16,17,31-65 bytes
to stress the 8-byte bulk loop and tail
- Add fuzz tests for hardware vs software agreement on CRC-32 and CRC-32C
Provide no-op JS implementations for crc_detect_cpu_features,
crc_has_hardware, and the hw_crc32* functions so the library
loads without errors in js_of_ocaml (falls back to software CRC).
Add bench/ with throughput comparison of the three implementation tiers:
- Byte-at-a-time (reference baseline): ~290 MB/s
- Slicing-by-8 (software fast path): ~730 MB/s
- Hardware ARM CRC intrinsics: ~12-16 GB/s
Expose crc32_software / crc32c_software for benchmarking and testing
the software path independently of hardware dispatch.
Update README to document performance tiers, hardware detection, and
portability story (jsoo/wasm).
Remove verbose MISSION-READY labels from test comments.
New packages:
- ocaml-tm-sync (131.0-B): TM randomizer (LFSR) with CCSDS PN
sequence test vector; RS/convolutional/LDPC/turbo stubs
- ocaml-proximity1 (211.0-B): Proximity-1 frame header Wire codec
with encode/decode and roundtrip tests
Tests with spec vectors (96 tests total):
- tm-sync: PN sequence from CCSDS 131.0-B-4 Annex B
- cltu: BCH(63,56) parity, CLTU/ASM sync parsers
- cop1: FOP-1/FARM-1 state machine transitions
- fsr: 32-bit FSR Wire codec with known bit patterns
- proximity1: frame header roundtrip for all frame types
- ccsds-time: CUC/CDS encode/decode with epoch constants
Tests that expose real gaps in our libraries when compared against GMAT:
ocaml-odm (2 FAIL):
- LEO interpolation midpoint: linear vs quadratic truth returns inf —
exposes precision bug in interpolate epoch conversion
- Molniya perigee interpolation: same issue at high-eccentricity perigee
ocaml-collision (1 FAIL):
- TCA precision: miss distance varies by 34 km in 10s at closest approach.
Step-based TCA finding is not mission-grade — need quadratic refinement.
ocaml-cam (new mission-ready tests, passing):
- Linear model (dv*dt) vs GMAT vis-viva SMA prediction (< 5% error)
- CAM evaluate internal consistency check
- Documents that linear along-track shift model is a first-order
approximation only — GMAT shows the real effect is an SMA change.
These failures are intentional — they document what needs to be fixed
before the libraries are mission-ready.
- ocaml-cltu: CLTU encoding/decoding (CCSDS 231.0-B) with BCH(63,56),
ASM sync markers (131.0-B), and stream sync parsers
- ocaml-cop1: COP-1 state machines (CCSDS 232.1-B) for FOP-1 (ground)
and FARM-1 (flight) with Eio service layer
- cltu-eio: CLTU/ASM send/recv over Eio flows
- cop1-eio: COP-1 service layer with Eio timer management
Application-layer chunking is custom, not CCSDS/RFC.
Remove assert (Sys.int_size > 32) that crashes on 32-bit targets.
CRC-32 and CRC-32C now use a C32 submodule with Int32 arithmetic,
correct on both 64-bit native and js_of_ocaml. CRC-16 unchanged.
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 doc comments to exported suite values in dupfind and ocaml-crc test .mli files.
Replace inline CRC-16/32 implementations in aos, bundle, cfdp, pid1, tc,
tm, uslp with shared ocaml-crc dependency. Fix ocaml-crc test formatting.
Pure OCaml table-based CRC checksums: CRC-16-CCITT (ITU-T V.41),
CRC-16-X.25, CRC-32 (ISO 3309), and CRC-32C (Castagnoli/RFC 3720).
All functions return native int (no Int32 boxing). Requires 64-bit OCaml.
Includes Alcotest vectors from ITU-T V.41, ISO 3309, RFC 3720 Section 12.1,
and Crowbar fuzz tests for string/bytes agreement, self-check residue,
range bounds, and determinism.
Sweep through 23 more packages flagged by [monopam lint] for
test-stanza references not declared in opam. Each verified by
[dune build] + [dune runtest] before moving on.
- irmin add (astring :with-test)
- ocaml-atproto-oauth add (eio_main :with-test) (nox-crypto-rng :with-test)
- ocaml-auth add (alcotest :with-test) (eio :with-test) (eio_main :with-test)
- ocaml-cam add (odm :with-test)
- ocaml-cbor add (alcotest :with-test) (ohex :with-test)
- ocaml-cfdp add (nox-csv :with-test)
- ocaml-claude add (vlog :with-test)
- ocaml-collision add (alcotest :with-test) (odm :with-test) (ptime :with-test)
- ocaml-cookie add (re :with-test)
- ocaml-cop1 add (nox-csv :with-test)
- ocaml-crc add (nox-csv :with-test) (nox-memtrace :with-test)
- ocaml-dns-eio add (mdx :with-test); also fix a misplaced
paren in the depends list.
- ocaml-gauth add (nox-crypto-rng :with-test)
- ocaml-http add (alcotest :with-test) (eio_main :with-test) (nox-csv :with-test)
- ocaml-ltp add (nox-csv :with-test)
- ocaml-matter add (ohex :with-test) (ptime :with-test)
- ocaml-oauth add (eio_main :with-test) (nox-crypto-ec :with-test)
- ocaml-ocm add (alcotest :with-test) (nox-csv :with-test)
- ocaml-oem add (alcotest :with-test) (nox-csv :with-test)
- ocaml-opm add (alcotest :with-test) (nox-csv :with-test)
- ocaml-pbkdf2 add (ohex :with-test)
- ocaml-requests add (astring :with-test) (nox-csv :with-test)
- ocaml-retry add (re :with-test)
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.
Previously the eight git-x subcommands sat flat at top level (split,
check, fix, verify, filter-paths, split-commit, drop-commit, reword),
with 'split' ambiguous between the subtree split and the per-directory
commit split.
Regrouped into two namespaces that mirror the object they act on:
git-x tree
split (was: git-x split)
add (new — inject a standalone history under a prefix)
drop (was: git-x filter-paths)
check (was: git-x check)
fix (was: git-x fix)
verify (was: git-x verify)
git-x commit
split (was: git-x split-commit)
drop (was: git-x drop-commit)
reword (was: git-x reword)
Each subcommand lives in cmd_<group>_<verb>.{ml,mli}; cmd_tree.ml and
cmd_commit.ml are the Cmd.group wrappers. git_x.ml registers just the
two groups.
'tree add' is a thin wrapper over Git.Subtree.add, which already
existed in the library but had no CLI exposure. It accepts a ref (e.g.
FETCH_HEAD after 'git fetch URL REF') and a --prefix, then builds a
subtree-merge commit with the current user's git config identity.
Log source names are updated to match (git-x.tree.split,
git-x.tree.fix). The cram test under test/cram/tree_split.t is
updated to use the new 'git-x tree split' invocation throughout.
Same refactor pattern as xmlt (d786b041, 067b745c):
- Dropped the custom error ADT (Missing_header, Missing_column,
Bad_value, Truncated_row, Encode_error, Invalid_utf8), error_to_string,
pp_error.
- module Error = Textloc.Error (re-exports shared infrastructure).
- module Sort = Row | Field | Header with to_string, pp, kinded,
or_kind.
- Internal helpers raise Textloc.Error.msgf/msg; try/with at boundaries.
- decode/decode_string/decode_channel/decode_file/fold_channel/fold_file
now return (_, string) result.
- Added primed variants returning (_, Error.t) result.
- Path threading: push_array for row index, push_object for column
name -- errors carry structural context.
- Added ?max_rows / ?max_cols limits on decode.
- Kept Invalid_utf8_encode of int exception.
Tests tightened to STRUCTURAL assertions (exact frames list, exact
message) instead of substring checks.
Same tightening retrofitted to xmlt's context tests -- 12 tests
now assert exact Textloc.Error.t shape (full frame list including
outer-first ordering, exact message) rather than 'contains'.
Downstream fixes: ocaml-cdm collapses its typed error ADT to
[Parse_error of string]; 38 interop test files updated from
[Alcotest.failf "%a" Csvt.pp_error e] to ["%s" e].
csvt: 60 tests pass. xmlt: 177 tests pass.
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.
ocaml-merkle-sync: reusable sync primitives for any content-addressed DAG.
- Layer 1: anti-entropy gossip (branch head exchange, O(log n))
- Layer 2: merkle descent (DAG diff by hash, dependency-order transfer)
- Bloom filter (FNV-1a, ~1% FP rate)
15 tests passing. Fuzz harness for bloom properties.
irmin/lib/sync.ml: Sync.S module type — discover/locate/fetch/push.
Each backend provides its own implementation.
Also: dune fmt across affected packages.
- Add CRC-32C single byte "A" test (0xE16DCDEE, RevEng catalogue)
- Add CRC-32 and CRC-32C residue tests: verify that CRC(data || LE(CRC))
yields the expected constant (residue XOR xorout per RevEng)
- Add slicing-by-8 boundary tests at 1,7,8,9,15,16,17,31-65 bytes
to stress the 8-byte bulk loop and tail
- Add fuzz tests for hardware vs software agreement on CRC-32 and CRC-32C
Add bench/ with throughput comparison of the three implementation tiers:
- Byte-at-a-time (reference baseline): ~290 MB/s
- Slicing-by-8 (software fast path): ~730 MB/s
- Hardware ARM CRC intrinsics: ~12-16 GB/s
Expose crc32_software / crc32c_software for benchmarking and testing
the software path independently of hardware dispatch.
Update README to document performance tiers, hardware detection, and
portability story (jsoo/wasm).
New packages:
- ocaml-tm-sync (131.0-B): TM randomizer (LFSR) with CCSDS PN
sequence test vector; RS/convolutional/LDPC/turbo stubs
- ocaml-proximity1 (211.0-B): Proximity-1 frame header Wire codec
with encode/decode and roundtrip tests
Tests with spec vectors (96 tests total):
- tm-sync: PN sequence from CCSDS 131.0-B-4 Annex B
- cltu: BCH(63,56) parity, CLTU/ASM sync parsers
- cop1: FOP-1/FARM-1 state machine transitions
- fsr: 32-bit FSR Wire codec with known bit patterns
- proximity1: frame header roundtrip for all frame types
- ccsds-time: CUC/CDS encode/decode with epoch constants
Tests that expose real gaps in our libraries when compared against GMAT:
ocaml-odm (2 FAIL):
- LEO interpolation midpoint: linear vs quadratic truth returns inf —
exposes precision bug in interpolate epoch conversion
- Molniya perigee interpolation: same issue at high-eccentricity perigee
ocaml-collision (1 FAIL):
- TCA precision: miss distance varies by 34 km in 10s at closest approach.
Step-based TCA finding is not mission-grade — need quadratic refinement.
ocaml-cam (new mission-ready tests, passing):
- Linear model (dv*dt) vs GMAT vis-viva SMA prediction (< 5% error)
- CAM evaluate internal consistency check
- Documents that linear along-track shift model is a first-order
approximation only — GMAT shows the real effect is an SMA change.
These failures are intentional — they document what needs to be fixed
before the libraries are mission-ready.
- ocaml-cltu: CLTU encoding/decoding (CCSDS 231.0-B) with BCH(63,56),
ASM sync markers (131.0-B), and stream sync parsers
- ocaml-cop1: COP-1 state machines (CCSDS 232.1-B) for FOP-1 (ground)
and FARM-1 (flight) with Eio service layer
- cltu-eio: CLTU/ASM send/recv over Eio flows
- cop1-eio: COP-1 service layer with Eio timer management
- 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
Pure OCaml table-based CRC checksums: CRC-16-CCITT (ITU-T V.41),
CRC-16-X.25, CRC-32 (ISO 3309), and CRC-32C (Castagnoli/RFC 3720).
All functions return native int (no Int32 boxing). Requires 64-bit OCaml.
Includes Alcotest vectors from ITU-T V.41, ISO 3309, RFC 3720 Section 12.1,
and Crowbar fuzz tests for string/bytes agreement, self-check residue,
range bounds, and determinism.