# Packages

kernl has four packages under the `@kernl` scope, not yet published to npm (see [Install](#install)). Three are pure contracts and engines with zero framework dependencies; one composes them with kehto and applesauce. The shell app at `apps/web` is not published.

| Package | Version | Role | Dependencies | Peer dependencies |
| --- | --- | --- | --- | --- |
| [`@kernl/guard`](https://kernlize.github.io/docs/packages/guard.md) | `0.1.0` | Ingress flood control, visibility gate, focus-aware firewall, CSP profile, nested-frame lock, mitigation descriptions. | `@kehto/firewall` | `@napplet/core` |
| [`@kernl/messaging`](https://kernlize.github.io/docs/packages/messaging.md) | `0.1.0` | Messaging provider contract, registry, composite direct-message adapter, in-memory backend. | none | `@napplet/core` (the `Dm*` wire types) |
| [`@kernl/bridges`](https://kernlize.github.io/docs/packages/bridges.md) | `0.1.0` | Locator parsing, bridge contract, registry, HTTP bridge with SSRF policy. | none | none |
| [`@kernl/core`](https://kernlize.github.io/docs/packages/core.md) | `0.1.0` | Composition root over kehto and applesauce: adapters, applet resolution, mount plan, consent summaries, layouts, persistence. | the three above, `@kehto/*`, `applesauce-*`, `rxjs` | `@napplet/core`, `@napplet/nap`, `@napplet/shim`, `nostr-tools` (required by kehto and applesauce; never imported) |

## Shared rules

- ESM only, TypeScript strict, `verbatimModuleSyntax`. Each package ships `dist/index.js` and `dist/index.d.ts` with `sideEffects: false`.
- Every public export has JSDoc with `@param`, `@returns` and `@example`, and appears in the [API reference](https://kernlize.github.io/docs/reference/api.md).
- Streams in `@kernl/core` are rxjs `Observable`s (`session$`, `guard.events$`, `grants.changes$`, `relays.changes$`, `AppletHandle.status$`); unsubscribe the `Subscription` they return. `MessagingBackend.subscribe` returns `{ subscriptionId }`, which you pass to `unsubscribe`. Thrown errors carry a stable prefixed reason: `denied:`, `invalid:`, `unavailable:`; the full list is in [Error reasons](https://kernlize.github.io/docs/reference/errors.md).
- No published package imports `nostr-tools` directly, and no published package depends on a UI framework. `pnpm check:deps` enforces both.
- Behaviour is specified in Gherkin under each package's `features/` and run by vitest with 100% coverage over `src`.

## Versioning

All packages are `0.x`. A breaking change is a `minor` bump; everything else is a `patch`. Releases are managed with changesets: one changeset per package whose shipped output changed. `@kernl/core` depends on the other three with `workspace:^`, so a release of a leaf package produces a patch of core.

## Install

The `@kernl/*` packages are not yet published to npm; `pnpm add @kernl/core` fails with a not-found error. During the alpha the source repository is private, and the packages are used from a clone of it:

```bash
# in a clone of the kernl source repository
pnpm install && pnpm build
```

`pnpm build` writes each package's `dist/`, which is what `main`, `types` and `exports` point at. Then add your code as a workspace package (under `packages/` or `apps/`, the globs in `pnpm-workspace.yaml`) and depend on what you need with the workspace protocol, as `apps/web` does:

```json
{
  "dependencies": {
    "@kernl/core": "workspace:^",
    "@kernl/guard": "workspace:^"
  }
}
```

Run `pnpm install` again after editing the manifest so pnpm links the workspace packages. `@kernl/core` pulls the other three in. Install a leaf package alone when you want its contract without kehto and applesauce, for example `@kernl/guard` to test an applet against the limits, or `@kernl/messaging` to write a provider.
