6 KiB
Changes
Record of accepted architectural decisions and visible surface changes for
lian-build. Format follows Keep a Changelog; project is pre-1.0 so the
SemVer guarantee is not yet in force — schema and CLI shape may break
between minor versions until 0.1.0 is tagged.
Dates reflect the ADR acceptance date or the date the on-disk artefact was recorded; this project does not yet publish git tags or release builds.
[Unreleased] — 0.1.0
Architecture
-
adr-003 — Nickel coupled via subprocess, not library linkage (2026-05-03) All NCL → Rust conversions flow through
directives::nickel_export(path, &[import_paths]), which spawnsnickel export --format jsonand feeds serde. Nonickel-lang*crate is added toCargo.toml.nickelis a runtime requirement on$PATH. -
adr-002 — CLI surface is subcommand-only with stdout reserved for structured envelopes (2026-05-03)
lian-buildnow exposes{build, integrate}as clap subcommands. There is no default subcommand and no flat-arg compatibility shim.tracing_subscriberis pinned towith_writer(std::io::stderr)so stdout carries at most one envelope per invocation. Breaking for any caller invoking the legacybuildkit-launcherflat-arg form: migrate tolian-build build <args>. -
adr-001 — lian-build is a standalone build substrate, not part of provisioning (2026-05-01)
buildkit-launcherandbuildkit_runnerextracted fromprovisioning/platform/crates/buildkit-launcherandprovisioning/extensions/components/buildkit_runnerinto this standalone project. Binary renamed frombuildkit-launchertolian-build.
Added
lian-build buildsubcommand. Accepts flat args or--directives <file.ncl>; directives take precedence over flat-arg fields when both are present (src/main.rs::resolve_build_plan).lian-build integratesubcommand. Federated probe that reads aSecretDeliveryContextJSON envelope from stdin and emits a singleResultEnvelopeJSON line on stdout (src/integration/).BuildDirectivesNCL vocabulary (schemas/build_directives.ncl) and matching Rust types insrc/directives.rswith serde round-trip tests.BuildSpecschema (schemas/build_spec.ncl) withbounded_cpu_≤ 256 andbounded_time_budget_≤ 1440 min contract bounds; honoured bysizing::resolveat the explicit-spec tier.CachePolicyschema (schemas/cache_policy.ncl) withBuildMode='ci | 'session,SessionActor('human | 'agent | 'ci_aux), andSessionCacheDisposition('export | 'discard | 'rollback).src/cache.rs—build_cache_flags(workspace, mode, registry)returning import/exportVec<String>; enforcesci/<workspace>/*(canonical, read-only to sessions) anddev/<actor-id>-<workspace>/*(per-session). Invariants guarded by unit tests:ci_never_imports_dev,session_never_exports_ci,session_imports_both_layers,mode_switch_purity.src/sizing.rs— three-tier resolution: explicit.build-spec.ncl→ P95 historical (×1.2, floored) → language defaults (rust=4/8/60, go=2/4/30, java|kotlin|scala=4/8/45, default=2/4/30).src/retry.rs—MAX_OOM_RETRIES = 1(hard bound),SIZE_TIERSwalkcx22 → cx32 → cx42 → cx52. OOM is detected via exit-code137or stderr matchingOOM/Killed.src/orchestrator_client.rs— HTTP client wrapping responses inApiResponse<T> { success, data, error }. Methods:spawn_runner,destroy_runner,get_p95,record_metrics.src/buildctl_runner.rs—rsync_contextandrun_buildctlover SSH.src/nats_events.rs—BuildEventPublisheroverplatform_nats::EventStream. Publishesstarted/completed/failedto<prefix>.<workspace>.build.<event>. Connect failures warn and disable publishing; they never fail a build.defaults/build_directives.ncl—make_*constructors andci_cache_policy/session_cache_policyhelpers.examples/sample.ncl— exampleBuildDirectivesinstance.- Ontoref scaffolding:
.ontology/{core,state,gate,manifest}.ncl,.ontoref/project.ncl,card.ncl,reflection/{backlog,qa}.ncl,reflection/modes/,catalog/{domains,modes}/. - Repository assets:
assets/(logo and branding),justfilewith imports fromjustfiles/{build,test,ci}.just,.pre-commit-config.yaml.
Changed
- Binary target renamed
buildkit-launcher→lian-build. Thetracingenv-filter directive remains the legacy crate name (buildkit_launcher=info) — explicitly noted inCLAUDE.md. --platformsis now a comma-separated list (multi-platform builds); legacy single-value invocations remain valid.
Constraints (grep-checked, ADR-001)
no-provisioning-lib-import—Cargo.tomlandsrc/must not matchplatform-config|provisioning|stratum-. Theplatform-natspath-dep fromstratumiopsis explicitly allowed (it is shared infrastructure, not the provisioning workspace).build-directives-ncl-vocabulary—src/must not matchprovisioning_workspace|vapora_|woodpecker_.
Status (.ontology/state.ncl)
| Dimension | Current | Desired |
|---|---|---|
| provider-pluggability-maturity | hcloud-zot-only | provider-trait-stable |
| session-multi-actor-maturity | ci-single-actor | multi-actor-stable |
| active-active-registry-maturity | single-zot-libre-wuji | active-active-verified |
| caller-integration-maturity | provisioning-only | multi-caller-stable |
| peer-publishing-status | packaged | production |
ComputeProvider / RegistryProvider Rust traits are not yet declared;
the orchestrator client is currently hcloud-shaped. Compute is selected via
NCL discriminant but dispatch in core is monolithic — see ADR-001 and the
provider-pluggability-maturity dimension.