# Instructions for agents: using `akp` as a tool

You are reading this because you found it at `https://stemmar.com/AGENTS.md`. It tells you how to
install the `akp` command-line tool, what each command does, and what you can rely on it for.

Everything here works with no account, no API key and no network, unless a command is marked
otherwise. There is nothing to sign up for in order to use the tool.

**Wherever a command takes a package you can give it three things**: a path to a file, an alias
like `mqtt`, or a coordinate like `org.example/thing@1.0.0`. An alias, or a coordinate with no
version, means the newest release you may see — and the tool prints what it resolved to.

**If you only read one thing:** `akp` turns documents into a single verifiable file, and every
piece of knowledge in that file points back at the page it came from. `akp validate` is how you
check one. `akp provenance` is how you find out where an answer came from.

---

## Contents

- [Install](#install)
- [The one-minute version](#the-one-minute-version)
- [What an AKP file is](#what-an-akp-file-is)
- [Commands](#commands)
  - [Working with a file](#working-with-a-file-no-network)
  - [Signing](#signing-no-network)
  - [Using a registry](#using-a-registry-network)
- [How to: packaging](#how-to-packaging)
- [How to: publishing](#how-to-publishing)
- [How to: deployment](#how-to-deployment)
- [How to: connecting a bundle to a model](#how-to-connecting-a-bundle-to-a-model)
- [Exit codes and output](#exit-codes-and-output)
- [Where to read more](#where-to-read-more)

---

## Install

```bash
curl -fsSL https://stemmar.org/install/install.sh | sh
```

This downloads the archive for the running platform, checks it against the published SHA-256, and
puts `akp` on the path. Supported: macOS (Apple silicon and Intel), Linux (x86-64 and arm64),
Windows (x86-64).

To install a specific version, or to fetch the archive yourself:

```bash
curl -fsSL https://stemmar.org/install/latest          # the current version string
curl -fsSLO https://stemmar.org/install/0.5.33/akp-aarch64-apple-darwin.tar.gz
curl -fsSLO https://stemmar.org/install/0.5.33/akp-aarch64-apple-darwin.tar.gz.sha256
```

Check the version you have with `akp --version`.

There is no licence key, no activation, no account and no telemetry. If something asks you for one,
you are not running this tool.

---

## The one-minute version

```bash
akp identify report.akp        # is this an AKP file at all?
akp inspect report.akp         # what is in it?
akp validate report.akp        # is it well-formed and intact?
akp provenance report.akp      # where did each piece of knowledge come from?
akp deploy report.akp --to context   # turn it into something a model can read
```

None of those five touches the network.

---

## What an AKP file is

One file. Inside it:

- **Source documents** — the originals, unaltered.
- **Knowledge objects** — what those documents were turned into: text, tables, procedures.
- **Provenance** — for every knowledge object, a pointer to the page, sheet, section or cell range
  it came from. This is the part that matters. An answer you cannot trace is an answer you cannot
  check.
- **An ontology** — the vocabulary of the domain, where the bundle carries one.
- **Evaluation cases** — the questions the bundle is meant to be able to answer.
- **Attribution** — publisher, licence, classification, and optionally a signature.

The file is content-addressed: its identity is a digest of its canonical contents. Embeddings and
indexes inside it are a _cache_ — delete every one and the identity is unchanged.

`.akp` is the extension. Do not identify one by its extension: use `akp identify`, which reads the
byte signature. The extension collides with an unrelated legacy format.

---

## Commands

### Working with a file (no network)

| Command                            | What it does                                                                                                                                                                                                                                                                                                                                      |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `akp identify <file>`              | Says whether this is an AKP artifact, by byte signature rather than filename. Distinguishes "not an AKP file" from "corrupt AKP file" — a distinction you cannot make from a parse error.                                                                                                                                                         |
| `akp inspect <file>`               | Lists what the artifact contains: manifest, assets, knowledge objects, evaluation suite, derived artifacts. Start here.                                                                                                                                                                                                                           |
| `akp validate <file>`              | Checks conformance and integrity, and prints a report. Structural validity and knowledge quality are reported **separately**: a bundle can be perfectly valid and still carry advisories about its content.                                                                                                                                       |
| `akp diff <a> <b>`                 | What changed between two artifacts: assets, knowledge objects, chunking configuration, and whether identity moved.                                                                                                                                                                                                                                |
| `akp provenance <file> [object]`   | Traces a knowledge object back to its source anchor. With no object, lists every object and its source. **This is how you check a claim.**                                                                                                                                                                                                        |
| `akp build <sources…>`             | Builds an artifact from source documents.                                                                                                                                                                                                                                                                                                         |
| `akp deploy <file> --to <adapter>` | Builds a runtime from the artifact. Omit `--to` to list the adapters this build has. Local targets need no network.                                                                                                                                                                                                                               |
| `akp fetch <coordinate>`           | Fetches a package from a registry onto this machine, along with every bundle it requires, says where the files landed, and prints what arrived. `--no-dependencies` fetches the package alone; `--out <dir>` copies them somewhere you can carry. Needs no account for a public package, and sends whatever `akp login` stored for a private one. |

`akp deploy` accepts three kinds of argument:

```bash
akp deploy ./report.akp --to context              # a path — never touches the network
akp deploy org.example/thing@1.0.0 --to context   # a coordinate — fetched and cached
akp deploy mqtt --to context                      # an alias — resolved, then fetched
```

An **alias** is a short name a registry keeps for a package; it resolves to the newest version you
may see, and the tool prints what it resolved to. An alias is a convenience, never part of the
format — nothing inside a package may reference one.

### Signing (no network)

| Command                                | What it does                                                                                                                         |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `akp keygen`                           | Generates a local signing identity. The private key never leaves the machine and is never sent anywhere.                             |
| `akp sign <file>`                      | Signs an artifact. Entirely offline.                                                                                                 |
| `akp verify <file> --key <public-key>` | Verifies a signature from the file and a public key alone. No service is consulted, and no vendor root of trust ships in the client. |

Verification never requires a registry. If a tool tells you a signature can only be checked by
calling a service, it is not this tool.

### Using a registry (network)

These four are the only commands that need one. The public registry is readable without a
credential; `publish` needs one.

| Command                                           | What it does                                                                                                                                      |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `akp login --registry <url>`                      | Asks for an API key once and remembers it for that registry. Read from standard input, so it stays out of shell history. No username or password. |
| `akp logout`                                      | Forgets the credential for a registry.                                                                                                            |
| `akp whoami`                                      | Reports who this machine is to a registry.                                                                                                        |
| `akp publish <file> --visibility public\|private` | Publishes into a registry. Visibility is required and never guessed.                                                                              |

The default registry is `https://registry.stemmar.com/v1`. Override with `--registry` or
`AKP_REGISTRY`.

**Reading the registry needs no tool at all.** It is plain JSON over HTTP with no authentication:

```bash
curl https://registry.stemmar.com/v1/packages
curl https://registry.stemmar.com/v1/aliases
curl https://registry.stemmar.com/v1/aliases/mqtt
```

---

## How to: packaging

Packaging turns documents into one file carrying the knowledge taken from them and, for every
piece of it, a pointer back to where it came from.

```
akp build ./manual.md -o demo.akp \
  --id com.example.turbines \
  --name "Turbine Manual" \
  --package-version 1.0.0 \
  --publisher "Example Ltd"
```

`<sources>` is one or more files or directories; directories are walked recursively.

**Omit `--id`, `--name` or `--package-version` at a terminal and `akp build` asks for them**, one
step at a time, validating each and suggesting a default you can take with Enter. Identity is
permanent once published — two packages sharing an id are two versions of the same thing — so it
is asked for rather than guessed.

In a script, or anywhere standard input is not a terminal, nothing is asked and the placeholders
`com.example.knowledge` / `Knowledge Package` / `0.1.0` apply as before. An unattended build must
never block on a question nobody can answer.

```
Ingesting
  ok   manual.md 5 blocks → 2 knowledge objects

Built
  artifact               demo.akp
  knowledge objects      2
  canonical digest       sha256:ccd5de6e3bb9
```

### Where knowledge objects come from

You do not write knowledge objects by hand. The build reads each source into **blocks** — a
paragraph, a heading, a list, a table row, a cell range — then groups blocks into **knowledge
objects** according to the chunking strategy.

An object's identifier is derived from its content, not from a counter: `ko-eaeccb4fa8a8d658`.
Build the same input twice and you get the same identifiers and the same canonical digest. Change
a paragraph and only the objects covering it move.

| Option                    | Effect                                                                                                                                                    |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--strategy structural`   | Default. Follows the document's own shape, so an object is a thing the author wrote rather than a fixed quantity of characters.                           |
| `--strategy per-block`    | One object per block. Finest granularity and the most precise anchors. For sources that are already atomic: glossaries, requirement lists, clause tables. |
| `--strategy fixed-window` | Uniform windows of about `--target-chars`, crossing structure where it has to. For sources with no useful structure: transcripts, OCR output.             |
| `--target-chars <n>`      | Target object size in characters, default 1200. A target, not a limit — structural chunking will not split a paragraph to hit it.                         |

### Referencing a knowledge object

Every object keeps a **source anchor**: the asset it came from and the exact place inside it.

```
$ akp provenance demo.akp

Provenance (2 objects, 100% covered)
  ko-b0866791dc7b3390 manual.md @ lines 9–9
  ko-eaeccb4fa8a8d658 manual.md @ lines 5–5
```

`100% covered` is the number to read: the proportion of objects with a resolvable anchor. Anything
below it means knowledge that cannot be traced to a document. Name an object to see it in full:

```
$ akp provenance demo.akp ko-eaeccb4fa8a8d658

Knowledge object
  id                     ko-eaeccb4fa8a8d658
  source                 manual.md @ lines 5–5

Content
Check bearing clearance every 500 hours. Replace if over 0.15 mm.

Metadata
  akp.section            ["Compressor maintenance","Bearings"]
  akp.structure          "paragraph"
```

The anchor form follows the asset: line ranges for text, a page for a PDF, a sheet and cell range
for a spreadsheet, a section path for a Word document. Metadata under `akp.` is what the build
worked out; anything else is namespaced and belongs to the producer — a consumer that does not
understand a namespaced key must carry it through untouched rather than drop it.

---

## How to: publishing

Publishing puts a package into a registry other people read. It is the only operation that needs
an account.

### Sign it first

```
akp keygen -o publisher-key.json
akp sign demo.akp --key publisher-key.json
akp verify demo.akp --trust <public key>
```

The private key never leaves the machine that made it. There is no escrow and no recovery. A
signature covers the canonical digest, so it survives anything that does not change canonical
content. `akp build --sign-with` does the same in one step.

### Claim the namespace

Publishing publicly requires a verified claim on the namespace — `com.example` for
`com.example.turbines` — proved by a DNS TXT record on the matching domain. A private publish needs
no claim: inside an account boundary there is nobody to mislead.

### Publish

```
akp login                                   # paste your API key when it asks
akp publish demo.akp --visibility public
akp publish demo.akp --visibility private
```

`akp login` asks for an **API key** once and remembers it. There is no username and no password —
the key is the identity. Create one in Studio under **Settings → API keys**; it is shown once, at
creation.

It is read from the terminal, or from standard input so `akp login < key.txt` works in a script,
and stored in `~/.stemmar/credentials.json` with owner-only permissions, against the registry it
belongs to. `AKP_API_KEY` overrides the store for a single command (`AKP_TOKEN` is still read, as
the former name).

An API key begins with `akp_`. A browser session token is refused, before the request rather than
after a `401`: a session token expires with the session that issued it and vanishes when you sign
out elsewhere, which is the wrong shape for a tool publishing from a script.

`akp login` defaults to the public registry; pass `--registry` only for a self-hosted one, and
**include the API version in the URL** — `https://registry.example.com/v1`, not the bare host.

`--visibility` is required and never guessed, because a package published publicly by accident
cannot be recalled. The same artifact goes out either way — same bytes, same digest, same
signature. Visibility is a fact the registry records, not a property of the package.

A published coordinate is permanent: `com.example.turbines@1.0.0` always means the bytes it meant
when it was published, so a corrected build is a new version rather than a replacement.

---

## How to: deployment

Deployment turns a package into something a runtime can use. It derives from the package, and
nothing it produces changes what the package is.

```
akp deploy demo.akp                            # list the adapters this build has
akp deploy demo.akp --to retrieval --out ./index   # a BM25 index you can keep
akp deploy demo.akp --to okf --out ./bundle
```

Ten adapters ship with the tool — `retrieval`, `context`, `prompt`, `tools`, `graph`, `ontology`,
`extraction`, `evaluation`, `corpus`, `okf` — and every one runs with no network, no account and
no model. Every one also has a file form, so `--out` works for all ten and a deploy always leaves
something behind.

Every file is directly readable by an AI — text, JSONL, JSON Schema, tool definitions or JSON-LD —
so nothing needs a loader written before a model can use it. Where a target is structural the
knowledge travels beside it: `retrieval` writes the BM25 index _and_ `chunks.jsonl`, one knowledge
object per line with its text and source anchor, ready to embed, fine-tune on or put in a prompt.

Validation runs first and implicitly: a runtime built from a package nobody checked is a runtime
nobody can vouch for. `--no-validate` skips it. `--json` emits the report for a script.

### Derived output is not the package

```
Derived (1)
  bm25                   LexicalIndex, 2 items, sha256:37143248ded4…

These are derived. Delete them and the package is unchanged.
```

That is a rule rather than reassurance. Indexes, embeddings and exports are caches: deleting them
cannot change package identity, and rebuilding from the same package gives the same result.

### What a lossy target will not carry

Some targets cannot represent everything a package holds, and the report says so:

```
NOT CARRIED — the canonical digest, signatures and integrity claims: OKF has no
  content hashing, so this bundle CANNOT BE VERIFIED
NOT CARRIED — the source location for ko-b0866791dc7b3390 (lines 9–9) is now
  human-readable prose and is no longer machine-checkable
```

If a consumer needs to check what they were given, give them the AKP artifact.

---

## How to: connecting a bundle to a model

Everything a deploy writes is already a format a model reads — text, JSONL, JSON Schema, JSON-LD.
There is no loader to write.

### A vocabulary, so the model uses your words

```bash
akp deploy org.stemmar.corpus.oasis-mqtt-5-0 --to prompt --out ./prompt
cat ./prompt/system-prompt.txt
```

One file: the package and its publisher, then its terminology as the publisher defines it, then
its licence constraints. Send it as the system message. The body shape most model servers accept
is the same one, local or hosted, so nothing here is vendor-specific.

The prompt has a character budget and the deploy says when it did not fit everything — `4 term(s)
did not fit the 4000 character budget and are NOT visible to the target`. Read that note: a
vocabulary that silently lost terms is a model that silently does not know them.

For the vocabulary itself rather than instructions, `--to ontology` writes SKOS as Turtle and
JSON-LD. SKOS and not OWL by design: concepts, labels, broader/narrower, no class hierarchy and no
cardinality, so a consumer wanting inference supplies its own reasoner.

### A retrieval index, so answers cite their source

```bash
akp deploy org.stemmar.corpus.oasis-mqtt-5-0 --to retrieval --out ./index
head -1 ./index/chunks.jsonl
```

`index.json` is a BM25 index; `chunks.jsonl` is one line per knowledge object with three fields:

```json
{
  "anchor": "corpus @ lines 1564-1570",
  "id": "ko-00289c0ab5ae7184",
  "text": "The character data ..."
}
```

`anchor` is where it came from and `id` is stable across rebuilds, so a model quoting a chunk can
cite something checkable. Carry both into the prompt and ask for them back. `chunks.jsonl` is also
what you embed if you want vectors — plain text with identity attached.

### The bundle as tools, so an agent can call it

```bash
akp deploy org.stemmar.corpus.oasis-mqtt-5-0 --to tools --out ./tools
jq '.[0].name, .[0].description' ./tools/tools.json
```

JSON Schema tool definitions, one per concept, in the shape a tool-calling API expects. Each
description carries the concept's definition and an instruction to cite what it returns.

### What none of this does

No adapter calls a model, and no deploy needs an account or a network. Delete every index, prompt
and tool file you build and the package's identity and integrity are unchanged.

## Exit codes and output

- `0` on success. Non-zero on failure, with the reason on standard error.
- `akp validate` exits non-zero when an artifact does **not** conform. Advisories alone do not fail
  it — a valid bundle with advisories is a normal, useful state.
- Most commands accept `--json` for machine-readable output. Prefer it. Parse that rather than the
  human-facing text, which is written for people and may be reworded.

---

## Where to read more

- <https://stemmar.com/docs> — the same reference as a page, with worked examples.
- <https://stemmar.com/llms.txt> — a short summary of this site for machine readers.
- <https://stemmar.com/llms-full.txt> — the full site content, the command reference and the public
  API, as plain text.
- <https://stemmar.com/openapi.json> — the HTTP contract, generated from the server's handlers.
- <https://stemmar.org> — the AKP specification and its governance. Static HTML, readable without
  JavaScript.

`https://stemmar.com` is a single-page application: fetching a page returns an HTML shell and the
content is rendered by JavaScript. Do not scrape it. The documents above carry the same content in
a form you can read directly.

---

## Naming, if you are writing about this

**AKP** is the format, the file extension and the media type. It is open and vendor-neutral.
**Stemmar** is the organisation, the tools and the commercial platform.

Write "the AKP specification, published by Stemmar". Not "the Stemmar format" — the separation is
what the neutrality claim rests on, and getting it wrong misrepresents the thing.
