Quickstart & concepts

lore is a thin, OKF-native documentation CLI. It makes the markdown already living in your repository’s docs/ tree agent-readable, couples it to your task tracker (Quest by default, or Backlog.md/Jira Cloud), and checks its own coherence — deterministically, with no LLM in its core. This page is a quickstart and a concept map, not the full manual.

Quickstart

  1. Install

    lore ships on npm as @opum-ai/lore (bin name lore). Run it without installing anything:

    npx @opum-ai/lore --help

    To pin it in a project instead, add it as a dev dependency: npm i -D @opum-ai/lore or bun add -d @opum-ai/lore. To use a bare lore command everywhere — the form this site’s own CI and agent instructions assume — install it globally instead: npm install -g @opum-ai/lore.

  2. Scaffold a bundle

    Run this from the root of a repository:

    npx @opum-ai/lore init

    This creates the docs/ OKF bundle (a root index.md plus room for your own concepts) and the .lore/ state directory. It’s idempotent — re-running it fills in only whatever is missing and never overwrites an existing file. At an interactive terminal, lore init also offers a short guided wizard for the rest of onboarding — which task tracker to use (Quest by default, or Backlog.md/Jira Cloud), the agent bridge, doc-site scaffold, and a tracker check; piped or scripted invocations, or any explicit flag such as --tracker jira, skip straight to the bare scaffold shown above.

  3. Verify

    Confirm the new bundle is internally coherent — this is the same command your CI will run as a gate (see The CI gate):

    npx @opum-ai/lore check

    On a fresh bundle with nothing linked to a tracker yet, this exits 0 without needing Quest, Backlog.md, or Jira Cloud configured at all — see the tracker prerequisite below.

The ten OKF types

Open Knowledge Format defines no closed vocabulary — a concept’s frontmatter just needs a non-empty type.lore supplies one as a producer profile: ten type values it validates strictly and uses to scaffold new concepts; lore types prints them with their fields and required sections. You are not limited to these ten: lore new accepts any type name, and a concept using one outside this profile still validates and links normally — an unknown type is a warning by default. A bundle that wants it closed sets strict_types = true under [profile] in .lore/profile.toml, which makes it an error in lore validate and lore check and makes lore new refuse (exit 6).

Epic
A large body of work.Typically links to child Arc concepts.
Arc
A unit of deliverable behavior, formerly Story (Story remains a deprecated alias until lore reaches 1.0, and lore new story still scaffolds an Arc).Typically links to task IDs (Quest by default, or Backlog.md/Jira Cloud), Spec, and ADR concepts.
Spec
Design or spec for a feature.Typically links to Arc, ADR, and code paths.
ADR
An architecture decision record.Typically links to Spec and other ADR concepts.
Runbook
An operational procedure.Typically links to Reference concepts and other resources.
Reference
A stable factual concept — a schema, an API, a metric.Typically links to anything.
Constitution
The principles a bundle is governed by, how they are amended, and an amendment log.Pinned first in every lore agent context pack.
Constants
A catalogue of named values, each checkable against the file it names as its source of truth.
Standard
A normative rule set: purpose, scope, rules, enforcement, exceptions, and related concepts.
Attested Computation
A representation-only record of a computation’s contract — runtime, parameters, and executor. Lore validates and inventories it; it never executes the code.

For example, a type this profile doesn’t define at all:

lore new playbook "Incident response"
created docs/playbook/incident-response.md
warning: unknown type "playbook" in docs/playbook/incident-response.md; validated on `type` only (known types: Epic, Arc, Spec, ADR, Runbook, Reference, Constitution, Constants, Standard, Attested Computation)

The file scaffolds and validates like any other concept — only the strict, template-backed scaffolding the ten built-in types get is missing.

Managed blocks

Some regions of a doc are generated, not authored. lore marks them with a visible HTML-comment fence and regenerates everything between the markers on lore sync — for example, the rolled-up task table on an Arc:

<!-- lore:tasks:begin -->
| Task | Title | Status |
|---|---|---|
| [LORE-1](../../.quest/tasks/LORE-1.json) | Bulk archive | Done |
<!-- lore:tasks:end -->

Hand edits inside a managed block are not protected — the next lore sync overwrites the block wholesale from your task tracker’s data, discarding anything you typed there by design. That is a different case from the denied exit code (4) below: 4 fires when one of lore’s own writes, not a human edit, targets a managed region and is refused. Everything outside the fence is yours; lore never touches it.

Arc–to–Task coupling

An Arc (formerly Story) or Spec couples to the tasks that deliver it — in Quest by default, or in Backlog.md/Jira Cloud once selected with lore init --tracker backlog/--tracker jira — through two independent references, one per direction:

Doc → task: the Arc’s tasks: frontmatter list (tasks: [task-42, task-57]) is the source of truth, edited by lore link / lore unlink or by hand.

Task → doc: the back-reference is a queryable doc:<conceptId> label, set by lore link on the task itself — not a custom field, since Backlog.md drops unknown frontmatter keys on edit and neither Quest nor Jira Cloud has a free-form field for it either. The same label-based back-reference is used across all three trackers.

lore sync then reads each linked task’s live status and reconciles the Arc’s authored status to match, rewriting the managed task block at the same time; lore check is the read-only version of that same comparison, reporting drift instead of fixing it.

The tracker prerequisite

A configured task tracker is a hard prerequisite for some commands and irrelevant to others — by default that means Quest on PATH; run lore init --tracker backlog for a --json-capable Backlog.md, or lore init --tracker jira for Jira Cloud, instead. The same command list applies whichever backend is selected. Stated exactly:

Needs a tracker

  • lore link
  • lore unlink
  • lore sync (only for concepts with a tasks: entry)
  • lore tasks (only for a concept with linked tasks; a concept with none rolls up to zero without one)
  • lore orphans
  • lore rename (only for concepts with a tasks: entry)
  • lore check (its status and managed‑block drift tiers)

Works without one

  • lore init
  • lore new
  • lore validate
  • lore graph
  • lore query
  • lore context
  • lore read (one concept exactly as authored, with no budget and no assembly)
  • lore scaffold
  • lore export (a read-only projection works with an empty task set on a tracker-disabled bundle)
  • lore types
  • lore replace
  • lore supersede
  • lore schema
  • lore path / lore impact
  • lore snapshot / lore changed / lore provenance / lore explorer
  • lore agent / lore agents

In short: authoring, validating, and navigating the OKF bundle never needs a task tracker. Coupling a doc to a task, keeping that coupling in sync, and reporting on it do — via Quest by default, or Backlog.md/Jira Cloud once selected with lore init --tracker backlog/--tracker jira.

Semantic exit codes

Every lore command draws its exit status from the same set of codes, in every output mode, so a script or agent can branch on the exit status alone. Six are shared by the whole CLI; the seventh, 7, is returned only by lore check:

0
success — the command completed, and for a gate, found nothing failing.
2
usage — an unknown flag or command, a malformed argument, a missing required argument.
3
not found — a referenced concept id, task id, file path, or link target doesn’t exist.
4
denied — the operation is refused, such as writing into a managed block.
5
conflict — already exists, or a concurrent-write race.
6
validation or drift — a gate failed: non-conformant OKF (lore validate), or bundle drift, broken links, committed-schema drift, or portability issues (lore check).
7
indeterminate — lore check cannot judge a committed schema (an orphaned .lore/schemas/ file this lore did not generate). Every finding is still reported, and 7 takes precedence over 6 in the same run. Do not run lore schema export or lore sync as the fix: read the file’s git history and decide by hand.

Exit code 1 is deliberately never used for an expected condition — it’s reserved for an uncaught, unexpected failure, so a caller can tell “lore told me my input was wrong” (2–7) apart from “lore itself broke” (1).

The CI gate

lore check is read-only — it never writes — and aggregates status-reconciliation drift, stale managed blocks, broken internal links and heading anchors, committed-schema drift (the fix is lore schema export), unknown types, and a portability lint, into a single exit code: 0 when the bundle is coherent, 6 when anything above is out of date, and 7 when a committed schema cannot be judged. Add --strict to fail on warnings too. That makes it a drop-in CI step:

- run: npx @opum-ai/lore check

Pair it with lore validate (per-file OKF conformance, also exit 6 on failure) to gate both the shape of each doc and the coherence of the bundle as a whole. Both run against your OKF content alone and don’t require a task tracker unless your docs link tasks (see the tracker prerequisite).

This page covers enough to evaluate lore and start a bundle. Every command, flag, and exit-code mapping is enumerated in the CLI surface and CLI contract references in the lore-cli repository on GitHub, lore help <command> prints one command’s flags and exit codes, and lore instructions prints the same agent-facing guidance on demand from your terminal.