Skip to content
docs
Arxo ↗

Packages, cases, and worlds

For LLMs7 sections

Three nouns carry the whole architecture:

  • A package is a versioned folder of source files with a manifest (law.toml). The manifest says what the package is called, which version it is, and which other packages it needs.
  • A case package is a package that holds one worked example: the facts of a case and the results expected from them.
  • A world is the complete set of packages used to answer a question. It contains the root package and all of its direct and indirect dependencies. The lockfile fixes the version of every dependency, so the world is the same on every machine.

Packages, case packages, and worlds are Available in the public release (S). Marks on this page follow the topic legend.

The fictional parcel fixtures make the three nouns concrete. They are cited by package id everywhere in this topic:

  • labparcels.iface — the shared vocabulary: entities, one keyed relation, one enum. No rules, no sources, no dependencies.
  • labparcels.registry — the fictional source act: pinned article text plus executable rules over the shared vocabulary.
  • labparcels.fees and labparcels.appeals — two consumers of the registry, each adding its own rules without touching the source.
  • labparcels.case1 — the case package: one fact pattern with expected results over the world of the other four.

An arrow reads “depends on”:

Output
labparcels.case1 ──┬──> labparcels.fees ─────┬──> labparcels.registry ──> labparcels.iface
├──> labparcels.appeals ──┘
├──> labparcels.registry
└──> labparcels.iface
fees and appeals also depend on labparcels.iface directly.

The world of labparcels.case1 is all five packages. Its manifest names each of the other four with one exact version (fees at 0.2.0, the others at 0.1.0), and every answer the case gives is computed over exactly those versions. The world of labparcels.fees alone is smaller: fees, registry, and iface.

Interface, source, consumers, case: that layering is the pattern every real subject area repeats. The lab tour runs these fixtures end to end.

The manifest declares identity and needs: name, version, language, namespace, dependencies, registries, and an optional canon-profile slot. The slot is optional — the manifest schema requires only the package block. When the slot names a profile, it names exactly one, read at the lock root.

For the manifest fields in depth, see A package in the corpus and Package passports.

The manifest only requests versions; the lockfile records the exact resolution. It holds:

  • every package pinned to one version;
  • content hashes for the compiled bytes;
  • dependency edges;
  • a resolution hash covering the profile block, expansions, and editions as presented.

Adding, installing, and updating packages write and check the lockfile; the engine lock subcommand rechecks it on demand. (S)

The details — exact pins, directory registries, and offline transfer — live on the Dependencies, locks, and registries page of this topic.

Linking joins the root with its dependency nodes by package name. Three rules apply:

  • one version of a package per world;
  • a single semantics line across the world;
  • any content-identity collision between nodes is refused with a compiler diagnostic (LDC-E1107). (S)

Two operations share that link step, and they are not the same:

  • New-root linking joins a fresh root with its locked dependencies. It happens inside asking, testing, and packing. For that reason there is deliberately no standalone build-the-world command. The absence is by design, not a missing feature: a world is always the locked world of some root, never a loose assembly.
  • Fixed-world-artifact execution runs against already-linked world bytes carried in a release artifact. Serving, replaying a saved evaluation, and replaying a decision journal take the world as given and never link again.

For the idea worked by hand, see Several packages and a world.

A new package starts from scaffolding:

Output
$ law --help
law — canon execution: packages, cases and questions (DECISION-0168)
law init <dir> [--name <package>] [--template case|package] [--json]

The excerpt above is verbatim; the full listing covers the whole command surface. The case template scaffolds a case package, the package template a plain one. (S)

The full case-work recipe — context, snapshots, results, and tests — is N. Package, context, snapshots, case, result, and test.

The low-level engine reads the same manifest back. Called with no target it says what it needs — both lines below are verbatim error-stream output, exit code 2 in each run:

Output
$ law engine manifest
manifest: requires law.toml or a package directory
$ law engine lock
lock: requires a package directory or law.toml

Manifest handling is command-line surface; the engine subcommands themselves are internal tooling. (S/I)

Running a scenario command outside any project shows the project discovery it relies on — verbatim error-stream output, exit code 2:

Output
$ law test
law test: REFUSAL: LPK-E0201: /private/tmp/empty-no-project: no law.toml here or above — pass the project via --project
→ run from the project or pass --project <dir>; a new one via `law init`

The fix is in the hint: run the command inside a project directory, pass --project <dir>, or create a project with law init.

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.