day11/layer: split into layer / opam_layer / doc_layer
Cleans up the layer library API after a series of incremental
refactors. The headline change: data layers are now split by domain
into three sibling libraries.
- day11_layer is now strictly generic. No opam-format dep, no
recursive build types, no opam_format anywhere. Just enough to
enumerate, hash, stack, mount-plan, and metadata-roundtrip layer
directories on disk.
- day11_opam_layer holds opam-package concerns: the recursive
Build.t / Tool.t types used by the planner and executor, the
build.json sidecar (Build_meta), Installed_files, Opam_repo,
Opamh.
- day11_doc_layer is a tiny new library holding only the doc.json
sidecar (Doc_meta with Compile/Link/Doc_all phase). Independent of
day11_opam_layer — it depends only on day11_layer + yojson, so a
doc-browsing tool could link it without pulling in opam-format.
Other changes that came along the way:
- Removed the kind field from layer.json. The kind of a layer is
now implicit in which sidecar files exist alongside layer.json
(build.json -> opam build, doc.json -> odoc layer, ...). This
removes a whole class of "the field in the JSON disagrees with
reality" bug.
- Sidecars must be valid JSON (documented in Layer_meta.mli and the
README). The library doesn't enforce this, but it lets generic
tooling display sidecar contents without depending on any domain
library.
- The day11_layer Layer_* prefixes are gone:
Layer_meta -> Meta
Layer_dir -> Dir
Layer_symlinks -> Symlinks
Layer_type.base -> Base.t
- Layer_meta is now a stripped-down record with only generic fields
(exit_status, parent_hashes, uid, gid, base_hash, disk_usage,
timing, created_at, failed_dep). Old layers in the cache still
load thanks to ppx_deriving_yojson { strict = false }.
- Build_layer.build no longer takes a kind parameter. It only writes
the generic layer.json and invokes an on_extract callback so the
caller can write its own sidecar (build.json or doc.json).
- Run_in_layers.run now takes a Types.build_env directly instead of
separate ~base ~uid ~gid arguments.
- day11-layer-cli is purely generic. Reads layer.json + lists every
other file in the layer directory. The show command pretty-prints
any sidecar as opaque JSON via Yojson directly — it doesn't link
any domain library, doesn't know what build.json or doc.json mean.
The cat subcommand was dropped; show does the job.
- Container library: Overlay.mount docstring fixed (was claiming
the wrong lower-ordering convention); Runc.write_spec moved to
Oci_spec.write; Oci_spec.make has optional defaults for the
obvious fields; mli files rewritten with odoc-style structure.
Test status: 12 suites, 196 tests, all green. Includes 16 generic
day11_layer tests, 8 day11_opam_layer tests, 3 day11_doc_layer
tests, 12 day11_container unit tests, plus the existing build/doc/
batch suites.
End-to-end smoke build of logs.0.10.0 verified:
- layer.json contains only generic fields (no kind, no package, no
opam stuff)
- build.json sidecar contains opam-specific fields (package, deps,
installed_libs, installed_docs, patches)
- The layer CLI reads and displays both correctly without depending
on any opam-aware library.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>