# Coral Package Manager Guide

Coral is the package manager for Zygaena, a ports-based operating system built on illumos. This guide covers all aspects of using Coral, from basic package management to creating repositories and signing packages.

## Table of Contents

1. [Installation and Setup](#installation-and-setup)
2. [Basic Usage](#basic-usage)
3. [Creating and Building Packages](#creating-and-building-packages)
4. [Package Groups](#package-groups)
5. [Alternative Dependencies](#alternative-dependencies)
6. [Creating Repositories](#creating-repositories)
7. [Package Signing](#package-signing)
8. [Database Management](#database-management)
9. [Port Development Tools](#port-development-tools)
10. [Configuration Reference](#configuration-reference)

---

## Installation and Setup

### Prerequisites

Coral requires:
- Zygaena or illumos-based system
- Reef compiler 0.5.0 or later
- Root privileges for package installation
- GCC or compatible C compiler (for building from source)

### Directory Structure

Coral uses the following directories:

| Path | Purpose |
|------|---------|
| `/usr/zports/` | Ports tree (package build definitions) |
| `/usr/zports/groups/` | Package group definitions |
| `/etc/coral/coral.conf` | Main configuration file |
| `/etc/coral/repos.d/` | Repository configurations |
| `/etc/coral/keys/` | Signing keys |
| `/var/lib/coral/installed/` | Installed package database (source of truth) |
| `/var/lib/coral/db/` | Package database indexes (MsgPack) |
| `/var/lib/coral/packages/` | Binary package cache |
| `/var/lib/coral/sources/` | Source archive cache |
| `/var/lib/coral/repos/` | Repository metadata cache |
| `/var/lib/coral/trusted-keys/` | Trusted public keys |
| `/var/tmp/coral/work/` | Build work directory |
| `/var/tmp/coral/pkg/` | Package staging directory |

### Initial Setup

1. Create required directories:
```bash
sudo mkdir -p /usr/zports/{core,base,devel,desktop,extra}
sudo mkdir -p /usr/zports/groups
sudo mkdir -p /etc/coral/repos.d
sudo mkdir -p /etc/coral/keys
sudo mkdir -p /var/lib/coral/{installed,packages,sources,repos,trusted-keys,db}
sudo mkdir -p /var/tmp/coral/{work,pkg}
```

2. Create initial configuration:
```bash
sudo tee /etc/coral/coral.conf << 'EOF'
[general]
arch = "x86_64"
jobs = 0
confirm = true
color = true

[build]
logging = true
quiet = false

[security]
require_signed_repos = false
require_signed_packages = false
EOF
```

3. Initialize the package database:
```bash
sudo coral db init
```

---

## Basic Usage

### Installing Packages

Install a single package:
```bash
coral install vim
```

Install multiple packages:
```bash
coral install vim nano htop
```

Install from a local package file:
```bash
coral install /path/to/package-1.0.0-1.pkg.tar.xz
```

Install without confirmation:
```bash
coral install -y vim
```

Force reinstall (also overrides conflict checks):
```bash
coral install --force vim
```

Dry run (show what would be done without making changes):
```bash
coral install -n vim
```

When a binary package is not found in any repository and `fallback_to_source = true` (default), Coral will attempt to build the package from the ports tree automatically.

### Removing Packages

Remove a package:
```bash
coral remove vim
```

Remove multiple packages:
```bash
coral remove vim nano htop
```

### Upgrading Packages

Upgrade all packages:
```bash
coral upgrade
```

Upgrade specific packages:
```bash
coral upgrade vim nano
```

Check for available updates:
```bash
coral outdated
```

### Querying Packages

List installed packages:
```bash
coral list
```

Show package information:
```bash
coral info vim
```

List files owned by a package:
```bash
coral files vim
```

Find which package owns a file:
```bash
coral owner /usr/bin/vim
```

Search for packages:
```bash
coral search editor
```

Show dependency tree:
```bash
coral depends vim
```

Verify package integrity:
```bash
coral verify vim
```

### Building Packages

Build a package from source:
```bash
coral build vim
```

The built package is stored in `/var/lib/coral/packages/`.

### Syncing Ports

Update the ports tree:
```bash
coral sync
```

---

## Creating and Building Packages

### Port Structure

A port consists of a directory under `/usr/zports/<category>/<name>/` containing:

```
/usr/zports/base/mypackage/
├── package.toml                    # Package metadata
├── build.sh                        # Build script (zsh)
├── fix-build.patch                 # Optional patch files
└── hammerhead-solaris-compat.patch  # (referenced in package.toml [patches])
```

### package.toml

The `package.toml` file defines package metadata:

```toml
[package]
name = "mypackage"
version = "1.2.3"
release = 1
description = "A useful package"
url = "https://example.com/mypackage"
license = "MIT"
maintainer = "Your Name <you@example.com>"
arch = "x86_64"

# Optional: alternatives this package provides
alternatives = ["editor", "pager"]

# Optional: packages this conflicts with (install aborts if any are installed)
conflicts = ["otherpackage"]

[dependencies]
# Packages required at runtime
runtime = ["libfoo", "libbar>=1.2"]

# Packages required only for building
build = ["gcc", "gmake"]

### Per-Package Path Overrides

Packages can override the default installation prefix and sysconfdir. This is useful for packages that install to `/opt`, `/srv`, or other non-standard locations:

```toml
[paths]
prefix = "/opt/myapp"
sysconfdir = "/opt/myapp/etc"
```

These override the system defaults from `coral.conf` and are exported as `$PREFIX` and `$SYSCONFDIR` to the build script. If omitted, the system-wide values are used.

### Source Files

Source files can be specified using TOML table arrays (`[[source]]`), which supports
mirror URLs for automatic failover:

```toml
[[source]]
file = "mypackage-1.2.3.tar.gz"
urls = [
    "https://example.com/mypackage-1.2.3.tar.gz",
    "https://mirror.example.org/mypackage-1.2.3.tar.gz"
]
checksum = "abc123def456..."

[[source]]
file = "extra-data.tar.gz"
urls = ["https://example.com/extra-data.tar.gz"]
checksum = "789xyz..."
extract = false  # Don't extract this archive
```

Each `[[source]]` entry supports:

| Field | Required | Description |
|-------|----------|-------------|
| `file` | Yes | Output filename to save as |
| `urls` | Yes | Array of mirror URLs (tried in order until success) |
| `checksum` | Yes | SHA256 checksum, or `"SKIP"` to skip verification |
| `extract` | No | Whether to extract the archive (default: `true`) |

**Mirror Failover**: When downloading, Coral tries each URL in the `urls` array
in order. If a download fails or checksum verification fails, the next mirror
is tried automatically.

#### Local Source Files

For packages where sources aren't available on public HTTP servers (private repos,
bundled tarballs), you can place source files directly in the port directory and
reference them by filename:

```toml
[[source]]
file = "reef-lang-0.1.10.tar.gz"
urls = ["reef-lang-0.1.10.tar.gz"]  # Local file in port directory
checksum = "abc123..."
```

URLs that don't start with `http://` or `https://` are treated as local paths:
- **Relative paths** (no leading `/`) are resolved relative to the port directory
- **Absolute paths** are used as-is

Local files are copied to the sources cache (`/var/lib/coral/sources/`) for
consistency with downloaded files.

You can also mix local and remote sources for fallback:
```toml
[[source]]
file = "mypackage-1.0.tar.gz"
urls = [
    "mypackage-1.0.tar.gz",                          # Try local first
    "https://example.com/mypackage-1.0.tar.gz"       # Fall back to remote
]
checksum = "abc123..."
```

#### Legacy Format (Deprecated)

The older `[sources]` format is still supported for backward compatibility:

```toml
[sources]
urls = [
    "https://example.com/mypackage-1.2.3.tar.gz"
]
checksums = [
    "abc123def456..."
]
```

**Note**: The legacy format does not support mirrors or the `extract` flag.

### Patches

Coral can apply patches to source code before running `build.sh`. Patch files
are placed in the port directory alongside `package.toml` and declared in a
`[patches]` section:

```toml
[patches]
files = ["hammerhead-solaris-compat.patch", "fix-build.patch"]
strip = 0
```

| Field | Required | Default | Description |
|-------|----------|---------|-------------|
| `files` | Yes | — | Array of patch filenames, applied in order |
| `strip` | No | `0` | Strip level passed to `patch -p<N>` |

Patches are applied from within the extracted source directory using `patch -p<strip>`.
The `strip` value controls how many leading path components are removed from filenames
in the diff header:
- `strip = 0` — paths used as-is (e.g., diff against `configure` / `configure.orig`)
- `strip = 1` — strips `a/` and `b/` prefixes (standard `git diff` output)

**Example**: Adding Hammerhead OS recognition to ncurses' configure script:
```diff
--- configure.orig
+++ configure
@@ -7066,7 +7066,7 @@
 		test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel
 		;;
-	(solaris2*)
+	(solaris2*|hammerhead*)
 		# tested with SunOS 5.5.1 (solaris 2.5.1) and gcc 2.7.2
```

[build]
# Enable parallel builds
parallel = true

# Number of parallel jobs (0 = auto)
jobs = 0
```

### Build Script (build.sh)

The build script is executed in the source directory. Environment variables available:

| Variable | Description |
|----------|-------------|
| `$DESTDIR` | Installation staging directory |
| `$PREFIX` | Installation prefix (default: `/usr/local`, configurable in `coral.conf` or per-package) |
| `$SYSCONFDIR` | System configuration directory (default: `/etc`, configurable in `coral.conf` or per-package) |
| `$PKG_ROOT` | Alternate root directory (empty when installing to `/`) |
| `$SRCDIR` | Extracted source directory |
| `$PKGDIR` | Package staging directory (alias for `$DESTDIR`) |
| `$CFLAGS` | C compiler flags |
| `$CXXFLAGS` | C++ compiler flags |
| `$LDFLAGS` | Linker flags (see [Linker Flags](#linker-flags-and-library-resolution) below) |
| `$PKG_CONFIG_PATH` | pkg-config search path (set to `$PREFIX/lib/pkgconfig`) |
| `$MAKEFLAGS` | Make flags (includes `-j` for parallel builds) |
| `$JOBS` | Number of parallel jobs |
| `$PKG_NAME` | Package name |
| `$PKG_VERSION` | Package version |
| `$BUILD_TRIPLE` | Canonical build triplet (e.g., `x86_64-zygaea-hammerhead`) |
| `$MAKE` | Make command (`gmake`) |
| `$TAR` | Tar command (`gtar`) |

Example build.sh:
```bash
#!/usr/bin/zsh
set -e

# Configure using $PREFIX and $SYSCONFDIR (don't hardcode paths)
./configure --prefix=$PREFIX --sysconfdir=$SYSCONFDIR

# Build
$MAKE ${MAKEFLAGS}

# Install to staging directory
$MAKE DESTDIR="${DESTDIR}" install
```

Build scripts are executed with `zsh` (the Zygaena standard shell).

#### Linker Flags and Library Resolution

Coral sets `LDFLAGS="-R$PREFIX/lib"` globally. This embeds an RPATH in every
built binary so the runtime linker can find shared libraries installed under
`$PREFIX` (e.g., `/usr/local/lib`) without requiring system-wide `crle`
configuration.

**Why only `-R` and not `-L`?**

Coral intentionally does **not** set `-L$PREFIX/lib` globally. The `-L` flag
changes the **build-time** linker search order, which could cause Coral-installed
libraries to shadow base OS libraries in `/lib` and `/usr/lib`. For example, if
both the base OS and a Coral port ship `libz.so`, a global `-L/usr/local/lib`
would cause all ports to link against the Coral version instead of the base
version, potentially introducing ABI mismatches or version conflicts.

The `-R` flag only affects **runtime** resolution and does not change build-time
search order, making it safe to set globally.

**When a build script needs `-L`:**

If a port's `configure` script cannot find a dependency's library on its own,
the build script should add `-L` explicitly:

```bash
export LDFLAGS="-L$PREFIX/lib $LDFLAGS"
```

This appends to Coral's RPATH setting rather than replacing it. Only add `-L`
when `configure` fails to locate the library — most autotools-based projects
find libraries via `pkg-config` (which Coral also configures via
`$PKG_CONFIG_PATH`) or their own `--with-*` flags.

#### pkg-config

Coral sets `PKG_CONFIG_PATH` to `$PREFIX/lib/pkgconfig` so that `configure`
scripts using `pkg-config` can find `.pc` files from Coral-installed packages.
This is the preferred mechanism for library discovery — most modern autotools
and meson projects use `pkg-config` and will automatically pick up the correct
`-I`, `-L`, and `-l` flags from `.pc` files.

### Install Scripts

Packages can include scripts that run during installation, removal, and upgrade. Create a `.SCRIPTS/` directory in the package:

```
.SCRIPTS/
├── pre-install.sh    # Runs before files are installed ($VERSION)
├── post-install.sh   # Runs after files are installed ($VERSION)
├── pre-remove.sh     # Runs before files are removed ($VERSION)
├── post-remove.sh    # Runs after files are removed ($VERSION)
├── pre-upgrade.sh    # Runs before upgrade ($OLD_VERSION $NEW_VERSION)
└── post-upgrade.sh   # Runs after upgrade ($OLD_VERSION $NEW_VERSION)
```

Scripts are executed with `zsh`. Version arguments are passed as positional parameters (`$1`, `$2`).

**Hook behavior:**
- Pre-hooks (`pre-install`, `pre-remove`, `pre-upgrade`) abort the operation if they exit non-zero
- Post-hooks (`post-install`, `post-remove`, `post-upgrade`) log a warning but don't abort on failure

**Upgrade flow:** When installing a newer version of an already-installed package, Coral runs: `pre-upgrade` → remove old files → install new files → `post-upgrade`.

Example post-install.sh:
```bash
#!/usr/bin/zsh
# Update font cache after installing fonts
fc-cache -f
```

Example pre-upgrade.sh:
```bash
#!/usr/bin/zsh
OLD_VERSION=$1
NEW_VERSION=$2
# Stop service before upgrade
svcadm disable myservice
```

### Config Files

To mark files as configuration files (preserved during upgrades), create a `.CONFIG` file listing them:

```
/etc/mypackage/config.conf
/etc/mypackage/settings.toml
```

Config files use checksum-based protection during upgrades:
- **Fresh install**: config file is installed normally
- **Upgrade, user has not modified config**: new version overwrites cleanly
- **Upgrade, user has modified config**: new version is installed as `.pkg-new`, user's file is preserved

On removal, user-modified config files are preserved (not deleted).

### Building the Package

```bash
coral build mypackage
```

This will:
1. Resolve dependencies recursively (build uninstalled deps from source first)
2. Download sources (with automatic mirror failover)
3. Verify checksums
4. Extract sources
5. Apply patches
6. Run build script
7. Compress man pages (if `compress_man = true`)
8. Create package archive
9. Clean up build directories

If a dependency is not installed, Coral builds it from source automatically using a topological sort of the full dependency tree. Circular dependencies are detected and reported.

#### Build Command Options

| Option | Description |
|--------|-------------|
| `--noclean` / `-n` | Skip cleanup of work and staging directories after build |
| `--clean` / `-c` | Force cleanup even if config says to keep directories |
| `--quiet` / `-q` | Hide subprocess output (still logged to file) |
| `--verbose` / `-v` | Show all output (overrides quiet mode) |
| `-y` | Skip confirmation prompts |
| `--force` | Force rebuild even if package exists |

Example: Keep build artifacts for debugging:
```bash
coral build --noclean mypackage
```

#### Build Cleanup Behavior

After a successful build, Coral cleans up:
- **Work directory** (`/var/tmp/coral/work/<package>`): Extracted sources and build files
- **Staging directory** (`/var/tmp/coral/pkg/<package>`): Package staging area

Cleanup behavior can be controlled via:
1. Command-line flags (`--noclean`, `--clean`)
2. Configuration file settings (`clean_work`, `clean_pkg`)

Downloaded source archives are preserved by default in `/var/lib/coral/sources/`.

#### Build Logging

By default, Coral logs all build output to a file in the work directory:

```
/var/tmp/coral/work/<package>/coral-build-<package>-<timestamp>.log
```

The log captures:
- All Coral status messages (download, extract, patch, build, package)
- Full subprocess output (build script, patch commands)
- Commands executed

Log files are cleaned up with the work directory unless `--noclean` is specified.

Use `--quiet` to hide subprocess output from the terminal while still logging everything:
```bash
coral build --quiet vim    # Clean output, full log file
coral build --verbose vim  # Show all output (overrides quiet)
```

---

## Package Groups

Groups allow installing multiple related packages with a single command.

### Creating a Group

Create a TOML file in `/usr/zports/groups/`:

```toml
# /usr/zports/groups/base-devel.toml

[group]
name = "base-devel"
description = "Base development tools"
packages = [
    "gcc",
    "gmake",
    "binutils",
    "autoconf",
    "automake",
    "libtool",
    "pkg-config"
]
```

### Installing a Group

Use the `@` prefix:
```bash
coral install @base-devel
```

This expands to all packages in the group and installs them with dependency resolution.

### Listing Groups

Groups are stored as `.toml` files in `/usr/zports/groups/`. List them with:
```bash
ls /usr/zports/groups/
```

---

## Alternative Dependencies

Alternatives allow a package to depend on one of several options. This is useful when multiple packages can satisfy a dependency.

### Version Constraints

Dependencies can include version constraints using operators:

```toml
[dependencies]
runtime = [
    "libfoo>=1.0",        # Version 1.0 or newer
    "libbar<=2.0",        # Version 2.0 or older
    "libqux=3.1.0",       # Exactly version 3.1.0
    "libbaz>0.9",         # Strictly newer than 0.9
    "libold<2.0",         # Strictly older than 2.0
]
```

If an installed package doesn't satisfy the version constraint, Coral includes it in the install order for upgrade.

### Specifying Alternatives

In `package.toml`, use the colon syntax:

```toml
[dependencies]
runtime = [
    "libfoo",
    "editor:vim,nano,emacs",     # Any of these editors
    "database:postgresql,mysql"  # Any of these databases
]
```

Format: `base_name:option1,option2,option3`

### How Alternatives Work

1. During dependency resolution, Coral checks if any alternative is installed
2. If one is installed, the dependency is satisfied
3. If none are installed, the first option is automatically selected
4. Users can override by pre-installing their preferred option

### Providing Alternatives

A package can declare that it provides certain alternatives:

```toml
[package]
name = "vim"
alternatives = ["editor", "vi"]
```

When another package depends on "editor", vim will satisfy that dependency.

---

## Creating Repositories

Repositories distribute pre-built binary packages.

### Repository Structure

```
/path/to/repo/
├── repo.toml           # Repository manifest
├── repo.toml.sig       # Manifest signature (optional)
└── packages/           # Binary packages
    ├── vim-9.0-1.x86_64.pkg.tar.xz
    ├── vim-9.0-1.x86_64.pkg.tar.xz.sig
    └── ...
```

### Initializing a Repository

```bash
coral repo init /path/to/repo
```

This creates the directory structure and an empty manifest.

### Adding Packages

Copy built packages to the `packages/` directory:
```bash
cp /var/lib/coral/packages/*.pkg.tar.xz /path/to/repo/packages/
```

### Rebuilding the Manifest

After adding packages, rebuild the manifest:
```bash
coral repo rebuild /path/to/repo
```

This scans all packages and generates `repo.toml`:

```toml
[repository]
name = "myrepo"
description = "My Package Repository"
url = "https://repo.example.com"

[packages.vim]
version = "9.0"
release = 1
description = "Vi IMproved"
license = "Vim"
category = "base"
file = "vim-9.0-1.x86_64.pkg.tar.xz"
sha256 = "abc123..."
size = 12345678
compressed = 2345678
depends = ["ncurses", "libfoo"]

[packages.nano]
# ... more packages
```

### Signing the Repository

```bash
coral repo sign /path/to/repo
```

This signs `repo.toml` with your private key, creating `repo.toml.sig`.

### Configuring Clients

Create a repository configuration file on client systems:

```toml
# /etc/coral/repos.d/myrepo.repo

[repository]
name = "myrepo"
url = "https://repo.example.com"
priority = 100
enabled = true
signed = true
keyid = "myrepo-key"
```

### Refreshing Repository Data

```bash
coral repo refresh
```

### Mirroring

Export a repository for offline use:
```bash
coral repo export /path/to/repo /path/to/output
```

---

## Package Signing

Coral uses Ed25519 signatures for package and repository verification.

### Key Management

#### Initialize Keyring

```bash
coral key init
```

Creates `/etc/coral/keys/` directory.

#### Generate a Signing Key

```bash
coral key generate mykey
```

Creates:
- `/etc/coral/keys/mykey.key` (private key - keep secure!)
- `/etc/coral/keys/mykey.pub` (public key - distribute this)

#### List Keys

```bash
coral key list
```

#### Export Public Key

```bash
coral key export mykey > mykey.pub
```

#### Import a Public Key

```bash
coral key import mykey.pub repokey
```

#### Trust a Key

```bash
coral key trust repokey
```

Adds the key to `/var/lib/coral/trusted-keys/`.

#### Revoke Trust

```bash
coral key revoke repokey
```

### Signing Packages

When building a package, sign it:
```bash
coral build mypackage
coral key sign /var/lib/coral/packages/mypackage-1.0-1.pkg.tar.xz mykey
```

### Signing Repositories

```bash
coral repo sign /path/to/repo
```

Uses the first available private key, or specify one:
```bash
coral repo sign /path/to/repo --key mykey
```

### Verification

Enable mandatory verification in `/etc/coral/coral.conf`:

```toml
[security]
require_signed_repos = true
require_signed_packages = true
```

When enabled:
- Repository manifests must have valid signatures
- Packages must have valid signatures
- Signatures must be from trusted keys

### Verification Process

1. Download package and signature
2. Find matching public key in trusted keys
3. Verify signature using Ed25519
4. Reject if verification fails (when required)

---

## Database Management

Coral maintains MsgPack-based indexes for fast package and file lookups. The source of truth is always the installed package database (`/var/lib/coral/installed/`); indexes can be safely rebuilt at any time.

### Database Files

| File | Purpose |
|------|---------|
| `/var/lib/coral/db/packages.db` | Indexed package metadata (name, version, description) |
| `/var/lib/coral/db/files.db` | File-to-package mapping for O(log N) ownership lookups |
| `/var/lib/coral/db/ports.db` | Ports index for fast search/list without parsing TOML from disk |

### Initializing the Database

After initial system setup, initialize the database:
```bash
coral db init
```

This creates the index files based on currently installed packages.

### Checking Database Status

View the current database status:
```bash
coral db status
```

Output shows:
- Index location
- Number of packages indexed
- Number of files indexed
- Number of ports indexed

### Rebuilding Indexes

If indexes become corrupted or out of sync (e.g., after manual edits to `/var/lib/coral/installed/`), rebuild them:
```bash
coral db rebuild
```

This scans all installed packages and regenerates both indexes from scratch.

### How Indexes Work

**packages.db**: Stores package metadata in MsgPack format, encoded as Base64. Contains name, version, release, description, install date, and file count for each installed package.

**files.db**: Maps file paths to owning packages. Files are sorted alphabetically, enabling O(log N) binary search lookups. This dramatically speeds up `coral owner` queries.

### Automatic Index Updates

Indexes are automatically updated when:
- A package is installed (`coral install`)
- A package is removed (`coral remove`)
- The ports tree is synced (`coral sync` — rebuilds ports.db)

You do not need to manually rebuild indexes during normal operation.

### Performance

| Operation | Without Index | With Index |
|-----------|---------------|------------|
| `coral list` (100 packages) | ~500ms | ~10ms |
| `coral owner /usr/bin/vim` (50K files) | ~2000ms | <10ms |

### Using with Alternate Root

All database commands support the `--root` flag for chroot environments:
```bash
coral --root /mnt/system db init
coral --root /mnt/system db status
coral --root /mnt/system db rebuild
```

---

## Port Development Tools

The `coral ports` command provides tooling for port developers.

### Scaffolding a New Port

Create a new port with boilerplate files:
```bash
coral ports new hammerhead/my-port
```

This creates:
- `{ports_dir}/hammerhead/my-port/package.toml` — package metadata template
- `{ports_dir}/hammerhead/my-port/build.sh` — build script stub

The generated `package.toml` includes all standard sections with placeholder values. Edit it to fill in your package's details, then test with:
```bash
coral build hammerhead/my-port
```

### Ports Index Cache

The ports index (`ports.db`) caches metadata from all ports so that commands like `coral search`, `coral list --available`, and `coral depends --reverse` don't need to parse every `package.toml` from disk.

Check index status:
```bash
coral ports cache status
```

Manually rebuild the index:
```bash
coral ports cache rebuild
```

The index is automatically rebuilt by `coral sync`, `coral db init`, and `coral db rebuild`.

### Dynamic Categories

Categories are discovered dynamically by scanning the ports directory. Any subdirectory under the ports tree (excluding infrastructure directories like `pkgs/` and `groups/`) is treated as a category. Adding a new category directory is all that's needed — no code changes required.

---

## Configuration Reference

### /etc/coral/coral.conf

```toml
[general]
# Target architecture
arch = "x86_64"

# Parallel build jobs (0 = auto-detect CPU count)
jobs = 0

# Ask for confirmation before operations
confirm = true

# Enable colored output
color = true

[paths]
# Installation prefix (exported as $PREFIX to build scripts)
prefix = "/usr/local"

# System configuration directory (exported as $SYSCONFDIR to build scripts)
sysconfdir = "/etc"

# Ports tree location
ports = "/usr/ports"

# Built packages cache
packages = "/var/lib/coral/packages"

# Downloaded sources cache
sources = "/var/lib/coral/sources"

# Installed package database
database = "/var/lib/coral/installed"

# Build work directory
work = "/var/tmp/coral/work"

# Package staging directory
pkg = "/var/tmp/coral/pkg"

[build]
# Default C compiler flags
cflags = "-O2 -pipe"

# Default C++ compiler flags
cxxflags = "-O2 -pipe"

# Default make flags
makeflags = ""

# Strip binaries
strip = true

# Compress man pages
compress_man = true

# Fall back to building from source if binary not available
fallback_to_source = true

# Log build output to file (in work directory)
logging = true

# Hide subprocess output from terminal (still logged)
quiet = false

[network]
# Download timeout in seconds
timeout = 30

# Number of retry attempts
retries = 3

# Use proxy (reads http_proxy/https_proxy env vars)
use_proxy = false

[sync]
# Auto-refresh repository metadata
auto_refresh = false

[cache]
# Keep downloaded packages after install
keep_packages = true

# Keep downloaded sources after build
keep_sources = true

# Clean work directory after successful build (part of [build] section)
clean_work = true

# Clean package staging directory after successful build
clean_pkg = true

[security]
# Require signed repository manifests
require_signed_repos = false

# Require signed packages
require_signed_packages = false
```

### Repository Configuration

Repository files in `/etc/coral/repos.d/*.repo`:

```toml
[repository]
# Repository name (used in messages)
name = "zygaena-main"

# Base URL for the repository
url = "https://repo.zygaena.org/main"

# Priority (lower = higher priority)
priority = 100

# Enable/disable this repository
enabled = true

# Repository is signed
signed = true

# Key ID for signature verification
keyid = "zygaena-main"
```

---

## Troubleshooting

### Common Issues

**"Package not found"**
- Check if the port exists: `ls /usr/zports/*/packagename`
- Refresh repository metadata: `coral repo refresh`
- Check repository configuration in `/etc/coral/repos.d/`

**"Signature verification failed"**
- Import the repository's public key: `coral key import`
- Trust the key: `coral key trust keyname`
- Check key hasn't been revoked

**"Dependency resolution failed"**
- Check for circular dependencies
- Verify all dependencies are available
- Try installing dependencies manually

**"Build failed"**
- Check build.sh for errors
- Verify build dependencies are installed
- Check logs in `/var/tmp/coral/work/`

### Debug Mode

Enable verbose output:
```bash
coral -v install vim
```

Dry run (show what would be done):
```bash
coral -n install vim
```

---

## Quick Reference

| Command | Description |
|---------|-------------|
| `coral install pkg` | Install package |
| `coral install @group` | Install package group |
| `coral install -n pkg` | Dry run (show what would happen) |
| `coral remove pkg` | Remove package |
| `coral upgrade` | Upgrade all packages |
| `coral list` | List installed packages |
| `coral info pkg` | Show package info |
| `coral files pkg` | List package files |
| `coral owner /path` | Find file owner |
| `coral search term` | Search packages |
| `coral depends pkg` | Show dependencies |
| `coral verify pkg` | Verify package integrity |
| `coral build pkg` | Build from port (no install) |
| `coral build --install pkg` | Build and install |
| `coral build --noclean pkg` | Build, keep work directories |
| `coral build --quiet pkg` | Build with quiet output |
| `coral sync` | Update ports tree |
| `coral outdated` | Show available updates |
| `coral repo list` | List repositories |
| `coral repo refresh` | Refresh repo metadata |
| `coral key list` | List signing keys |
| `coral key generate name` | Generate new key |
| `coral clean status` | Show build artifact status |
| `coral clean all` | Clean all build artifacts |
| `coral clean --force all` | Clean all, override cache protection |
| `coral db init` | Initialize database indexes |
| `coral db status` | Show database status |
| `coral db rebuild` | Rebuild indexes from installed packages |
| `coral ports new cat/name` | Scaffold a new port |
| `coral ports cache status` | Show ports index status |
| `coral ports cache rebuild` | Rebuild ports index |

---

## License

Coral is part of the Zygaena project.

Copyright (C) 2025 Leafscale, LLC
Licensed under BSD-2-Clause

https://www.leafscale.com
