{"id":26009223,"url":"https://github.com/ocicl/ocicl","last_synced_at":"2026-04-18T23:11:34.173Z","repository":{"id":166061415,"uuid":"641453246","full_name":"ocicl/ocicl","owner":"ocicl","description":"An OCI-based ASDF system distribution and management tool for Common Lisp","archived":false,"fork":false,"pushed_at":"2026-02-07T10:10:54.000Z","size":121925,"stargazers_count":272,"open_issues_count":24,"forks_count":24,"subscribers_count":17,"default_branch":"main","last_synced_at":"2026-02-07T19:11:08.356Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ocicl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2023-05-16T13:54:33.000Z","updated_at":"2026-02-07T10:10:56.000Z","dependencies_parsed_at":"2023-11-17T14:06:41.172Z","dependency_job_id":"32a79ba2-4d38-4d5a-8d53-f6f797ec079c","html_url":"https://github.com/ocicl/ocicl","commit_stats":null,"previous_names":[],"tags_count":100,"template":false,"template_full_name":null,"purl":"pkg:github/ocicl/ocicl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocicl%2Focicl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocicl%2Focicl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocicl%2Focicl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocicl%2Focicl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ocicl","download_url":"https://codeload.github.com/ocicl/ocicl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ocicl%2Focicl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29481010,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-15T11:35:25.641Z","status":"ssl_error","status_checked_at":"2026-02-15T11:34:57.128Z","response_time":118,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-05T22:02:01.369Z","updated_at":"2026-04-18T23:11:34.127Z","avatar_url":"https://github.com/ocicl.png","language":"Common Lisp","funding_links":[],"categories":["REPLs ##","Offline ##","Dependency intelligence"],"sub_categories":[],"readme":"# ocicl\n\u003e A modern ASDF system distribution and management tool for Common Lisp\n\nNOTE: To request additions to the ``ocicl`` repo, create an Issue\n[here](https://github.com/ocicl/request-system-additions-here/issues/new?assignees=\u0026labels=\u0026projects=\u0026template=request.yml\u0026title=%5BSystem+Request%5D%3A+).\n\n## Table of Contents\n\n- [What is it?](#what-is-it)\n- [Installation](#installation)\n  - [Linux Packages](#linux-packages)\n  - [Homebrew](#homebrew)\n  - [MacPorts](#macports)\n  - [From Source](#from-source)\n- [Setup](#setup)\n- [Lisp Usage](#lisp-usage)\n- [Command Line Tool](#command-line-tool)\n  - [Installing Systems](#installing-systems)\n  - [Listing Available Versions](#listing-available-versions)\n  - [Updating Systems](#updating-systems)\n  - [Removing Systems](#removing-systems)\n  - [Comparing Versions](#comparing-versions)\n  - [Using an Alternate Registry](#using-an-alternate-registry)\n  - [Registry Authentication](#registry-authentication)\n- [ocicl Scope](#ocicl-scope)\n  - [Local (default)](#local-default)\n  - [Global (--global)](#global---global)\n  - [Local-Only Mode (OCICL_LOCAL_ONLY)](#local-only-mode-ocicl_local_only)\n  - [Custom Systems Directory (OCICL_SYSTEMS_DIR)](#custom-systems-directory-ocicl_systems_dir)\n- [Proxy Configuration](#proxy-configuration)\n- [TLS Verification](#tls-verification)\n  - [Advanced TLS Troubleshooting](#advanced-tls-troubleshooting)\n- [AI-Generated Change Summaries](#ai-generated-change-summaries)\n- [Code Linting](#code-linting)\n- [Dependency Freshness](#dependency-freshness)\n- [License Collection](#license-collection)\n- [SBOM Generation](#sbom-generation)\n- [Self-Updates](#self-updates)\n- [Security](#security)\n- [Self-Hosting](#self-hosting)\n- [Systems](#systems)\n- [Project Templates](#project-templates)\n- [Tips and Troubleshooting](#tips-and-troubleshooting)\n- [Author and License](#author-and-license)\n\nWhat is it?\n-----------\n``ocicl`` is a modern tool for Common Lisp development that provides:\n* **Package management**: A modern alternative to quicklisp for ASDF system distribution and management\n* **Code linting**: An integrated linter that checks your code for style issues, common errors, and best practices\n* **Project scaffolding**: Template-based project creation to quickly start new applications\n\nAs a package manager, ``ocicl`` is modern in the sense that:\n* All software is [packaged as OCI-compliant artifacts](https://github.com/opencontainers/) and distributed from mirrored OCI-compliant registries (the GitHub and Docker Hub Contain Registries).\n* All software packages are securely distributed over TLS connections.\n* All connections respect ``HTTPS_PROXY`` environment settings for authenticated proxy support.\n* [sigstore](https://www.sigstore.dev/) is used to ensure the integrity and authenticity of all software packages.\n* Software packages are project-local by default, simplifying the process of tying specific versions to your projects.\n* All software packages are built and published transparently using hosted CI infrastructure ([github actions](https://github.com/ocicl/ocicl-action)).\n* LLM-generated summaries of changes between versions are available for all packages.\n\n``ocicl`` is pronounced like\n\"[ossicle](https://en.wikipedia.org/wiki/Ossicles)\", a tiny bone\nembedded in your middle ear.  Like the ossicles in your ear, the\n``ocicl-runtime`` is a tiny library that is embedded in your lisp\nimage.  It is responsible for finding and loading\n[ASDF](https://asdf.common-lisp.dev/) systems that you manage with the\n``ocicl`` command line tool.\n\nThe main innovation behind ``ocicl`` is the idea of applying the\necosystem of tooling and services from the world of application\ncontainer images to ordinary tarballs of Lisp code. In essence, OCI + CL = ``ocicl``.\n\n``ocicl`` is under active development.  The ``ocicl-runtime`` is known\nto work with the following Common Lisp implementations:\n- [abcl](https://abcl.org)\n- [ecl](https://gitlab.com/embeddable-common-lisp)\n- [SBCL](https://www.sbcl.org/)\n- [Allegro Common Lisp](https://franz.com/products/allegro-common-lisp/)\n\nHowever, the ``ocicl`` command-line tool currently must be built with\nSBCL on either Linux, Windows or MacOS.  Adapting to other systems and\nplatforms should not be difficult, and pull requests are welcome at\nhttps://github.com/ocicl/ocicl/pulls.  Feedback is also welcome at\nhttps://github.com/ocicl/ocicl/issues.\n\nInstallation\n------------\n\nYou can install `ocicl` using native Linux packages, [homebrew](https://brew.sh), or from source.\n\n### Linux Packages\n\nNative RPM and DEB packages are available for x86_64 systems.\n\n**Fedora/RHEL/CentOS (via dnf repo):**\n```bash\nsudo dnf config-manager addrepo --from-repofile=https://ocicl.github.io/ocicl/rpm-repo/ocicl.repo\nsudo dnf install ocicl\nocicl setup\n```\n\nThe RPM packages are GPG-signed. The signing key is imported automatically by dnf on first install.\n\n**Debian/Ubuntu (via apt repo):**\n```bash\ncurl -fsSL https://ocicl.github.io/ocicl/deb-repo/ocicl-archive-keyring.gpg | sudo tee /usr/share/keyrings/ocicl-archive-keyring.asc \u003e /dev/null\necho \"deb [signed-by=/usr/share/keyrings/ocicl-archive-keyring.asc] https://ocicl.github.io/ocicl/deb-repo stable main\" | sudo tee /etc/apt/sources.list.d/ocicl.list\nsudo apt update\nsudo apt install ocicl\nocicl setup\n```\n\nThe DEB packages are GPG-signed. The signing key is imported in the first step above.\n\n### Homebrew\n\nFor [homebrew](https://brew.sh) on Linux, Windows WSL, or macOS,\ninstall and configure `ocicl` as follows:\n```\ngreen@fedora:~$ brew install ocicl\n==\u003e Downloading https://ghcr.io/v2/homebrew/core/ocicl/manifests/2.3.4\n########################################################################################################################################## 100.0%\n==\u003e Fetching ocicl\n==\u003e Downloading https://ghcr.io/v2/homebrew/core/ocicl/blobs/sha256:fe9b2d51c012851588baef450ff39b453526a7fc2c5df38e9071fc253b136150\n########################################################################################################################################## 100.0%\n==\u003e Pouring ocicl--2.3.4.x86_64_linux.bottle.tar.gz\n🍺  /home/linuxbrew/.linuxbrew/Cellar/ocicl/2.3.4: 8 files, 36.4MB\n==\u003e Running `brew cleanup ocicl`...\ngreen@fedora:~$ ocicl setup\n;; Add the following to your lisp startup file\n;; (~/.sbclrc, ~/.eclrc, ~/.abclrc or ~/.roswell/init.lisp):\n\n#-ocicl\n(when (probe-file #P\"/home/green/.local/share/ocicl/ocicl-runtime.lisp\")\n  (load #P\"/home/green/.local/share/ocicl/ocicl-runtime.lisp\"))\n(asdf:initialize-source-registry\n  (list :source-registry (list :directory (uiop:getcwd)) :inherit-configuration))\n```\n### MacPorts\n\nFor [MacPorts](https://ports.macports.org/port/ocicl/) on macOS\ninstall and configure `ocicl` as follows:\n\n```\n$ sudo port install ocicl\n---\u003e  Upgrading already installed dependencies of ocicl\n---\u003e  Computing dependencies for ocicl\n---\u003e  Fetching archive for ocicl\nAttempting to fetch https://fra.de.packages.macports.org/ocicl/ocicl-2.16.5_0.darwin_20.x86_64.tbz2\nAttempting to fetch https://fra.de.packages.macports.org/ocicl/ocicl-2.16.5_0.darwin_20.x86_64.tbz2.rmd160\n---\u003e  Installing ocicl @2.16.5_0\n---\u003e  Activating ocicl @2.16.5_0\n---\u003e  Cleaning ocicl\n---\u003e  Scanning binaries for linking errors\n---\u003e  No broken files found.\n---\u003e  No broken ports found.\n---\u003e  Some of the ports you installed have notes:\n  ocicl has the following notes:\n    After installation run 'ocicl setup' to install the ocicl-runtime library:\n        $ ocicl setup\n        ;; Add the following to your lisp startup file\n        ;; (~/.sbclrc, ~/.eclrc, ~/.abclrc or ~/.roswell/init.lisp):\n\n        #-ocicl\n        (when (probe-file #P\"/home/green/.local/share/ocicl/ocicl-runtime.lisp\")\n        (load #P\"/home/green/.local/share/ocicl/ocicl-runtime.lisp\"))\n        (asdf:initialize-source-registry\n         (list :source-registry (list :directory (uiop:getcwd)) :inherit-configuration))\n```\n\n### From Source\n\nTo install from source, run ``sbcl --load setup.lisp`` in the source\ndirectory.  This will build and install the ``ocicl`` binary in\n``~/.local/bin`` on non-Windows systems, and\n``%UserProfile%\\AppData\\Local\\ocicl\\`` on Windows.\n\nThe `setup.lisp` script will build an `ocicl` binary with 3072MB of\ndynamic memory space.  If you need a different amount, run it like so:\n```\nsbcl --eval \"(defconstant +dynamic-space-size+ 2048)\" --load setup.lisp\n```\n\n#### TLS Library Selection\n\nBy default, `ocicl` is built with [pure-tls](https://github.com/atgreen/pure-tls),\na pure Common Lisp TLS 1.3 implementation with no external dependencies.\n\nTo build with OpenSSL (via cl+ssl) instead, set the `USE_LEGACY_OPENSSL`\nenvironment variable:\n```\nUSE_LEGACY_OPENSSL=1 sbcl --load setup.lisp\n```\n\nThis may be useful if you need TLS 1.2 support for older servers, or prefer\nOpenSSL for other reasons. Note that this requires OpenSSL libraries to be\ninstalled on your system.\n\nSetup\n-----\n\nRun ``ocicl setup``.  This is a mandatory step that installs the\n``ocicl-runtime`` library, and suggests configurations for your\nlisp startup file.\n\n```\n$ ocicl setup\n;; Add the following to your lisp startup file\n;; (~/.sbclrc, ~/.eclrc, ~/.abclrc or ~/.roswell/init.lisp):\n\n#-ocicl\n(when (probe-file #P\"/home/green/.local/share/ocicl/ocicl-runtime.lisp\")\n  (load #P\"/home/green/.local/share/ocicl/ocicl-runtime.lisp\"))\n(asdf:initialize-source-registry\n  (list :source-registry (list :directory (uiop:getcwd)) :inherit-configuration))\n```\n\nThe default behavior for the runtime is to invoke ``ocicl`` when ASDF\ntries to load a system that it can't find.\n\nIf you are running behind a proxy, be sure to set your ``https_proxy``\nenvironment variable appropriately.  For instance, the following could\nbe used for an authenticating proxy:\n```\n$ export https_proxy=https://username:password@myproxyhost:8080\n```\n\nLisp Usage\n----------\n\nTry loading a system:\n\n```\n$ sbcl --eval \"(asdf:load-system :str)\"\n```\n\nLook at your current directory.  You should see a directory called\n``ocicl`` and a file called ``ocicl.csv``.  The ``ocicl``\ndirectory contains the code you just downloaded, and ``ocicl.csv``\ncontains a mapping of system names to OCI artifacts and ``.asd``\nfiles.\n\n```\nstr, ghcr.io/ocicl/str@sha256:..., cl-str-20230511-b1c8380/str.asd\ncl-ppcre, ghcr.io/ocicl/cl-ppcre@sha256:..., cl-ppcre-20230511-b4056c5a/cl-ppcre.asd\n...\n```\n\nThe next time you try to load ``str``, ASDF will load the code that\nyou've already downloaded and compiled.\n\nNow try deleting the ``ocicl`` directory, and loading ``str`` again\nas above.  ``ocicl`` will download the exact version specified in the\n``ocicl.csv`` file.  The idea here is that you would commit your\n``ocicl.csv`` file to your project's source repo, but never the\n``ocicl`` directory.  When you run your program, you will always be\nusing the library versions locked in your ``ocicl.csv`` file.\n\nTo get a list of all of the systems already downloaded (both locally\nand globally), call `(ocicl-runtime:system-list)`.\n\nProxy Configuration\n-------------------\n\n`ocicl` and its HTTP client respect common proxy environment variables.\n\n- Supported: `HTTPS_PROXY`, `https_proxy`, `HTTP_PROXY`, `http_proxy`\n- Format options:\n  - `http[s]://user:pass@host[:port]`\n  - `host[:port]` (scheme assumed http)\n  - `user:pass@host[:port]`\n- Bypass list: `NO_PROXY`/`no_proxy` as a comma-separated list of hosts/domains\n  - Example: `export NO_PROXY=localhost,127.0.0.1,.example.com`\n- Authentication: sends HTTP Basic credentials via `Proxy-Authorization`.\n- Precedence: first non-empty variable in the order above is used.\n\nSecurity note: Environment variables can be visible to other processes/users on the\nsystem. Prefer short-lived shells and avoid committing credentials into scripts.\n\nTLS Verification\n----------------\n\n- Verification: Enabled by default (server certificates are verified).\n- Insecure mode: Use `-k` or `--insecure` to skip certificate verification (similar to `curl -k`).\n  - Alternatively, set `OCICL_INSECURE=1` in the environment.\n- Custom CA paths:\n  - `OCICL_CA_FILE`: path to a PEM bundle file\n  - `OCICL_CA_DIR`: path to a directory containing CA files\n- Connection timeout:\n  - `OCICL_HTTP_TIMEOUT`: connection timeout in seconds for HTTP requests\n\nTroubleshooting\n- CA not trusted: set `OCICL_CA_FILE`/`OCICL_CA_DIR` to include your organization's CA bundle (common on corporate proxies), or temporarily use `-k` for testing.\n- Hostname mismatch: verify the registry host (`--registry`) and proxy settings (`HTTPS_PROXY`/`HTTP_PROXY`/`NO_PROXY`).\n- Self-signed certificate: provide the signing CA via `OCICL_CA_FILE`/`OCICL_CA_DIR`, or use `-k` for testing only.\n- Expired/not yet valid: check your system clock and the server's certificate validity.\n- Timeouts: check network/proxy reachability and consider increasing `OCICL_HTTP_TIMEOUT`.\n\nDisabling verification reduces security and should be used only for testing on trusted networks.\n\n### Advanced TLS Troubleshooting\n\nIf you're experiencing TLS connection failures (especially with the default pure-tls backend), try these steps:\n\n**1. Enable TLS debugging:**\n```bash\nexport OCICL_TLS_DEBUG=1\nocicl install \u003cpackage\u003e\n```\n\nThis will show:\n- Which TLS implementation is in use (pure-tls or cl+ssl)\n- Which CA certificate file/directory is being used\n- Number of CA certificates loaded\n\n**2. Verify CA certificates are installed:**\n\nThe default pure-tls backend requires system CA certificates to be installed:\n\n- **Fedora/RHEL:** `sudo dnf install ca-certificates`\n- **Debian/Ubuntu:** `sudo apt-get install ca-certificates`\n- **macOS:** Certificates should be installed by default\n\nExpected CA bundle locations by platform:\n- Fedora/RHEL 9+: `/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem`\n- Debian/Ubuntu: `/etc/ssl/certs/ca-certificates.crt`\n- RHEL/CentOS (older): `/etc/pki/tls/certs/ca-bundle.crt`\n- macOS: `/etc/ssl/cert.pem`\n\n**3. Manually specify CA location:**\n\nIf CA certificates are in a non-standard location:\n```bash\nexport OCICL_CA_FILE=/path/to/ca-bundle.pem\n# or\nexport OCICL_CA_DIR=/path/to/ca/directory\n```\n\n**4. Use the legacy OpenSSL backend:**\n\nIf pure-tls continues to have issues, rebuild ocicl with the cl+ssl backend:\n```bash\nUSE_LEGACY_OPENSSL=1 sbcl --load setup.lisp\n```\n\n**Common error messages and solutions:**\n\n| Error | Cause | Solution |\n|-------|-------|----------|\n| \"Could not find system CA certificates\" | CA certificates package not installed | Install ca-certificates package |\n| \"TLS verification failed: certificate not trusted\" | Empty or missing trust store | Verify CA certificates exist, set `OCICL_CA_FILE`, or install ca-certificates |\n| Silent installation failures | TLS error not being reported | Enable `OCICL_TLS_DEBUG=1` to see actual error |\n| \"Certificate chain not anchored\" | Trust store not loaded (pure-tls) | Install ca-certificates or rebuild with `USE_LEGACY_OPENSSL=1` |\n\nCommand Line Tool\n-----------------\n\nThe ``ocicl`` command line tool provides commands for managing systems.\n\n```\nocicl 2.14.3-gfe4beec+dirty - copyright (C) 2023-2026 Anthony Green \u003cgreen@moxielogic.com\u003e\n\nUsage: ocicl [-h|--help] [-v|--verbose] [-f|--force] [-g|--global]\n             [-r|--registry REGISTRY] [-c|--color WHEN] [-k|--insecure] command\n\nAvailable options:\n  -h, --help              show this help text\n  -v, --verbose           produce verbose output\n  -f, --force             force action\n  -g, --global            operate on the global system collection\n  -r, --registry REGISTRY use alternate oci registry [Default: ghcr.io/ocicl]\n  -c, --color WHEN        color the output WHEN (auto, always, or never)\n  -k, --insecure          allow insecure TLS (skip certificate verification)\n\nChoose from the following ocicl commands:\n\n   help                                   Print this help text\n   changes [SYSTEM[:VERSION]]...          Display changes\n   clean                                  Remove system directories not listed in ocicl.csv\n   collect-licenses                       Collect licenses from vendored dependencies\n   create-sbom [FORMAT] [OUTPUT]          Create SBOM (cyclonedx/spdx, default: cyclonedx)\n   diff SYSTEM                            Diff between the installed and latest versions\n   diff SYSTEM VERSION                    Diff between the installed version and VERSION\n   diff SYSTEM VERSION1 VERSION2          Diff between files in different system versions\n   install [SYSTEM[:VERSION]]...          Install systems\n   latest [SYSTEM]...                     Install latest version of systems\n   libyear                                Calculate the libyear dependency freshness metric\n   lint [OPTIONS] PATH...                 Lint Common Lisp files\n   list SYSTEM...                         List available system versions\n   new APP-NAME [TEMPLATE] [KEY=VALUE]... Create a new app\n   remove [SYSTEM]...                     Remove systems\n   setup [GLOBALDIR]                      Mandatory ocicl configuration\n   templates [list]                       List available templates\n   templates dirs                         Show template search path\n   tree [OPTIONS] [SYSTEM]...             Print tree of installed systems\n   update [OPTIONS]                       Update ocicl from GitHub releases\n   version                                Show the ocicl version information\n\nUse 'ocicl COMMAND --help' for command-specific options.\n\nDistributed under the terms of the MIT License\n```\n\n### Installing Systems\n\nRunning ``ocicl install`` will download all of the systems specified in your\n``ocicl.csv`` file.\n\n```\n$ ocicl install\n; downloading ghcr.io/ocicl/str@sha256:...\n; downloading ghcr.io/ocicl/cl-ppcre@sha256:...\n...\n```\n\nYou can download additional systems like so:\n```\n$ ocicl install trivial-garbage\n; downloaded ghcr.io/ocicl/trivial-garbage@sha256:...\n```\n\nThis downloads the latest version of trivial-garbage, which is the OCI\nimage with the ``latest`` tag, and is equivalent to ``ocicl install\ntrivial-garbage:latest``.\n\nTo install any specific version of a system, just use the appropriate\nversion label in your ``ocicl install`` command.  For example:\n``ocicl install trivial-garbage:20230511-b3af9c0`` or\n``ocicl install str:latest``.\n\nRunning ``ocicl install SYSTEM`` with no version will do nothing\nif any version of ``SYSTEM`` is already installed (unless\n``--force`` is specified).  However, if a system version is specified\n(including ``latest``) then ``ocicl install`` will always download and\ninstall the system, even if it already exists on disk.\n\n### Listing Available Versions\n\nTo see what versions of a package are available, run ``ocicl list``:\n```\n$ ocicl list trivial-garbage\ntrivial-garbage:\n latest\n 20230511-b3af9c0\n```\n\nHere we only have one version, 20230511-b3af9c0, which also has the\n``latest`` tag.  Many lisp libraries are built from git sources\nwithout release tags.  In this case, the version label represents the\nbuild date and the git commit hash (b3af9c0).\n\n### Updating Systems\n\nTo update all systems in your ``ocicl.csv`` file to the latest\nversion, run ``ocicl latest``.\n\n### Removing Systems\n\nTo remove an installed system, use ``ocicl remove``.  By default,\n``ocicl`` will refuse to remove systems that are required to satisfy any\ndependencies.  Use the ``ocicl --force remove`` option to ignore any\ndependencies and always uninstall.\n\n### Comparing Versions\n\nTo compare differences between system versions, run `ocicl diff SYSTEM VERSION1\nVERSION2`.\n\n### Using an Alternate Registry\n\nTo use an alternate OCI registry for any operation, use the\n``--registry`` option.  Using ``--registry`` with the ``setup``\ncommand will persist this registry choice for all future ``ocicl``\ninvocations.  Subsequent uses of ``setup`` will preserve existing\nregistry choices unless the ``--force`` option used.\n\nWhile the `ocicl` cli tool only supports setting a single alternate\nregistry, it's possible to use multiple registries by adding multiple\nentries to the `ocicl-registry.cfg` file in your `${XDG_DATA_DIR}/ocicl`\ndirectory.\n\n### Registry Authentication\n\nTo pull from private or authenticated registries, create a credentials\nfile at `${XDG_DATA_HOME}/ocicl/ocicl-credentials.cfg` (typically\n`~/.local/share/ocicl/ocicl-credentials.cfg`).\n\nEach line contains a server, login, and password separated by whitespace.\nLines starting with `#` are comments.\n\n```\n# Private registry credentials\nregistry.example.com myuser mytoken\ngitlab.company.com deploy-token abc123\n```\n\nWhen credentials are configured for a registry server, `ocicl` will:\n\n1. Authenticate to the registry's token endpoint (Bearer token flow).\n2. If no token endpoint is available, fall back to HTTP Basic\n   authentication directly.\n\nThis works with any OCI-compliant registry that supports Basic\nauthentication, including GitHub Container Registry, GitLab Container\nRegistry, and self-hosted registries.\n\nocicl Scope\n-----------\n\n### Local (default)\n\nAll system downloads are recorded in the current working directory by default.\nHowever, when `ocicl.csv` appears in any parent directory, all\nsystems are downloaded and recorded in the `ocicl` sub-directory of\nthat parent.  The ocicl runtime mirrors this behaviour when it comes\nto loading systems.  See the following for example usage.\n\n```\ngreen@fedora:~/hacking$ touch ocicl.csv\ngreen@fedora:~/hacking$ mkdir project-1\ngreen@fedora:~/hacking$ mkdir project-2\ngreen@fedora:~/hacking$ cd project-1\ngreen@fedora:~/hacking/project-1$ ocicl install str\n; downloaded str@sha256:3771c466d33a923d4fd1b1aa71f7a60d0029405e7fb3bafae1a3f19b7ac9b121\n; downloaded cl-ppcre@sha256:584907e0683621973579f397115945ef73e9d5b7afa77fae7cacecb3ad272f89\n; downloaded cl-unicode@sha256:d98f12c1271fb3c1812a27d64dfbe95b0bc5bcfd545b71b8101874e61270b120\n; downloaded cl-change-case@sha256:63b6a033f762d6dc5d365ce49f2a2c691677f2ec1375ebe4226d13b19a29dc7c\ngreen@fedora:~/hacking/project-1$ cd ../project-2/\ngreen@fedora:~/hacking/project-2$ ocicl install str\n; str:1bcf26d already exists\ngreen@fedora:~/hacking/project-2$ ls -l ../ocicl\ntotal 0\ndrwxr-xr-x. 1 green green 112 Oct 17 23:05 cl-change-case-0.2.1\ndrwxr-xr-x. 1 green green 642 Oct 17 23:05 cl-ppcre-20240503-80fb19d\ndrwxr-xr-x. 1 green green 216 Oct 17 23:05 cl-str-20240708-1bcf26d\ndrwxr-xr-x. 1 green green 344 Oct 17 23:05 cl-unicode-20240503-07e7ff5\n```\n\n### Global (--global)\n\nYou may also choose to download systems \"globally\" for the current\nuser by using the ``--global`` option.  This is equivalent to\ntemporarily changing directory to a user-global directory before\nperforming any operation with the `ocicl` cli.  These \"global\" systems\nare available at runtime using the following heuristic:\n- If the system is available locally, then it is loaded from from the local `ocicl` directory.\n- Else if the system is available in the global `ocicl` directory, it loaded from there.\n- Otherwise, if `ocicl-runtime:*download*` is non-nil, then the system is downloaded either locally or globally:\n    - if `ocicl-runtime:*force-global*` is non-nil, then the system is downloaded to the global `ocicl` directory.\n    - else if `ocicl-runtime:*force-global*` is nil (default), then the system is downloaded locally.\n\nTo change the default user-global directory, provide the\noptional ``GLOBALDIR`` argument when you invoke ``ocicl setup``.\n\nYou can change the default behaviour of downloading systems on demand\nby setting ``ocicl-runtime:*download*`` to nil.\n\n### Local-Only Mode (OCICL_LOCAL_ONLY)\n\nFor CI pipelines and reproducible builds, you may want to ensure that\n`ocicl` only uses systems from the current working directory, ignoring\nany `ocicl.csv` files in parent directories and any globally installed\nsystems.\n\nSet the `OCICL_LOCAL_ONLY` environment variable to enable this mode:\n\n```bash\nexport OCICL_LOCAL_ONLY=1\nocicl install\nsbcl --load my-app.lisp\n```\n\nOr inline:\n```bash\nOCICL_LOCAL_ONLY=1 ocicl install\n```\n\nWhen `OCICL_LOCAL_ONLY` is set:\n- The CLI tool only looks for `ocicl.csv` in the current directory (no parent directory traversal)\n- Global systems are not loaded or searched\n- The runtime behaves the same way, ensuring your Lisp code won't accidentally pick up systems from parent directories or global repos\n\nYou can also set it programmatically in Lisp before loading systems:\n```lisp\n(setf ocicl-runtime:*local-only* t)\n```\n\nThis is particularly useful for:\n- **CI/CD pipelines**: Ensures builds are isolated and reproducible\n- **Testing**: Prevents interference from development environments\n- **Containerized builds**: Guarantees only explicitly declared dependencies are used\n\n### Custom Systems Directory (OCICL_SYSTEMS_DIR)\n\nIf you want to store downloaded systems outside of your project\ndirectory, set the `OCICL_SYSTEMS_DIR` environment variable.  It acts\nas an overlay prefix: the project's absolute path is appended to it,\nso each project gets its own isolated storage.\n\n```bash\nexport OCICL_SYSTEMS_DIR=/data/ocicl\n```\n\nWith the example above, a project at `/home/user/.scripts/my-app/`\nwould store its systems in\n`/data/ocicl/home/user/.scripts/my-app/ocicl/` instead of\n`/home/user/.scripts/my-app/ocicl/`.\n\nThis is useful when you want to keep a project directory clean (e.g.\nfor syncing with tools like Syncthing) while still using\nproject-specific dependencies.  The `ocicl.csv` file remains in the\nproject directory; only the downloaded systems are redirected.\n\nAI-Generated Change Summaries\n-----------------------------\n\nThe `ocicl` tool can provide summaries of changes between versions of\nLisp systems.  These summaries are produced by an LLM, and are\ndesigned to describe key changes and user impacts for newer versions\nof systems you depend on.\n\n* `ocicl changes`: describes every change for every newer version of systems `ocicl` has installed\n* `ocicl -v changes`: same, but provides verbose reporting on progress\n* `ocicl changes cl-chat`: describes changes for every newer version of `cl-chat`\n* `ocicl changes omg:20240427-5b316a0`: describes changes for every version of `omg` newer than `20240427-5b316a0`.\n\nThese summaries are pre-generated by the `ocicl` maintenance system by\nfeeding source code diffs to an LLM and uploading the results to the\nOCI registry.\n\nIn some cases the description may be missing as they only started\nbeing generated as of May 2024.\n\nCode Linting\n------------\n\n`ocicl` includes an integrated Common Lisp linter that checks your code for style issues, common errors, and best practices. The linter supports linting individual files, entire directories, or ASDF system definitions.\n\n### Usage\n\n```bash\nocicl lint [--fix] [--dry-run] PATH...\n```\n\nWhere `PATH` can be:\n- **Individual files**: `ocicl lint myfile.lisp`\n- **Directories**: `ocicl lint src/` (recursively lints all `.lisp` files)\n- **ASDF systems**: `ocicl lint myproject.asd` (lints all components in the system definition)\n\n### Options\n\n| Option | Description |\n|--------|-------------|\n| `--fix` | Automatically fix issues where possible |\n| `--dry-run` | Show what would be fixed without modifying files |\n\n### Auto-Fixable Rules\n\nThe following 49 rules can be automatically fixed with `--fix`:\n\n**Whitespace \u0026 Formatting:**\n| Rule | Transformation |\n|------|---------------|\n| `whitespace-after-open-paren` | Remove whitespace after `(` |\n| `whitespace-before-close-paren` | Remove whitespace before `)` |\n| `trailing-whitespace` | Remove trailing spaces/tabs |\n| `no-tabs` | Replace tabs with spaces |\n| `closing-parens-same-line` | Collapse `)))))` to one line |\n| `final-newline` | Add newline at end of file |\n| `consecutive-blank-lines` | Remove extra blank lines |\n\n**Symbol \u0026 Quote Fixes:**\n| Rule | Transformation |\n|------|---------------|\n| `use-first-rest` | `CAR` → `FIRST`, `CDR` → `REST` |\n| `use-eql` | `EQ` → `EQL` for numbers/chars |\n| `setf-vs-setq` | `SETQ` → `SETF` |\n| `quoted-nil` | `'NIL` → `NIL` |\n| `quote-keyword` | `':foo` → `:foo` |\n| `quote-number` | `'42` → `42` |\n| `quote-true` | `'TRUE` → `T` |\n\n**List Operations:**\n| Rule | Transformation |\n|------|---------------|\n| `car-cdr` | `(CAR (CDR x))` → `(CADR x)` |\n| `cdr-cdr` | `(CDR (CDR x))` → `(CDDR x)` |\n| `cons-with-nil` | `(CONS x NIL)` → `(LIST x)` |\n| `cons-list` | `(CONS x (LIST ...))` → `(LIST x ...)` |\n| `cons-cons-acons` | `(CONS (CONS k v) alist)` → `(ACONS k v alist)` |\n| `append-single` | `(APPEND x NIL)` → `(COPY-LIST x)` |\n| `append-list-list` | `(APPEND (LIST x) y)` → `(CONS x y)` |\n| `rplaca` | `(RPLACA x y)` → `(SETF (CAR x) y)` |\n| `rplacd` | `(RPLACD x y)` → `(SETF (CDR x) y)` |\n\n**Logic Simplification:**\n| Rule | Transformation |\n|------|---------------|\n| `not-null` | `(NOT (NULL x))` → `x` |\n| `not-consp` | `(NOT (CONSP x))` → `(ATOM x)` |\n| `equal-with-nil` | `(EQUAL x NIL)` → `(NULL x)` |\n| `needless-and` | `(AND x)` → `x` |\n| `needless-or` | `(OR x)` → `x` |\n| `needless-and-t` | `(AND ... T)` → `(AND ...)` |\n| `needless-or-nil` | `(OR ... NIL)` → `(OR ...)` |\n\n**Conditionals:**\n| Rule | Transformation |\n|------|---------------|\n| `when-for-unless` | `(WHEN (NOT x) ...)` → `(UNLESS x ...)` |\n| `unless-for-when` | `(UNLESS (NOT x) ...)` → `(WHEN x ...)` |\n| `if-for-not` | `(IF test NIL T)` → `(NOT test)` |\n| `if-no-else` | `(IF test then)` → `(WHEN test then)` |\n| `if-or` | `(IF test T else)` → `(OR test else)` |\n| `cond-vs-if` | `(COND (test then))` → `(WHEN test then)` |\n| `progn-in-when` | `(WHEN x (PROGN ...))` → `(WHEN x ...)` |\n| `progn-in-if` | `(IF x (PROGN ...))` → `(WHEN x ...)` |\n| `redundant-progn` | `(PROGN form)` → `form` |\n\n**Arithmetic:**\n| Rule | Transformation |\n|------|---------------|\n| `plus-one` | `(+ x 1)` → `(1+ x)` |\n| `minus-one` | `(- x 1)` → `(1- x)` |\n| `use-zerop` | `(= x 0)` → `(ZEROP x)` |\n| `add-zero` | `(+ x 0)` → `x` |\n| `setf-incf` | `(SETF x (+ x n))` → `(INCF x n)` |\n| `setf-decf` | `(SETF x (- x n))` → `(DECF x n)` |\n| `setq-incf` | `(SETQ x (+ x n))` → `(INCF x n)` |\n\n**Functions:**\n| Rule | Transformation |\n|------|---------------|\n| `use-identity` | `(LAMBDA (X) X)` → `#'IDENTITY` |\n| `use-constantly` | `(LAMBDA (...) val)` → `(CONSTANTLY val)` |\n| `needless-shiftf` | `(SHIFTF a b)` → `(SETF a b)` |\n\n### Features\n\n- Comprehensive style checking based on Common Lisp best practices\n- Detects common errors and anti-patterns\n- **Auto-fix support** for many common issues\n- Configurable rules via `.ocicl-lint.conf` file\n- Colorized output (respects `--color` flag)\n- Zero configuration required for basic usage\n\n### Configuration\n\nCreate a `.ocicl-lint.conf` file in your project root to customize linting behavior:\n\n```ini\n# .ocicl-lint.conf\n# Maximum line length (default: 120)\nmax-line-length = 100\n\n# Rules to suppress globally (comma-separated)\nsuppress-rules = eval-usage, trailing-whitespace\n\n# Library suggestions (opt-in, comma-separated)\n# Suggests utility functions from popular Common Lisp libraries\n# Available: alexandria, uiop, serapeum\nsuggest-libraries = alexandria, uiop, serapeum\n\n# You can also use line-specific suppression with comments:\n# ; lint:suppress rule-name\n# ; lint:suppress  (suppress all rules on this line)\n```\n\n#### Library Suggestions\n\nThe linter can suggest utility functions from popular Common Lisp libraries when it detects common patterns. This feature is **opt-in** and disabled by default. To enable it, add the libraries to your `.ocicl-lint.conf`:\n\n```ini\nsuggest-libraries = alexandria, uiop, serapeum\n```\n\nSupported libraries:\n- **Alexandria**: Comprehensive utility library with functions like `when-let`, `if-let`, `ensure-list`, `mappend`, `emptyp`, etc.\n- **UIOP**: Part of ASDF, always available. Suggests functions like `file-exists-p` and `read-file-string`.\n- **Serapeum**: Extended utilities including `nor`, `nand`, `filter-map`, `car-safe`, `append1`, etc.\n\nExamples of suggestions:\n- `(let ((x ...)) (when x ...))` → Suggests `ALEXANDRIA:WHEN-LET`\n- `(apply #'append (mapcar ...))` → Suggests `ALEXANDRIA:MAPPEND` or `SERAPEUM:FILTER-MAP`\n- `(not (or a b c))` → Suggests `SERAPEUM:NOR`\n- `(probe-file path)` → Suggests `UIOP:FILE-EXISTS-P`\n\nTo disable all library suggestions, use:\n```ini\nsuggest-libraries =\n```\n\n### Example Output\n\n```bash\n$ ocicl lint src/main.lisp\nsrc/main.lisp:42:10: unused-parameter: Parameter FOO is unused\nsrc/main.lisp:55:121: max-line-length: Line exceeds 120 characters\nsrc/main.lisp:67:1: naming-underscore: Use hyphens instead of underscores in symbol names\n\nScanned 1 file(s), found 3 issue(s).\n```\n\nThe linter returns exit code 0 if no issues are found, or 1 if issues are detected.\n\n### Git Pre-Commit Hook\n\nTo automatically lint your code before commits, create a `.git/hooks/pre-commit` file in your project:\n\n```bash\n#!/bin/bash\n# Lint staged .lisp and .asd files before commit\n\n# Get list of staged .lisp and .asd files\nSTAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\\.(lisp|asd)$')\n\nif [ -n \"$STAGED_FILES\" ]; then\n    echo \"Running ocicl lint on staged files...\"\n    ocicl lint $STAGED_FILES\n    LINT_EXIT=$?\n\n    if [ $LINT_EXIT -ne 0 ]; then\n        echo \"Linting failed. Please fix the issues before committing.\"\n        echo \"To bypass this hook, use: git commit --no-verify\"\n        exit 1\n    fi\nfi\n\nexit 0\n```\n\nMake it executable:\n```bash\nchmod +x .git/hooks/pre-commit\n```\n\nThis will prevent commits if linting issues are found. You can bypass the hook with `git commit --no-verify` if needed.\n\nDependency Freshness\n--------------------\n\n`ocicl` can compute the [libyear](https://libyear.com) dependency\nfreshness metric for the projects on which you depend.  It is a single\nnumber telling you how up-to-date your dependencies are.  The libyear\nvalue for a single project indicates the time between your version and\nthe most recent version.\n\n```\n$ ocicl libyear\nOMGlib              0.02 libyears (6.01 days)\ncl-opengl           0.02 libyears (7.01 days)\nlqn                 0.01 libyears (1.00 days)\nopenapi-generator   0.01 libyears (1.00 days)\ntrivial-arguments   0.01 libyears (3.01 days)\ngraven-image        0.01 libyears (2.01 days)\ncl-oju              0.02 libyears (4.01 days)\npy4cl2-cffi         0.02 libyears (6.01 days)\n\nTOTAL libyears: 0.09 (30.06 days)\n```\n\nLicense Collection\n------------------\n\nThe `ocicl collect-licenses` command collects license information from all vendored dependencies in your project's `ocicl/` (or `systems/`) directory.\n\n### Usage\n\n```bash\nocicl collect-licenses\n```\n\nThe command outputs a comprehensive license report to stdout, including:\n- **Table of contents**: Lists all dependencies with their license sources\n- **Full license text**: Complete license information for each dependency\n- **Source attribution**: Shows which file provided the license (LICENSE file, README, .asd file, etc.)\n- **OCI URLs**: Container registry URLs for each vendored system\n- **Missing systems**: Lists any systems without detectable license information\n\n### License Detection\n\nThe command uses intelligent heuristics to find license information from multiple sources, checking in priority order:\n\n1. **Dedicated license files**: `LICENSE*`, `LICENCE*`, `COPYING*`, `COPYRIGHT*`\n2. **README sections**: Markdown or underline-style license headers\n3. **.asd file comments**: Header comments in ASDF system definitions\n4. **.asd :license field**: The `:license` field from system definitions\n5. **Source file footers**: Last ~50 lines of main source files\n\nIn testing on a project with 78 vendored dependencies, this approach successfully found licenses for 77 systems (98.7% success rate).\n\n### Example Output\n\n```bash\n$ ocicl collect-licenses \u003e LICENSES.txt\n```\n\nThe output includes a structured report like:\n\n```\n================================================================================\nVENDORED DEPENDENCY LICENSES\n================================================================================\n\nTable of Contents:\n\n   1. alexandria (LICENSE)\n   2. cl-ppcre (LICENSE)\n   3. str (README.md)\n   ...\n\n================================================================================\n\n1. alexandria\n   Source: LICENSE\n   OCI: ghcr.io/ocicl/alexandria@sha256:...\n================================================================================\n\n[Full license text here]\n...\n```\n\nSBOM Generation\n---------------\n\nThe `ocicl create-sbom` command generates Software Bill of Materials (SBOM) documents for your project, cataloging all vendored dependencies.\n\n### Usage\n\n```bash\nocicl create-sbom [FORMAT] [OUTPUT]\n```\n\n**Arguments:**\n- `FORMAT`: Optional format specifier - `cyclonedx` (or `cdx`) or `spdx` (default: `cyclonedx`)\n- `OUTPUT`: Optional output file path (default: stdout)\n\n### Features\n\n- **CycloneDX format**: Industry-standard SBOM format (default)\n- **SPDX format**: Alternative SBOM standard for compliance\n- **Comprehensive cataloging**: Includes version, license, checksum, and OCI URL for each dependency\n- **License inference**: Automatically identifies SPDX license identifiers from license text\n- **Timestamped**: Includes generation timestamp and tool information\n\n### Examples\n\n```bash\n# Generate CycloneDX SBOM to stdout\nocicl create-sbom\n\n# Generate CycloneDX SBOM to file\nocicl create-sbom cyclonedx sbom.json\n\n# Generate SPDX SBOM\nocicl create-sbom spdx sbom.spdx.json\n\n# Short format name\nocicl create-sbom cdx my-sbom.json\n```\n\n### SBOM Contents\n\nThe generated SBOM includes:\n- **Project metadata**: Name, timestamp, tool information\n- **Component list**: All vendored dependencies with:\n  - Package name and version\n  - SPDX license identifier\n  - MD5 checksum of .asd file\n  - OCI package URL (purl)\n  - Distribution URL (OCI registry)\n\n### Use Cases\n\n- **Compliance**: Meet regulatory requirements for software transparency\n- **Security**: Track dependencies for vulnerability management\n- **Supply chain**: Document your software supply chain\n- **Auditing**: Provide auditors with comprehensive dependency information\n\nSelf-Updates\n------------\n\nThe `ocicl update` command checks for new versions and updates the `ocicl` binary itself from GitHub releases.\n\n### Usage\n\n```bash\nocicl update [OPTIONS]\n```\n\n### Options\n\n| Option | Description |\n|--------|-------------|\n| `-c`, `--check` | Check for updates without downloading |\n| `-n`, `--dry-run` | Download but don't apply the update |\n| `-p`, `--prerelease`, `--pre` | Include prerelease versions |\n| `-h`, `--help` | Show update command help |\n\n### Examples\n\n```bash\n# Check for updates without installing\nocicl update --check\n\n# Update to the latest version\nocicl update\n\n# Include prerelease versions in update check\nocicl update --prerelease\n\n# Download but don't apply (for testing)\nocicl update --dry-run\n```\n\n### How It Works\n\nThe update command:\n1. Queries GitHub releases for the `ocicl/ocicl` repository\n2. Compares the latest release version with your installed version\n3. Downloads the appropriate binary for your platform (Linux, macOS, Windows)\n4. Validates the download (SHA256 checksum when available)\n5. Atomically replaces the current executable with a backup for rollback\n\nThe update is performed in-place with automatic rollback on failure, ensuring your installation is never left in a broken state.\n\nSecurity\n--------\n\nAll system tarballs have their sha256sum digest digitally signed with\nthe ocicl-tarball-signer key:\n[`B96ACDBF35C5C1AB81596FB6D3AFE1884397BDC8`](https://raw.githubusercontent.com/ocicl/ocicl/refs/heads/main/ocicl-tarball-signer-public-key.asc).\n\nYou can download the unexpanded tarballs using [skopeo](https://github.com/containers/skopeo) or [oras](https://oras.land/) like so:\n```\n$ oras pull ghcr.io/ocicl/str:latest\nDownloading 577fc7118b8a cl-str-20230511-b1c8380.tar.gz\nDownloaded  577fc7118b8a cl-str-20230511-b1c8380.tar.gz\nPulled [registry] ghcr.io/ocicl/str:latest\nDigest: sha256:0903b59c33d3026ac55a6f4b25a79094d08e3110758d8ae728bf4188db659313\n\n$ ls -l\ntotal 32\n-rw-r--r--. 1 green green 24609 May 19 09:02 cl-str-20230511-b1c8380.tar.gz\n```\n\nSimilarly, the signature is available by appending ``.sha256sum.sig`` to the system name.\n```\n$ oras pull ghcr.io/ocicl/str.sha256sum.sig:latest\nDownloading 2a97da913ef7 cl-str-20230511-b1c8380.tar.gz.sha256sum.sig\nDownloaded  2a97da913ef7 cl-str-20230511-b1c8380.tar.gz.sha256sum.sig\nPulled [registry] ghcr.io/ocicl/str.sig:latest\nDigest: sha256:47903679d96504c5e83f08f7d6dfc4e613e7ab968e44dc46cb13b29f7917ddea\n```\n\nYou can verify the signature like so:\n```\n$ sha256sum cl-str-20230511-b1c8380.tar.gz | gpg --verify cl-str-20230511-b1c8380.tar.gz.sha256sum.sig -\ngpg: Signature made Thu 11 May 2023 05:44:45 AM EDT\ngpg:                using RSA key B96ACDBF35C5C1AB81596FB6D3AFE1884397BDC8\ngpg: Good signature from \"ocicl-tarball-signer\" [ultimate]\n```\n\nThese signatures are also archived in the\n[sigstore](https://www.sigstore.dev) [rekor transparency\nlog](https://docs.sigstore.dev/logging/overview/).  This gives you and\nyour auditors confidence that the code you are running is what it\nclaims to be.\n\nYou can search for these signatures based on the sha of the sha of the tarball\nlike so:\n```\n$ rekor-cli search --sha $(sha256sum cl-str-20230511-b1c8380.tar.gz | sha256sum -)\nFound matching entries (listed by UUID):\n24296fb24b8ad77a6594635675d0e6365b89ee0d5e3b1ce823adb19c28aa3602c2537163710638d9\n\n$ rekor-cli get --uuid 24296fb24b8ad77a6594635675d0e6365b89ee0d5e3b1ce823adb19c28aa3602c2537163710638d9\nLogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\nIndex: 20300488\nIntegratedTime: 2023-05-11T09:44:49Z\nUUID: 24296fb24b8ad77a6594635675d0e6365b89ee0d5e3b1ce823adb19c28aa3602c2537163710638d9\nBody: {\n  \"RekordObj\": {\n    \"data\": {\n      \"hash\": {\n        \"algorithm\": \"sha256\",\n        \"value\": \"577fc7118b8a21285ad871dd44e4fe25126fd05d2d4fad52a4015d5a01788d44\"\n      }\n    },\n    \"signature\": {\n      \"content\": \"LS0tLS1CRUdJTiBQR1AgU0lHTkFUVVJFLS0tLS0KCmlRR3pCQUFCQ2dBZEZpRUV1V3JOdnpYRndhdUJXVysyMDYvaGlFT1h2Y2dGQW1SY3VRMEFDZ2tRMDYvaGlFT1gKdmNqcGh3d0FsSUJ6N3IrcnhZSml5dHhHZlFXMDJ6Z0tzQ1BKcC9RRXI1NUdIZjBQN3U0QlBod0ZmRlFRbWhRWQpsYndoclpjMEcvRFRXdm5vdzBOa0RTRXFBbVhtUjIyMzJOWDFEMVVBSEVRYWUzc3lhbld0aTd4ZEhLdXI3TE90CmsyRmFFMFl0VGt0a1RscDBzSGlxazliWHkzVVpqUHBFazBWZzZCaTM2QVUzVVFCMHFpc1dKQ2o4RGVLZnhSN1EKdkgvblo0MnJSMUNsTkRhdzBXQWc5eFR0WmNCSTRydEM4UXFIbWIzQ2N6elJ2WVM3T3V2VFRaM1h4NkNPQVFjUgpjVHNKa25qSGI4MXFQNFlBNDFiQ3l1L28xWGVCUmxIM1ZXVURyWHBoWEhETm1FcFFaTVFpWVBOYUl2Q1dOQ09lCkRqSFhLazk3NnFBcFVzVHBxcFRIdmgxUGNxSFpFeFdPRWQwSkxpR3BzZW9vODN4M1k0bTBDaXRBTDhDK2xzTk4KTGxWeFNCbmZ6STJVZnpBK3lWMFVVT1pHMXhJY1QzMVNaRGRZV1VKdG9OZmVuSnA0RTNXdlZzZXA3UDhXMXZxOApHY0RVU2lxT010ajFIdHhqTmdMTldCUk01aDNaMHhyaHQ0SjFRejArZHVESGxCOWJxeU9OS240eGtLZnBrWlRBCkRUakJkZTJlCj1DdS9LCi0tLS0tRU5EIFBHUCBTSUdOQVRVUkUtLS0tLQo=\",\n      \"format\": \"pgp\",\n      \"publicKey\": {\n        \"content\": \"LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgp4c0ROQkdSYnIrY0JEQUM5YUlXaElpc08zNjRCdnhYc093QjZwUklKWGQrbWJINHp1VXdRNHIrcmQvb3M0TG1SCkxaaVRDekVZbVMrcHhnUWQwb1haR2o5elZ3VzRYMndaVzI4K0RVRDljWnpHL1J6RkRHeExnZzc1d2dDYmp1czcKeVc0UmtQQkhYOXRsNUFuRHU0SjFKK01Ra3hyUEVHZFpFSVp2QVlKOVJFWDRDSVhHQUNjdXgyaGtaVUlTNVpxZQpvdjRwd1FReFhTNm5SOVpUOHpieWo1SkhQWmtRek02eU42c0F6aXFlUUZpK3pKdXJaTG9kdU9BbEs2Z3BjY1F1CkRnQ0JCM280S2cvSk5lZVB0VTlHYUxHSXB1ZGdxd0N2VHpSbUR0NUc5bjd0cVJaV0ZFMitxSmg5MVBFdzhyUjkKOG5NQWxZSFI1S3BJcUpwbldjOFRSME0yQ0tCOEd2UzNjS3E3NHYvQTZ5bUFPNzErbmVad3pxTENyTEsydllNeApHbjdOSUVKM0grRVFQcEplNGkrbWxoeGE5Rm1zMi9qSUdjemJMNGtSbGdqVE9wazFmOE4zaWZDbnp1YkpxQ3ZXCnZGbWMxM2I0eE9ic3BlWndjckk3Kzg2R092a2FaZk1ONWZweGt4U1lETStLSVEyZlNYcXp0ZGlHWDBVZEp3dG4KOEZhTlBnTUJvckFGMzAwQUVRRUFBYzBVYjJOcFkyd3RkR0Z5WW1Gc2JDMXphV2R1WlhMQ3dSRUVFd0VJQURzVwpJUVM1YXMyL05jWEJxNEZaYjdiVHIrR0lRNWU5eUFVQ1pGdXY1d0liQXdVTENRZ0hBZ0lpQWdZVkNna0lDd0lFCkZnSURBUUllQndJWGdBQUtDUkRUcitHSVE1ZTl5TEZ6Qy85TmJmVUIzYncyMUhHQStBTk03WHg5VVdpZVlNSzkKcWlFUUFyYVgvQm85cnl6c3ZtcnUxcDZYN2RsTmtoTEJzMWl1MFZ0eFB4SWhHdUdncHNPekV2N0Y3OFdvM0pwNQo4dVQ5cW5kelV2aXh2S2lFTTJsdzZHZWFrallCMjV4Zy9VSnpWNmxGYWhhcVZ6emhUSkovbkI5YU9jNDg1WjBpCnV1UnIxU3Nkb3VHbHdRTVZydktRbU1rMjlaTzlKcnNIUmxQR2hnY1p0K2J1bUJPdDNKZTQ0WGtkL0NtNDBxdXYKb2Mwb0FFNGN2c2JkSmE2d3EwODlQK3VPWFZNZlhpUDVBd3ZWSjYxQ2NEYWRJWk1kT29KYnc0b1k3V2dWS2NIWQpYd0tlS0NzOFpzRWs2OGlTRm1FQ3Q3THI4U2tENVcwRXY0QWV3clh4dEFXNElCYUtRaE1pSEZsQ2kvdzdLdjduCm1lM0t4Q1JEc0F4NEdld05iTXRaUjBnZHRwV21CWGVpRytROC8wZGdMUFRqRmFBWHFRQithUWNuMzFscnZCYVgKd0Jib3FtUlNtWDVwdk1uaHhiNSt0R0hsRU9QekMrZ0k0VU50cVZ4L1NIRCtSZHNNM0owd2huRjh3R09KWlRZUwo1WkxrZWR6Qjc3VEtzakNhci92Q2x5UTUvalIrck81VjlwSE93TTBFWkZ1djV3RU1BTUJkY1JYYUpCQ2V2dHV1CklnU3Nmc3hDb3NLRnJQN3JTdmN2bHlHT3pCVlBKT2JFbE5NbjVTOGNwZCtuMXcrQS9rdXFobUNHVmJjaHI2YkMKUERRbmJad2pwWUU3bGVISGtQT2tkT2JHY3VOWjZ1YVNsSktWcWg5aHpHeHZZUlhIMFhUSDNkb2NJTTdyRkdtOQpSMWdKcDhBNmtSbWg4ZVNSOWpMRWNhS2lRTUZPbEYzU3RFZms4VzFsZ0x2Z2VTVnJkc0s0Rnc3Ui9BRVlmek5xClpTZEdRYmx0WXkyekVKcG04M2QxN1BCZXN4eE5FdVNWYUlibCtqai9TLzVkL1h0OGVKdVJzbDVOeDdLSTRpenkKK1pFWkxOWkJZa3FzMTZsSnRva2oxclZOUitLWEtCN1pDenVacGxjYURJbExWMUN0YXFqVXpMazFlcVh0TXBZOQordTFocXd0em5vWnRsTTZTTmVYZnUzS3YzSFlaWUlJVGcrSDBLQVVnZko1S1F1YnNaN2dmSVpaMno0WkZHUHJPCllhWlRJQmNGMGlIbEhZWitPTVRONWpKR2VrU0NlTW0yVUZzZVBqSUtQdHhudTk0ajNDanhWbmlzZURzUkJja1oKcFRaY2VPNkZVa3pCYkltQ2FqNklZd2NmdFhBWVRFQjZXdzE0OUdFYnpONEVyV1pKaXdBUkFRQUJ3c0QyQkJnQgpDQUFnRmlFRXVXck52elhGd2F1QldXKzIwNi9oaUVPWHZjZ0ZBbVJicitjQ0d3d0FDZ2tRMDYvaGlFT1h2Y2lGCmxndi9URndrYXYzYWFFVnhvU0hDNDJzTGl0YmZGOC83YW53ZGZPZkhFdFVSejBmdk1vVEVsamdtS05jb3FQYkEKdkhJMmN1MXA3RTAvOXNZY0VTaXlPNzJVR29oWmZtaWFsTlhROE53TVcySzFnM1FZS0hKam55WWV2WnlkV3dlegpDbXovU0RpNXFBYmMzSVprTFZXRk5LOXdrenljVlhYcVB6ZnJzdDkyTXJ1ZktYSDc2eEExZlA2NXl6S21ZSW9WCnc3eHJkaGp2VzMvS0JHeU5iZHk0dmNucWdERUFCbWR5OUJxRkhKK0p4QnFIZXZKTjV6SXAySHFRK2x4YWVGYmgKQTllckJKYVMzNDU4eXVxd0FvTEJ4OURscHZYQzE2c3NXVVU3WGlJQ1pFb255aXVxQVN4QXMxZjk3SFNjVWx3UQpxWExLUURmZEFud25PeE9wcXFHS1E1M3FzN3UxdUJ0RzJrN0JQMmEwbE1EUW9Za1hoK2tPNTRVT0ZtS1lFNGdvCjE0SFdYSmc3S0Y5UjMxQ0ZrNXNGUU9yYmR1bCtoNC80VVRMSFhGTFBMVkkvTzYwZDNCNkd4cm91SlRSeWJDUHAKV0tvZjg0VGcyY1FiV2FmVko5bzlIbklwb2lPNGJCMVZrQndoM3E2TTE2L0kyWC9zNGhaVVNLODJYSWJ0TlFxRgpRZmxZCj1hbnlKCi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0=\"\n      }\n    }\n  }\n}\n```\n\nFurther explanation of the sigstore tooling and ecosystem is beyond\nthe scope of this document, but you can read about it at\n[https://docs.sigstore.dev/](https://docs.sigstore.dev/).\n\nSelf-Hosting\n------------\n\nYou may wish to self-host the ``ocicl`` registry.  This is easy, given\nthat the registry is just a regular OCI-compatible artifact registry.\nYou can use tools like\n[``skopeo``](https://github.com/containers/skopeo) to copy artifacts\nfrom the default registry, ``ghcr.io/ocicl``, into your own.  Or you\nmay choose to run a local registry that does pull-through caching,\nlike the [Zot registry](https://zotregistry.dev).\n\nThe ``ocicl`` source distribution includes a [sample shell\nscript](https://raw.githubusercontent.com/ocicl/ocicl/main/mirror-example.sh)\nfor mirroring systems from ``ghcr.io/ocicl`` into a locally-hosted OCI\nregistry.\n\nBe sure to run ``setup`` with the ``--registry`` option to make this\nnew registry your default.\n\nSystems\n-------\n\nSystems managed by ``ocicl`` are maintained in github, at\n[https://github.com/ocicl](https://github.com/ocicl).  Each system has\nits own source repo, with a ``README.org`` file containing everything\nrequired to build and publish to the OCI registry via github actions.\n\nThe list of ocicl systems is always available at\n[https://raw.githubusercontent.com/ocicl/request-system-additions-here/main/all-ocicl-systems.txt](https://raw.githubusercontent.com/ocicl/request-system-additions-here/main/all-ocicl-systems.txt).\n\nContributions are welcome and appreciated!  See\nhttps://github.com/ocicl/request-system-additions-here for details.\n\n## Project Templates\n\nThe `ocicl new` command creates a new application from a\ntemplate. Templates are a hierarchy of directories containing files\nthat a processed before being copied into your current working\ndirectory.  They are processed using\n[cl-template](https://github.com/alpha123/cl-template) and optional\nkey/value pairs that you pass into the templating engine. Templates\ncan be stored locally in your template directories or use the built-in\ntemplates that come with `ocicl`.\n\n### Usage\n\n```bash\nocicl new APP-NAME [TEMPLATE] [KEY=VALUE]...\n```\n\n#### Arguments\n\n| Argument | Description |\n|-----------|------------|\n| `APP-NAME` | Name of the directory to create for your new project. This value is also available inside templates as the `#:app-name` keyword. |\n| `TEMPLATE` | *(Optional)* Template to use. Defaults to `basic`. If you have a template named `user`, it will override the `basic` default. |\n| `KEY=VALUE` | *(Optional)* Additional template variables (e.g., `author=Alice`, `license=MIT`). Keys are automatically converted to keywords (`#:AUTHOR`, `#:LICENSE`, etc.). |\n\n#### Example\n\n```bash\n# Create a basic project\nocicl new my-blog\n\n# Create a project with a specific template and variables\nocicl new my-api web-service author=\"Jane Doe\" license=GPL3\n```\n\n### Template Discovery\n\nTemplates are searched in the following order (first match wins):\n\n1. **Command line option**: `--template-dir DIR` (can be used multiple times)\n2. **Environment variable**: `$OCICL_TEMPLATE_PATH` (colon-separated list of directories)\n3. **Configuration file**: `~/.local/share/ocicl/config/ocicl/ocicl-template-path.cfg` (one directory per line)\n4. **Default location**: `~/.local/share/ocicl/templates/` (installed by `ocicl setup`)\n\n#### Template Management Commands\n\n- **List available templates**: `ocicl templates [list]`\n- **Show template directories**: `ocicl templates dirs`\n\n### How Templates Work\n\n#### File Processing\n\n**Text files** are processed as templates when they:\n- End with the `.clt` extension, OR\n- Contain at least one `\u003c% ... %\u003e` directive\n\nThese files use [cl-template](https://github.com/alpha123/cl-template) syntax for variable substitution and logic.\n\n**Binary files** (containing NUL bytes) are copied without modification.\n\n**Git directories** (`.git/`) are ignored during template processing.\n\n#### File and Directory Naming\n\nUse the `{{app-name}}` token (case-insensitive) in file or directory names to have it replaced with your `APP-NAME`.\n\nExample: A template file named `{{app-name}}.asd` becomes `blog.asd` when you run `ocicl new blog`.\n\nTips and Troubleshooting\n------------------------\n\n* In the unlikely event that ``ghcr.io`` is unreachable, all packages\nare also available at ``docker.io/ocicl``.  Switch registries by\nrunning ``ocicl setup -r docker.io/ocicl``.\n\n* You may find it convenient to tell ASDF to load from the current directory.\nDo this by placing the following in your ``.sbclrc`` file:\n```\n(asdf:initialize-source-registry\n  (list :source-registry (list :directory (uiop:getcwd)) :inherit-configuration))\n```\n* As an ``ocicl`` user, you may have had experience using quicklisp's\n``local-projects`` mechanism, and are wondering how to do something\nsimilar.  ASDF itself provides a simple mechanism for searching a\ncollection of subdirs for ``.asd`` files.  If, for instance, you had\na directory in which you cloned various lisp systems called\n``/path/to/my/local-projects``, you would configure ASDF thusly:\n```\n(asdf:initialize-source-registry '(:source-registry :inherit-configuration (:tree #P\"/path/to/my/local-projects/\")))\n```\n* Setting ``ocicl-runtime:*verbose*`` to a stream (like ``t``, ``*standard-output*``, ``*error-output*``, etc) will output useful and\ninteresting log info.\n\n* ``ocicl`` is bundled with ``asdf`` version 3.3.7.  You can delete it\n(along with any fasl files) from the directory containing\n``ocicl-runtime.lisp`` if you do not want this version to be loaded by\nthe runtime at startup.\n\n* In addition to `ocicl.csv` with the `ocicl` systems directory, `ocicl`\n  additionally supports `systems.csv` and `systems` for backward compatibility\n  with earlier versions of ocicl.\n\nAuthor and License\n-------------------\n\n``ocicl`` was created by [Anthony Green](https://github.com/atgreen),\nwith significant contributions from [Diego](https://github.com/dieggsy)\nand [Sebastian Christ](https://github.com/rudolfo-christ).\nSee the [full list of contributors](https://github.com/ocicl/ocicl/graphs/contributors).\n\n``ocicl`` is distributed under the terms of the MIT license.\n\nThis software includes Lisp source code files written by Zachary\nBeane, Mark Karpov, Ava Fox, and PMSF IT Consulting Pierre R. Mai.\nPortions of the linter were borrowed from and inspired by Chris\nRiesbeck's MIT licensed lisp-critic project, and Eitaro Fukamachi's\nMIT licensed mallet project.  See the ``ocicl`` source files for\ndetails.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Focicl%2Focicl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Focicl%2Focicl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Focicl%2Focicl/lists"}