Skip to content

Distribution Source Build Architecture ​

Norm uses the root Gradle Kotlin DSL as its sole upstream build entry for development, CI, and releases. It includes isolated build logic and the compiler product JPMS module in cli/compiler/build.gradle.kts. Build logic is not part of Norm's runtime or public API. Gradle writes build output to the repository's root build/ directory.

Build boundaries ​

gradle/build-logic implements build metadata, Builtin ABI, dependency catalogs, reachability metadata, launchers, runtime trees, the jlink runtime, and release archives as strongly typed Java components. Gradle tasks pass their actual resolved dependency graph and JAR files to those components rather than duplicating product logic. Component tests verify these boundaries; see the toolchain development guide for entry points.

The release targets are the sole source for platforms, runners, distribution directories, and launchers. The release model derives asset names, while the distribution manifest generator derives package-manager manifests. Formal release versions come only from SemVer tags and are passed by the workflow through -PnormVersion. Untagged development versions come from the root Gradle definition; candidate validation does not publish same-version assets.

Entry pointDeliverableDependency source
./gradlew qualityCheckCompilation, tests, and Java formatting checksPinned upstream dependencies
./gradlew :compiler:installRuntimeDistSelf-contained runtime tree at build/compiler/norm-runtimePrivate Java dependencies and verified non-Java inputs
./gradlew :compiler:packageDistribution -PnormVersion=$VERSIONTarget-platform release asset in build/distributionsThe same verified runtime tree and release targets

The current self-hosted APT and RPM repositories use formal release assets and application-private dependencies. Distribution preflight records candidates for system dependencies; it does not establish an official source package build. Offline building, distribution system libraries, and clean SRPM or Debian source-package rebuilding each require separate acceptance. The official packaging track retains its historical evidence and is not currently being advanced. Missing non-Java inputs such as reachability metadata must fail explicitly rather than trigger an implicit download during an offline build. ReachabilityMetadataArchive defines that input contract.

If the official source-package track resumes, it must declare complete Build-Depends or BuildRequires and rebuild offline in a fresh isolated environment. A precompiled compiler, JAR, or Gradle cache must not be treated as source input. A local candidate dependency repository proves only that a technical package chain can rebuild; official inclusion also requires those dependencies to be available in the target official repository.

Release and source-package acceptance ​

  • The same upstream source passes Java 25, JPMS, annotation-processor, test, and formatting checks.
  • The same build model generates target-platform assets. Version, filenames, runtime tree, licenses, toolchain catalog, and digests agree. CLI, LSP, dynamic Java binding, application archives, and Native Image are exercised after real installation.
  • The bundled JDK is generated by jlink; Java dependencies live in the application's private directory and do not replace system Java libraries. See the release process for complete platform and VSIX gates.
  • If official source-package inclusion resumes, Debian requires clean sbuild, lintian, autopkgtest, and post-install acceptance; Fedora requires clean mock, rpmlint, and post-install acceptance. Record the dependency repository, build root, and offline conditions. Acceptance of the current self-hosted repositories does not constitute official inclusion.

Kryo replacement boundary ​

Replacing Kryo formats is separate from the build entry and distribution recipes. Each data owner supplies explicit encoding and decoding:

  • Disposable caches use an internal format with a schema version; the owner rebuilds them after a version mismatch.
  • Content-addressed data fixes field, collection, and integer-encoding order; its digest is based solely on canonical bytes.
  • Distributable data such as NARs, published bindings, and application programs use a public binary envelope with magic, format version, and length boundaries.

Each format needs golden-byte, round-trip, determinism, corrupt-input, and size-boundary tests. After every caller has migrated, remove PortableObjectCodec, Kryo, and MinLog, ReflectASM, and Objenesis only after actual dependency analysis confirms they are unused. core.store retains only shared binary read/write primitives.

Norm 0.24 development line