Releases: linchpinhq/linchpin
v0.7.0 — Dreams (research preview)
Research preview. Mirrors Anthropic's own research-preview posture for the same feature. Operators opt in by setting
LINCHPIN_DREAMER_AGENT_ID.
Dreams — async memory curation. A Dream reads an input memory store + a filtered slice of past sessions and produces a new memory store with the curated content. The input store is never modified — the user decides whether to swap to the curated one or keep both.
Why
After hundreds of sessions writing to the same memory store you get duplicates, contradictions, and stale entries. Dreams is the cleanup pass — expensive, opt-in, run only when needed.
API
POST /v1/dreams — start a Dream
GET /v1/dreams — list dreams (newest first, ?status= filter)
GET /v1/dreams/{id} — status + output store id when complete
POST /v1/dreams/{id}/cancel — cancel a running dream
Request body:
{
"input_memory_store_id": "memstore_...",
"output_store_name": "curated-prefs",
"session_filter": {"agent_id": "agt_...", "since": "2026-05-01", "limit": 50},
"dreamer_agent_id": "agt_dreamer_..."
}Status lifecycle
pending → running → completed / failed / canceled
A Dream is itself a managed Linchpin session running the configured dreamer agent. Most of the implementation is the lifecycle table + linkage to the input store, output store, and dreamer session.
Operator notes
- Set
LINCHPIN_DREAMER_AGENT_IDto the agent id Linchpin should default-spawn for dreams. Without it,POST /v1/dreamsreturns 422dreamer_not_configuredunless the request suppliesdreamer_agent_iddirectly. - Session filter caps at 100 sessions per Dream — matches Anthropic's limit.
- Output is a new memory store, not a mutation. Users/operators decide whether to swap their agent's attached resource to the curated store or keep both around.
Out of scope
- Auto-scheduling Dreams (operators wire that themselves).
- Cross-store curation, cross-workspace visibility.
Schema migration
0015_dreams — new dreams table + indexes. Run alembic upgrade head after pulling.
See CHANGELOG.md for full details.
v0.6.0 — Outcomes + Multi-agent threads
Linchpin starts looking less like "an API for running an agent" and more like "an API for running a team." Two PRs.
Highlights
Outcomes
Declare a goal at session create and let the runtime grade it:
{
"outcome": {
"definition": "Tests pass and a PR is open with the fix.",
"rubric": [
{"criterion": "All tests in pytest pass", "weight": 0.5},
{"criterion": "A PR is open referencing the issue", "weight": 0.3},
{"criterion": "The fix is minimal and focused", "weight": 0.2}
],
"grader": {"type": "agent", "agent_id": "agt_grader_..."},
"success_threshold": 0.8,
"auto_terminate": true
}
}- Rubric ≤16 criteria, weights sum to 1.0.
POST /v1/sessions/{id}/outcome_evaluationsrecords grader results; emitssession.outcome_evaluation_ended; auto-terminates + emitssession.status_terminatedwhen the score crosses the threshold.GET /v1/sessions/{id}/outcome_evaluationsreturns history newest-first.- Threshold read from the stored outcome — a grader can't lower the bar inline.
Multi-agent threads
Coordinator agents spawn worker sub-sessions via POST /v1/sessions/{parent_id}/threads:
- Each thread is a normal session (own container, own event log, optionally its own outcome) linked back via the new
sessions.parent_session_idcolumn. - Event mirroring: every event a thread emits is appended to each ancestor's event log with a
thread_idpayload tag, so a coordinator watching its own stream sees one interleaved view. - Depth cap via
LINCHPIN_MAX_THREAD_DEPTH(default 3) — coordinator → worker → grader is the canonical pattern. A 32-hop walker guard prevents pathological-cycle runaways. session.thread_createdfires on spawn;session.thread_terminatedfires on terminate — symmetric.
Schema migrations
0013_sessions_outcome—sessions.outcomeJSONB + newoutcome_evaluationstable.0014_sessions_parent—sessions.parent_session_idself-FK withON DELETE SET NULL.
Run alembic upgrade head after pulling.
Operator notes
LINCHPIN_MAX_THREAD_DEPTHdefaults to 3 — raise only when a workflow legitimately needs deeper trees.- Event-mirroring writes are best-effort; a mirror failure logs and continues so the thread's own log isn't held hostage to an upstream NOTIFY hiccup.
See CHANGELOG.md for the full per-PR breakdown.
v0.5.0 — Multimodal + Remote MCP + Git repos
Three medium-sized features that round out Linchpin's resource and content surface — none individually justifying a minor, together rounding it out cleanly.
Highlights
Multimodal content blocks
user.message.content[] now accepts text + image + document blocks alongside the legacy plain-string shape:
{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{"type": "image", "source": {"type": "file", "file_id": "fi_..."}}
]
}- Sources:
base64,url, orfile(resolved through the existing Files API). - Images: JPEG / PNG / GIF / WebP. Documents: PDF / text / markdown.
- Provider routing trusts the model — Claude family gets Anthropic's native document shape; other models error cleanly upstream when unsupported.
Remote URL MCP transport
mcp_servers[] widens to a discriminated union — alongside the existing stdio subprocess shape, agents can now attach SaaS MCP servers over HTTP:
{
"mcp_servers": [
{"type": "stdio", "name": "fs", "command": "npx", "args": ["@modelcontextprotocol/server-filesystem"]},
{"type": "url", "name": "gh-copilot", "url": "https://api.githubcopilot.com/mcp/", "vault_ids": ["vault_xyz"]}
]
}- Legacy stdio configs (no
typekey) keep validating — no DB migration needed. - Connector adds
MCPRemoteManagermirroring the stdio manager's surface. Handles both JSON and SSE responses (MCP streamable HTTP transport). - Connector stays credential-blind — the API resolves vault tokens to a Bearer header.
Git repository resource (real clone)
The resources[] framework declared github_repository back in v0.2.0 — v0.5 fills it in and generalizes to any HTTPS remote:
{
"type": "git_repository",
"url": "https://github.com/org/repo",
"mount_path": "/workspace/repo",
"authorization_token": "ghp_...",
"branch": "main",
"shallow": true
}- Generic, not GitHub-only. GitLab, Bitbucket, Gitea, self-hosted — anything that speaks HTTPS git.
- Per-environment cache. Two sessions in the same env that mount the same (url, branch) share one on-disk clone.
- Cache hit refresh:
git fetch+git checkout+git reset --hard. Cache miss: clone into.tmpthen atomic rename. - Token safety: embedded only during clone, then the remote is rewritten to the clean URL so subsequent fetches don't leak the secret. Clone errors redact the token from stderr.
GithubRepositoryResourceretained as a legacy alias — v0.2-v0.4 clients keep working; persisted rows canonicalize togit_repository.
Schema migrations
None. All three features ride on existing JSONB columns / tables.
Operator notes
LINCHPIN_GIT_CACHE_ROOTdefaults to/var/lib/linchpin/git_cache— provision durable storage; clones are typically the largest single resource volume.- Existing v0.4 stdio MCP rows keep validating; no migration needed.
See CHANGELOG.md for the full per-PR breakdown.
v0.4.0 — Skills
Skills — filesystem-based packaged expertise that progressively discloses to the agent. Pairs with v0.3.0's Memory: Memory is history, Skills is expertise.
Highlights
/v1/skillsCRUD — multipart tar.gz or zip upload (10 MB cap), content-addressable storage underLINCHPIN_SKILLS_ROOT, slug-named (gh-pr,xlsx, …) and soft-deletable. Re-uploading the same name updates the existing row.SKILL.mdfrontmatter —name≤64 chars (lowercase + digits + hyphen, reserved namespaces forbidden),description≤1024 chars. Same validator runs in the CLI and the API so a clean local build is guaranteed to upload cleanly.agent.skills[]— up to 8 per agent (MAX_SKILLS_PER_AGENT), validated at create/patch time. Snapshotted intoagent_versionsso sessions pinned to a prior version see the exact skill set.- Sandbox mount + system prompt — each attached skill bundle unpacks into
$TMPDIR/linchpin-sessions/<sid>/skills/<name>/(with Python 3.12+datafilter for traversal safety) and bind-mounts read-only at/mnt/skills/<name>/. The orchestrator prepends a<linchpin:skills>block to the system prompt with each skill's metadata + a read-pointer to/mnt/skills/<name>/SKILL.md. Level-1 metadata always in context; level-2 instructions via the agent'sreadtool; level-3 scripts viabash. linchpin skill buildCLI — package a directory into a deployable.tar.gz. Excludes hidden files + common noise dirs by default.- Sample skill —
examples/skills/gh-pr/demonstrates the frontmatter + bundled-scripts pattern.
What's not here
- Pre-built skill catalog (
pptx,xlsx,docx,pdf) — community contributions or a v0.4.x patch series. - Enterprise governance (eval suites, version pinning, registry, role-based bundles) — post-v1.0.
- Memory-aware Skills — possible follow-up once both have been in production.
Schema migrations
0011_skills— newskillstable.0012_agents_skills—skillsJSONB column onagents+agent_versions.
Run alembic upgrade head after pulling.
See CHANGELOG.md for the full per-PR breakdown.
v0.3.0 — Memory
Memory stores — persistent, workspace-scoped, filesystem-mounted state that survives across sessions. The biggest single missing concept in Linchpin per RFC-0001's parity-gap analysis. Six PRs, one minor.
Highlights
- Three new resources matching the Anthropic shape:
memory_store,memory,memory_version. - Path-addressed memories with 100 KB cap + optimistic-concurrency precondition (
content_sha256). - Per-write immutable version snapshots; redact endpoint zeros bytes while preserving the audit row.
- Sandbox bind mount at
/mnt/memory/<store_name>/with kernel-enforced ro/rw based on resourceaccessfield. Read-write stores get a watchfiles-backed writeback watcher that mirrors agent writes back into the canonical FileStore. <linchpin:memory>system-prompt block auto-prepended so agents discover their persistent state with zero caller-side prompt management.- Hourly GC pass tombstones expired versions; FileStore objects unlinked only when no other live version dedupes to the same content sha.
vault_ids→resources[]fold-in:VaultResourcelands in the unified discriminator; legacy field deprecated for v0.4 removal.
What's not here
- Cross-workspace sharing (single-tenant in self-host).
- Dreams / async curation (deferred to v0.7).
- Embeddings or vector search over memories.
- Memory-aware Skills (Skills land in v0.4; memory-aware behavior is downstream).
Deprecations
- New:
vault_idsfield — slated for v0.4 removal. - Extended one minor: the four v0.2.0 deprecations move from v0.3 → v0.4 removal because v0.3 shipped inside the 60-day minimum-deprecation window of v0.2.
See CHANGELOG.md for the full per-PR breakdown and DEPRECATIONS.md for migration paths.
Schema migration
0010_memory_stores — three new tables. Run alembic upgrade head after pulling.
v0.2.0 — RFC-0001 Parity Phase A
v0.2.0 — RFC-0001 Parity Phase A
13 of 14 scope items from the v0.2.0 Requirements (RFC-0001 Parity Phase A). Item #4 limited-networking enforcement and the breaking-bundle phase 2 ship in v0.2.x with the surface-vs-enforcement split documented inline (mirroring the v0.2.0 Foundations PR4 deferral, eng-review decision D1).
See CHANGELOG.md for the full Added / Deprecated / Schema-migrations breakdown.
Theme
API-shape parity with Anthropic's Managed Agents. A developer who has read the Managed Agents docs and points their existing SDK at a Linchpin instance now hits zero gratuitous mismatches before they hit any real difference. Conceptual gaps (Memory, Skills, Outcomes, Multi-agent) are intentionally deferred to v0.3.0+.
Highlights
Linchpin-API-Versionheader introduced. SendLinchpin-API-Version: 2026-05-13to opt into v2 wire shapes. Absent header → v1 (legacy).- Resources framework — discriminated
resources[]onPOST /v1/sessions. v0.2.0 wires thefiletype end-to-end (linchpin-api/app/sandbox.py);memory_store,git_repository, andvaultslots reserved for later minors. - Files API — full Anthropic-shape surface with content-addressable storage and an auto-registered deliverables watcher for anything the agent writes under
/mnt/session/outputs/. - Environment packages — pre-install lists across
apt,pip,npm,cargo,gem,go, with content-hashed derived images so identical package sets share one cached image. - Webhooks scaffold — HMAC-signed (
Linchpin-Signature: t=<ts>,v1=<hex>), at-least-once delivery via a multi-process-safe worker with exponential backoff. - Richer base image —
linchpinhq/sandbox:v0.2.0(Debian trixie + 7 language runtimes + the usual CLI tools). - Agent versions, span events, cumulative cache-token usage, event-type filtering — observability + auditability fillers across the existing surface.
Deprecations (all → v0.3.0)
See DEPRECATIONS.md for full migration paths.
permission_policyas a flat string → discriminated object- Flat
tools: [...]list →linchpin_toolset_20260512bundle session.requires_actionevent →session.status_idle.stop_reasonagent.tool_usefor custom HTTP tools →agent.custom_tool_use
Both shapes accepted on input throughout v0.2.x; v0.3.0 strips the v1 shapes.
Migration
- Pin to
v0.2.0in your install:pip install linchpin-api==0.2.0(or the equivalent for your deploy pipeline). - New clients should send
Linchpin-API-Version: 2026-05-13and use the v2 input shapes today. - Existing v0.1 clients keep working unchanged — the breaking-bundle phase 2 (output translation) hasn't shipped yet, so v0.1 responses are still the default.
Coming in v0.2.x
- Live mount/unmount endpoints on session resources (Foundations PR4)
- Limited-networking egress proxy (item #4 enforcement)
- Breaking-bundle phase 2: output translation, event-shape conversion,
Linchpin-Deprecationrequest-mismatch header
Coming in v0.3.0+
- Memory Stores (v0.3)
- Skills (v0.4)
- Multimodal content + Remote MCP + Git repos (v0.5)
- Outcomes + Multi-agent (v0.6)
v0.1.0 — Launch baseline
First formal release — the launch baseline. Establishes the post-launch versioning + deprecation rules; everything before this tag is "pre-release," everything after follows the changelog/deprecation ledger.
🌐 Live at linchpin.work
What ships
A self-hostable, open-source managed-agent runtime — Apache-2.0.
- Managed-agent runtime. Agents (model + system prompt + tools + permissions), environments (sandbox templates), and sessions (per-session Docker container driving the agent loop).
- HTTP + SSE API under
/v1with bearer auth, cursor-paginated event log, and SSE stream replay. - Model providers.
openrouter(~200 cloud models — Claude, GPT, Gemini, Llama, DeepSeek, Mistral, Qwen, …) andollama(local). No upstream SDK dependency. - Built-in tools.
bash,read,write,edit,glob,grep,web_fetch,web_search— all executed inside the session's container. - Extensibility. MCP servers (stdio) and custom HTTP tools via
linchpin-connector. - Per-tool permissions.
always_alloworalways_ask(blocks on user confirmation). - Per-session Docker sandbox. Ubuntu 22.04 · Python 3.12 · Node 20 · git · curl · jq · ripgrep. Networking is
noneorunrestrictedper environment. - Credential vaults. Workspace-scoped encrypted store (Fernet, keyed off
VAULT_ENCRYPTION_KEY), injected as env vars when sessions start. - Web console (
linchpin-console). React + Vite UI for browsing agents/environments/sessions and chatting live.
Stack
FastAPI · React + Vite · Postgres 16 · Docker · docker-compose.yml for local dev.
Quick start
git clone https://github.com/linchpinhq/linchpin.git
cd linchpin
cp .env.example .env # set LINCHPIN_API_KEY + OPENROUTER_API_KEY
docker compose up --buildDocs
- README — quickstart + API reference
- ARCHITECTURE — topology, session state machine, event taxonomy
- CHANGELOG — this release
- CONTRIBUTING — DCO sign-off
Notes
- No
Linchpin-API-Versionrequest header yet. The wire surface is treated as v1; explicit per-request version negotiation arrives in a later release. - Backend (
pyproject.toml× 2) and console (package.json) version strings currently bump independently. A release script that keeps them in lockstep is planned for the next release.