Replace the incorrectly copied Barycenter (OIDC IdP) content with accurate IPS project documentation including workspace structure, build commands, error handling conventions, architecture overview, and a pkg5 legacy compatibility reference mapping our docs and implementation to the original pkg5 specifications. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7.3 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
IPS (Image Packaging System) is a Rust reimplementation of the illumos/OpenIndiana package management system (replacing the Python-based pkg5). It handles software packaging, installation, updates, and dependency resolution for illumos distributions.
Workspace crates: libips (core library), pkg6 (client CLI), pkg6repo (repo management CLI), pkg6depotd (HTTP depot server), pkg6recv, pkgtree, specfile, ports, userland, xtask.
Build and Development Commands
cargo build # Build all crates
cargo check # Check without building
cargo nextest run # Run tests (CRITICAL: use nextest, not cargo test)
cargo nextest run test_name # Run specific test
make release # Build release + copy to artifacts/
RUST_LOG=libips=trace cargo run # Run with logging
CRITICAL: Always use cargo nextest run instead of cargo test. Tests need process isolation to avoid port conflicts.
Coding Conventions
Error Handling (miette + thiserror)
- All error enums derive
#[derive(Debug, Error, Diagnostic)] - Each variant has
#[diagnostic(code(...), help(...))]with actionable guidance - Subsystem errors chain via
#[error(transparent)] #[diagnostic(transparent)] - Return
IpsResult<T>(alias forResult<T, IpsError>) from the top-level API - Subsystem functions return their own result type (e.g.,
RepositoryResult<T>,ImageResult<T>,FmriResult<T>) - Each module defines:
pub type Result<T> = std::result::Result<T, ModuleError>; - Diagnostic codes follow the pattern
ips::module::variant(e.g.,ips::image_error::io)
Rust Style
- Use strongly typed idiomatic Rust — express logic in datatypes
- Do error handling — express options for how to handle issues for calling functions
- Use miette's diagnostic pattern to inform the user thoroughly what they need to do
- Never use raw SQL — use rusqlite with proper abstractions
- Edition 2024
Architecture
libips (core library)
fmri.rs— FMRI parsing (pkg://publisher/name@version)actions/— Manifest action types (File, Dir, Link, User, Group, etc.) and filesystem executorsimage/— Image metadata, catalog queries, installed packages DB (SQLite)repository/—ReadableRepository/WritableRepositorytraits, FileBackend (local), RestBackend (HTTP)solver/— Dependency resolution via resolvodigest/— SHA1/SHA2/SHA3 hashingpayload/— Package payload handlingpublisher.rs— Publisher configurationtransformer.rs— Manifest transformation/lintingdepend/— Dependency generation and parsing
Key Types
Fmri— Fault Management Resource Identifier (pkg://publisher/name@release,branch-build:timestamp)Manifest— Collection of actions describing a packageImage— Full or Partial image with metadata, publishers, catalogsFileBackend/RestBackend— Repository implementations
pkg5 Legacy Documentation and Compatibility
We carry the original pkg5 reference documentation in doc/pkg5_docs/ to guide compatibility with the legacy Python client. Our own docs in doc/ describe how we've implemented the compatibility layer.
Reference Specifications (from pkg5)
| Topic | File | What it covers |
|---|---|---|
| Depot protocol | depot.txt, depot.rst |
HTTP REST API: /file/0/{hash}, /catalog/0/, /manifest/0/{fmri}, /search/0/, /p5i/0/, /publisher/0/, /versions/0/ |
| Retrieval protocol | guide-retrieval-protocol.rst |
Client-depot wire protocol, ETag/If-Modified-Since caching, content negotiation |
| Publication protocol | guide-publication-protocol.rst |
Transaction-based publishing (open, add, close) |
| Repository format | guide-repository-format.rst |
On-disk layout: pkg/, file/ (two-level hash dirs), catalog/, trans/, updatelog/ |
| Catalog v1 | catalog-v1.txt, catalog.txt |
Delta-encoded text catalog with catalog.attrs, npkgs, incremental updates |
| Actions | actions.txt, actions.rst |
All 12 action types: file, dir, link, hardlink, depend, service, user, group, driver, license, legacy, set |
| FMRI & versioning | versions.txt, dev-guide chpt3.txt |
pkg://publisher/name@release,branch-build:timestamp, component ordering |
| Image types | image.txt, image.rst |
Full, Zone, User images and their metadata layout |
| Server API versions | server_api_versions.txt, client_api_versions.txt |
Protocol version negotiation between client and depot |
| Signed manifests | signed_manifests.txt |
Manifest signature format and verification |
| Linked images | linked-images.txt, parallel-linked-images.txt |
Zone/parent-child image constraints |
| Facets & variants | facets.txt |
Conditional action delivery (variant.arch, facet.doc) |
| Mediated links | mediated-links.txt |
Conflict resolution for symlinks across packages |
| On-disk format | on-disk-format.txt |
Container format proposal for packages |
| Dev guide | dev-guide/chpt1-14.txt |
Full IPS developer guide chapters |
Our Compatibility Implementation
| Feature | Our doc | Implementation |
|---|---|---|
| p5i publisher files | doc/pub_p5i_implementation.md |
FileBackend generates pub.p5i JSON files per publisher for backward compat with pkg set-publisher -p |
| Obsoleted packages | doc/obsoleted_packages.md |
Detects pkg.obsolete=true during pkg5 import; stores in <repo>/obsoleted/ with structured metadata |
| pkg5 import | pkg6repo/src/pkg5_import.rs |
Reads pkg5.repository, two-level hash dirs, gzip payloads, URL-encoded versions; converts to pkg6 format |
| Depot REST API | pkg6depotd/src/http/ |
Serves same HTTP paths as pkg5 depot (/file/0/, /manifest/0/, /catalog/0/, /publisher/0/) |
| libips integration | doc/forge_docs/ips_integration.md |
Typed API replacing pkg5 CLI tools (pkgsend, pkgmogrify, pkgdepend, pkglint, pkgrepo) |
| Error handling | doc/rust_docs/error_handling.md |
miette + thiserror patterns with ips::module::variant codes |
Key Compatibility Surfaces for Legacy Client
The legacy pkg(1) Python client expects these from a depot server:
/versions/0/— lists supported operations and protocol versions/publisher/0/— returnsapplication/vnd.pkg5.info(p5i JSON)/catalog/0/— catalog withLast-Modifiedheader, incremental updates/manifest/0/{fmri}—text/plainmanifest withETag/file/0/{hash}— gzip-compressed file content withETagandCache-Control/search/0/{token}— search returningindex action value packagetuples
Documentation Maintenance
- Keep
docs/ai/architecture.mdupdated when making structural changes. Bump the "last updated" date. - Create a new timestamped plan in
docs/ai/plans/before starting a new phase or significant feature. - Create a new timestamped ADR in
docs/ai/decisions/when making meaningful technology or design choices. Number sequentially from the last ADR. - Never delete old plans or decisions. Mark superseded plans with status
Supersededand link to the replacement.