# https://github.com/sjquant/skul Project Manual

Generated at: 2026-07-03 22:20:04 UTC

## Table of Contents

- [Architecture & Module Layout](#page-1)
- [CLI Commands & User-Facing Workflows](#page-2)
- [Bundle Discovery, Fetching & Manifest](#page-3)
- [Materialization, Tool Mapping, Root Instructions & State](#page-4)

<a id='page-1'></a>

## Architecture & Module Layout

### Related Pages

Related topics: [CLI Commands & User-Facing Workflows](#page-2), [Bundle Discovery, Fetching & Manifest](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/index.ts](https://github.com/sjquant/skul/blob/main/src/index.ts)
- [src/cli.ts](https://github.com/sjquant/skul/blob/main/src/cli.ts)
- [bin/skul.js](https://github.com/sjquant/skul/blob/main/bin/skul.js)
- [src/fs-utils.ts](https://github.com/sjquant/skul/blob/main/src/fs-utils.ts)
- [package.json](https://github.com/sjquant/skul/blob/main/package.json)
</details>

# Architecture & Module Layout

## Purpose and Scope

`skul` is a Node.js / TypeScript command-line utility distributed through npm. It installs and manages developer-tool bundles sourced from GitHub repositories. The project follows a deliberately small architecture: a thin executable shim hands control to a TypeScript entry point, which composes a Commander-style command surface and delegates I/O and network operations to focused helper modules. This separation keeps CLI parsing, business logic, and filesystem interactions cleanly layered and individually testable.

Source: [package.json:1-60]()

## Layered Architecture

### 1. Executable Shim Layer

`bin/skul.js` is the npm bin entry referenced from `package.json`. It performs only the minimal bootstrapping required to locate the compiled output and invoke the main module. This indirection lets `npx skul` or a globally installed `skul` binary resolve the runtime entry without exposing TypeScript compilation concerns to end users.

Source: [bin/skul.js:1-20]()

### 2. Composition Root

`src/index.ts` is the composition root of the application. It imports the CLI module, registers commands, and hands control back to the runtime. No business logic or filesystem interaction lives in this file; its sole role is to glue the command layer to the Node runtime and ensure a single, predictable startup path. Centralizing wiring here also makes it possible to import the CLI module from tests without re-bootstrapping the full process.

Source: [src/index.ts:1-40]()

### 3. CLI Command Surface

`src/cli.ts` defines the user-facing command tree. As of v0.1.1, the surface centers on `skul add` (renamed from the earlier `use` command for clarity) and `skul list`, both of which accept a `--tool` flag for per-tool filtering inside a multi-tool bundle. This module owns argument parsing, help text, and subcommand dispatch, then delegates the actual installation and listing work to helper modules rather than embedding that logic inline.

Source: [src/cli.ts:1-120]()

### 4. Filesystem and I/O Utilities

`src/fs-utils.ts` encapsulates every filesystem interaction: resolving the local install root, writing and reading manifest files, and ensuring target directories exist before use. Centralizing I/O here keeps `src/cli.ts` free of direct `fs` calls and gives the project a single seam for swapping the storage backend or mocking the filesystem in tests.

Source: [src/fs-utils.ts:1-80]()

## Data and Network Flow

The typical request flow follows the layered path described above: the executable shim loads the entry point, which activates the CLI parser; the active command resolves its target bundle, applying the `--tool` filter when supplied; the command then either downloads an archive directly or falls back to the GitHub API archive endpoint introduced in v0.1.2; finally, the archive is unpacked into the local root managed by `fs-utils`, and the installed set is recorded in a manifest file.

Source: [src/cli.ts:40-100](), [src/fs-utils.ts:20-70](), [bin/skul.js:1-15]()

## Module Layout Summary

| Layer | File | Responsibility |
|-------|------|----------------|
| Executable | `bin/skul.js` | Process bootstrap, locate compiled entry |
| Composition | `src/index.ts` | Wire runtime to CLI |
| Commands | `src/cli.ts` | Argument parsing, command dispatch, help text |
| I/O | `src/fs-utils.ts` | Local filesystem operations |
| Metadata | `package.json` | Bin mapping, dependencies, scripts |

Source: [package.json:1-60](), [bin/skul.js:1-15](), [src/index.ts:1-30](), [src/cli.ts:1-100](), [src/fs-utils.ts:1-70]()

## Design Notes and Community Context

- **Thin shim pattern**: Keeping `bin/skul.js` minimal means Node version checks and TypeScript resolution stay out of the user-facing surface, reducing friction for npm distribution.
- **Single composition root**: `src/index.ts` is the only place where modules are wired together. This is what allows the CLI module to be unit-tested in isolation.
- **Command-level filtering rather than a new module**: The v0.1.1 introduction of the `--tool` flag kept the architecture flat; filtering is treated as an argument-level concern in `src/cli.ts` rather than spawning a new subsystem.
- **Contained archive fallback**: The GitHub API archive fallback added in v0.1.2 was implemented inside the existing fetch flow rather than as a generalized fetcher abstraction, suggesting the maintainers favored a contained retry strategy over expanding the module surface for a single reliability concern.

Source: [src/cli.ts:1-120](), [src/index.ts:1-40](), [src/fs-utils.ts:1-80](), [bin/skul.js:1-20](), [package.json:1-60]()

---

<a id='page-2'></a>

## CLI Commands & User-Facing Workflows

### Related Pages

Related topics: [Architecture & Module Layout](#page-1), [Bundle Discovery, Fetching & Manifest](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/cli.ts](https://github.com/sjquant/skul/blob/main/src/cli.ts)
- [bin/skul.js](https://github.com/sjquant/skul/blob/main/bin/skul.js)
- [src/cli-parser.test.ts](https://github.com/sjquant/skul/blob/main/src/cli-parser.test.ts)
- [src/cli-run-basic.test.ts](https://github.com/sjquant/skul/blob/main/src/cli-run-basic.test.ts)
- [src/cli-run-items.test.ts](https://github.com/sjquant/skul/blob/main/src/cli-run-items.test.ts)
- [src/cli-run-apply-update.test.ts](https://github.com/sjquant/skul/blob/main/src/cli-run-apply-update.test.ts)
</details>

# CLI Commands & User-Facing Workflows

The skul CLI is the public surface through which users install, list, apply, and update tool bundles. Its command surface is intentionally narrow but expressive: a handful of subcommands cover the full lifecycle from fetching an archive on GitHub to persisting a selected tool version locally. This page describes the command grammar, the role of each subcommand, and the workflows they support.

## Command Surface Overview

The binary entrypoint is `bin/skul.js`, which delegates argument parsing and dispatch to the TypeScript module `src/cli.ts`. The CLI exposes commands for selecting and persisting tools (`add`, previously called `use`), listing available tool versions (`list`), and the underlying run pipeline that powers ad-hoc execution. Source: [bin/skul.js:1-40](). Source: [src/cli.ts:1-120]().

| Command | Purpose | Notable flags |
|---------|---------|---------------|
| `skul add <ref>` | Adopt a tool version into the project | `--tool <name>` (filter bundle to a single tool) |
| `skul list` | Print available tools/versions | `--tool <name>` (per-tool filter) |
| `skul run` | Internal/explicit invocation pipeline | — |
| `skul apply` / `skul update` | Re-resolve and refresh existing installs | — |

The `--tool` flag was introduced alongside multi-tool bundle support and was the headline usability change in v0.1.1. Source: [src/cli-parser.test.ts:1-80]().

## The `add` Workflow

`skul add` is the primary user-facing workflow. It accepts a reference (a tag, branch, or commit on a GitHub-hosted bundle) and a `--tool` selector. The parser verifies the flag combinations, then the run pipeline fetches the archive, extracts the requested binary, and writes it to the project-local store. The behavior is exercised end-to-end in the integration-style tests under `src/cli-run-basic.test.ts` and `src/cli-run-items.test.ts`, which assert that the resolved path, version metadata, and binary contents match expectations. Source: [src/cli-run-basic.test.ts:1-120](). Source: [src/cli-run-items.test.ts:1-160]().

A typical invocation looks like:

```bash
skul add sjquant/example-bundle@v1.2.0 --tool formatter
```

The renaming from `use` to `add` in v0.1.1 was a deliberate clarity improvement; the parser tests still verify the legacy spelling where relevant. Source: [src/cli-parser.test.ts:40-100]().

## Apply and Update Pipelines

Once a tool is `add`-ed, subsequent invocations do not re-download. The apply/update path re-reads the stored ref, checks whether the archive has changed (using the GitHub API archive fallback introduced in v0.1.2), and re-extracts only when needed. The fallback handles cases where the original archive URL has been deleted or moved by routing through the GitHub API's archive endpoint. Source: [src/cli-run-apply-update.test.ts:1-180]().

```mermaid
flowchart LR
    A[User: skul add <ref>] --> B[Parser validates args]
    B --> C[Download archive]
    C --> D{Archive OK?}
    D -- yes --> E[Extract --tool target]
    D -- no --> F[GitHub API archive fallback]
    F --> E
    E --> G[Persist to local store]
    G --> H[User: skul list --tool <name>]
    H --> I[User: skul apply / update]
    I --> C
```

## Listing, Filtering, and Discovery

`skul list` enumerates either all known tools in the active bundle or, when `--tool` is supplied, narrows the output to a single named tool. The parser-level test fixture confirms that combining `--tool` with a positional ref is rejected when semantically inconsistent, while combining it with `list` filters the displayed set. Source: [src/cli-parser.test.ts:80-160]().

This is the discovery path users rely on before running `add` — it answers "what tools are available in this bundle?" without forcing a download.

## Error Handling and Community-Relevant Notes

The parser layer centralizes validation so that run-pipeline code can assume well-formed arguments. Tests under `src/cli-run-basic.test.ts` and `src/cli-run-items.test.ts` cover both the happy path and common failure modes (missing ref, unknown tool, archive unreachable). The v0.1.2 release specifically strengthened the unreachable-archive path via the GitHub API fallback, which is the most user-visible reliability change to date. Source: [src/cli-run-apply-update.test.ts:60-140]().

Multi-tool bundle support (Option A, formalized in v0.1.1) means a single `skul add` can carry multiple binaries; `--tool` is the escape hatch for users who only want one. This dual model — bundle-first, tool-second — is the conceptual center of the CLI.

---

<a id='page-3'></a>

## Bundle Discovery, Fetching & Manifest

### Related Pages

Related topics: [CLI Commands & User-Facing Workflows](#page-2), [Materialization, Tool Mapping, Root Instructions & State](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/bundle-discovery.ts](https://github.com/sjquant/skul/blob/main/src/bundle-discovery.ts)
- [src/bundle-fetch.ts](https://github.com/sjquant/skul/blob/main/src/bundle-fetch.ts)
- [src/bundle-manifest.ts](https://github.com/sjquant/skul/blob/main/src/bundle-manifest.ts)
- [src/bundle-items.ts](https://github.com/sjquant/skul/blob/main/src/bundle-items.ts)
- [src/bundle-item-refs.ts](https://github.com/sjquant/skul/blob/main/src/bundle-item-refs.ts)
- [src/bundle-translation.ts](https://github.com/sjquant/skul/blob/main/src/bundle-translation.ts)
</details>

# Bundle Discovery, Fetching & Manifest

## Purpose and Scope

The "Bundle" subsystem is the central data and transport layer of skul. A bundle is a named, versioned collection of tool-related items (commands, agents, snippets, helpers, or other artifacts) that can be distributed across repositories and consumed by the `skul add` and `skul list` commands. The subsystem is responsible for three tightly coupled concerns:

1. **Discovery** — locating bundles referenced by a user, whether locally installed or remote on GitHub.
2. **Fetching** — pulling bundle content reliably, including archive retrieval with fallback strategies.
3. **Manifest resolution** — interpreting the bundle's manifest so items can be addressed, filtered by tool, and applied.

Multi-tool bundle support was formally documented in v0.1.1 (`Source: [src/bundle-discovery.ts:1-40]()`), and the GitHub API archive fallback added in v0.1.2 improved the resilience of remote fetches (`Source: [src/bundle-fetch.ts:1-60]()`). The shared manifest format is what allows per-tool filtering via the `--tool` flag introduced alongside the `add` command rename in v0.1.1 (`Source: [src/bundle-manifest.ts:1-50]()`).

## Bundle Discovery

Discovery is the entry point invoked when a user references a bundle by name or by repository shorthand. The discovery layer normalizes references, distinguishes between already-installed bundles and remote ones, and produces a uniform handle that downstream layers can fetch or inspect.

Responsibilities attributed to the discovery module:

- Parse short forms (e.g. `owner/repo`, `owner/repo@ref`) into structured `BundleRef` objects (`Source: [src/bundle-discovery.ts:20-80]()`).
- Resolve a reference against the local install cache before attempting any network call (`Source: [src/bundle-discovery.ts:80-140]()`).
- Surface install state to commands such as `skul list` so they can present both available and already-added bundles without a round trip (`Source: [src/bundle-items.ts:30-90]()`).

This separation is what allows the `skul add` and `skul list` commands to share a single resolution path before diverging into fetch and item-walk logic respectively.

## Bundle Fetching

Once discovery yields a remote reference, the fetching layer is responsible for obtaining the bundle's raw archive and delivering it to a staging area where the manifest can be read.

Key behaviors of the fetching module:

- Default transport uses GitHub's archive endpoints, which offer stable, content-addressable tarballs (`Source: [src/bundle-fetch.ts:1-60]()`).
- A GitHub API archive fallback was introduced in v0.1.2 (PR #84). When the primary archive endpoint fails — for example due to rate limits, transient network errors, or private archive restrictions — the fetcher retries via the GitHub API archive route (`Source: [src/bundle-fetch.ts:60-140]()`).
- Caching ensures repeated `skul add` invocations do not re-download unchanged bundles (`Source: [src/bundle-fetch.ts:140-200]()`).

The fallback strategy is the most user-visible reliability improvement in the recent release history and directly addresses common failure modes users encountered when adding bundles from larger or rate-limited sources.

## Manifest, Items & References

After a bundle archive is staged, the manifest module parses its top-level metadata and produces an in-memory representation that the rest of the pipeline consumes.

The manifest typically declares:

- A bundle identifier and version.
- The list of supported tools (used by the `--tool` flag for per-tool filtering on `skul add` and `skul list`).
- References to individual items by path, tool scope, and optional metadata (`Source: [src/bundle-manifest.ts:50-140]()`).

`bundle-items.ts` is responsible for walking the staged archive according to the manifest and materializing the item graph — each command, agent, or helper that the bundle exposes (`Source: [src/bundle-items.ts:90-180]()`). `bundle-item-refs.ts` complements this by maintaining stable references between items and the tool/feature scopes they belong to, which is what enables filtering without loading every item into memory (`Source: [src/bundle-item-refs.ts:1-100]()`).

When a bundle ships localized or alias-based names, `bundle-translation.ts` resolves display names and aliases at the item level so that commands remain stable across locales and renames (`Source: [src/bundle-translation.ts:1-80]()`).

## End-to-End Flow

The following diagram summarizes how the three layers compose when a user runs `skul add owner/repo`:

```mermaid
flowchart LR
    A[User: skul add owner/repo] --> B[bundle-discovery.ts]
    B --> C{Local cache hit?}
    C -- Yes --> G[bundle-items.ts]
    C -- No --> D[bundle-fetch.ts]
    D --> E{GitHub archive OK?}
    E -- No --> F[GitHub API archive fallback<br/>v0.1.2]
    F --> H[bundle-manifest.ts]
    E -- Yes --> H
    H --> I[bundle-item-refs.ts]
    I --> G
    G --> J[bundle-translation.ts]
    J --> K[Apply per-tool filter via --tool]
    K --> L[Installed bundle]
```

The pipeline is intentionally linear: discovery gates every other stage, fetching is the only network-aware step, and the manifest + items + refs + translation stages are pure functions over the staged archive. This shape makes it straightforward to add new transport strategies (such as the v0.1.2 fallback) without touching discovery or manifest code (`Source: [src/bundle-fetch.ts:60-140]()`).

## Summary

The Bundle Discovery, Fetching & Manifest subsystem is the contract between skul's CLI surface and the distributed bundle ecosystem. Discovery normalizes references and consults the local cache; fetching reliably retrieves archives with a documented GitHub API fallback; the manifest, items, refs, and translation modules turn the staged archive into a filtered, addressable item graph ready to be applied by `skul add` or enumerated by `skul list`. Together they implement the multi-tool, per-tool-filterable bundle model that has shaped the project since v0.1.1 and that gained an important reliability upgrade in v0.1.2.

---

<a id='page-4'></a>

## Materialization, Tool Mapping, Root Instructions & State

### Related Pages

Related topics: [Bundle Discovery, Fetching & Manifest](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/bundle-materialization.ts](https://github.com/sjquant/skul/blob/main/src/bundle-materialization.ts)
- [src/tool-mapping.ts](https://github.com/sjquant/skul/blob/main/src/tool-mapping.ts)
- [src/root-instruction-content.ts](https://github.com/sjquant/skul/blob/main/src/root-instruction-content.ts)
- [src/root-instruction-render.ts](https://github.com/sjquant/skul/blob/main/src/root-instruction-render.ts)
- [src/root-instruction-state.ts](https://github.com/sjquant/skul/blob/main/src/root-instruction-state.ts)
- [src/state-layout.ts](https://github.com/sjquant/skul/blob/main/src/state-layout.ts)
</details>

# Materialization, Tool Mapping, Root Instructions & State

This page documents the internal subsystems that turn a referenced bundle (an external skill definition) into concrete files on disk, route its pieces to the correct agent runtime, and maintain a coherent picture of what has been installed and where. Together these modules implement the "Option A: multi-tool bundle support" model introduced in v0.1.1 and the per-tool filtering exposed by `skul add --tool` and `skul list --tool`.

## 1. Bundle Materialization

`bundle-materialization.ts` is the module responsible for taking a bundle reference (the identifier passed to `skul add`) and producing a fully resolved, on-disk representation of every artifact that the bundle declares. The high-level role is to be the single, idempotent point where external bundle metadata becomes local state.

Materialization is invoked after bundle metadata has been fetched (either from a GitHub archive or, as of v0.1.2, via the GitHub API archive fallback `Source: [src/bundle-materialization.ts:1-120]()`). The module:

- Validates the bundle manifest against the layout rules enforced by `state-layout.ts`.
- Resolves each declared skill into the canonical directory shape used by `skul`.
- Writes derived artifacts (for example, the tool-specific fragments that `tool-mapping.ts` produces) so that later commands do not need to re-derive them.
- Emits a deterministic result describing what was created or updated, which `root-instruction-state.ts` then consumes to update tracked state.

Because materialization is idempotent, running `skul add` on an already-installed bundle is safe and produces no drift, only an updated state record.

## 2. Tool Mapping

`tool-mapping.ts` implements the layer between a bundle and the specific AI agents the user might be targeting (Claude Code, Cursor, and other tools listed by the `--tool` flag added in v0.1.1). A single bundle is authored once but may need different filenames, different frontmatter, or different installation roots depending on the target tool.

The module centers on a mapping table from canonical bundle artifacts to tool-specific paths and formats `Source: [src/tool-mapping.ts:1-180]()`. Key responsibilities include:

- Maintaining the registry of supported tools and their canonical installation roots.
- Translating a bundle's logical skill set into the per-tool fragments that materialization writes.
- Honoring the `--tool` filter used by `skul add` and `skul list` so that a single bundle can be installed selectively `Source: [src/tool-mapping.ts:60-140]()`.
- Falling back to a sensible default tool set when the user has not specified one.

This separation is what allows skul to ship one bundle format while still targeting multiple agent runtimes without duplicating source content.

## 3. Root Instruction Content, Render, and State

The three root-instruction modules work in a producer/renderer/persister pipeline. They are responsible for the top-level instruction file (for example a project-level `CLAUDE.md`-style file) that aggregates the per-tool fragments produced during materialization.

| Module | Role | Output |
| --- | --- | --- |
| `root-instruction-content.ts` | Builds the logical content tree (sections, per-tool blocks, bundle headers). | In-memory content model. |
| `root-instruction-render.ts` | Serializes the content model to the host's expected format, applying tool-specific transforms. | Final instruction text. |
| `root-instruction-state.ts` | Tracks which bundles and tool fragments are currently reflected in the rendered file and reconciles them on each run. | Updated state record. |

`root-instruction-content.ts` composes a structured tree of sections, where each bundle contributes a header and per-tool sub-blocks `Source: [src/root-instruction-content.ts:1-150]()`. The renderer then walks this tree, applies any tool-specific framing, and emits a stable textual output suitable for the target agent `Source: [src/root-instruction-render.ts:1-160]()`. Finally, `root-instruction-state.ts` compares the proposed render against the last persisted state so that `skul list` and follow-up `skul add` invocations can report drift accurately `Source: [src/root-instruction-state.ts:1-200]()`.

## 4. State Layout

`state-layout.ts` defines the on-disk conventions shared by every other module in this page. It is the source of truth for where bundles, tool fragments, rendered root instructions, and state records live relative to the project root.

By centralizing paths in one module, the rest of the codebase can refer to locations symbolically rather than by literal string, which keeps the GitHub archive fallback (added in v0.1.2, PR #84) and future transport layers compatible with the same layout `Source: [src/state-layout.ts:1-120]()`. The state layout is also what makes the materialization→render→state pipeline reproducible: given the same bundle reference and the same `--tool` filter, every run writes to the same paths and produces comparable state records.

## End-to-End Flow

When a user runs `skul add <bundle> --tool <tool>`:

1. The bundle is fetched and handed to `bundle-materialization.ts`.
2. `tool-mapping.ts` filters and shapes the bundle's artifacts for the requested tool.
3. `root-instruction-content.ts` and `root-instruction-render.ts` rebuild the top-level instruction file.
4. `root-instruction-state.ts` updates the persisted state using the directory layout from `state-layout.ts`.

This pipeline is what the v0.1.1 release refers to as "multi-tool bundle support (Option A)": one bundle, one materialization step, many tool outputs, all tracked in a single state model.

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: sjquant/skul

Summary: Found 9 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

## 1. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this installation risk before relying on the project: v0.1.1
- User impact: Upgrade or migration may change expected behavior: v0.1.1
- Evidence: failure_mode_cluster:github_release | https://github.com/sjquant/skul/releases/tag/v0.1.1

## 2. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.host_targets | https://github.com/sjquant/skul

## 3. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/sjquant/skul

## 4. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/sjquant/skul

## 5. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/sjquant/skul

## 6. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/sjquant/skul

## 7. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/sjquant/skul

## 8. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/sjquant/skul

## 9. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this maintenance risk before relying on the project: v0.1.2
- User impact: Upgrade or migration may change expected behavior: v0.1.2
- Evidence: failure_mode_cluster:github_release | https://github.com/sjquant/skul/releases/tag/v0.1.2

<!-- canonical_name: sjquant/skul; human_manual_source: deepwiki_human_wiki -->
