# Slovo Local Package And Workspace Guide

Sanjin Gumbarevic<br>
hermeticum_lab@protonmail.com

This guide documents the current beta local package model. It is intentionally
smaller than a package manager: Slovo supports closed local workspaces,
package metadata, local path dependencies, package-qualified imports, and
deterministic project-wide tooling.

Remote registries, lockfiles, semantic-version solving, package publishing,
optional/dev/target dependencies, feature flags, build scripts, package
archives, and stable package ABI/layout promises are not part of the current
beta contract.

## Workspace Manifest

A workspace root contains `slovo.toml` with a `[workspace]` section:

```toml
[workspace]
members = ["packages/app", "packages/mathlib"]
default_package = "app"
```

`members` is required and must be a non-empty array of relative paths that stay
under the workspace root. Paths are normalized before package loading, so
spelling the same member twice is invalid.

`default_package` is optional. When more than one package has its configured
entry module, `glagol build` and `glagol run` use `default_package` to select
the entry package. Without it, build/run require exactly one package with an
entry module.

## Package Manifest

Each member contains its own `slovo.toml`:

```toml
[package]
name = "app"
version = "0.1.0"
source_root = "src"
entry = "main"

[dependencies]
mathlib = { path = "../mathlib" }
```

`name` must be lowercase ASCII and may contain digits or `-` after the first
letter. `version` currently uses literal `MAJOR.MINOR.PATCH` numeric shape.
The version is metadata for manifests and generated documentation; it is not
used for solving dependency constraints.

`source_root` defaults to `src`. `entry` defaults to `main`. Source roots and
dependency paths must stay inside the workspace/package boundary after
normalization and canonical path checks.

Duplicate keys in package manifests are `PackageManifestInvalid` diagnostics.
The manifest loader does not silently choose one spelling for repeated package
identity or dependency entries.

Dependencies are local path records only. The dependency key must match the
target package name:

```toml
mathlib = { path = "../mathlib" }
```

Dependency keys use the same package-name shape as package identities. Invalid
dependency keys are `InvalidPackageDependencyName` diagnostics, and duplicate
dependency keys are `DuplicatePackageDependencyName` diagnostics before the
local dependency graph is accepted.

## Imports

Within a workspace, a package imports a dependency module through the package
name and module name:

```slo
(module main)

(import mathlib.math (add_one))

(fn main () -> i32
  (add_one 41))
```

Only exported declarations are visible across package boundaries. Packages do
not imply automatic imports, glob imports, aliases, re-exports, or registry
resolution.

## Tooling

The project-wide commands operate over the closed workspace graph:

```bash
glagol check path/to/workspace
glagol test path/to/workspace
glagol fmt --check path/to/workspace
glagol fmt --write path/to/workspace
glagol doc path/to/workspace -o docs-out
glagol build path/to/workspace -o app-bin
glagol run path/to/workspace
glagol clean path/to/workspace
```

`glagol doc <workspace>` emits a deterministic workspace summary with members,
packages, and local package dependency edges before the module sections.

## Diagnostics

The package/workspace gate covers these user-facing error families:

- missing member manifests
- duplicate normalized workspace members
- invalid member or dependency paths
- duplicate package manifest keys
- invalid package names and versions
- duplicate package names
- missing local path dependencies
- invalid dependency keys
- duplicate dependency keys
- dependency key/name mismatches
- package dependency cycles
- private cross-package imports
- ambiguous workspace build/run entry packages
- missing or invalid `default_package` references
- selected default packages that lack their configured entry module

These diagnostics are part of the beta package discipline surface, but the
exact text remains subject to beta refinement before stable `1.0.0`.
