commits
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.
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.
Cosmetic-only changes from a workspace-wide $(dune fmt) run that
were pending in the working tree across packages: docstring re-wraps
in several .mli files (rego, space-packet, spacewire, tcpcl), and
single-line collapses of trivial match arms in test files (atp,
ldpc, mst, pus, sse) and one xtce.ml site.
No behavioural changes.
The Python generator built the AR4JA H matrix from CCSDS 131.0-B-4 and
performed GF(2) Gaussian elimination in numpy to produce reference
codewords. Per the interop-testing skill, that's an internal verification
of the OCaml encoder against another implementation of the same spec, not
an interop oracle. Library roundtrip + decoder coverage stays in
test_ldpc.ml.
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.
Removes redundant test_ prefix from functions in interop test.ml files
across the monorepo: test_decode → decode, test_encode → encode, etc.
112 files across the monorepo. Printf.sprintf → Fmt.str,
Printf.printf → Fmt.pr for consistent formatting library usage.
Adds traces/codewords.csv generated from the CCSDS AR4JA rate 1/2 H
matrix using GF(2) Gaussian elimination. The oracle is the syndrome
check (H·c mod 2 = 0), which is the spec itself — not a reimplementation
of any specific encoding algorithm.
15 test vectors covering all-zeros, all-ones, alternating patterns,
single-bit information words, deterministic PRNG sequences. Tests
verify encode (byte-exact match), decode (BP recovers original), and
roundtrip.
Also fixes generate.sh permissions and dune rule path.
LDPC and Turbo interop tests reimplemented the CCSDS encoder in
Python ("we implement the full CCSDS H-matrix construction",
"we implement the full CCSDS turbo encoder here"). Not interop.
SCC dariol83 interop extended with Reed-Solomon traces using
dariol83's RS codec.
- 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
Location can be specified three ways:
--lat 34.05 --lon=-118.25 (coordinates)
--location la (city preset via Arg.enum)
--here (auto-detect via IP geolocation)
Known cities: la, sf, nyc, london, paris, tokyo, ksc, kourou,
baikonur, bangalore, sydney. Cmdliner provides tab completion
and error messages for invalid city names.
- ocaml-rice: CCSDS 121.0-B lossless compression (Rice/Golomb)
- ocaml-udpcl: RFC 7122 UDP convergence layer for Bundle Protocol
- ocaml-erasure: CCSDS 131.5-B erasure correcting codes (GF(2^8))
- ocaml-short-ldpc: CCSDS 131.4-B short block-length LDPC
- ocaml-opm: CCSDS 502.0-B Orbit Parameter Message (KVN)
- ocaml-aem: CCSDS 504.0-B Attitude Ephemeris Message (KVN)
- ocaml-tdm: CCSDS 503.0-B Tracking Data Message (KVN)
- ocaml-rdm: CCSDS 508.1-B Re-entry Data Message (KVN)
The package provides CCSDS-specific channel coding glue
(randomizer, RS interleaving, coding presets) on top of the
generic ocaml-viterbi, ocaml-turbo, ocaml-ldpc, ocaml-reed-solomon
packages. "tm-sync" was too narrow — the same coding applies to
TC, AOS, and USLP as well.
Extract from ocaml-tm-sync into standalone packages:
- ocaml-viterbi: convolutional codes + Viterbi decoder (6 tests)
- ocaml-turbo: parallel concatenated codes + BCJR/MAP decoder (10 tests)
- ocaml-ldpc: belief propagation decoder (7 tests)
These implement standard algorithms reusable beyond CCSDS:
Viterbi (DVB-T, DAB, 802.11a/g), turbo (3G, LTE),
LDPC (DVB-S2, 5G NR, WiFi 6).
tm-sync keeps CCSDS-specific code (randomizer, RS interleaving)
and re-exports the generic packages for backward compat.
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.
Cosmetic-only changes from a workspace-wide $(dune fmt) run that
were pending in the working tree across packages: docstring re-wraps
in several .mli files (rego, space-packet, spacewire, tcpcl), and
single-line collapses of trivial match arms in test files (atp,
ldpc, mst, pus, sse) and one xtce.ml site.
No behavioural changes.
The Python generator built the AR4JA H matrix from CCSDS 131.0-B-4 and
performed GF(2) Gaussian elimination in numpy to produce reference
codewords. Per the interop-testing skill, that's an internal verification
of the OCaml encoder against another implementation of the same spec, not
an interop oracle. Library roundtrip + decoder coverage stays in
test_ldpc.ml.
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.
Adds traces/codewords.csv generated from the CCSDS AR4JA rate 1/2 H
matrix using GF(2) Gaussian elimination. The oracle is the syndrome
check (H·c mod 2 = 0), which is the spec itself — not a reimplementation
of any specific encoding algorithm.
15 test vectors covering all-zeros, all-ones, alternating patterns,
single-bit information words, deterministic PRNG sequences. Tests
verify encode (byte-exact match), decode (BP recovers original), and
roundtrip.
Also fixes generate.sh permissions and dune rule path.
Location can be specified three ways:
--lat 34.05 --lon=-118.25 (coordinates)
--location la (city preset via Arg.enum)
--here (auto-detect via IP geolocation)
Known cities: la, sf, nyc, london, paris, tokyo, ksc, kourou,
baikonur, bangalore, sydney. Cmdliner provides tab completion
and error messages for invalid city names.
- ocaml-rice: CCSDS 121.0-B lossless compression (Rice/Golomb)
- ocaml-udpcl: RFC 7122 UDP convergence layer for Bundle Protocol
- ocaml-erasure: CCSDS 131.5-B erasure correcting codes (GF(2^8))
- ocaml-short-ldpc: CCSDS 131.4-B short block-length LDPC
- ocaml-opm: CCSDS 502.0-B Orbit Parameter Message (KVN)
- ocaml-aem: CCSDS 504.0-B Attitude Ephemeris Message (KVN)
- ocaml-tdm: CCSDS 503.0-B Tracking Data Message (KVN)
- ocaml-rdm: CCSDS 508.1-B Re-entry Data Message (KVN)
Extract from ocaml-tm-sync into standalone packages:
- ocaml-viterbi: convolutional codes + Viterbi decoder (6 tests)
- ocaml-turbo: parallel concatenated codes + BCJR/MAP decoder (10 tests)
- ocaml-ldpc: belief propagation decoder (7 tests)
These implement standard algorithms reusable beyond CCSDS:
Viterbi (DVB-T, DAB, 802.11a/g), turbo (3G, LTE),
LDPC (DVB-S2, 5G NR, WiFi 6).
tm-sync keeps CCSDS-specific code (randomizer, RS interleaving)
and re-exports the generic packages for backward compat.