commits
The block called [Eio_main.run] at top level (mdx executes it) and
referenced a non-existent [Respond.post_request_body]; the body is
just [req.body] on the [post_request] record. Wrap as [run () = ...]
and use the right field. Add [eio] / [eio.unix] to the mdx libs.
The Quick Start example was a sketch that called [run] with free
[net]/[root] and used [...] ellipses inside the route handlers.
Replaced with a pure-helpers spec that exercises the parts of the
API a unit test would: parse_url splits path + params,
status_line/reason_phrase produce the documented strings, and
Response.json wires content-type correctly. The actual server
loop ([run]) requires Eio main, so it's documented in the prose
and not executed in the doc example.
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.
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.
Moves package metadata into dune-project for kdf, monopam-info,
ocaml-ax25, ocaml-collision, ocaml-crypto (4 subpackages), ocaml-csv,
ocaml-respond, ocaml-sdnv, ocaml-tls (2 subpackages), ocaml-vec3, and
ocaml-x509, and flags each .opam with the generated-by-dune header.
Running dune build after the ocaml-toml build break is resolved will
regenerate the .opam files from dune-project and reveal any
canonical-form drift in a separate commit.
Drops the "t" suffix and follows the value/codec/toml/core pattern
(jsont.json_base style). The internal raw TOML module moves from
[Toml] to [Value] (file: lib/value.ml, was lib/toml.ml) to make room
for the top-level Toml facade (file: lib/toml.ml, was lib/tomlt.ml).
External callers now reach the raw AST through [Toml.Value.X] instead
of [Tomlt.Toml.X]. Every downstream reference updated in lockstep.
- Inline Alcotest.(check bool) at the 31 call sites and drop the
check_bool alias whose signature (string -> bool -> bool -> unit)
tripped E350.
- Shorten three 5-underscore test identifiers
(test_catchall_not_greedy_past_pattern -> test_catchall_stops_at_pattern,
test_bindings_order_is_pattern_order -> test_bindings_pattern_order,
test_query_does_not_affect_match -> test_query_doesnt_affect_match).
- Move Alcotest.run from test_respond.ml into a new test.ml runner;
expose a flat [Test_respond.suite] (E600). Sub-suite names get
prefixed onto the case names so the alcotest output keeps the
RFC-section grouping.
The body limit was hard-coded at 1 MiB in two places (the read buffer
and the Content-Length gate), which prevents file uploads of any real
size. Expose it as a single parameter on Respond.run; bump the default
to 16 MiB so multipart/form-data uploads work out of the box without
every caller threading a custom value.
Commit 5fbed21c switched every cram test fixture from Printf to Fmt
without updating the dune stanzas to depend on fmt, so `dune build`
inside the fixtures fails and the cram expected output stopped
matching reality. Add fmt to each executable/library and refresh the
one stale expected block (cascade_cleanup) still showing Printf.
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).
- Add missing .ocamlformat to 4 packages (E500)
- stix: use Fmt.failwith instead of failwith (Fmt.str ...) (E700)
- mbr: rename _unused1/_unused2 fields — underscore prefix implies
unused but they're stored in the record (E726)
Add missing opam dependencies across 17 packages (vec3, bytesrw, http,
cbort, fmt, etc.) and remove unused deps (requests from respond, menhir
from sqlite). Teach monopam lint to recognize (menhir ...) dune stanzas
as requiring the menhir package. Move bytesrw dep from scitt to
atp-lexicon-scitt where it actually belongs.
Resolve E400 (missing documentation), E410 (bad doc style), E615
(missing test suite), and E616 (use failf) across the monorepo.
Also fix test_timing to reference Requests.Timing instead of
non-existent Http.Timing.
Irmin:
- MST codec keyed by Atp.Cid.t (removed Hash↔CID conversion layer)
- Backend.{Memory,Disk}.create_cid — CID-native backends
- Proof.encode_cbor / decode_cbor — CBOR serialization for COSE receipts
- pds_interop: trivial passthrough (no conversion needed)
- 72 tests pass
SCITT:
- Receipt vds (395) in protected header per COSE Receipts spec
- Receipt vdp (396) in unprotected header for proof data
- RFC 9162 VDS: O(1) amortized append, RFC-compliant verify_inclusion
with test vectors from the spec
- MST VDS: Irmin.Proof.Mst.produce at registration, encode_cbor into
receipt, decode + Irmin.Proof.Mst.verify for fully offline verification
- Leaf hash authentication binds proof to specific statement
- 34 main + 17 ATP = 51 tests, all pass
Sigstore:
- Certificate chain validation against Fulcio root CA
- Rekor entry binding (body/log_index/integrated_time comparison)
- Hash algorithm from bundle (not hardcoded SHA256)
- 58 tests pass
Auth:
- Per-provider callback URLs (/auth/<slug>/callback)
- provider_name (raw, for DB) vs provider_slug (URL-safe, for routes)
- Token exchange includes grant_type=authorization_code
- No credential leakage in logs or error responses
Respond:
- HEAD responses suppress body per RFC 9110 §9.3.2
OAuth:
- Provider variant type (Github | Google | Gitlab | Custom)
- Per-provider userinfo JSON schemas (no field guessing)
parse_url now decodes %XX sequences and '+' (as space) in query
parameter names and values. Fixes double-encoding when OAuth callback
parameters like code=abc%2Fdef were re-encoded by the token exchange.
READMEs for all new packages. Fix missing docs (ocm, stix, globe),
naming (project_visible→visible, label_info→info, shader_kind→kind),
add .ocamlformat to csvt, add 11 KVN tests.
Rewrite SGP4 propagator ported from python-sgp4 with deep-space (SDP4)
satellite support including lunar/solar perturbations and resonance
handling. Add canonical Vallado verification vectors (33 satellites,
~700 test points from SGP4-VER.TLE + tcppver.out).
Also: ocamlformat reformatting across ocaml-respond, ocaml-odm,
ocaml-cdm, ocaml-requests, ocaml-spacedata; update root.opam deps.
Removes the transitive dependency on ocaml-crypto (C stubs fail
with -fPIC in Docker amd64 builds). Status is now plain int with
reason_phrase lookup. 78 tests still pass.
Will re-add typed Status.t/Method.t when either:
- ocaml-crypto C stubs are fixed for Docker builds, or
- http-types is extracted as a lightweight package
Minimal HTTP/1.1 server reusing requests.core types (Status.t, Method.t,
Headers.t). Features: static file serving with MIME detection and ETag,
custom route handlers, structured logging via Logs, path traversal
prevention, CORS support.
89 tests covering RFC 7230-7235 compliance: URL parsing, path
normalization, status codes, HTTP methods, ETag generation, MIME
detection, header injection prevention, routing.
The Quick Start example was a sketch that called [run] with free
[net]/[root] and used [...] ellipses inside the route handlers.
Replaced with a pure-helpers spec that exercises the parts of the
API a unit test would: parse_url splits path + params,
status_line/reason_phrase produce the documented strings, and
Response.json wires content-type correctly. The actual server
loop ([run]) requires Eio main, so it's documented in the prose
and not executed in the doc example.
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.
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.
Moves package metadata into dune-project for kdf, monopam-info,
ocaml-ax25, ocaml-collision, ocaml-crypto (4 subpackages), ocaml-csv,
ocaml-respond, ocaml-sdnv, ocaml-tls (2 subpackages), ocaml-vec3, and
ocaml-x509, and flags each .opam with the generated-by-dune header.
Running dune build after the ocaml-toml build break is resolved will
regenerate the .opam files from dune-project and reveal any
canonical-form drift in a separate commit.
Drops the "t" suffix and follows the value/codec/toml/core pattern
(jsont.json_base style). The internal raw TOML module moves from
[Toml] to [Value] (file: lib/value.ml, was lib/toml.ml) to make room
for the top-level Toml facade (file: lib/toml.ml, was lib/tomlt.ml).
External callers now reach the raw AST through [Toml.Value.X] instead
of [Tomlt.Toml.X]. Every downstream reference updated in lockstep.
- Inline Alcotest.(check bool) at the 31 call sites and drop the
check_bool alias whose signature (string -> bool -> bool -> unit)
tripped E350.
- Shorten three 5-underscore test identifiers
(test_catchall_not_greedy_past_pattern -> test_catchall_stops_at_pattern,
test_bindings_order_is_pattern_order -> test_bindings_pattern_order,
test_query_does_not_affect_match -> test_query_doesnt_affect_match).
- Move Alcotest.run from test_respond.ml into a new test.ml runner;
expose a flat [Test_respond.suite] (E600). Sub-suite names get
prefixed onto the case names so the alcotest output keeps the
RFC-section grouping.
The body limit was hard-coded at 1 MiB in two places (the read buffer
and the Content-Length gate), which prevents file uploads of any real
size. Expose it as a single parameter on Respond.run; bump the default
to 16 MiB so multipart/form-data uploads work out of the box without
every caller threading a custom value.
Commit 5fbed21c switched every cram test fixture from Printf to Fmt
without updating the dune stanzas to depend on fmt, so `dune build`
inside the fixtures fails and the cram expected output stopped
matching reality. Add fmt to each executable/library and refresh the
one stale expected block (cascade_cleanup) still showing Printf.
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).
Add missing opam dependencies across 17 packages (vec3, bytesrw, http,
cbort, fmt, etc.) and remove unused deps (requests from respond, menhir
from sqlite). Teach monopam lint to recognize (menhir ...) dune stanzas
as requiring the menhir package. Move bytesrw dep from scitt to
atp-lexicon-scitt where it actually belongs.
Irmin:
- MST codec keyed by Atp.Cid.t (removed Hash↔CID conversion layer)
- Backend.{Memory,Disk}.create_cid — CID-native backends
- Proof.encode_cbor / decode_cbor — CBOR serialization for COSE receipts
- pds_interop: trivial passthrough (no conversion needed)
- 72 tests pass
SCITT:
- Receipt vds (395) in protected header per COSE Receipts spec
- Receipt vdp (396) in unprotected header for proof data
- RFC 9162 VDS: O(1) amortized append, RFC-compliant verify_inclusion
with test vectors from the spec
- MST VDS: Irmin.Proof.Mst.produce at registration, encode_cbor into
receipt, decode + Irmin.Proof.Mst.verify for fully offline verification
- Leaf hash authentication binds proof to specific statement
- 34 main + 17 ATP = 51 tests, all pass
Sigstore:
- Certificate chain validation against Fulcio root CA
- Rekor entry binding (body/log_index/integrated_time comparison)
- Hash algorithm from bundle (not hardcoded SHA256)
- 58 tests pass
Auth:
- Per-provider callback URLs (/auth/<slug>/callback)
- provider_name (raw, for DB) vs provider_slug (URL-safe, for routes)
- Token exchange includes grant_type=authorization_code
- No credential leakage in logs or error responses
Respond:
- HEAD responses suppress body per RFC 9110 §9.3.2
OAuth:
- Provider variant type (Github | Google | Gitlab | Custom)
- Per-provider userinfo JSON schemas (no field guessing)
Rewrite SGP4 propagator ported from python-sgp4 with deep-space (SDP4)
satellite support including lunar/solar perturbations and resonance
handling. Add canonical Vallado verification vectors (33 satellites,
~700 test points from SGP4-VER.TLE + tcppver.out).
Also: ocamlformat reformatting across ocaml-respond, ocaml-odm,
ocaml-cdm, ocaml-requests, ocaml-spacedata; update root.opam deps.
Removes the transitive dependency on ocaml-crypto (C stubs fail
with -fPIC in Docker amd64 builds). Status is now plain int with
reason_phrase lookup. 78 tests still pass.
Will re-add typed Status.t/Method.t when either:
- ocaml-crypto C stubs are fixed for Docker builds, or
- http-types is extracted as a lightweight package
Minimal HTTP/1.1 server reusing requests.core types (Status.t, Method.t,
Headers.t). Features: static file serving with MIME detection and ETag,
custom route handlers, structured logging via Logs, path traversal
prevention, CORS support.
89 tests covering RFC 7230-7235 compliance: URL parsing, path
normalization, status codes, HTTP methods, ETag generation, MIME
detection, header injection prevention, routing.