Contextual continuity infrastructure for AI agents. Every new AI session starts at zero — no memory of past conversations, no access to your knowledge base, no awareness of your tools. agent-config solves this: when you switch agents, sessions, or even models, the same human's memory, knowledge, and work context carries over.
This is a front door, not a manual. It is written for someone who wants to see what one operator actually runs day to day — not for someone about to install a framework. Four things to hold before the first table.
1. This repo is not the engine. The engine is entwurf (v0.17.2, 2026-09-03) — the dispatch substrate that lets six already-existing harnesses address one another by garden id. agent-config is the resident side: the skills SSOT plus the 시험소 (proving ground) where config is hardened on a real daily surface before entwurf absorbs it. So when a table below describes harness wiring, read it as what is currently being proven here, not as a finished contract.
2. A quiet repo is a healthy one. The end state is a thin skills SSOT plus a test bench. Growth here is not progress — a busy changelog usually means something is still being proven. Do not read the skill count as a feature list; the identity is the working method, not the tool count.
3. Read one of three passes, depending on why you came:
| You came for | Read |
|---|---|
| What can these agents actually do? | § Skills · § Semantic Memory |
| How does context survive a new session? | § Why This Exists · § Session Management |
| Is any of this measured, or just asserted? | § Agent Runtime Bench · OMP.md · MODELS.md |
4. Sentences here try to carry their evidence. Where a claim was measured, the receipt is named — a date, a host, a file, a version. Where it is inherited or still open, it says so. A sentence that cannot name one of those is a hypothesis, including in this document. This is the same rule the agents working in this repo are held to.
What this is NOT: not a prompt collection, not a LangChain-style automation layer, not a generic multi-agent framework. It is the infrastructure that lets one human's memory, knowledge, and working surface survive across sessions, harnesses, and models.
Official reference consumer and proving ground for entwurf.
entwurf is the integrated substrate that configures every harness and unifies agent integration — the strong, stable core (a garden-citizen dispatch substrate, not a pi adapter). agent-config is the resident-side layer that feeds it: the skills SSOT (skills/) plus a 시험소 (proving ground) where harness config, hooks, and wiring are hardened on the operator's real surface and soak-tested for weeks before being promoted into entwurf. Pushing unproven config straight into entwurf would weaken the core, so agent-config absorbs that churn first.
The two are not co-equal halves — entwurf is the destination, agent-config is where things are proven before they get there:
- entwurf → integrated harness config, agent integration, backend bridge, MCP injection, verification harnesses — the stable core
- agent-config → skills SSOT, real consumer profile, day-to-day operating surface, and the incubator that hardens config before promotion
The natural end state is a thin skills SSOT plus a test bench: agent-config quiet means the pipeline is healthy. See ROADMAP § purpose shift.
Why the boundary moved, in the operator's own words: §agent-config: 스킬 SSOT와 시험소 — 멀티하네스 이후. That is the 담당자 문서 (resident's note) for this repo — a public, append-only record in the digital garden of how the job here was re-scoped when harness integration went to entwurf and semantic memory went to andenken. It reads as a chronology rather than a spec, which is the point: this README says what is true now, that note says how it got here.
A proving ground that can only install what it already believes in is not a proving ground. This repo's run.sh stands up, pins, and tears down the things it evaluates on its own — including whole agent runtimes that compete with the stack it currently runs. Nothing about that path routes through entwurf, pi, or any harness under test.
That self-sufficiency is what lets the subject matter widen. The bench started at "does this skill load in five harnesses"; it now asks whether a runtime that writes its own skills beats a human-authored set, whether one sibling with an internal team costs the operator fewer inspection points than three visible ones, and — on the arm being built here rather than installed — whether a Lisp workspace can stand up an RLM loop that a Python REPL currently carries. See § Agent Runtime Bench. The rule that makes those answers worth anything is boring and strict: the subject is version-pinned and installed small, so a re-run means the same thing twice.
If entwurf asks “what does a real consumer look like?”, this repo is the answer.
| Surface | Owned by | Reference in this repo |
|---|---|---|
| ACP backend bridge | entwurf |
consumed through pi/settings.json (_common + device overlay) |
MCP servers (entwurf-bridge) |
entwurf |
not wired here — entwurf's own install writes entwurfProvider.mcpServers and records its stable bin |
| Entwurf install / auth / setup | entwurf |
not consumer-installed here — this repo clones the source for dogfooding and hands install to entwurf's own ./run.sh setup; a consumer install here would weaken entwurf's release gate |
| Claude skill plugin farm | pair boundary | this repo builds one consumer layout at ~/.pi/agent/claude-plugin/, then points entwurf at it |
| Skills / prompts / themes / profile | agent-config |
SSOT in skills/, commands/, pi-themes/, home/AGENTS.md |
| Consumer install/update policy | agent-config |
run.sh setup / server-device upgrade path |
| Production verification | pair boundary | day-to-day use here, bridge invariants in entwurf |
In short: entwurf defines the bridge contract; agent-config proves the contract against lived use.
The hardest problem in working with AI agents is not code generation — it's continuity. You build context over hours, then the session ends. Next session: blank slate. Switch from Claude to GPT: blank slate. Move from your laptop to your phone: blank slate.
agent-config attacks this with three layers:
-
Shared memory layer (andenken) — past conversations from every harness + the exported public digital garden in a semantically searchable index. Ask "보편 학문 관련 노트 찾아줘" and it searches the garden md memory without being told the English word.
-
Shared skill set — the same capabilities (search notes, read bibliography, check git history, write to journal) available identically whether you're in pi, Claude Code, Codex, Antigravity, Copilot CLI, Kiro, or OpenClaw. One rail is held out on purpose: OMP gets no skills from here, because it is the subject of a measurement (below), and a subject you have already furnished is no longer a subject.
-
Session continuity protocol —
/new+ recap + semantic search when a new session is the right move; normal in-session compaction is also allowed to preserve a long Pi/Codex run.
Claude, GPT, and Gemini are "graduates from different schools" — trained on different data with different philosophies. Trying to control them means writing hundreds of lines of system prompts per model. Instead, throw one being-profile at all of them equally. They keep their unique lenses while aligning around a single universe — this is the Profile Harness. Multi-harness support is a means, not the goal. The goal is a single 1KB being-profile that exerts the same gravitational pull across any harness.
The result: context survives across sessions, across harnesses, across models. One human's digital universe stays coherent no matter which AI is looking at it.
Part of the -config ecosystem by glg @junghan0611
| Harness | Memory | Skills | Notes |
|---|---|---|---|
| pi + entwurf (default Claude path) | andenken extension on pi side; Claude side gets full skill set via this repo's plugin farm | full skill set on both sides — semantic-memory mounted as a SKILL.md skill, plus session_search / knowledge_search registerTool on pi for direct calls |
SDK isolation (settingSources: []); skills injected via entwurfProvider.skillPlugins |
pi + anthropic (claude-opus-4-8 / claude-sonnet-5) |
andenken extension (in-process LanceDB) | full skill set including semantic-memory skill; session_search / knowledge_search registerTool also available |
Direct provider — available, not the current default |
| Claude Code | andenken skill (CLI wrapper) | full skill set | CLAUDE.md + hooks; entwurf-bridge MCP available; settings tuned to mirror entwurf overlay (autoMemoryEnabled: false, binary/external tools deny-listed); permissions.defaultMode: bypassPermissions — agent-config owns the native key, entwurf owns the ACP overlay's |
| Codex CLI | skill surface + repo-managed MCP registration | full skill set | ~/.codex/skills/ from SSOT + codex/config.toml carries entwurf-bridge; verified as a garden citizen from a direct session |
Antigravity CLI (agy) |
repo-managed settings + skills | full skill set | ~/.gemini/antigravity-cli/skills from SSOT; settings.json + mcp_config.json are entwurf-owned. Native-push citizen (entwurf_register_native) — no mailbox, replies inject into the live conversation |
| Copilot CLI | skill surface only from this repo | full skill set | ~/.copilot/skills → skills/ (directory symlink). settings.json / birth plugin / statusLine are entwurf-owned (install-copilot-bridge, install-copilot-statusline). No MCP doorbell on this rail yet |
| Kiro CLI (optional) | skill surface only from this repo | full skill set when installed | ~/.kiro/skills → skills/ when kiro-cli is on PATH. Kiro is intentionally not an entwurf citizen; its settings, agents, and sessions remain Kiro-owned. |
OMP (omp, oh-my-pi) |
custom task-agent catalog from this repo; bridge configuration from entwurf | deliberately no shared skills | GLG's working submarine: one visible OMP parent calls its in-process agents for the work it receives. omp/agents/*.md is linked by ./run.sh setup:links into ~/.omp/agent/agents/; profiles bind only a name to a model and “Assist the GLG-requested sibling.” Its built-in automatic roles (reviewer, scout, security-reviewer, sonic, task) are disabled; a new harness gets the same default. Entwurf owns install-omp-bridge / install-omp-receive / install-omp-config; ~/.omp/skills remains absent. |
| OpenClaw (4 bots) | andenken skill (same SSOT via symlink) | full skill set | settings / Nix store mount |
OpenCode is not used. It once appeared in this table and in the fan-out list, but run.sh never wires it — there is no ~/.config/opencode/skills link and no OpenCode branch anywhere in setup. The rows have been removed rather than left as an aspiration; a harness this repo does not actually reach should not be advertised as supported.
Session indexing is currently strongest on the pi + claude axes inside andenken's unified index. Each chunk carries a source field ("pi" | "claude") so you can filter, compare, or roll back across those transcript families. Other direct harnesses now share the same skills/MCP dignity surface here even where session indexing has not yet been widened to first-class source tags.
Semantic Memory → andenken
Semantic memory has graduated to its own repo: andenken — "recollective thinking" (Heidegger).
| Tool | DB | Purpose |
|---|---|---|
session_search |
sessions.lance | Past pi + Claude Code conversations |
knowledge_search / search-md |
md.lance | Public digital garden export (~/repos/gh/notes/content) — agent-facing knowledge axis |
Both axes embed through OpenRouter Qwen3-Embedding-8B at 4096d (LanceDB + hybrid retrieval: vector + FTS with score normalization). The Gemini embedding path is retired — gemini-embeddings.ts and GeminiProvider survive in andenken only as an unreferenced back-compat shim, and no preset selects them.
Agents call these autonomously. Ask "보편 학문 관련 노트 찾아줘" and the md knowledge surface fires with dictcli query expansion. The older org embedding track is disabled in production; use denotecli for exact/raw Denote lookups. Loading strategy per harness lives in the Harness Support table above.
Pi Extensions (pi-extensions/)
| Extension | Purpose |
|---|---|
background-bash.ts |
bash_background — run a slow command without blocking; the agent is re-invoked with its exit code and output when it finishes |
@ogulcancelik/pi-codex-compaction |
openai-codex lifecycle → OpenAI native opaque checkpoint; same-model long-session continuity |
@ogulcancelik/pi-session-recall |
Pi-local past-session literal search + focused session question; its raw extension is filtered because session_search belongs to andenken |
review.ts |
/review — review a PR, base branch, commit, uncommitted changes, or a folder |
goal.ts |
/goal — long-running objective mode; keeps continuing itself until the objective is met or a budget is hit |
decision-gate.ts |
When a goal turn declares itself blocked, run one turn on a fast model so the slow resident does not spend its own quota digging, and leave the result as a single custom JSONL entry — not conversation inflow. The entry carries which axes were searched, which hits came back, and which the sibling actually cited, so "did this help?" stays answerable later (#24). Which model digs is the operator's call — /decision-gate model <provider/id> for this session, DECISION_GATE_MODELS in ~/.env.local to make it stick; the resident's own rail is always skipped. It digs; it does not open the gate |
heartbeat.ts |
/heartbeat 10m — wake this session on a timer; the tick instruction makes it look up grounds and leave them where a reader can find them before taking one step. Off until a human types it, dies with the session |
continue.ts |
shift+alt+enter — send "continue" when the agent has stopped |
raw-paste.ts |
Keep an unmarked multi-line paste from being submitted line by line. pi accepts a paste only with bracketed-paste markers, and Termux over tmux does not always send them; this coalesces an ESC-free burst of two or more line breaks into one paste, and restores tmux's re-encoded control bytes inside a marked one. /rawpaste reports which of the two fired |
env-loader.ts |
Load ~/.env.local at session start |
hide-providers.ts |
Keep skill-only keys (OpenRouter, HF, Google, Groq) out of pi so their 440 models stay out of the picker — see MODELS.md |
upstage-provider.ts |
Register Upstage Solar as an OpenAI-compatible provider |
context.ts |
/context — show loaded extensions, skills, context usage |
glg-footer.ts |
Footer signature — device + cwd + branch + model id on line 1, which degrades from the left so a narrow i3wm tile keeps the model name |
go-to-bed.ts |
Disabled 2026-09-08 — blocked every tool 00:00-04:59, so autonomous sessions and entwurf's overnight tests stalled. Kept as go-to-bed.ts.disabled |
peon-ping.ts |
Sound notifications |
gemini-image-gen.ts |
Gemini image generation (nanobanana) |
session-breakdown.ts |
Session cost breakdown |
whimsical.ts |
Personality touches |
Boundary, not shrinkage. A skill is the cross-harness door; a Pi extension is the local lifecycle/provider/TUI hand. Do not duplicate ordinary capability into a Pi-only extension when the skill can travel, but do support an extension when it can touch a Pi turn in a way a CLI cannot. semantic-memory remains the canonical example of the former: its skill works everywhere, while Pi-native session_search / knowledge_search are convenience. Native Codex compaction and Pi-local session recall are the latter: their value is precisely inside Pi's session and provider lifecycle.
Supported third-party Pi packages are tracked in pi/packages.json. ./run.sh setup — therefore a fresh oracle too — runs setup:pi-packages: it installs a missing package or runs Pi's extension-only update for an installed one. Sources are intentionally unpinned, so setup receives upstream extension releases; package code is not silently copied into this repo. It deliberately does not merge a packages[] array into settings because Pi and entwurf co-own that live surface.
One package filter is deliberate: andenken owns semantic session_search, while upstream session-recall also names its literal rg tool session_search. The manifest loads its package code but filters that raw extension; session-recall-compat.ts loads it as session_literal_search and preserves session_query. ./run.sh test:pi-packages is the install seam: it loads Pi without an LLM call, proves those three recall tools retain their owners, and asserts that session_before_compact is unique to tier-3 entwurf then Codex compaction. This prevents an accidental local/tier-2 compaction handler, a duplicate package during a future fork cutover, or a later handler silently replacing Codex's checkpoint result. Local extensions follow the same boundary: review, goal, and continue hook Pi's turn loop; background-bash receives process completion; heartbeat owns an in-process timer; raw-paste owns stdin parsing.
이 시계는 게이트(decision-gate)·dm과 한 세트다. 목적: 판단 근거를 찍지 말고 뒤져보게 하는 것. 깨어난 턴이 기억축·시간축을 본인이 찾든 형제를 부르든 뒤지고, 근거가 있으면 한 걸음, 없으면 DM 한 통. 그게 힣의 자율주행 루프다.
/heartbeat 10m arms a timer that wakes this session and runs one turn. Every harness has that much; Claude Code and Copilot ship it as "proceed if no answer" / autopilot, and GLG keeps those off for one reason — proceeding with no grounds. The refusal is not of the clock but of the blank: "왜 내 기억도 안쳐다보고 무슨 근거로 진행을 하냐는거야" (2026-09-09). We have the memory and time axes, so a woken turn can look, record what it found, and then move.
So the tick prompt is the product, not the timer. Its step order is the contract: look up grounds → leave them where a reader who never opens the session can find them → take exactly one step → if there were no grounds, stop and say where you looked → and only then, if nothing needs attention, HEARTBEAT_OK. The silence token comes last on purpose. openclaw measured the inverse: 1330 heartbeats, 529 consecutive NO_REPLY, 6-8 tokens a turn — the prompt's own right answer arrived before any judgement did, and designed silence became indistinguishable from reflex silence from outside.
What it deliberately is not: no job store, no scheduler class, no daemon, no residency. prime-agent's heartbeat is daemon-only by construction (in-process-agent-connection.ts:264 throws "Heartbeats require daemon mode"), and its scheduled-jobs.json is state whose loss would erase registered work — the shackle test this repo applies elsewhere. We took the syntax (/heartbeat [--every <interval>] [--steer|--follow-up] [instruction], 10s floor) and two policies (busy means drop the tick, never stack it; steer/follow_up as a field), and none of the code.
Two consequences worth knowing before using it. It is off until a human types it and it dies with the session — session_start disarms on every reason including resume, which is the only thing standing between "every pi session on this machine loads this file" and "sessions that wake themselves with nobody asking". And --steer cannot actually interrupt a running turn here: pi's extension surface exposes isIdle() alone, whose expression is !_isAgentRunActive && !isCompacting — two states behind one boolean — and steering into a compaction is the unsafe case prime-agent names, so both modes wait for a plainly idle session.
/heartbeat status states both in one line each, and this section is where their reasoning lives. That split is deliberate: the panel is four lines total (state, instruction, the two facts) because a status view that wraps to ten rows stops being read, which would lose the very facts it was widened to carry.
Who digs is closed (2026-09-09): this turn or a sibling — both allowed. The tick prompt names three hands: semantic-memory (memory), timeline (time), entwurf_fresh_call / entwurf_v2 (sibling). How to narrow each axis lives in that skill's own doc. A miss pages GLG once via skill dm for this armed heartbeat, not every tick. That one-DM budget assumes earlier ticks (and that DM) are still in the session context; if compaction drops that span, the same miss can fire twice. Still open, and still not decided in the code: where the record lands (#24 열린 결정 2). The prompt requires the property, not the path.
pi's built-in bash tool is synchronous only. A slow pnpm check therefore either blocks the whole turn or gets parked in tmux, and parked work needs a human to come back and look at it. The observed failure mode is the agent announcing "I'll run pnpm check" and then ending the turn, waiting on a keystroke. Claude Code does not have this problem: run_in_background plus a completion notification re-invokes the model.
pi has no completion hook — but it does not need one. pi.sendMessage(..., { triggerTurn: true }) may be called from any async callback, and agent-session.ts explicitly runs a continuation for messages queued after a turn ends ("queued by agent_end extension handlers"). So the child process's exit handler queues the result and triggers a turn; if a turn is already running it is delivered as a follow-up. goal.ts uses the same mechanism from agent_end. The footer shows ⏳ n tasks while anything is pending.
Two things learned the hard way, recorded so they are not re-derived: spawn through pi's own getShellConfig() (it returns bash -c, and a login shell sources a profile that injects OSC escape bytes into model context), and detached: true + process.kill(-pgid, …) (signalling only the bash pid leaves a pipeline's descendants running).
External Pi packages have two ownership paths: andenken remains the cross-harness semantic-memory skill and entwurf self-registers its citizen surface; supported Pi-only packages are tracked in pi/packages.json, installed or updated through setup:pi-packages. None are merged directly into this repo's settings reference.
This repo is the official consumer reference for the entwurf surface.
| entwurf surface | Where this repo consumes it |
|---|---|
backend provider (entwurfProvider) |
pi/settings.json (_common + device overlay) |
MCP bridge (entwurf-bridge) |
same settings files |
entwurf_v2 / entwurf_peers / entwurf_self / entwurf_inbox_read / entwurf_fresh_call / entwurf_resume_call / entwurf_register_native |
home/AGENTS.md, operational use, skills like entwurf-peek |
| skill plugin injection | run.sh setup builds this repo's local plugin root and points settings at it |
| install / version pin | entwurf's own ./run.sh — this repo pins nothing on its behalf |
So when entwurf changes, this is the first consumer that should stay green.
Six rails, one address layer (entwurf 0.17.2). The citizen set is no longer Claude-plus-others: Claude Code, Copilot CLI and OMP are mailbox-backed self-fetch citizens, Antigravity is a native-push citizen with no mailbox at all, Codex has a verified delivery probe but no managed install lane yet, and pi supplies the control sockets. entwurf_fresh_call opens a new visible sibling on pi / claude-code / copilot / omp; entwurf_resume_call reopens a dormant pi citizen under its own garden id without running a turn. A dormant citizen on any other rail is honestly unreachable rather than silently resumed in the background — the hidden-resume path was withdrawn under entwurf's visible-first rule, and that refusal is a feature this repo relies on.
The seven tools above are what this session's MCP schema actually exposes (read 2026-09-04); the bridge surface is the v2 one. The v1 trio (entwurf / entwurf_resume / entwurf_send) was removed in a hard cut (entwurf CHANGELOG.md #50) and no longer exists anywhere — a doc row naming those tools is stale, not a fallback. Note also that session_search / knowledge_search never came from this bridge: they are andenken's pi-native registerTool surface.
There is deliberately no release-pin row here. This repo does not carry an entwurf version constant, an install spec, or a tracking ref — setup_repos clones the source for dogfooding and stops there. It does not even declare entwurf as a pi package any more: entwurf's own ./run.sh install registers it as a user-scope citizen in ~/.pi/agent/settings.json, and remove-user-scope is the inverse. Install, auth, and version selection belong to that side, because a consumer that pins its own copy weakens the release gate it is supposed to exercise.
Spec, verification harnesses, and the sync/async contract remain in entwurf AGENTS.md § Entwurf Orchestration.
When entwurf isn't the path (operator chooses native Claude Code, or the 2026-06-15 Anthropic billing shift puts more sessions on direct Claude Code), claude/settings.fragment.json (workstation) and claude/settings.server.json (server) keep the native session as close to entwurf's ACP overlay as possible.
~/.claude/settings.json is co-owned with entwurf's meta-bridge installer (keysets intended to be disjoint — see the warning below). On workstations setup therefore merges the agent-config keyset (settings.fragment.json) into the live file instead of symlinking it — a symlink is whole-file ownership and the next writer's atomic rename would silently clobber the other side. agent-config owns hooks / language / 개인취향 toggles / enabledPlugins.*@claude-plugins-official / permissions.defaultMode; entwurf owns permissions.allow/deny / statusLine / B-lite single-driver scalars / meta wiring (enabledPlugins.entwurf-meta-receive, extraKnownMarketplaces). The permissions object is split down the middle and stays disjoint: the fragment carries defaultMode alone and jq's recursive object merge leaves entwurf's allow/deny arrays untouched. The SSOT for entwurf's side is entwurf.install-state.json, and entwurf ships the preventive check: ./run.sh check-keyset-overlap <fragment> from the entwurf repo names every colliding key. Server devices take the same keyset-merge path (run.sh merges settings.server.json into the live file — it is not a symlink), and they do carry a meta-bridge: oracle's install-state owns 17 settings keys plus mcpServers.entwurf-bridge in ~/.claude.json (measured 2026-09-01 — python3 scripts/meta-bridge-state.py check from the entwurf repo).
The keyset is disjoint again (2026-09-01). check-keyset-overlap went 2 → 0 for settings.fragment.json and 18 → 2 for settings.server.json. The server file had carried entwurf's whole keyset from the pre-merge single-owner era — statusLine, extraKnownMarketplaces.meta-bridge-local, enabledPlugins.entwurf-meta-receive, cleanupPeriodDays and the B-lite scalars — and two of those copies had gone stale: the statusLine.command still named ~/.claude/statusline.sh and the marketplace .assembled path still named ~/repos/gh/entwurf/pi/meta-bridge/, both locations entwurf has since moved from (live values: entwurf/scripts/meta-bridge-statusline.sh, ~/.local/share/entwurf/meta-bridge/). EXISTING-WINS meant the stale copies never reached the live file, which is exactly the silent shape 5b9c75c called a drift bomb. The remaining 2 collisions are permissions.allow/deny, kept on purpose: entwurf's ledger records one added item there (allow: ["mcp__entwurf-bridge__*"], deny: []), so the arrays are substantially ours, and under permissions.defaultMode: "bypassPermissions" they are inert anyway. permissions.defaultMode is not among the collisions — the pin below is clean. Run the guard before adding any key to either file.
| Axis | entwurf overlay | agent-config Claude Code |
|---|---|---|
permissions.defaultMode |
"default" (overlay-authored, overlay.ts) — should be "bypassPermissions" |
"bypassPermissions" |
| auto-memory | autoMemoryEnabled: false + empty projects/ tree |
same — per-cwd memory/ kept empty |
| binary tools (PlanMode / Worktree) | not exposed | deny-listed |
| external surface tools (AskUserQuestion / Task* / Cron*) | not exposed | deny-listed |
| plugin farm | none | enabledPlugins false for all |
| MCP entwurf bridge | entwurf-bridge mounted |
mcp__entwurf-bridge__* allowed |
| operator hooks | empty (hooks: {}) |
peon-ping retained (deliberate) |
permissions.defaultMode: "bypassPermissions" — two surfaces that must carry the same value. Both settings.fragment.json (workstation) and settings.server.json (server) pin the key here as of 2026-08-08. This pin is a stopgap held on entwurf's behalf, not a claim of ownership — see the handover condition below.
Two surfaces, because there are two config reads. Native Claude Code reads ~/.claude/settings.json. An ACP peer does not: claude-agent-acp reads through CLAUDE_CONFIG_DIR, which entwurf's overlay redirects at a pi-owned directory whose settings.json the overlay authors itself (pi-extensions/lib/acp/overlay.ts, overlaySettingsJson()). A peer session therefore never sees this repo's value at all. If the two surfaces disagree, the failure is silent and asymmetric — the operator's own sessions run bypass while every peer still stalls on a skill edit, which reads as "entwurf is broken" rather than "one config key is unpaired."
An allow-list cannot substitute. The overlay's premise — "default auto-passes every tool we expose, because permissionAllow names them explicitly" — has one hole: Claude Code carries a hardcoded .claude/ write guard that no allow-list clears (regression from v2.1.79, claude-code#36497, still open; two sibling reports closed not planned, upstream's position being "use bypass"). Measured on v2.1.226: under default + full allow-list an edit to ~/.claude/skills/…/SKILL.md prompts (Yes, and allow Claude to edit its own settings for this session) and the session blocks until a human answers — and the prompt's only escape hatch is scoped for this session, so there is no durable opt-out. Under bypassPermissions the same edit passes silently, as does a write to ~/.claude/ itself. A peer editing a skill mid-collaboration therefore stalls indefinitely; that is the whole failure mode.
merge_settings is EXISTING-WINS, so this pin only fills the key on a device that lacks it. A device already carrying "default" keeps it and setup emits a divergence warning instead — clear the key from the live file to let the new default land.
The split is deliberate and settled (2026-08-08, with entwurf's steward) — this key stays here. The dividing line is blast radius, not key tidiness:
| Layer | Owner | Why |
|---|---|---|
| Native Claude Code, operator-wide | agent-config / operator | ~/.claude/settings.json governs every native session. bypassPermissions is the same authority as --dangerously-skip-permissions, so a public package must not switch it on as a side effect of installing a plugin and a mailbox. Turning global YOLO on is the operator's own act. |
| ACP child runtime, isolated | entwurf overlay | The child is sealed off by CLAUDE_CONFIG_DIR and never reads the file above, so the value has to be pinned again in overlay.ts. entwurf also constrains the callable-tool surface and owns the unattended turn, so the risk stays inside its own sandbox. |
entwurf's meta-bridge deliberately does not claim permissions.defaultMode: its smoke-meta-keyset-guard.sh fixture lists the key as a legitimate consumer-owned field ("permissions.defaultMode … must NOT trip the guard"). Reading its ownership of permissions.allow/deny as an argument that it should own defaultMode too gets the boundary backwards — those constrain which tools exist, this one decides how much authority the operator hands the whole machine.
Entwurf claiming the native key later would be a policy change, not a one-line addition: managed-scalar entry, install/uninstall snapshot and restore, keyset-guard update, removal from this repo in the same beat, explicit opt-in for public installs, and clean-host docs carrying the warning. Not scheduled.
MANAGED_SETTINGS_SCALARS pins skipDangerousModePermissionPrompt: true, and that key only does anything under bypassPermissions — it suppresses the confirmation Claude Code shows on entering the dangerous mode. So the package declines to turn global YOLO on, yet disarms the last warning shown to whoever does. Observed directly: flipping defaultMode on thinkpad and oracle brought bypass up silently on both, no prompt. If the boundary is "the operator owns this decision," the operator arguably owns the warning attached to it too. Raised with entwurf; unresolved.
Aside from the hook channel, the two surfaces are interchangeable. This is the resident-side counterpart to Asymmetric Mitsein (비대칭 공존) — pi can spawn or message native Claude Code without the native surface drifting from pi conventions. Both halves of the harness pair stay aligned regardless of which one the operator is sitting in.
Skills (skills/)
47 skills (recounted 2026-09-23 against tracked skills/ directories plus the new evidence-closure; the list below names all 47 — the two work-repo links that used to sit outside it are gone: voscli was dropped in 113e096, incidentcli never had git history here). A machine may also carry an untracked local symlink — butlercli does on the workstation — which the */ glob counts but this number does not. Categories: data access (denotecli, bibcli, gitcli, lifetract, gogcli, ghcli, day-query, timeline), agent memory (session-recap, dictcli, semantic-memory, memory-sync, improve-agent), writing (botlog, botment, agenda, punchout, autholog-mend), communication (dm, slack-latest, jiracli, telegram), code surface (forge — linked, owned by forge-config), work workbench (plane), web/media (brave-search, exa-search, browser-tools, youtube-transcript, medium-extractor, summarize, transcribe), release hygiene (commit, tag-release, next-handoff), reasoning (logickocli, subtract, evidence-closure), entwurf (entwurf-peek), cross-repo care (sorge — linked, owned by its own repo), harness wrappers (command-recall, command-glgimage — for harnesses with no custom-command surface), harness bench (harness-bench), tools (emacs, tmux, diskspace, cloudflare, quota).
Linked skills: one repo owns it, this one only connects. skills/sorge is a relative symlink into sorge/.claude/skills/sorge — the SKILL.md exists exactly once, in the repo whose facts it depends on, and editing it there reaches every harness at once. agent-config keeps no copy and has nothing to re-sync. run.sh clones such repos (LINKED_SKILL_REPOS) so the link is never dangling, and update pulls them too — a stale clone would freeze that one skill while every other repo moves, which is precisely the failure the design exists to prevent. Portability is structural rather than lucky: the link is relative (../../sorge/…), and ensure_repo clones into ~/repos/gh, so it resolves identically on every machine. A missing target degrades safely — a dangling symlink does not match bash's */ glob, so pi's per-skill loop skips it instead of erroring (measured 2026-09-04). skills/forge is the same shape, into forge-config/.claude/skills/forge. It was this repo's own counter-example until 2026-09-04: documented as a thin pointer to forge-config while 361 lines actually lived here, so nobody could tell which side was true. What made the split visible was the commit log — every one of the five dates that touched bin/forge touched SKILL.md too, one change costing two commits in two repos. Repo name and skill name need not match (forge-config owns forge); LINKED_SKILL_NAMES carries that mapping. Do not re-open the shape that was closed.
Binary skills: agent-config owns the skill surface, alone. For skills backed by a sibling-repo CLI (denotecli, bibcli, gitcli, lifetract), this repo owns both the SKILL.md and the deployed binary; the sibling repo holds code only and its own deploy never writes into the skill directory. Two owners means nobody knows which one is true. run.sh setup:build gates each install behind the sibling repo's test suite and refuses uncommitted sources, then writes skills/.provenance.json — per tool: vcs_revision, src_tree, and the installed binary's sha256. A snapshot whose tools cannot be named is not reproducible, it only looks it. The gate only guards setup:build, though — a sibling repo's own build <dir> can write into skills/ and bypass both checks, which happened on 2026-09-04. So ./run.sh doctor:bins re-derives the answer from the binary itself: wrong arch, source newer than the deploy, and a sha that disagrees with .provenance.json are each named separately, because only the first one is loud. (dictcli is the open gap: GraalVM native-image doesn't ride the Go gate, so it carries no provenance yet.)
Web search: brave-search for cheap keyword/freshness/country-scoped lookups; exa-search for intent-based semantic queries, code-context retrieval (GitHub + Stack Overflow + docs aggregated for an LLM), and structured grounded output via --output-schema.
Code surface: forge is the code-side sibling of botment — same single-bot identity (glg-bot), same footer-signature model, same closed-loop instinct, but pointed at self-hosted Forgejo instead of remark42. v1.5 박힘 (2026-05-27): bin/forge 5-command (list-open / state / comment / label-add / issue-create), multi-profile (oracle: forge.junghanacs.com 가동 / work: 회사 인스턴스 가동), machine identity SSOT 분리 (~/.current-forge-profile), footer 자동 조립, mutating stderr observability. SSOT 는 forge-config — 이 repo 의 skills/forge/SKILL.md 는 thin pointer. 로드맵: agent-config #13.
Skill doc principle (LSP pattern): Agents don't read full docs. Each SKILL.md has a single API table at the top — function/command + args + example. English body, Korean description only. Target: <100 lines, <4KB. Like LSP autocomplete: see the signature, call immediately.
Pi Config (pi/)
| File | Purpose |
|---|---|
settings.json |
The single pi settings reference: _common plus _workstation / _server overlays, with _-prefixed keys carrying the prose. setup resolves one overlay and merges the result — never symlinks, because the pi runtime co-owns the live file |
keybindings.json |
Custom keybindings |
claude-plugin.json |
Manifest used by this repo's local entwurf Claude plugin root |
This repo is a place to look a setting up, not a live config store. The merge is EXISTING-WINS, so editing pi/settings.json provisions a fresh machine and only warns on a running one — to change a running one, edit ~/.pi/agent/settings.json. pi/settings.server.json was folded in on 2026-08-06: with entwurf's packages[] entry and the runtime's lastChangelogVersion both removed as not-ours, its only remaining divergence was defaultThinkingLevel, and a whole second copy of a file for one scalar is a file that drifts.
entwurf runs Claude with settingSources: [] (SDK isolation), so ~/.claude/skills/ is not auto-discovered. The bridge's install contract — plugin shape, skillPlugins, fail-fast validation — is documented upstream in entwurf's README §Custom Skills.
What this repo does is narrower: run.sh setup builds one local consumer layout under ~/.pi/agent/claude-plugin/ (manifest + per-skill symlinks back to agent-config/skills/) and points this repo's pi settings at that path. That path is an agent-config convention, not a entwurf contract.
Adding a new skill here still works the same way: drop it into agent-config/skills/<name>/SKILL.md and re-run ./run.sh setup. The same SSOT fans out to pi, Claude Code, the entwurf Claude plugin, Codex, Antigravity, and Copilot when its runtime/home is present. When kiro-cli is installed, it also links Kiro's personal root at ~/.kiro/skills/.
~/.gemini/is Antigravity's home, not Gemini CLI's. The standalonegeminibinary is gone from this machine and its legacy surface (~/.gemini/settings.json,~/.gemini/skills/) was retired 2026-08-06 — but~/.gemini/antigravity-cli/and~/.gemini/config/are live and must survive any cleanup of that directory.
Codex's config.toml is materialized as a regular file, never linked. agent-config supplies only its initial non-Entwurf defaults and preserves an existing regular file byte-for-byte; entwurf's run.sh setup subsequently owns the MCP/env boundary and the thread-title status atom (and their inverse). Do not add either Entwurf atom to codex/config.toml here.
For Antigravity direct mode, run.sh setup wires only the skills path. Both settings.json and mcp_config.json are not wired from here — entwurf's install-agy-bridge / install-agy-statusline adapters own them: they adopt or create a regular file and record the bare entwurf-bridge / entwurf-agy-statusline stable bins. A symlink from this repo makes those adapters REFUSE.
The same split now covers Claude Code's own status line. claude/statusline.sh and its ~/.claude/statusline.sh symlink were removed 2026-09-01: statusLine is an entwurf-owned key (meta-bridge-statusline.sh), the repo copy was unreferenced once that key left the fragments, and a stale script sitting on the path entwurf had moved off is how the last drift bomb was built. Do not re-add it — open the entwurf repo to change how the status line renders.
The same ownership split applies to Copilot CLI: run.sh setup links only ~/.copilot/skills (directory symlink to SSOT). ~/.copilot/settings.json, the birth plugin marketplace unit, and statusLine stay with entwurf (install-copilot-bridge / install-copilot-statusline). Do not symlink Copilot settings from this repo.
settings.json was linked from here until 2026-08-13. It caused a silent regression loop: every setup:links pushed the live file — carrying entwurf's exact permission grants and statusLine — aside as .bak.YYYYMMDD and replaced it with the repo copy, so agy lost its entwurf wiring until the next install-agy-* run (observed twice each on thinkpad and oracle). agy also replaces the file rather than following a symlink when it saves settings, so the link never survived anyway. Skills stay ours; settings and MCP do not.
Because Antigravity and Codex do not expose the same repo-managed custom command-file surface as pi / Claude Code, selected high-value commands can also be translated into thin wrapper skills (current prototypes: skills/command-recall/, skills/command-glgimage/). command-glgimage now bundles a zero-dependency Gemini REST CLI, so Claude Code and other harnesses can generate exact-prompt document figures to a requested path without pi's native generate_image tool; GLGMAN world anchoring is an explicit mode, not a restriction on general image generation.
Themes (pi-themes/)
glg-dark (custom, Ghostty Dracula compatible).
Commands (commands/)
| Command | Purpose |
|---|---|
/recall |
Multi-axis context hydration without compact — daily memory-axis ritual |
/discuss |
Planning interviewer — turns a rough idea into a plan by asking at most three questions a round, each with a recommended default. Does not implement |
/boom |
Capture a crashed entwurf session into .agent-reports/ for later triage |
/pandoc-html |
Markdown/Org → Google Docs HTML/DOCX |
/glg-image |
Image generation entry |
/metaplay |
Meta agent play |
/docplay |
Random document polish play (front matter/title/tags/links/rename) |
/authologplay |
Mend one raw autholog piece into garden core text + links + a GLGMAN Universe image |
/scaleplay |
Take a scene whose scale won't sit still: commit the first intuition, measure it, accumulate in studies/ |
git clone https://github.com/junghan0611/agent-config.git
cd agent-config
./run.sh setup # clone/pull + build CLIs + symlink everything + pnpm install
./run.sh env # verify: system, API keys, links, binaries, memory index./run.sh setup performs:
- Clone missing tracked repos (
setupdoes not pull existing repos; use./run.sh updatefor pulls) - Build native CLI binaries (Go + GraalVM) — gated: each Go CLI must pass its sibling repo's test suite and be built from committed sources, or it is not installed.
skills/.provenance.jsonrecords what actually landed;./run.sh doctor:binswarns when a live binary drifts from its recorded build, is stale against its source, or was built for another arch - Symlink pi extensions, full skill set (including
semantic-memory), themes, settings, keybindings, prompts, and the repo-managed OMP task-agent catalog - Run andenken's own
run.sh setup(build + deps). It is no longer declared as a pi package here — agents reach it through thesemantic-memoryskill, which every harness can invoke. Where it is already registered as a pi package, pi additionally gets thesession_search/knowledge_searchregisterTool; that is a pi-local convenience, not the shared door - Link Codex / Antigravity / Copilot skill surfaces (
~/.codex/skills,~/.gemini/antigravity-cli/skills,~/.copilot/skills) plus Claude Code commands.~/.codex/config.tomlis materialized as a regular file: agent-config supplies initial defaults, entwurf owns its MCP/env +thread-titleatoms. When installed, Kiro gets only~/.kiro/skills; its settings, agents, and sessions stay Kiro-owned. Antigravity/Copilot settings are not linked here (entwurf-owned).~/.claude/settings.jsonis merged (keyset, never symlinked) — co-owned with entwurf meta-bridge; both workstation (settings.fragment.json) and server (settings.server.json) merge the same way, andpi/settings.jsonmerges too (co-owned with the pi runtime) - Symlink
~/.local/binPATH binaries - pnpm install for extensions and skills
- Hand off entwurf validation (typecheck, MCP, dual-backend smoke, persisted-bootstrap continuity, cancel-cleanup) to entwurf's own
run.sh
What setup deliberately does not do: install entwurf (that is entwurf's own ./run.sh setup — see § entwurf Surface Reference) and install the runtime under evaluation (./run.sh setup:hermes, § Agent Runtime Bench). Both are omissions with a reason, not gaps to fill.
Some questions cannot be answered by reading a project's README. Does a runtime that generates its own skills from experience beat a human-authored skill set? You only find out by standing both up on the same machine, giving them the same repeated task, and looking at what each wrote down afterwards.
Six subjects sit on this bench, and they ask different questions:
| Subject | Question | Standing |
|---|---|---|
| Hermes Agent | Does a self-learning runtime out-write a hand-authored skill set? | candidate, pinned, not adopted |
oh-my-pi (omp) |
Can one visible parent call an in-process team while reducing GLG's inspection hops? | GLG's working submarine — admitted as a sibling (entwurf 0.16.0); custom agents active |
| prime-agent (fork) | Can a Lisp workspace stand up the RLM loop a Python REPL carries today? | built here, not installed — matrix in PRIME.md |
| Ouroboros | Besides entwurf, how does a popular Agent OS carry task-memory across harnesses, and how does it run long? | candidate, not pinned, not installed — matrix in OUROBOROS.md |
| herdr | Besides our tmux/entwurf floor, how does a popular agent-terminal runtime show stuck panes and survive detach? | installed and running (0.9.1 measured 2026-09-21), not declared in nixos-config; entwurf now ships a Herdr plugin (Herdr Entwurf 0.4.0) on the public marketplace — matrix in HERDR.md |
| Xirp (Spotify) | When one product owns the whole factory — sessions, worktrees, workflow status, institutional memory — what does it get that a three-part workshop does not? | cannot be installed: macOS-only — observation in XIRP.md |
This comparison belongs here, not in entwurf. entwurf guarantees its own garden-id, delivery, and visible-lifecycle logic and compares today's code with yesterday's; it does not rank other harnesses. agent-config is the operator-side proving ground, so it asks whether an external runtime actually reduces GLG's inspection points without weakening identity, memory, or alignment. This is not a tournament and it is not a reason to grow entwurf into a planner.
The fifth subject is herdr — "the runtime your coding agents live on." It does not wrap agents; it owns their terminals. The bench asks how pane working/blocked/idle and detach-without-dying compare with entwurf liveness and tmux, not whether to replace tmux. The isolation premise broke on 2026-09-14: herdr is installed at ~/.local/bin/herdr with a running server (0.9.1 as of 2026-09-21), it is absent from nixos-config, and its agent-state integrations are already installed into the pi, omp, claude, codex, copilot, antigravity-cli, and grok trees that entwurf co-owns. Replacing tmux is still 안 함. Matrix and the measured delta: HERDR.md. DHH-uses-it is inherited from GLG and unverified here.
The fourth subject is Ouroboros — a popular Agent OS
(Seed · Ledger · multi-runtime adapters). entwurf stays the floor; this bench asks how
they carry a task ledger across harnesses and how they run long, against our life
memory axis and /goal·/heartbeat. It is not adopted and not installed: no
setup:ouroboros, no skill link, no live ouroboros setup (that command writes MCP into
host settings this repo co-owns with entwurf). The matrix is OUROBOROS.md.
The first subject is Hermes Agent — an independent runtime with its own gateway, state tree, cron, memory and skill generation. It is a candidate under evaluation, not adopted infrastructure: nothing about it is declared in nixos-config, and setup:hermes is not part of setup.
./run.sh setup:hermes # pinned tag, minimal closure, explicit call onlyTwo constraints carry the whole thing, and both are one careless edit from being lost:
Pinned, never fast-forwarded. THIRD_PARTY_PACKAGE_REPOS is the obvious home for the clone, but every entry there is pulled to latest on setup and update. A subject that moves between runs cannot be re-measured, so hermes is kept out of that map on purpose and HERMES_TAG selects the version.
Installed small, not merely configured small. Upstream's default build adds 18 optional groups — messaging (Telegram/Discord/Slack), voice, web-search backends. Built that way, "integrations stay off" is a promise about configuration. Built from .#minimal they are absent from the closure and cannot be switched on by mistake. The single group added back is anthropic, without which hermes auth add anthropic --type oauth logs in successfully and only fails later at inference — the auth layer and the SDK are separate, so a successful login proves nothing about reachability.
What that leaves is a runtime that reaches Claude, GPT (openai-codex OAuth) and Solar (auto-discovered UPSTAGE_API_KEY) while being structurally unable to talk to a messaging platform. State lives in ~/.hermes; deleting it resets the baseline, and the first run after that is t=0 for anything the runtime claims to have learned.
The comparison target is not another product. It is this repo's own loop — AGENTS.md + skills/ + semantic memory + botlog/NEXT — and the honest question is whether a machine-written skill trail is more transparent and reproducible than the hand-written one.
The second runtime is oh-my-pi (omp) — a fork of the harness this repo already runs, tuned as a coding-first surface and now GLG's working submarine. One visible OMP parent receives one garden id and calls its internal agents in process for the work it is given. The parent, not the agent profiles, chooses which models to call from the task and the quota currently available. Each profile binds only a name to its model and says “Assist the GLG-requested sibling”; it does not assign rank, speed, cost, context, or a fixed role. The currency is not tokens. It is the number of boundaries the operator has to personally inspect.
OMP is an admitted sibling and active work surface. entwurf 0.16.0 (2026-08-31) admitted OMP as the fifth garden backend: birth hook, an OMP-native MCP hand, an addressed-receive extension, and entwurf_fresh_call on all three public surfaces. It is live on this host with entwurf-meta-omp and entwurf-receive-omp under ~/.omp/agent/extensions/ plus a native entwurf-bridge entry in ~/.omp/agent/mcp.json (measured on oracle, 2026-09-04).
The two responsibility boundaries remain distinct:
| Owner | Standing | |
|---|---|---|
| Is omp addressable as one garden citizen? | entwurf |
Yes — one process = one garden id. In-process agents are not citizens and do not widen the contract. |
| Does the working submarine reduce GLG's inspection hops? | agent-config |
Active and observed — the D-axis in OMP.md remains the record of that operating evidence. |
This repo wires the OMP task-agent catalog only: omp/agents/*.md is linked by ./run.sh setup:links into ~/.omp/agent/agents/. OMP installation remains outside run.sh and nixos-config, and the shared skills SSOT is still not injected into ~/.omp; the operational team stays reproducible without turning the measurement surface into a furnished copy. The provider seal, bridge ownership, operator boundary, and reproduce block live in OMP.md.
prime-agent is a fork of PrimeIntellect-ai/prime-agent, and it is where the bench stops measuring other people's runtimes and grows an arm of its own.
Upstream's core abstraction is the Recursive Language Model — context as variables, subagents as function calls, all of it inside a persistent Python REPL that survives across turns. This fork replaces that language. prime-agent-runtime-clj/ stands a Clojure/SCI workspace on a GraalVM native image beside the Python one, and since checkpoint edc3a3e8 (H8) Clojure is the default kernel with no fallback — a missing binary raises a teaching error instead of quietly reverting to Python (PRIME_AGENT_KERNEL_RUNTIME, branch feat/clojure-runtime).
The reason is not language preference. It is what a Lisp workspace makes legible:
Natural language is exploration; Lisp is the public state, the contract, and the form. What the model did has to survive as a form in the workspace, not as a paragraph claiming it did. — the fork's
AGENTS.md
Which makes the success condition unusual for an agent project: not a benchmark score, but whether GLG can read the workspace forms and decide the next design from them. Three rules keep that honest, and they are the same rules this repo's bench runs on:
- The Python oracle is never deleted. Two arms have to stand side by side or there is no comparison — only an assertion.
- Coverage is standing, not procedure. "When coverage is there and the possibility is real, the possibility becomes real. Get it wrong and it is just fraud." (GLG) No claim of performance or advantage is made before the contract coverage exists to back it.
- A failure is an observation to classify, not a verdict. A red on the Clojure arm is recorded as
semantics-gap,model-fumble, orharness-gap— whichever the receipt supports. A prose-only pass or a Python fallback is not a Lisp success.
Scope boundary, stated once so it is not re-derived: this is an experiment in computation inside one citizen. It does not touch entwurf's address, delivery, or receipt layer, and it never promotes a message between siblings into an executable form. Coordination and computation stay apart (entwurf#88). Current position and the open board live in the fork's NEXT.md and issue #1.
YEGGE.md is the lighter observation log. Wheelhouse is neither installed nor a candidate: it is an occasional external sighting used to separate durable runtime facts from cockpit fashion. Its current entry records one useful confirmation only — tmux can own session lifetime while Emacs remains a replaceable projection — and explicitly opens no implementation lane.
XIRP.md is the sixth subject and the only one this machine cannot run: Xirp is
macOS-only, so the question is never whether to adopt it but how far a product that owns the
whole factory has actually gone. Spotify calls it a vendor-neutral agentic development
environment and states that as an architectural requirement — context is decoupled from any
single agent or harness; switch tools mid-project, and the full working state carries over —
built to coordinate 50+ parallel sessions, each in its own worktree. That last phrase names the
same problem garden-id solves, with the opposite answer: Xirp holds the context and swaps the
harness; entwurf holds only the address and leaves context with each citizen. The memory axis
diverges further — Portal accumulates institutional memory as a substrate it owns, while
/recall deliberately refuses to become a memory emperor. One caution is written large in that
file: the claim that Pi became a first-class Xirp harness is inherited from a ChatGPT analysis
and could not be confirmed here — Spotify's own docs still list Claude Code, Codex and Gemini,
and the changelog names Cursor but not Pi. Verifying or retiring that one sentence is the file's
first open item.
UNCLEBOB.md sits beside it but looks at a different surface: what a harness
uses to prove itself. Robert C. Martin spent 2026 building SwarmForge — 331 commits, git
worktrees, a babashka handoff daemon, a constitution, nine pack/forge branches — and then on
2026-09-12 wrote that the need for it was obviated. What he kept is the finding: CRAP,
mutation, coverage, DRY, all as external deterministic tools, with a 6-line AGENTS.md whose
only rule is do not pin prompt prose with automated tests. Constraint by prose went down;
judgement by measurement did not. Measured the same day, pi-mono (TS, tests at 77% of
source, per-package test/) and herdr (Rust, #[cfg(test)] in 186 of 378 files, plus
python maintenance-test modules that gate CHANGELOG, config-reference and docs-translation
parity) reach the same shape in different languages — and none of the three gates on a
coverage percentage. That convergence is now lens 5 of harness-bench.
This file is the one bench document that deliberately crosses the no-verdict line, at
GLG's explicit request, because entwurf 0.23.0 and the herdr plugin 0.2.0 were shipping and
the standard had to exist before the user base widened. Its §D is material prepared for
entwurf 담당자 — coordinates and precedent, never an instruction — and it opens by naming the
line it crosses. No other NAME.md inherits that license.
/new + recall is the explicit cross-harness recovery path when a new session is the right boundary. It is not an alternative policy that suppresses in-session compaction.
- When a fresh session is preferable,
/newto start fresh - The index-authority Pi host requests one detached local session refresh at session start / native session search; it never waits, uses a timer, or publishes to Oracle. Run
memory-syncexplicitly only when fresh-now is required. - In the new session, recover context with
/recall
Compaction is an allowed lifecycle on every harness; agent-config and entwurf do not write a suppress/enable policy. The current surfaces are:
| Surface | Compaction key | Measured |
|---|---|---|
~/.claude/settings.json |
no compaction key at all | oracle, 2026-09-04 |
~/.pi/agent/settings.json (live) |
compaction.enabled: true |
oracle, 2026-09-04 |
pi/settings.json (this repo's reference) |
removed 2026-09-04 — was enabled: false |
this release |
entwurf retired autoCompactEnabled and env.DISABLE_AUTOCOMPACT from its managed settings in 0.17.2 (#94). That retirement leaves timing and enablement to the harness that owns them; it does not prescribe a state. pi/settings.json likewise carries no compaction key, so a fresh machine receives Pi defaults rather than a stale policy.
For Pi's openai-codex same-model sessions, @ogulcancelik/pi-codex-compaction strengthens the lifecycle: Pi still owns timing and continuation, but at Pi's normal compact boundary the extension requests Codex remote_compaction_v2, persists the returned opaque checkpoint in the Pi compaction entry, and rebuilds later Codex requests from that checkpoint plus the active tail. It activates for Codex only; other providers retain Pi's text-summary compaction. A malformed checkpoint, model-id mismatch, or failed native request fails closed rather than sending Pi's local marker or silently substituting text summarization. Receipt: on thinkpad, 2026-09-14, a 257,745-token Codex session completed native compaction with fromHook: true, details.kind: openai-codex-native-compaction, and details.version: 1. This is a Pi-only provider concern; /recall continues to serve the distinct job of crossing sessions and harnesses.
/recall is the multi-axis context hydration protocol owned by agent-config — not a per-session recap, not a entwurf bridge contract. It starts with session-recap -p <repo> -m 15 but does not stop at one repo transcript. When the work crossed projects or days, it combines:
session-recap— repo-local transcript extractor, no raw JSONLsession_search— cross-project / cross-session semantic recallknowledge_search/search-md— public garden md concepts, journal exports, botlog/llmlog-derived design historygitcli day --summary+denotecli day— day-axis reconstruction- journal
§repomarkers — sibling/담당자 call index
The answer must state which axes were seen and which were not. This keeps /recall token-light while avoiding false confidence from a plausible single-session summary.
The protocol itself lives in commands/recall.md. The 2026-05-08 derivation history and raw evidence log are kept as a Denote llmlog note (20260508T090911, ~/org/llmlog/) rather than as in-repo docs — /recall is a resident-side memory workflow, not a spec this repo carries. Renamed from /recap on 2026-05-12 to avoid shadowing Claude Code's built-in /recap (one-line session summary, feature-flagged via tengu_sedge_lantern); the two now coexist.
This repo also owns the resident-side policy for publishing session artifacts when GLG wants public verification of harness behavior.
entwurfowns bridge mechanism and invariants.agent-configowns export/review/upload workflow and publication criteria.- Goal: long-term trust through evidence — raw-session publication, reject history, and later failure/drift analysis.
- Minimum publication gates: secret redaction, deny patterns, secret scanning (e.g. TruffleHog), semantic privacy review, small-batch dry-run.
pi-share-hfis a strong reference shape for this pipeline.
# Claude Code + Telegram bridge
alias claude-tg='claude --channels plugin:telegram@claude-plugins-official'
alias claude-tgd='claude --channels plugin:telegram@claude-plugins-official --dangerously-skip-permissions'
# pi garden launcher helper — a --entwurf-control session needs NO id injection.
# pi mints its own session id (a uuidv7 is normal), session_start attaches it to
# its meta-record, and the RECORD mints the garden id and keys the control socket
# on it. The old `--session-id "$(run.sh new-session-id)"` form was retired in
# entwurf #50 C2; it gave a session two address-shaped strings, only one of which
# was an address. The wrapper is kept only so the variants below stay one edit wide.
_pi_garden_pi() { command pi "$@"; }
# pi: garden citizen with the agent Emacs socket
# (`pihome`, the --telegram presence variant, was dropped 2026-08-06 with the bridge)
pia() { _pi_garden_pi --entwurf-control --emacs-agent-socket server "$@"; }| Repo | Layer | Description |
|---|---|---|
| nixos-config | OS | NixOS flakes, hardware, services |
| doomemacs-config | Editor | Doom Emacs, org-mode, denote |
| zotero-config | Bibliography | 8,000+ references, bibcli |
| agent-config | Agent infra | Extensions, skills, themes, settings — this repo |
| entwurf | Provider (ACP bridge) | Default Claude path in pi. ACP bridge to Claude Code + Codex |
| andenken | Memory | Semantic memory — sessions + md public garden knowledge |
| memex-kb | Knowledge | Legacy document conversion pipeline |
| GLG-Mono | Font | Custom monospace programming font |
| geworfen | Being | Existence data viewer — WebTUI agenda |
| prime-agent | Runtime (fork) | RLM harness fork whose persistent workspace is Clojure/SCI on GraalVM instead of Python — the bench subject GLG builds rather than installs |
| sorge | Care | Sorge — the cross-repo view no single repository can hold. Owns the sorge skill this repo only links to |
| CLI | Repo | Language | Purpose |
|---|---|---|---|
| denotecli | junghan0611/denotecli | Go | Denote knowledge base search (3,000+ notes) |
| gitcli | junghan0611/gitcli | Go | Local git commit timeline (50+ repos) |
| lifetract | junghan0611/lifetract | Go | Samsung Health + aTimeLogger tracking |
| dictcli | junghan0611/dictcli | Clojure/GraalVM | Personal vocabulary graph (3,971 triples) |
| bibcli | junghan0611/zotero-config | Go | BibTeX search (8,000+ entries) |
- NEXT.md — volatile next-step anchor for the next session
- ROADMAP.md — medium-horizon tracks and direction
- CHANGELOG.md — closed history
- MODELS.md — the manually curated sibling-launch roster: active rails, spending order, and exact model selectors (
./run.sh modelschecks it against pi's live catalog)
See CHANGELOG.md.
MIT