Releases: aakarim/OpenLore
Release list
v0.6.1
What's Changed
- fix(http): apply mcp.require_auth to the JSON API as well as /mcp by @aakarim in #77
- fix(mcp): set is_error and exit_code on non-zero shell exit by @aakarim in #74
- fix(config): let an explicit config file take precedence over the embedded openlore.yml by @aakarim in #76
- fix(shell): print rule rejections verbatim instead of redirect: : rules: by @aakarim in #75
- docs(deploy): verify authenticated connectivity by @aakarim in #81
- fix(history): migrate legacy commit journals by @aakarim in #79
- fix(shell): support attached cut option values by @aakarim in #80
- Support direct file editing over SFTP by @aakarim in #78
- chore: release v0.6.1 by @aakarim in #82
Full Changelog: v0.6.0...v0.6.1
v0.6.0 — Context controls: folder rules with fixed and sticky file budgets
Introducing context controls
Agents are good at adding detail and bad at knowing when a shared file has enough. A focused engineering plan grows marketing context; an architecture document becomes an implementation dump; every later agent pays to read all of it.
OpenLore v0.6.0 governs that problem at write time. Set a budget for matching files and OpenLore checks every incoming write before it reaches the shared knowledge base.
What is new
- Three budgets: kibibytes, lines, and estimated tokens (
size/kilobytes,size/lines,size/tokens). - Directory and glob scope: put
.lore/config.yamlin a folder and match paths below it. Folder rules layer withlore.jsonrules; a child folder can add or tighten but never loosen a parent's rule unless the parent marks itdefault: true. - Fixed limits: set an absolute
max. - Sticky limits: set
max: initialwithgrowthto derive a durable cap from the file's first baseline. Usegrowth: 1.0for a strict first-write ceiling; values above 1 allow controlled growth.lore size baseline <path>shows the history;lore size baseline reset <path> [--note]appends a new baseline and is audited. - Actionable rejection: an over-budget write names the rule and its origin, reports measured versus allowed size, tells the agent to rewrite within budget or split detail into a linked sibling file, and names the override path.
- One rules engine: file rules run on every write surface (SSH, MCP, HTTP shell; redirects, append,
patch,sed -i,tee, batches) and underlore validate. The existing OKF docset block is now shorthand forokf,okf/bundle,link/resolvesandlink/aliasrules. - Discoverable policy:
lore package listandlore package doc size/linesshow compiled-in members and their parameters. - Permissioned: editing a folder's
.lore/config.yaml(or resetting a baseline) requires a write grant plus a role in the docset'sconfig.edit.
Example
# specs/.lore/config.yaml
version: 1
rules:
spec-lines:
match: ["**/*.md"]
exclude: ["drafts/**"]
use: size/lines
with: { max: 200 }
stable-architecture:
match: ["architecture/*.md"]
use: size/tokens
with: { max: initial, growth: 1.0 }size/tokens uses estimate/v1: ceil(bytes / 4). It is an approximate content budget, not a provider tokenizer or billing counter.
When a write exceeds its budget
rules: /docs/adr/a.md: size/lines (adr-sticky @ /docs/adr/.lore/config.yaml)
11 lines exceeds the limit of 10 (baseline 10 lines × growth 1, set 2026-09-04 on create)
this file cannot grow past 10 lines under this rule
suggested: keep a.md under 10 lines; move the new material into a sibling file such as a-details.md and add a link to it from a.md so readers can drill in
override: a role in config.edit can run `lore size baseline reset /docs/adr/a.md`
see: lore package doc size/lines
OpenLore rejects the whole write or batch. It does not rewrite the content automatically.
Rules and provenance
Sticky baselines are durable, append-only state stored beside the governed content (<dir>/.lore/size/<file>.jsonl, never listed or readable through the VFS). Baseline creation and reset retain attribution, rm clears and recreate restarts a baseline, and moving a file carries its baseline.
Also in this release
- Persistent HTTP shell sessions (#42) and interactive shell tab completion (#63).
- Externalized deployment lifecycle, container images on GHCR, and Fly.io/Railpack deployment (#41, #44, #46).
- Guided setup and onboarding skills (#47, #48, #50, #51, #55–#62).
- OAuth refresh retry tolerance (#38, #43); config tolerates invalid value types at startup (#49).
- Path-sharded file-history index fixing 503s on large histories (#68).
- Race-detector CI (#52).
Install or upgrade
go install github.com/aakarim/go-openlore/cmd/openlore@v0.6.0
openlore version # openlore 0.6.0Container images: ghcr.io/aakarim/openlore:0.6.0, :0.6, :0. Verify downloaded binaries with checksums.txt below.
Upgrade notes
Upgrading from v0.5.0 requires no policy migration. Deployments without rules keep their prior write behaviour; folder rules are opt-in. Back up content and data directories before upgrading; sticky baseline state is additive under hidden .lore/ package state.
Known limitations
- Estimated tokens use
ceil(bytes / 4), not a model-specific tokenizer.rules.tokenizerinopenlore.ymlis reserved and rejected. - The release rejects or warns; it does not summarize, rewrite, or split content itself.
- The folder configuration path is
.lore/config.yaml, not.lore.yaml. - User-authored scripts, hooks, operations, and LLM policy workflows are not part of v0.6.0; the
packages,hooksandoperationssections are reserved. - Bundle-scoped checks (OKF bundle structure, link resolution) run under
lore validate, not on each write.
Docs
Commit set
Base: v0.5.0 (ce05c3a) · Release head: 682fc65 · Comparison: git log --oneline v0.5.0..v0.6.0 (36 commits)
Artifacts and checksums (SHA-256)
3474fa0ff448165c176116e67b7902fda62015838a8cf61ece6c153277a430f4 openlore-darwin-amd64
7025259f9d972a03058e444171c2f1b620efa366fe3ff0b0af8be89f790a6744 openlore-darwin-arm64
6452e56413dea2218711cf5ef1d23ab914600bc37e35f7307fde5247e53fcca5 openlore-linux-amd64
8641e7ac1d5fd20eeb49909c83978b031682fc38dc61126e6e7631c986dc135b openlore-linux-arm64
96e6e1d705e82551a2e701414f94769f02ba61004396058535844ba3aad923a7 openlore-windows-amd64.exe
Source SHA recorded in source-sha.txt. Built from the tagged checkout by .github/workflows/release.yml.
What's Changed
- fix(oauth): tolerate concurrent refresh retries by @aakarim in #38
- feat(browser): identity header with permission-settings dropdown by @aakarim in #39
- UI theme overhaul: Oiya purple/orange palette by @aakarim in #40
- Add Fly.io deployment with Railpack by @aakarim in #41
- Add persistent HTTP shell sessions and prevent shell panics by @aakarim in #42
- Tolerate OAuth refresh retries after client backoff by @aakarim in #43
- ui(browser): blue links and lighter body weight for legibility by @aakarim in #45
- Add externalized deployment lifecycle and container images by @aakarim in #44
- build: copy only binary into container image by @aakarim in #46
- skills: make setup a guided interview by @aakarim in #47
- Tolerate invalid config value types at startup by @aakarim in #49
- skills: seed shared lore context during setup by @aakarim in #48
- teach: interactive welcome with A/B/C server question by @aakarim in #51
- Add agent-type skills: shellm support, portable openlore-skill, teach onboarding by @aakarim in #50
- ci: run Go tests with race detector by @aakarim in #52
- test: enforce VFS preconditions in test doubles by @aakarim in #53
- docs: add SSH admin guide to embedded lore by @aakarim in #54
- teach: short interactive router that fetches guides over SSH by @aakarim in #55
- setup: prefer local Go, teach the permission model, fix lore.json schema by @aakarim in #56
- setup: set the blueprint-vs-server mental model before asking for a folder by @aakarim in #57
- Set up Amp orb development environment by @aakarim in #58
- docs(setup): default_cwd / instead of /user/onboarding by @aakarim in #60
- docs(setup): accept a website address for the who-is-this-for question by @aakarim in #59
- docs(setup): add user role and enroll the setup agent as a delegate by @aakarim in #61
- docs(deploy): offer a passkey for the web UI at the end of onboarding by @aakarim in #62
- Add interactive shell tab completion by @aakarim in #63
- docs: move HTTP inbox uploads into guide by @benturner11 in #64
- Folder rules system: Phase 1 by @aakarim in #66
- Rules: add Phase 2 package discoverability by @aakarim in #67
- Implement Phase 3 folder rule configuration by @aakarim in #69
- Implement folder rules phase 4 by @aakarim in #70
- docs: folder rules guide, lore size commands, config keys, skill update by @aakarim in #72
- Fix file-history 503s with path-sharded index by @aakarim in #68
- chore: release v0.6.0 by @aakarim in #73
New Contributors
- @benturner11 made their first contribution in https://github.com/aakarim/OpenLore/pull...
v0.5.0 — Verified agent identity, permissions, and provenance
Provenance: who changed what, on the record
Every committed write is now recorded durably as a queryable CommitRecord: who (verified principal and delegate), how they authenticated, what changed (changeset and content hash), and when.
Verified client identity
- OAuth 2.1 Client ID Metadata Documents (CIMD) provide stable client identities.
private_key_jwtauthentication is verified against same-origin JWKS and cannot silently downgrade to a public client when advertised.- Optional mTLS corroboration records stronger client authentication when OpenLore terminates TLS.
openlore oauth keys rotatesupports hot signing-key rotation and compromise revocation.
Per-agent, per-docset permissions
- Read/write grants per docset with roles, nested carve-outs, and home docsets.
- A permissions dashboard manages docset viewership per delegated identity in real time.
- Custom roles remain extensible through the plugin system.
Workload Identity Federation
- The
jwt-bearergrant verifies registered OIDC issuers and exchanges external assertions for short-lived, scope-capped OpenLore tokens. - Claim-to-identity rules narrow rather than widen access, unmatched claims fail closed, and token lifetime is capped.
- Existing non-WIF tokens retain full scope, so the feature is additive for v0.4.x users.
WIF verification is covered by the injected-verifier test suite. A live-IdP exchange was not available in the release environment and remains an explicit verification exception.
Also in this release
- MCP tool safety annotations.
- Browser file edit-history sidebar and delegated-identity permissions dashboard.
- Shell support for multiline
sed, SSH redirection,/dev/null, and stderr redirects. - Improved unsupported-shell diagnostics and agent-facing browser copy-path guidance.
- OAuth auth-state writability fix and updated authentication documentation.
Install or upgrade
go install github.com/aakarim/go-openlore/cmd/openlore@v0.5.0
openlore versionUpgrading from v0.4.x requires no config changes. WIF and authenticated clients are opt-in.
Known limitations
- mTLS is best-effort corroboration, not mandatory authentication; reverse-proxy certificate forwarding is unsupported.
- Write provenance is a local durable JSONL log and is not replicated.
- Per-identity permission management is available through the dashboard and configuration; there is not yet a dedicated per-identity CLI.
Verified release
- Source:
ce05c3a26dcfae3a6ba684f12973cfd15f60d6a4 - Gates: tests, race tests, vet, build, all five cross-platform builds, downloaded checksums, version smoke test, and downloaded-artifact OKF validation.
- Artifacts were built directly from the immutable tagged checkout.
source-sha.txtrecords the source commit.
SHA256
56e5ac4a165c64f61c5d4abdc4077bd8ea0ac64fd60f5d2316e12209186d9308 openlore-darwin-amd64
7eb07a06647a255ea1bf225125f8f77d3793929fcd8306a591d06b1be487d335 openlore-darwin-arm64
1207f9c6ac8efb1f5e21ae063101669b7b99337b2acaad434161c15dcc0e0886 openlore-linux-amd64
33083e26e04a411260091e1e4b72f6b1cc8919e899e223f803d712ed3cb37c20 openlore-linux-arm64
a821df94f3013f3fc1c400eeadcdcb330b6fa2a0ebb6aa18746b1dbdf325e505 openlore-windows-amd64.exe
Full changelog: v0.4.1...v0.5.0
v0.4.1 — Open Knowledge Format v0.2
OKF v0.2 support
The built-in OKF validator now targets Open Knowledge Format v0.2 while continuing to accept v0.1 bundles.
- Version detection: a bundle's spec revision is read from the
okf_versiondeclaration in its rootindex.md(quoted or unquoted); versionless bundles are linted against the latest revision, and unknown versions warn instead of rejecting, per §12. - v0.2 field families:
lore validatenow shape-checks the optional provenance (sources,usage_window), trust (generated,verified), lifecycle (status,stale_after), and Attested Computation contract fields — as warnings, never errors, per §11's permissive conformance policy. - Composable checks: each family is an exported
okf.ConceptCheck; consumers can assemble custom check sets or pin a spec version withokf.ValidateBundleAs. - v0.1 bundles: declaring
okf_version: "0.1"skips v0.2 family checks and shape-checks the legacytimestampfield instead. Write admission (hard conformance) is identical across both revisions.
Full changes: v0.4.0...v0.4.1
v0.4.0 — Agent Skills: import, track, and discover
OpenLore v0.4.0 makes Agent Skills a first-class, governed capability: turn any writable folder into a self-validating Skills collection, import public skills from any major Git forge, keep them synchronized with upstream, and let agents discover them with one metadata query. The web app also becomes an installable PWA, and inboxes gain authenticated HTTP upload routes.
Agent Skills: collections, remote imports, and discovery
-
Portable Skills collections.
skills enable [folder]marks a directory as a recursive Agent Skills collection. The marker travels with the directory, works at runtime without a server restart, and needs no static docset configuration.skills disableturns collection behavior off without deleting skills. -
Import from any public Git forge.
skills import <spec> [parent-dir]imports a public skill from GitHub, GitLab, Bitbucket, Codeberg, or self-hosted GitLab/Gitea/Forgejo over HTTPS. Shorthandowner/repomeans GitHub. Repositories containing multiple skills return a candidate list with names and descriptions; rerun with the selected path, e.g.skills import owner/repo/path/from/candidate@main. -
Tracked remotes. An omitted ref tracks the repository's default branch; a
@branchref tracks upstream and checks for updates whenSKILL.mdis read (throttled byremote_check_ttl); a tag or full commit SHA is pinned.skills updateforces a check-and-apply,skills remove-remotekeeps the files but stops tracking. Linked skill files are read-only locally, so upstream stays the source of truth. -
Agent-legible management.
skills statusandskills validatereport collection state, linked remotes, and findings as NDJSON. Ordered ChangeSet batches are rollback-safe, so a failed import leaves no partial state. -
Discovery.
lore meta --filter skillsscopes metadata to Skills collections and returns only validSKILL.mdrecords — frontmatter plus path:lore meta --filter skills | jq -r 'select((.name + " " + .description) | test("pdf"; "i")) | .path'
-
Configuration. Enable the plugin in
openlore.yml; the remote settings are optional and default as shown:plugins: skills: enabled: true remote_check_ttl: 60s remote_timeout: 3s remote_max_bytes: 10MB
Mutating skills commands require writing to be enabled and a named
rwgrant on the destination docset; a home docset is implicitlyrwfor its owner.
See the skills import demo in the README.
Web and PWA
- The web app is now an installable PWA.
- File actions in the PWA, including an open action on the file overlay.
- Path aliases are hidden from the browser; canonical paths remain authoritative.
Inbox HTTP uploads
- New authenticated HTTP upload routes for docset inboxes: identity-bound inbox credentials, bearer and HMAC authentication, an isolated upload policy, multipart metadata batches, token management, and middleware-safe partial commit reporting.
Documentation
- README restructured with a detailed installation section and demo videos.
- Remote skill imports and skill discovery via
lore meta --filter skillsdocumented indocs/plugins.mdanddocs/commands.md. - Stale docs removed.
Limitations
- Skill imports support public repositories over HTTPS only; authenticated or private forges are not supported yet.
- Update checks happen on
SKILL.mdreads (subject toremote_check_ttl), not as a background sync.
Upgrading from v0.3.x
No breaking configuration changes. To use Agent Skills management, add plugins.skills.enabled: true to openlore.yml and run skills enable in a writable collection directory.
Full Changelog: v0.3.0...v0.4.0
v0.3.0 — OKF validation, RBAC, and knowledge doc tooling
OpenLore v0.3.0 adds first-class Open Knowledge Format (OKF) v0.1 support: validate knowledge as it is written, inspect its metadata efficiently, and lint complete bundles before publishing. This release also introduces role-based access control, Agent Skills collections, path aliases, a root writable overlay, and improved MCP and web experiences.
Breaking: authorization is now role-based, and writable disk content is configured as one root overlay. Existing v0.2 configurations should be updated using the migration notes below.
Open Knowledge Format (OKF)
- Built-in, per-docset OKF v0.1 validator plugin checks Markdown writes before commit. It can reject invalid documents (
enforce: true, the default) or warn while allowing them. - OKF scope follows docset ownership and nested-docset boundaries, keeping validation aligned with authorization. Patterns are configurable and default to
*.md. - New dependency-light
pkg/okfpackage exposes frontmatter parsing and single-file/bundle validation for downstream Go tooling. - New
lore validate [bundle]lints complete bundles with grep-friendly diagnostics for OKF conformance, broken/local links, paths that escape a bundle, and alias portability. - New
lore metaemits frontmatter as NDJSON and lets plugins enrich metadata. When OKF applies, records include validation status. - Built-in plugins now report their names and semantic versions in startup logs.
Role-based access control
- Roles now group docset grants and capabilities; docsets define resource-centric allow/deny ACLs, with deny precedence and additive grants.
- Authorization is resolved dynamically for current identities, while writes and capabilities are reauthorized at invocation time.
- Nested docsets are hard access boundaries: ancestor grants cannot expose or mutate an ungranted child docset.
- Ungranted namespaces and nested docset names are hidden while navigation ancestors remain visible only when needed.
- Home directories remain implicitly read/write for their owners;
guestis reserved for keyless access. - New CLI management commands cover roles, identity assignments, docset ACLs, and role capabilities.
Knowledge organization and agent tooling
- Docsets support durable path aliases while authorization, writes, hooks, CAS state, and events use canonical paths.
lore docsetsreports canonical and alias mounts explicitly. - A single
writable_dircan overlay embedded content at the virtual root, replacing separate named folder mounts. - New opt-in Agent Skills docset plugin validates Agent Skills collections during admission and commit, and exposes skill discovery through
lore meta --filter. - The writable shell now supports atomic, file-only
mvoperations.
MCP, OAuth, and web
mcp.require_authcan force OAuth for MCP independently of keyless SSH, or explicitly allow anonymous MCP while SSH requires a key.- OAuth resource matching accepts equivalent canonical root URIs with or without a trailing slash, improving compatibility with OAuth-native MCP clients.
- The authenticated browser now renders Markdown with breadcrumbs and navigation while keeping raw HTML disabled.
- YAML frontmatter is displayed separately and preserves nested formatting instead of rendering as Markdown.
Migration from v0.2.x
- Define top-level
roles, assign identities withroles, and move docset permissions todocsets.<name>.access.allow/deny. Legacy per-identity docset grants remain parseable but are non-authoritative when RBAC is enabled. - Replace
foldersmounts with onewritable_dirinopenlore.yml; filesystem paths define content layout whilelore.jsonindependently defines docsets and access. - Review nested docsets: the most-specific docset now governs access, so roles need an explicit grant on each nested boundary they should enter.
- To enable OKF, add an
okfobject to each governing docset inlore.json; no global OKF configuration is required. - To require browser authentication for hosted MCP while preserving keyless SSH, set
mcp.require_auth: true.
Maintenance
- Relocated the metadata scanner to
pkg/openlore/metaso the reusable read-side package lives under the OpenLore namespace. - Removed stale internal design documents after their behavior was incorporated into current documentation.
See lore.json.example, openlore.yml.example, and the README for complete configuration and usage.
Full Changelog: v0.2.0...v0.3.0
v0.2.0 — experimental writes, grant-based access control, and MCP/HTTP auth
OpenLore v0.2.0 turns the read-only lore server from v0.1.0 into a writable, multi-identity knowledge substrate with per-docset access control, agent write capabilities, and token-based auth for MCP/HTTP.
Breaking: the
loreview + per-identitypublishlist + docsetpublish_dirmodel is replaced by a per-docset grant model. See Migration below.
Writable substrate
- Experimental writable filesystem (
readonly: false) with atomic writes and a single ordered write log as the sole substrate writer. - Shell write surface:
>,>>,tee,patch,sed -i, andpublish. - Session compare-and-swap: last-read hashes are tracked so a blind overwrite fails if the file changed since it was read (
hash/last_write_wins, per-docset overridable). - Async
spawnjobs (capability-gated) with output written back through the scoped FS; surfaced read-only at/jobs.
Access control: grant model
- Each identity holds a named grant per docset:
ro(read whole docset) orrw(read + write anywhere in it). - Inbox plugin adds a
publishgrant: read the whole docset, never delete, create/edit only within the docset's configuredinboxfolder. - Reads are path-subtree scoped — a session only sees the docsets it holds a grant on (sibling docsets are hidden).
- Writes run through a per-operation authorizer (grant ∩ token scope ∩ readonly locks), fail-closed.
- Unknown grant names are a hard startup error.
public_keyis now optional — passkey/token-only identities are allowed.- Per-identity home docset (
$HOME,cdwith no args).
Auth for MCP + HTTP
- Bearer-token auth with OAuth login (
/authorize,/oauth/token), Dynamic Client Registration, and discovery endpoints. - Workload Identity Federation: exchange external IdP JWTs for OpenLore tokens (jwt-bearer grant), with per-identity
matchrules that can narrowscope/ttl. - SSH/SFTP sessions are identity-scoped through the same layered FS — SFTP no longer bypasses read scoping.
MCP
- Always-on MCP-over-HTTP mounted on a path of the existing HTTP server (no separate port).
Introspection
lore docsetsshows the per-session docset views (grant, inbox, writability, home).
Migration from v0.1.0 lore.json
- Remove
docsets.<name>.publish_dir; addinbox: "<folder>"where an inbox is wanted. - Replace the top-level
loremap with per-identitydocsets: { "<docset>": "<grant>" }. - Replace per-identity
lore(read) +publish(write) with grants:rofor read-only docsets,rwfor writable,publishfor inbox-only. - Add a top-level
default: { "<docset>": "ro" }for keyless/anonymous access. - Bearer-token config (
tokens:) lives inopenlore.yml, notlore.json.
See lore.json.example for the full new schema.
v0.1.0 — read-only SSH knowledge file server
The original OpenLore: an SSH-accessible, read-only virtual filesystem that serves developer documentation ("lore") to humans and coding agents over plain SSH.
Highlights
- Browse docs over SSH with familiar shell commands —
ls,cat,grep,find,tree,head,tail,sed,awk,jq, and many more — all operating on a read-only virtual filesystem. - Docsets & lore — organize documentation into docsets and compose them into named "lore" views per identity.
- Auth — SSH public keys,
allow_keylessanonymous access, and passkeys (WebAuthn). - MCP-over-HTTP — expose the same content to MCP clients on a path of the existing HTTP server.
- Embeddable — ship your own docs as an embedded filesystem with the
teachworkflow.
This release marks the last version before the writable substrate and agent write capabilities were introduced. Write support (atomic writes, scoped per-agent writes, human-gated approvals, and async write-back) lands in later releases.