This page is the repository's CHANGELOG.md, rendered at build time; the current release is 0.2.0. Versions follow Semantic Versioning at 0.x while OpenContext is in beta, and 1.0.0 is reserved for general availability. The notes are written for developers and use their shorthand: CLI is the command-line tool, MCP is the Model Context Protocol, SDK is a software development kit, OAuth is the sign-in grant a service such as Google issues, SSRF is server-side request forgery (a fetch tricked into reaching an internal address), CI is continuous integration (the checks that run on every push), UI is the user interface, and SSE is server-sent events (the stream the interface watches).
All notable changes to OpenContext are recorded here.
The format follows Keep a Changelog, and
the project follows Semantic Versioning at
0.x while it is in beta: the minor number carries breaking changes, and 1.0.0
is reserved for general availability. How a release is cut is in
docs/operations/RELEASE.md.
[Unreleased]
Added
- A repeatable security test gate (
npm run test:security) with an automatically discovered route sweep, hostile markdown fixtures, model handoff checks and source/policy-hashed evidence retained by CI. Seedocs/security/README.md. - Required-sign-in health checks now return availability only. Early request rejections carry privacy headers, and model callers cannot override the configured destination through SDK environment options.
- Native Codex prompt hooks alongside Claude Code hooks.
opencontext contextsupplies bounded repository and personal graph evidence with one-hop links;diagnoseexplains the actual CLI/vault target and each client's installation. - Settings > AI tools can preview the exact task context locally, with no model call. Hook installation and live-client trust are described separately.
- A double-clickable macOS app.
npm run desktopbuildsOpenContext.appinto~/Applicationsand puts a shortcut on the Desktop; clicking it finds Node (the Finder's PATH has neither nvm nor Homebrew on it), starts the server unless OpenContext already answers on the port, waits for/api/health, and opens the UI in a Chrome app window, or the default browser with--browser defaultor when Chrome is not installed. Clicking again while it runs skips the boot and opens the window, and failures are a dialog with the log rather than a bouncing icon.open -a OpenContext --args --stophands the port back. The bundle is generated, not tracked: it bakes in the checkout path, the port, and the browser choice, and the icon is drawn from the favicon's graph glyph in pure Node, so there is nothing to install first. - The account chip is present with sign-in off, where it used to be absent: a person glyph whose popover says this install trusts whoever reaches it on localhost, so there is no account to sign into, and how to turn sign-in on.
- The public site's legal and policy pages (docs/go-live/SITE-COMPLIANCE.md):
terms, a privacy policy for the website and the local software, a cookie
policy that explains why there is no consent banner (the site stores
nothing), a refund policy (nothing is sold), and an accessibility statement
with measured contrast, all linked from every page's footer and listed
under a Legal section of
llms.txt. Who publishes the site (name, location, governing law, contact routes) lives insite/publisher.jsonand reaches every page through placeholders;npm run site:build -- --releaserefuses to build while the contact email is empty (decision D-E). agents.mdat the site root, the agent primer as markdown, and aPersonpublisher entity plusdateModifiedin the JSON-LD.- Site accessibility: a visible focus ring, tables that keep their semantics
inside a scrollable wrapper with
scope="col"headers, keyboard-focusable code blocks, "Copy code" buttons that announce their result, larger tap targets, and reduced-motion support. The site suite now pins these, the no-form/no-cookie/no-storage/no-fetch claims of the policies, alt text on every image, heading order, and a plain-language rule (an acronym is expanded before its first use on every page). - Area rebaseline (docs/features/area-rebaseline.md): a coverage map that says
where a repository's knowledge graph is thin (
GET /api/repos/:id/coverage, with?for=<prompt>nominating the areas a task's words live in, thinnest first, with who cites them, commits since the graph, and the packages they import), a deepen job that runs one deep pass per named area without a re-survey (POST /api/repos/:id/deepen, capped per job like a baseline's dives, refused over the cap with the number), registry memory of every survey nomination and every area pass, a Coverage card on the project pane, andopencontext coverage/opencontext deepen. - The recall hook quotes with the files and identifiers an entity cites, names the prompt terms no entity mentions, and stops quoting on a single common word (calibrated on this repository's graph; the sign-in prompt of AB1/AB2 no longer quotes an unrelated decision on "credential").
- AB3 replicated to N=3 (docs/metrics/PLAN.md section 8): the injected arm was about a fifth cheaper every time; the blind judge preferred the control two of three on completeness, a trade the record names.
- Discoverability: a crawlable public site under
site/(seven answer-first pages, each with a markdown twin, canonical, Open Graph, and JSON-LD), generated bynpm run site:buildtogether withllms.txt,llms-full.txt, andsitemap.xml; crawler files (robots.txtallowing every documented AI crawler by name,ai.txt,humans.txt,agents.txt,.well-known/security.txt); a GitHub Pages workflow; and thesitesuite. - The running app answers
GET /llms.txt(the active vault rendered as an llms.txt index, one section per domain, every entity linked through/api/raw) andGET /agents.txt(the agent primer plus the MCP tool list), so an agent that only knows the server's address can discover the graph. Covered by thediscoverysuite. - A prepared, not yet published, manifest for the official MCP registry
(
mcp/server.json) and package.json metadata (description, keywords, repository, homepage). The unscoped npm namesopencontext,opencontext-cli, andopencontext-mcpare taken by unrelated packages; the manifest uses the scoped@alec-merle/opencontextpending decision D6. docs/marketing/DISCOVERABILITY.md: the playbook for becoming the cited answer in web search and AI answer engines, what is built, the naming collision, the compounding tricks, and the order of operations.
Changed
- Site copy corrected to what the code does: the distillation cost figure is labelled an estimate, the entity scan is listed as its own outbound path (its page fetches leave the machine through the address guard), the embedding index is "deliberately absent" rather than "on the roadmap", the 100-item confirmation is scoped to Drive and Gmail, and acronyms are expanded on first use.
Fixed
npm run demonow creates a disposable vault and blocks vault switching, so simulator output cannot contaminate the personal vault or its saved choice.- The live model diagnostic explicitly enables Read and requires a real tool call plus an exact random fixture result before reporting success.
- Structured-output turn-limit errors now reach the ingestion fallback even when the SDK throws after returning the error result. Failed-pass cost and cancellation behavior are preserved.
- Mobile navigation, graph focus/details, file headers and chat now fit phone viewports; the chat context graph is optional and appears below the conversation.
- Named graph components survive common-word filtering, linked decision excerpts prefer substance to attribution, and missing CLI vaults produce useful errors.
- Dev startup now stops the portable tsx watcher as well as the older npm-bin form, preventing stale servers from reclaiming the fixed API port after edits.
[0.2.0] - 2026-09-02
The production-readiness effort ("Go Live", branch go-live), aimed at the local
beta. What it is and its eight gates: docs/go-live/GO-LIVE.md.
Current status: docs/go-live/CHECKLIST.md.
Security
- An HTTP guard in front of every route: a Host allowlist (the loopback forms,
the bind address, the configured OAuth redirect hosts, and
OPENCONTEXT_ALLOWED_HOSTS) that refuses DNS-rebinding requests, and an Origin / Sec-Fetch-Site gate on every state-changing request. A non-loopback bind now prints a warning at every boot, and a busy port exits 1 with the fix instead of leaving the process listening to nothing. - Capture fetches connect only to addresses the SSRF guard vetted, with the lookup pinned and every redirect re-vetted. The scan agent's WebFetch calls go through the same guard, and invoked saved agents are vault-only with no web tools.
- Zip-based extractors are bounded before and during inflation (entry count, per-entry and total inflated bytes, compression ratio) against decompression bombs. Upload limits map to 413/400 sentences with temp-file cleanup.
/api/fileand/api/rawrefuse symlinks and decide forbidden prefixes on the real path.- Google state files (
_state/gdrive.json,_state/gmail.json) are written 0600 and atomically; a corrupt one is moved aside as<name>.corrupt-<timestamp>and reported rather than silently reset. - The privacy deep reviewer can no longer read held originals, findings in
_projects/are redacted, reviewer findings survive a re-audit, discard removes staged copies, and classifier truncation is visible instead of silent.
Added
- Agent links. Installing the CLI now also points the repository you installed
from at this machine's knowledge graph: a managed, marker-delimited block in
AGENTS.md,CLAUDE.md,CODEX.mdandREADME.md, naming the vault, the read commands, and that repository's own_projects/<slug>/graph, so a coding agent finds the graph in the first file it reads.opencontext linkandopencontext unlinkdo it in any other repository. The block is content-keyed: the begin marker carries a hash of its own body, so re-running refreshes a stale block in place rather than appending a second copy, an oldagent-guide >> AGENTS.mdappend is adopted into markers, and a block edited by hand is reported and left alone.--checkpreviews without writing and exits non-zero on drift (usable as a CI gate);--portableomits machine paths;--filenarrows the set;unlinkrestores the file byte for byte. The installers link only inside a git worktree, are guarded so a failure cannot fail an install, and honourOPENCONTEXT_LINK=0(skip) andOPENCONTEXT_LINK=<path>(retarget).RepoInfo.agentLinkreports link state for registered local repositories, and the Project pane shows it; the server never writes those files itself. See docs/features/agent-links.md. npm run setup(install both packages and build the web app) andnpm run doctor, a free offline prerequisite check covering Node, git, the Agent SDK's platform runtime, the web build,.env, the visible model credential, the vault, and the dev ports. The paid half staysnpm run doctor:live.GET /api/setup/status: version, Node version, platform, demo mode, the vault and where it came from, whether the web build is served, which credential is present (presence only), and areadyverdict with plain-sentence reasons.- In-app Anthropic key storage (
PUT/DELETE /api/settings/anthropic-key, mode 0600, outranks.env, no restart needed). GET /api/healthnow reports the running version frompackage.json..env.examplecovering every environment variable,.nvmrc,.editorconfig, andengines.node >= 22on both packages.- Continuous integration:
.github/workflows/ci.ymlruns typecheck, the offline suite, and the web build on every push and pull request, with the agent simulator on and every credential blanked, plus an advisorynpm audit. - The root-index audit:
GET /api/index-auditandPOST /api/index-audit/fix, which repairs the vault's README indexes in one revertible commit. - Thirteen offline suites:
index-audit,harness,http-guard,file-route,privacy-routes, andonboardingin wave 1;chats,knowledge-routes,ingest-paths, andcore-routesin wave 2; thenweb(the production build, a bundle audit, and the pure web modules under test),secret-scrub(sentinel credentials seeded into every store and proven absent from every response, log, feed entry, vault file, and the packaged CLI tarball), andagent-link. The offline run is now 46 suites. - A first-run "Get started" card on the Intake pane for empty vaults: add a credential, drop a document, connect a source, point your coding agents at the graph - each step with a live done check, gone once the vault has entities.
- A favicon, canvas glyphs for agent and skill graph nodes, and vault-scoped browser state (a vault switch drops the old vault's remembered chat, project, and pane instead of pointing at another vault's ids).
- A React error boundary around every pane
(
web/src/components/ErrorBoundary.tsx), so a render exception no longer blanks the whole app. - A placeholder LICENSE: a proprietary evaluation license for beta invitees, marked in the file as pending the maintainer's decision D-C.
- Documentation: docs/README.md as the index, the operations set (configuration, runbook, release), the testing guide, the Go Live definition, gap register, subsystem map, progress log and checklist, this changelog, CONTRIBUTING.md, SECURITY.md, and GitHub issue and pull request templates.
Changed
- The test runner enforces per-suite deadlines (default 600s,
--timeoutto change), rejects unknown flags with usage instead of silently running everything, gained--fail-fast, and reports the slowest suites. A hung suite is killed together with every process it spawned. - Every suite that binds a socket owns a row in one port table (
PORT_SLOTS) with its own environment override for parallel sessions; theharnesssuite fails the build on a duplicate port, a duplicate override name, or a listening script with no row.npm run free-portsreclaims only this project's own processes and reports anything else by pid, command, and directory. - Boot refuses to scaffold a vault into a populated folder that OpenContext did
not create, unless
OPENCONTEXT_VAULT_ADOPT=1grants it; a chosen vault that has gone missing falls back with a warning and amissingChoicestatus instead of being silently recreated; a vault living inside the app checkout is reported as such. - The activity feed's history follows the vault chosen at boot rather than the environment default, and the job list resets on a vault switch.
- The re-distillation verdict carries a sentence explaining why a source went stale.
- A vault whose entity catalog outgrows the single-shot prompt cap now distills against a relevance-filtered subset of the catalog instead of silently falling back to the roughly 10x-cost agent loop.
- Gmail gained an "API disabled in Google Cloud" diagnosis, per-account census resilience, and one paced runner for every metadata pass. Ghost "unknown account" grants are marked and swept, disconnect is refused while a job runs on the grant, the census reports a real summary, scan snapshots persist only privacy-masked subjects, and Drive detail walks are cached with loose shared-with-me files syncable as single-file sources.
- Forge clone URLs are validated against the connection's own host, GitHub
secondary rate limits read as transient instead of flagging reauth, ssh
origins fail fast instead of prompting, and repository notes write
local_pathhome-portable (~/...) through the guard and privacy screen so a pushed vault leaks no username. - X bookmark syncs resume without dropping the rest of a capped page, refuse overlapping runs, and mark posts imported only when the enqueue succeeded.
- The server sends conservative security headers (a strict app-shell CSP,
nosniff, no-referrer, frame denial), answers malformed or oversized JSON with
readable 400/413 sentences, sweeps orphaned upload temp files at boot, exits
cleanly on an uncaught exception instead of serving in an unknown state,
validates vault remote URLs before handing them to git, and bounds PDF text
extraction by pages and wall clock with the truncation narrated. Agent
invocations get a wall-clock deadline. The privacy events ledger rotates past
8 MB and reads a bounded tail, and unscreenable documents are counted as
"not screenable" instead of screened. An
npm audit fixcleared every high finding lockfile-only (three moderates remain in the express body-parser qs chain, not reachable without an upstream release - waived for the beta). - PDFs past 100 pages with a usable text layer distill from that text instead of being skipped, and the large-file hold estimates text size per format.
- The CLI's server probe distinguishes down, timeout, and unhealthy, and the MCP server answers with the reason when its pinned vault is missing rather than reporting an empty graph.
Fixed
- A frontmatter block-list parser bug.
gmail-doctorread the pre-multi-account state shape, so its grant check never ran.- A Gmail 401 retry now drops the cached token first.
- A "Flag only" privacy rule no longer quarantines the document.
[0.1.0] - 2026-09-01
The version carried by package.json since the project began. It was never
tagged and never released; this entry records what the product was when the Go
Live effort started, so the section above reads as a delta. Dates come from the
Status lines in ROADMAP.md.
Added
- Ingestion and distillation. Drop a document in and an agent decomposes it
into a knowledge graph of plain markdown, one entity per file, relationships as
relative markdown links, agent-maintained README indexes at every level.
Universal extraction (2026-08-21): sniffing from the bytes, a format registry,
_extracted/, and PDF, Word, Excel, PowerPoint, OpenDocument, EPUB, RTF, HTML, email, markdown, CSV, and source code. Single-shot distillation (2026-08-27): one toolless model call plus a deterministic writer, roughly 10x cheaper than the agent loop, with the loop kept as the automatic fallback. The default model isclaude-sonnet-5, chosen by a three-way bake-off (2026-08-21). - Vault versioning and rollback (2026-08-24): git underneath the vault, one commit per operation, a History pane, and undo. Remote push added 2026-08-27.
- Privacy and security layer (2026-08-24): deterministic detectors with structural validation, a preflight hold before the model reads a document, a write-boundary redaction hook, and an audit over the vault. The PDF text-layer pass shipped 2026-08-27.
- Chat. Server-persisted conversations with citations, checkpoints, and a sidebar list (2026-08-21); the context-graph panel and composer amenities (2026-08-23); anchored conversations; context economics and the evidence surfaces (2026-08-24), with the aggregate Evidence pane added 2026-08-26 and rebuilt as a ledger 2026-08-27.
- Insights (2026-08-21): a signal engine over the graph plus a fresh-context agent whose analysis streams into a review queue.
- Knowledge graph views (2026-08-23): the Organize layout engine.
- Sources. Google Drive (2026-08-23), Gmail (2026-08-25, later multi-account with the financial census), GitHub and GitLab connections (2026-08-24) with repository ingestion (2026-08-21), X bookmarks, link and paste capture, and assistant-history import for ChatGPT, Claude, and Gemini exports (2026-08-26). Every integration uses your own OAuth client or token, read-only scopes, and on-demand syncs.
- Entity web scan (2026-08-23, extended 2026-08-24): hydrating people and organizations from the web, within the same write guard.
- Coding-agent surface: the
opencontextCLI and an MCP server with a one-line install (2026-08-26), so an external agent can search, read, traverse, and contribute to the vault. - Agents and Skills (2026-08-30): reusable agents built from the vault's own patterns, with a review queue, promotion, and invocation.
- Duplicates: detection with a source-of-truth sign-off and a dedupe commit.
- Projects (2026-09-01): per-repository knowledge graphs under
_projects/<slug>/, pointer metadata on the repository's note, and project-scoped chat. - Vault search:
GET /api/searchand a Cmd/Ctrl+K palette. - Settings: in-app vault switching, the OpenRouter model provider as an alternative to Anthropic direct, self-set spend budgets, and naming conventions.
- Metrics and the bench harness (2026-08-29): per-run token and cost
instrumentation, and
npm run benchfor measured accuracy and cost. - Demo mode: the whole pipeline on a deterministic simulator, no tokens spent.